【问题标题】:Linker returning "Undefined symbols" for symbols that are in a library being linked链接器为正在链接的库中的符号返回“未定义的符号”
【发布时间】:2014-01-16 06:43:34
【问题描述】:

我正在 Mavericks 上编译 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++?

【问题讨论】:

  • -L 开关告诉链接器在/opt/local/lib 中查找libstdc++,但您拥有的libstdc++ 可能在/usr/lib 中。

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


【解决方案1】:

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-08
    • 2010-09-17
    • 2013-10-01
    相关资源
    最近更新 更多