当我尝试编译时,我收到一个特定的错误。 但是,这是不可能的,因为我使用正确的标志。 在server.c有库pthread.h 。 那么,我该如何解决我的链接问题呢? 我正在使用Linux(Ubuntu)。
make gcc -c -Wall -Wunused -ansi -pedantic -ggdb -o Server1.o Server.c gcc -c -Wall -Wunused -ansi -pedantic -ggdb Util.c gcc -o Server1.exe -Wall -Wunused -ansi -pedantic -ggdb -lpthread -lm Server1.o Util.o Server1.o: In function `main': /home/ruggero/ruggero_fine/Server.c:1002: undefined reference to `pthread_create' collect2: ld returned 1 exit status make: *** [Server1.exe] Errore 1
ld-linux.so以什么顺序search共享库?
在GNU / Linux上连接插件时如何巧妙地检测未定义的符号?
链接器如何确定.rodata节中某些数据的地址?
为什么剥离的二进制文件仍然可以在反汇编的文件中有库调用信息?
链接时LD_LIBRARY_PATH和-L有什么区别?
在目标文件之后列出库
gcc -o server1.exe -Wall -Wunused -ansi -pedantic -ggdb server1.o Util.o -lpthread -lm
当链接命令包含源文件时,在libaries之前列出源文件和目标文件(如果有的话)。 因此, -l选项位于命令行的末尾。 指定找到库的相关-L选项应位于指定库的-l选项之前。
附属问题是:
为什么它工作?
当C编译器调用链接器时,它会告诉链接器将一些名称为crt0.o系统对象文件提取出来,并告诉它寻找一个符号main (或可能是_main() ,这取决于本地命名约定)。 它还按照您在命令行上指定的顺序提供对象文件和库。 当遇到目标文件时,链接器会记录它提供的定义以及它所做的不满意的引用。 当它遇到一个图书馆,它扫描图书馆,看它是否能满足任何不满意的参考。 如果图书馆可以提供任何尚未满足的参考资料,那么它包括图书馆(在可执行文件中)的相关部分。 对于共享库,链接器确保库在运行时被加载。 对于静态库,链接器包含库中的至少满足一个引用的对象文件,重新扫描直到没有可以满足的更多引用。 如果库不满足引用,则忽略它。 当过程完成时,如果任何引用仍然不满意,您会收到错误消息。
所以,在你的场景中,你已经在server1.o或Util.o之前使用了-lpthread 。 由于-lpthread不提供main功能,这是唯一的相关不满意的符号,它被忽略。 数学库-lm也可能被忽略,或者它可能是一个空的存根,为其他数学库与主C库分离的系统设计代码。 然后链接器读取您的对象文件,并找到对pthread_create()的引用。 之后当它扫描C库-lc ( libc.so )时,发现符号满足除pthread_create之外的所有内容。
当这些库在对象文件之后列出时,链接器在扫描-lpthread时知道它需要pthread_create ,并确保在运行时加载共享库。
GNU ld和--as-needed选项
上面的讨论基本上是平台中立的。 如果您按照“对象文件之后的库”规则,则链接器行在所有平台上都有最大可能正常工作。
如果您使用的是GNU binutils软件包,特别是GNU ld命令,则可能会发现不同的行为。
来自Sourceware的手册(如果您尝试使用http://www.gnu.org/software/binutils/manuals ,则是您重定向的地方)包含以下信息:
--as-needed
--no-as-needed
此选项会影响在--as-needed选项之后在命令行中提到的动态库的ELF DT_NEEDED标记。 通常,链接器将为命令行中提到的每个动态库添加一个DT_NEEDED标记,而不管该库是否实际需要。 --as-needed会导致DT_NEEDED标记仅在链接中的某个库满足来自常规对象文件的非弱定义符号引用的库时发出,或者如果在其他DT_NEEDED列表中找不到该库库,来自另一个动态库的非弱的未定义符号引用。 在问题库之后的命令行中出现的对象文件或库不会影响库是否被视为需要。 这与从档案中提取目标文件的规则类似。 --no-as-needed恢复默认行为。
看来不同版本的不同系统使用不同的值as-needed选项。 尽管“ --no-as-needed行为是非常方便的,因为它允许您在命令行上以或多或少顺序排列库和对象文件,这也意味着命令行上列出的所有库在运行时都会加载,即使从库中没有实际使用的符号(因此--no-as-needed就相当于一个假设的--whether-needed-or-not标志)。 使用--as-needed选项是经典和可移植的行为。
有传言说,有些Linux发行版在过去的5年左右(第三个千年的第二个十年的前半部分)将其系统中的默认行为从“ --no-as-needed改为“ --as-needed ”争论的缘故)。 你可以在SO的许多问题上找到支持这个谣言的证据。
编译时使用-pthread。 试试看,你会解决你的问题
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。