简体   繁体   English

多个已定义符号的C / C ++链接器顺序

[英]C/C++ linker order for multiple defined symbols

If I have the same symbol defined in an object file and in a library the GNU linker takes the symbol from the object file. 如果我在目标文件和库中定义了相同的符号,GNU链接器将从目标文件中获取符号。 Consider this example: 考虑这个例子:

g++ -L"dir/to/lib" -o Executable Test.o foo.o -lMyLib

If I have defined a function foo with the same signature in both foo.cpp and in a source file "MyLib" was compiled from, the GNU linker always prefers the one from the former if I use this order. 如果我在foo.cpp中定义了一个具有相同签名的函数foo ,并且在源文件中编译了“MyLib”,那么如果我使用这个顺序,GNU链接器总是更喜欢前一个。

Is this behaviour GNU toolchain specific? 这种行为GNU工具链是否具体? Do you know from other linkers that behave the same way? 您是否知道其他连接器的行为方式相同? Is this anywhere documented (GNU documentation, C++ standard)? 这是否记录在案(GNU文档,C ++标准)? I couldn't find anything... 我找不到任何东西......

I would like to use this feature to replace/mock certain functions while doing unit testing (aka link seam). 我想在进行单元测试(也就是链接接缝)时使用此功能来替换/模拟某些功能。

From http://gcc.gnu.org/onlinedocs/gcc/Link-Options.html : 来自http://gcc.gnu.org/onlinedocs/gcc/Link-Options.html

"the linker searches and processes libraries and object files in the order they are specified" “链接器按照指定的顺序搜索和处理库和目标文件”

Maybe. 也许。

Exactly how the linker processes the files it was given depends on the linker, but in the exact case you've described, I don't think there will be any variation. 链接器处理文件的确切方式取决于链接器,但在您描述的确切情况下,我认为不会有任何变化。 When you specify an object file, it is included into your final build, and you will get any symbols it defines from it; 当您指定的目标文件,它包含到您的最终版本,你会得到它从它定义的任何符号; if two object files define the same symbol, you will normally get an error from the linker (but there are exceptions, due to weak symbols or Fortran-like handling of data definitions). 如果两个目标文件定义相同的符号,通常会从链接器中获得错误(但由于弱符号或类似Fortran的数据定义处理,因此存在异常)。 A library is a collection of object files; 库是对象文件的集合; the standard handling of a library is for the linker to scan it, and incorporate any objects (and only those objects) which define an otherwise undefined external. 库的标准处理是链接器扫描它,并合并任何定义其他未定义外部的对象(并且只包含那些对象)。 If the object file in the library only defines the symbol in question, and its definition has already been resolved by an explicitly specified object file, the linker will not incorporate the object file from the library into the program. 如果库中的目标文件仅定义了相关符号,并且其定义已由显式指定的目标文件解析,则链接器将不会将库中的目标文件合并到程序中。 If the object file in the library also defines other symbols, however, and one of those resolves an otherwise undefined external, the object file from the library will be incorporated into your program, along with all of the symbols it defines. 但是,如果库中的目标文件也定义了其他符号,并且其中一个符号解析了未定义的外部符号,则库中的目标文件将与其定义的所有符号一起合并到程序中。 Which could lead to multiple definitions. 这可能导致多种定义。

By the language standpoint, the "linking order" is unspecified, and cannot be used in reliable way. 从语言的角度来看,“链接顺序”是未指定的,不能以可靠的方式使用。

By a platform (toolchain) standpoint it has to be somehow specifyed, and -usually- it consider libraries for all symbols not resolved in objects and objects for all symbold not locally resolved. 通过平台(工具链)的观点,它必须以某种方式指定,并且 - 通常 - 它考虑所有未在本地解析的所有symbold的对象和对象中解析的所有符号的库。 This allow a developer to mask/replace library functions. 这允许开发人员屏蔽/替换库函数。

Right now, gcc (as msvc) links in the same order of the command line that launches the linker. 现在,gcc(作为msvc)以启动链接器的命令行的相同顺序链接。 Whether this behavior can be "trusted" (in the sense it will be maintained in future releases) is not clear. 这种行为是否可以“信任”(从某种意义上说,它将在未来的版本中保留)尚不清楚。 (The GCC documentation is written using present verbs...) (GCC文档使用现有动词编写......)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM