未定义参考“pthread_create的' - 链接命令选项的顺序(?库目标文件后/前) [英] Undefined reference to 'pthread_create' — linker command option order (libraries before/after object files?)
问题描述
当我尝试编译,我收到一个特别的错误。但是,这是不可能的,因为我用的是右旗。在 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 librarypthread.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 symbolmain
(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 eitherServer1.o
orUtil.o
. Since-lpthread
does not provide amain
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 topthread_create()
. When it scanned the C library-lc
(libc.so
) afterwards, it found symbols to satisfy everything exceptpthread_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
optionThe 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 GNUld
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屋!