pak*_*ade 2 ubuntu linker dynamic-library
我在我的Ubuntu系统中写了这样的代码:
我的.h
#include <stdio.h>
int a;
int set(void);
Run Code Online (Sandbox Code Playgroud)
库文件
#include "my.h"
int set(void) {
a = 100;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
主程序
#include "my.h"
int main(void){
set();
printf("a = %d\n", a);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
然后我使用以下命令来构建它们:
gcc -shared -fPIC -o libmy.so -I. lib.c
gcc -L. -lmy -I. -o test main.c
Run Code Online (Sandbox Code Playgroud)
当我构建测试时,我收到错误信息:
main.c:(.text+0x5):undefined reference to 'set'
collect2: error: ld returned 1 exit status
Run Code Online (Sandbox Code Playgroud)
但是当我使用在 Fedora23 和 Fedora24 中运行的相同代码时,它运行良好。
所以我想知道为什么会发生这种情况?Ubuntu系统有什么限制吗?
您已经遇到了 Fedora 的 GCC 构建和 Debian/Ubuntu 的 GCC 构建之间的链接约定之间的差异。
当您调用gcc执行 C 可执行文件的链接时,它会依次调用系统链接器
,将命令行链接选项传递给它,并默默地向其中添加大量“样板”链接选项,这些选项对于 C 语言链接是不变的(对于 C ++ 和 C++ld也是如此)g++语言联系)。
这些不变的链接选项由您的发行版决定并配置到其 GCC 版本中。因此它们在各个发行版中并不是一成不变的。
Debian/Ubuntu GCC--as-needed在输入文件和库之前的位置默默地添加链接选项。Fedora 的 GCC 没有。
其作用--as-needed是使链接器链接它在链接序列中找到的共享库,前提是该库提供了一个或多个符号的定义,而链接器已经找到了未定义的引用(即在链接序列中较早的目标文件或库中)。连接序列)。此行为在任何情况下都适用于静态库。因此,--as-needed静态库和共享库的链接规则相似——这可能对普通用户有帮助。
这种差异是发行版之间的链接策略差异。这对您意味着要在 Ubuntu 上成功链接,您的链接命令行必须在任何对象文件或依赖于它的其他库之后提及任何库。如果您在一个命令中进行编译和链接,那么您必须在其对应的目标文件依赖于该库的任何源文件之后提及该库。所以在 ubuntu 上,你的问题命令行应该是:
gcc -I. -o test main.c -L. -lmy
Run Code Online (Sandbox Code Playgroud)
成功。这当然也适用于 Fedora。
如果您有兴趣检查两个发行版之间的链接选项中隐藏的差异,您可以通过添加到-Wl,-v编译和链接命令来获取详细的链接器输出来揭示它们。
| 归档时间: |
|
| 查看次数: |
4736 次 |
| 最近记录: |