未定义参考“pthread_create的' - 链接命令选项的顺序(?库目标文件后/前) [英] Undefined reference to 'pthread_create' — linker command option order (libraries before/after object files?)

查看:115
本文介绍了未定义参考“pthread_create的' - 链接命令选项的顺序(?库目标文件后/前)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我尝试编译,我收到一个特别的错误。但是,这是不可能的,因为我用的是右旗。在 server.c 有图书馆 pthreads.h中
所以,我怎么能解决我的问题链接?
我使用Linux(Ubuntu的)。

 制作
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:在函数'主':
/home/ruggero/ruggero_fine/Server.c:1002:未定义的引用`pthread_create的
collect2:劳工处返回1退出状态
使:*** [Server1.exe] Errore 1


解决方案

的目标文件后,库列表

当链接只有目标文件和库,列出库的目标文件后:

 的gcc -o Server1.exe -Wall -Wunused -ansi -pedantic -ggdb Server1.o Util.o -lpthread -lm

当连接命令包括源文件中,libaries之前列出源文件和目标文件(如有)。在 -l <​​/ code>选项来在命令行的末尾,因此。有关 -L 选项指定的地方图书馆发现应该在 -l <​​/ code>选项之前指定库。

该子公司的问题是:


  

为什么它的工作?


当C编译器将调用链接程序,它告诉链接器在某些系统中的目标文件来拉像的crt0.o 的名字,并告诉它寻找一个符号(或可能 _main(),根据当地的命名约定)。它还提供你在命令行上指定的顺序目标文件和库。当它遇到一个对象文件,链接器指出它提供的定义,它使不满意引用。当它遇到一个库,它会扫描库,看它是否能满足任何不满意的引用。如果库可以提供任何尚未满足的引用,那么它包括在可执行'库(的有关部分)。对于共享库,链接器确保库将在运行时加载。为一个静态库中,接头包括来自满足至少一个参考,重新扫描直到没有进一步的引用,可以得到满意的库中的对象的文件。如果库满足任何引用,它会被忽略。当这个过程完成后,如果任何引用仍然不满意,您得到的错误消息。

所以,在你的场景中,你有 -lpthread 之前为 Server1.o Util.o 。由于 -lpthread 不提供功能,这是唯一的相关不满意的象征,它被忽略了。数学库, -lm 也可能被忽略,或者它可能是一个空存根,以保持code设计用于其它系统,其中数学库是独立的主要的C库。然后连接器读取你的目标文件时,发现引用在pthread_create()。当它扫描C库 -lc libc.so )之后,它发现的符号来满足不同的<$一切C $ C>在pthread_create

在该库的目标文件后上市,那么链接器知道它需要在pthread_create 当扫描 -lpthread 并确保共享库将在运行时加载。

GNU LD - 按需选项

上面的讨论基本上是中性平台。如果你按照规则'的目标文件后库,你的连接线有在所有平台上正常工作的最大机会。

如果您使用的是GNU 的binutils 封装,GNU特别 LD 命令的系统上,你可能会发现不同的行为。

Sourceware (手动这是你在哪里,如果重定向您尝试 http://www.gnu.org/software/binutils/manuals )包括:信息:


  

- 按需结果
   - 无按需结果
  此选项会影响对之后,在命令行中提到的动态库ELF DT_NEEDED标签 - 按需选项。通常情况下,连接器将添加一个DT_NEEDED标签在命令行上提到的每一个动态库,无论库是否实际需要与否。 - 按需导致DT_NEEDED标签只能发出针对在链接点满足从常规目标文件中的非弱未定义的符号引用库或如果库没有在其他图书馆,从另一个动态库非弱未定义符号引用的DT_NEEDED名单中。出现问题的文库之后在命令行上的对象的文件或库不影响作为所需的库是否被看到。这类似于从存档的对象文件的提取的规则。 - 无按需还原默认的行为


看来,不同版本不同的系统使用不同的值对按需选项。而 - 无按需行为是,它可以让您订购库和目标在命令行上或多或少的任何命令,这也意味着文件方便在命令行上列出的所有库在运行时加载,即使没有从库(因此实际使用的符号 - 无按需相当于一个假设的 - 是否需要的有或没有标志)。使用 - 按需选项是经典和便携行为

有传言,一些Linux发行版从改变他们的系统上的默认行为 - 没有按需 - 按需的某个时候在过去的5年左右(上半年第三个千年的第二个十年,因为参数的缘故)。你可以找到所以在支持这一传闻中若干问题的证据。

When I try to compile that, I receive a particular error. But, it's not possible because I use the right flag. In server.c there is the library pthread.h. So, how can I resolve my linking problem? I'm using 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

解决方案

List libraries after the object files

When linking only object files and libraries, list the libraries after the object files:

gcc -o Server1.exe -Wall -Wunused -ansi -pedantic -ggdb  Server1.o Util.o -lpthread -lm

When the linking command includes source files, list the source files and object files (if any) before the libaries. The -l options come at the end of the command line, therefore. Relevant -L options specifying where a library is found should come before the -l option specifying the library.

The subsidiary question is:

Why does it work?

When the C compiler invokes the linker, it tells the linker to pull in some system object files with names like crt0.o, and tells it to look for a symbol main (or possibly _main(), depending on local naming conventions). It also supplies the object files and libraries in the order you specified on the command line. When it comes across an object file, the linker notes the definitions it provides, and the unsatisfied references it makes. When it comes across a library, it scans the library to see whether it can satisfy any unsatisfied references. If the library can supply any as yet unsatisfied references, then it includes (the relevant parts of) the library 'in the executable'. For a shared library, the linker ensures that the library will be loaded at runtime. For a static library, the linker includes the object files from the library that satisfy at least one reference, rescanning until there are no further references that can be satisfied. If the library satisfies no references, it is ignored. When the process is complete, if any references are still unsatisfied, you get the error messages.

So, in your scenario, you had -lpthread before either Server1.o or Util.o. Since -lpthread does not provide a main function and that was the only relevant unsatisfied symbol, it was ignored. The mathematics library, -lm may also have been ignored, or it may be an empty stub to keep code devised for other systems where the mathematics library is separate from the main C library. Then the linker read your object files, and found the reference to pthread_create(). When it scanned the C library -lc (libc.so) afterwards, it found symbols to satisfy everything except pthread_create.

When the libraries are listed after the object files, then the linker knew it needed pthread_create when it scanned -lpthread and ensured that the shared library would be loaded at runtime.

GNU ld and the --as-needed option

The discussion above is essentially platform-neutral. If you follow the 'libraries after object files' rule, your linker line has the maximum chance of working correctly on all platforms.

If you are on a system using the GNU binutils package, and the GNU ld command in particular, you may find different behaviour.

The manual from Sourceware (which is where you are redirected if you try http://www.gnu.org/software/binutils/manuals) includes the information:

--as-needed
--no-as-needed
This option affects ELF DT_NEEDED tags for dynamic libraries mentioned on the command line after the --as-needed option. Normally the linker will add a DT_NEEDED tag for each dynamic library mentioned on the command line, regardless of whether the library is actually needed or not. --as-needed causes a DT_NEEDED tag to only be emitted for a library that at that point in the link satisfies a non-weak undefined symbol reference from a regular object file or, if the library is not found in the DT_NEEDED lists of other libraries, a non-weak undefined symbol reference from another dynamic library. Object files or libraries appearing on the command line after the library in question do not affect whether the library is seen as needed. This is similar to the rules for extraction of object files from archives. --no-as-needed restores the default behaviour.

It appears that different versions of different systems use different values for the as-needed option. While the --no-as-needed behaviour is convenient in that it lets you order libraries and object files in more or less any order on your command line, it also means that all the libraries listed on the command line are loaded at run time, even if there are no symbols actually used from the library (thus --no-as-needed is equivalent to a hypothetical --whether-needed-or-not flag). Using the --as-needed option is the classic and portable behaviour.

Rumour has it that some Linux distributions changed the default behaviour on their systems from --no-as-needed to --as-needed sometime in the last 5 years or so (the first half of the second decade of the third millennium, for sake of argument). You can find evidence in support of this rumour in a number of questions on SO.

这篇关于未定义参考“pthread_create的' - 链接命令选项的顺序(?库目标文件后/前)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆