【问题标题】:How to force clang to use some library by default?如何强制 clang 默认使用某些库?
【发布时间】:2017-02-04 14:44:56
【问题描述】:

我通过 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 32 位和 64 位版本构建 libcxx 并正确安装它们。
  • 然后针对 libc++ 32 位和 64 位版本构建 libc++abi 并正确安装它们。
  • 然后针对 32 位和 64 位版本的 libc++abi 构建 libc++,并在链接到 libcxxrt 的先前版本上正确安装它们em>。
  • 毕竟我针对libc++、libc++abi、libunwind、compiler-rt构建了整个项目树em> 并将其安装在 /usr/local 中的旧 clang 上。

(我几乎可以肯定这里没有多余的步骤。)

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

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

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

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

【问题讨论】:

  • 如果您使用的是 Linux,只需将类似 INPUT(libc++.so.1 -lc++abi -lunwind) 的内容放入您的 libc++.so
  • @SK-logic 这是一个很好的解决方法。很可能我必须使用它,但另外我想通过 llvm 构建的配置找到一种方法。
  • 我不认为有一个神奇的变量可以做到这一点(至少不是一眼就能找到的东西),但它肯定可以通过修补 lib/Driver/Tools.cpp 来完成,各种标准库都在那里硬编码。
  • 现在我想我可以将libc++.a、libc++abi.a 和libunwind.a 合并到一个libc++.a 文件中。但是*.so怎么处理呢?
  • 是的,如果您在 Linux 上使用,请将 INPUT(libc++.so.1 -lc++abi -lunwind) 放入您的 libc++。

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


【解决方案1】:

建议了几种解决方法。我最终得到了以下解决方法:

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++abi 和 libunwind)合并到一个 *.a 或 *.so 文件中。然后libc++.a 和libc++.so 被替换为(链接到)生成的汇编文件,保存以前的版本以供可能的备份。

它非常适合我。

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

【讨论】:

    猜你喜欢
    • 2011-01-10
    • 2016-11-12
    • 1970-01-01
    • 2014-09-10
    • 1970-01-01
    • 1970-01-01
    • 2023-03-09
    • 2018-02-02
    • 2012-09-04
    相关资源
    最近更新 更多