链接器为链接的库中的符号返回“未定义的符号”

时间:2014-01-16 06:43:34

标签: macos clang linker-errors libstdc++ libc++

我正在为小牛队编译OpenTTD。我所做的唯一改变是定义CXXFLAGS =“ - stdlib = stdc ++”。链接时,我收到许多链接器错误,如下所示:

  "std::string::compare(char const*) const", referenced from:
     LoadTranslations() in game_text.o
     IsSameScript(ContentInfo const*, bool, ScriptInfo*, Subdirectory) in script_scanner.o
  "std::string::compare(unsigned long, unsigned long, char const*) const", referenced from:
     LoadTranslations() in game_text.o

但是,我知道这些符号应该在libstdc ++中,它是链接的:

$ nm -a /usr/lib/libstdc++.dylib  | c++filt | grep "std::string::compare"
000000000002ed12 T std::string::compare(char const*) const
000000000002ec02 T std::string::compare(std::string const&) const
000000000002ed68 T std::string::compare(unsigned long, unsigned long, char const*) const
000000000002ede6 T std::string::compare(unsigned long, unsigned long, char const*, unsigned long) const
000000000002ec44 T std::string::compare(unsigned long, unsigned long, std::string const&) const
000000000002eca4 T std::string::compare(unsigned long, unsigned long, std::string const&, unsigned long, unsigned long) const

我知道libstdc ++正在链接中,正如我在链接器调用中看到的-lstdc ++(使用“make VERBOSE = 1”):

g++ -L/opt/local/lib  -framework Cocoa  3rdparty/md5/md5.o <lots of .o files> video/cocoa/wnd_quickdraw.o   -lstdc++ -lc -F/System/Library/Frameworks -framework Cocoa -framework Carbon -framework AudioUnit -framework AudioToolbox -lz -L/opt/local/lib -llzma    -llzo2 -L/opt/local/lib -lpng15  -L/opt/local/lib -lfreetype -lz -lbz2  -L/opt/local/lib  -licui18n -licuuc -licudata  -licule -liculx   -o openttd

我正在使用当前版本的clang:

Apple LLVM version 5.0 (clang-500.2.78) (based on LLVM 3.3svn)
Target: x86_64-apple-darwin13.0.0
Thread model: posix

为什么链接器不匹配丢失的符号及其在libstdc ++中的定义?

编辑:我手动运行上面的GCC命令,这次手动将-stdlib = stdc ++添加到命令行的末尾,它运行得很好。我知道顺序很重要,但哪个标志会覆盖早期的-stdlib = stdc ++?

1 个答案:

答案 0 :(得分:0)

  

我知道顺序很重要,但哪些标志会覆盖早期的-stdlib = stdc ++?

猜测,我希望Clang的行为与g++类似,并在链接器命令中添加一些内容以链接到标准库。 g++在您指定的所有库之后添加-lstdc++,因此Clang可能默认添加-lc++-lstdc++,具体取决于您使用的stdlib的值。如果你想要添加-lstdc++,它甚至可以过滤掉你指定的任何-lc++,所以如果你想让Clang可靠地链接到正确的库,你需要使用正确的选项,而不是试图通过-lstdc++手动。

您可以将-v添加到clang命令中,它应该显示它用于调用链接器的精确命令,包括隐式添加的任何选项。