如何强制clang默认使用某个库?

时间:2016-09-27 05:33:42

标签: c++ build clang llvm clang++

我通过 clang libc ++ libc ++ abi compiler-rt构建 clang 以下步骤:

  • 要下载(和更新) llvm 和子项目,我使用以下脚本:

    svn co http://llvm.org/svn/llvm-project/llvm/trunk llvm
    cd llvm/tools
    svn co http://llvm.org/svn/llvm-project/cfe/trunk clang
    svn co http://llvm.org/svn/llvm-project/clang-tools-extra/trunk clang/tools/extra
    svn co http://llvm.org/svn/llvm-project/lldb/trunk lldb
    svn co http://llvm.org/svn/llvm-project/lld/trunk lld
    svn co http://llvm.org/svn/llvm-project/polly/trunk polly
    cd ../projects/
    svn co http://llvm.org/svn/llvm-project/compiler-rt/trunk compiler-rt
    svn co http://llvm.org/svn/llvm-project/libunwind/trunk libunwind
    svn co http://llvm.org/svn/llvm-project/openmp/trunk openmp
    svn co http://llvm.org/svn/llvm-project/libcxxabi/trunk libcxxabi
    svn co http://llvm.org/svn/llvm-project/libcxx/trunk libcxx
    
  • 首先,我针对 libgcc 构建 llvm clang libunwind libstdc ++ 使用 gcc 并将其安装在/usr/local中。在除了最后一个步骤之外的所有其他步骤中,我使用了这个新的clang / clang++

  • 然后我分别构建 libunwind ,32位和64位版本(它们是必不可少的,因为 asan 需要32位在整个项目树的最终编译期间,一些库的版本)并相应地安装在/usr/local/lib/usr/local/lib32中(我也分别更新LD_LIBRARY_PATH)。
  • 构建 libcxxrt ABI库32位和64位版本并正确安装。
  • 针对 libcxxrt 构建 libcxx 32位和64位版本并正确安装。
  • 然后针对 libc ++ 构建 libc ++ abi 32位和64位版本并正确安装。
  • 然后针对 libc ++ abi 构建 libc ++ 32位和64位版本,并在链接到 libcxxrt
  • 毕竟我构建整个项目树来对抗 libc ++ libc ++ abi libunwind compiler-rt 并将其安装在/usr/local
  • 中的旧 clang

(我几乎可以肯定这里没有任何步骤。)

在最后一步,我遇到了一个问题:我必须向链接器添加额外的参数(我将它们添加到CMAKE_EXE_LINKER_FLAGSCMAKE_SHARED_LINKER_FLAGS-lunwind-lc++abi。此外,每次我在项目中使用生成的clang++ -stdlib=libc++编译器-rt (或者同等地,CLANG_DEFAULT_CXX_STDLIB=libc++CLANG_DEFAULT_RTLIB=compiler-rt)我必须一遍又一遍地做。这很烦人。说 Qt Creator 生成的项目CMakeLists.txt应该由手或cmake-gui更正。

如何让clang驱动程序在运行时自动为ld指定这些选项?有没有类似于RPATH机制的东西?或者是否有一些特定的 CMake 变量(在 llvm 构建过程之前指定)以实现所需的行为?

我可以将RPATH用于我的目的吗?

当然,我不想像包装器(类似于clang++-libc++)那样制作一些 bash -script来指定其他参数。我希望库在clang二进制文件本身的某处硬编码。

1 个答案:

答案 0 :(得分:2)

已经提出了几种解决方法。我最终得到了以下解决方法:

mkdir build
cd build
# backup:
cp -vaf /usr/local/lib/libc++.{a,so.1.0} /usr/local/lib/libc++abi.{a,so.1.0} /usr/local/lib/libunwind.{a,so.1.0} .
clang -shared -fPIC -pthread -o fuse.so -Wl,--whole-archive libc++.a libc++abi.a libunwind.a -Wl,--no-whole-archive -ldl -lm
ar x libc++.a
ar x libc++abi.a
ar x libunwind.a
ar rc fuse.a *.o
sudo chown root:root fuse.*
sudo cp -vaf fuse.so /usr/local/lib/
sudo ln -svf /usr/local/lib/libc++.so.1 /usr/local/lib/fuse.so
sudo cp -vaf fuse.a /usr/local/lib/
sudo mv -vf /usr/local/lib/libc++.a /usr/local/lib/libc++.a.bak
sudo ln -svf /usr/local/lib/libc++.a /usr/local/lib/fuse.a

它将所有使用的库(libc++libc++abilibunwind)合并到一个*.a*.so文件中。然后将libc++.alibc++.so替换为(链接到)生成的汇编文件,保存以前的版本以进行可能的备份。

它非常适合我。

但这不是答案。也许有一天clang不会出现这样的问题。