【问题标题】:clang appears not to be linking to a libraryclang 似乎没有链接到图书馆
【发布时间】:2015-09-09 00:48:14
【问题描述】:

我将问题归结为以下示例:

int main()
{
    try {
        throw false;
    } catch (bool x)
    {
        if (x)
        {
            return 0;
        }
        else
        {
            return 1;
        }
    }
}

Coliru 上生成以下错误:

/tmp/main-c8b47a.o: In function `main':
main.cpp:(.text+0xf): undefined reference to `typeinfo for bool'
/tmp/main-c8b47a.o: In function `GCC_except_table0':
main.cpp:(.gcc_except_table+0x30): undefined reference to `typeinfo for bool'
clang: error: linker command failed with exit code 1 (use -v to see invocation)

命令行:

clang++ -std=c++11 -stdlib=libc++ -O2 -Wall -pedantic -pthread main.cpp && ./a.out

这听起来好像没有链接到库。有谁知道命令行开关是哪个和什么?我以前没用过clang。这在 g++ 下有效。

这是带有 -v 开关的输出:

clang version 3.6.0 (tags/RELEASE_360/final 235480)
Target: x86_64-unknown-linux-gnu
Thread model: posix
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/4.6
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/4.6.4
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/4.7
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/4.7.3
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/4.8
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/4.8.1
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/4.9
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/4.9.2
Found candidate GCC installation: /usr/local/bin/../lib/gcc/x86_64-unknown-linux-gnu/4.8.2
Found candidate GCC installation: /usr/local/bin/../lib/gcc/x86_64-unknown-linux-gnu/4.9.0
Found candidate GCC installation: /usr/local/bin/../lib/gcc/x86_64-unknown-linux-gnu/4.9.2
Found candidate GCC installation: /usr/local/bin/../lib/gcc/x86_64-unknown-linux-gnu/5.1.0
Found candidate GCC installation: /usr/local/bin/../lib/gcc/x86_64-unknown-linux-gnu/5.2.0
Selected GCC installation: /usr/local/bin/../lib/gcc/x86_64-unknown-linux-gnu/5.2.0
Candidate multilib: .;@m64
Selected multilib: .;@m64
 "/usr/local/bin/clang" -cc1 -triple x86_64-unknown-linux-gnu -emit-obj -disable-free -disable-llvm-verifier -main-file-name main.cpp -mrelocation-model static -mthread-model posix -fmath-errno -masm-verbose -mconstructor-aliases -munwind-tables -fuse-init-array -target-cpu x86-64 -target-linker-version 2.22 -momit-leaf-frame-pointer -v -dwarf-column-info -resource-dir /usr/local/bin/../lib/clang/3.6.0 -internal-isystem /usr/include/c++/v1 -internal-isystem /usr/local/include -internal-isystem /usr/local/bin/../lib/clang/3.6.0/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wall -pedantic -std=c++11 -fdeprecated-macro -fdebug-compilation-dir /tmp/1441759762.34715 -ferror-limit 19 -fmessage-length 0 -pthread -mstackrealign -fobjc-runtime=gcc -fcxx-exceptions -fexceptions -fdiagnostics-show-option -vectorize-loops -vectorize-slp -o /tmp/main-47c098.o -x c++ main.cpp
clang -cc1 version 3.6.0 based upon LLVM 3.6.0 default target x86_64-unknown-linux-gnu
ignoring nonexistent directory "/include"
#include "..." search starts here:
#include <...> search starts here:
 /usr/include/c++/v1
 /usr/local/include
 /usr/local/bin/../lib/clang/3.6.0/include
 /usr/include/x86_64-linux-gnu
 /usr/include
End of search list.
 "/usr/bin/ld" --eh-frame-hdr -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o a.out /usr/lib/x86_64-linux-gnu/crt1.o /usr/lib/x86_64-linux-gnu/crti.o /usr/local/bin/../lib/gcc/x86_64-unknown-linux-gnu/5.2.0/crtbegin.o -L/usr/local/bin/../lib/gcc/x86_64-unknown-linux-gnu/5.2.0 -L/usr/local/bin/../lib/gcc/x86_64-unknown-linux-gnu/5.2.0/../../../../lib64 -L/usr/local/bin/../lib64 -L/lib/x86_64-linux-gnu -L/lib/../lib64 -L/usr/lib/x86_64-linux-gnu -L/usr/local/bin/../lib/gcc/x86_64-unknown-linux-gnu/5.2.0/../../.. -L/usr/local/bin/../lib -L/lib -L/usr/lib /tmp/main-47c098.o -lc++ -lm -lgcc_s -lgcc -lpthread -lc -lgcc_s -lgcc /usr/local/bin/../lib/gcc/x86_64-unknown-linux-gnu/5.2.0/crtend.o /usr/lib/x86_64-linux-gnu/crtn.o
/tmp/main-47c098.o: In function `main':
main.cpp:(.text+0xf): undefined reference to `typeinfo for bool'
/tmp/main-47c098.o: In function `GCC_except_table0':
main.cpp:(.gcc_except_table+0x30): undefined reference to `typeinfo for bool'
clang: error: linker command failed with exit code 1 (use -v to see invocation)

【问题讨论】:

  • 你是如何安装 Clang 和 libc++ 的?你知道 Clang 使用的是哪个 ABI 库吗?您可以尝试添加例如-lc++abi?
  • @JoachimPileborg,我没有安装。我从 SO 获得了一个在线编译器的链接。看起来如果我删除-stdlib=libc++,它会起作用。嗯。为什么会这样?
  • 添加您指定的开关也不起作用。错误:/usr/bin/ld: cannot find -lc++abi
  • 编译器可以在这里找到:coliru.stacked-crooked.com

标签: c++ c++11 clang++


【解决方案1】:

看来你需要在main.cpp后面加上-lsupc++(see it live):

clang++ -std=c++11  -stdlib=libc++ -O2 -Wall -pedantic -pthread main.cpp -lsupc++
                                                                         ^^^^^^^^

正如 Andre Kostur 所说,libc++ documentation 推荐以下内容,尽管我似乎无法在 Coliru 上使用它:

不幸的是,你不能简单地用“-stdlib=libc++”运行clang 点,因为 clang 设置为链接 libc++ 链接到 libsupc++。到 解决这个问题,您必须自己设置链接器(或补丁 铛)。例如,

  • clang++ -stdlib=libc++ helloworld.cpp -nodefaultlibs -lc++ -lcxxrt -lm -lc -lgcc_s -lgcc

或者,您可以将 libcxxrt 添加到您的库列表中,这 在大多数情况下会给出相同的结果:

  • clang++ -stdlib=libc++ helloworld.cpp -lcxxrt

这看起来与此线程 Making libc++ on Linux user-friendly 中正在讨论的问题有关,下面有选择性的引号:

问题是:在构建 libc++ 时,链接器会发现各种 ABI 在 libstdc++ 中运行,并且对它们的存在感到非常满意。 但是,当 Clang 为实际程序调用链接器时,它并没有 传递 libstdc++ 的链接标志,仅适用于 libc++。因此,链接 失败。

和:

这又可以通过明确指定对源库的链接来解决,这里 -lsupc++ 有效。

另见Linux equivalent of Windows DLL forwarders or MacOS reexport_library

【讨论】:

  • 有趣的是,clang 人(libcxx.llvm.org)提倡使用不同的命令行:clang++ -stdlib=libc++ helloworld.cpp -nodefaultlibs -lc++ -lcxxrt -lm -lc -lgcc_s -lgcc 或者,您可以将 libcxxrt 添加到您的库列表中,在大多数情况下会得到相同的结果:clang++ -stdlib=libc++ helloworld.cpp -lcxxrt
  • @AndreKostur 我在回答中添加了该注释,但它对 Coliru 不起作用,我不清楚为什么。
猜你喜欢
  • 2012-07-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多