如何强制ang默认使用一些库? [英] How to force clang to use some library by default?

查看:174
本文介绍了如何强制ang默认使用一些库?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

通过 clang 反对 libc ++ libc ++ abi compiler-rt

要下载(和更新) 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


  • 首先,我建立 llvm clang libunwind / em>使用 gcc 并安装在 / usr / local 中。在所有以下步骤中,除了最后一个,我使用这个新鲜 clang / clang ++


  • 然后我单独构建 libunwind ,32位和64位版本(它们是必不可少的,因为 asan 在整个项目树的最终编译期间需要一些库的32位版本),并将其安装在 / usr / local / lib usr / local / lib32 (也分别更新 LD_LIBRARY_PATH )。

  • 建立libcxxrt ABI库32位和64位版本,并正确安装。

  • 建议使用libcxxrt

  • 然后为 libc ++ 建立 libc ++ abi 这两个32位元

  • 然后对 libc ++ abi 建立32位和64位版本的 libc ++

  • 毕竟我根据 libc ++ 构建整个项目树, libc ++ abi libunwind 编译器rt 并将其安装到 / usr / local



(我几乎可以肯定, / p>

在最后一步我有一个问题:我必须添加额外的参数到链接器(我添加到 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 like wrappers(类似于 clang ++ - libc ++ )来指定其他参数。我想要在 clang 二进制本身的某处硬编码库。

解决方案

p>有几个建议的解决方法。我结束了以下解决方法:

  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, - 整个归档libc ++。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:根保险丝。*
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.a.bak
sudo ln -svf /usr/local/lib/libc++.a /usr/local/lib/fuse.a

它合并所有使用的库( libc ++ libc ++ abi libunwind )写入单个 *。a *。 。然后 libc ++,a libc ++,因此被替换为(链接到)生成的汇编文件,可能的备份。



它对我来说是完美的。



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


I build clang by clang against libc++, libc++abi, compiler-rt in the following steps:

  • To download (and update) llvm and sub-projects I use the following script:

    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
    

  • First of all I build llvm, clang, libunwind against libgcc and libstdc++ using gcc and install them in /usr/local. In all the following steps except the last one I use this fresh clang/clang++.

  • Then I separately build libunwind, both the 32-bit and 64-bit versions (they are essential, as will be further, because asan needs the 32-bit versions of some libraries during the final compilation of the whole project tree) and install it in /usr/local/lib and /usr/local/lib32 correspondingly (also I update LD_LIBRARY_PATH respectively).
  • Build libcxxrt ABI library both 32-bit and 64-bit versions and install them properly.
  • Build libcxx against libcxxrt both 32-bit and 64-bit versions and install them properly.
  • Then build libc++abi against libc++ both 32-bit and 64-bit versions and install them properly.
  • Then build libc++ against libc++abi both 32-bit and 64-bit versions and install them properly over the previous version linked to libcxxrt.
  • After all I build the whole project tree against libc++, libc++abi, libunwind, compiler-rt and install it over old clang in /usr/local.

(I am almost sure that no step is redundant here.)

At the final step I have a problem: I have to add extra parameters to the linker (I add them to CMAKE_EXE_LINKER_FLAGS and CMAKE_SHARED_LINKER_FLAGS) -lunwind and -lc++abi. Moreover, every time I use the resulting clang++ with -stdlib=libc++ and compiler-rt (or, equally, CLANG_DEFAULT_CXX_STDLIB=libc++ and CLANG_DEFAULT_RTLIB=compiler-rt) in my projects I have to do it over and over. It annoying. Say Qt Creator generated project's CMakeLists.txt should be corrected by hand or by cmake-gui.

How to make clang driver to automatically specify these options to ld at runtime? Is there something similar to RPATH mechanism? Or is there some specific CMake variable (specified before llvm building process) to achieve desired behaviour?

Can I use RPATH for my purposes?

Surely I don't want to make some bash-script like wrappers (similar to clang++-libc++) to specify additional parameters. I want the libraries to be hardcoded somewhere in the clang binary itself.

解决方案

There are a couple of workarounds have been suggested. I ended up with the following workaround:

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

It merges all the libraries used (libc++, libc++abi and libunwind) into the one single *.a or *.so file. Then libc++.a and libc++.so are replaced with (links to) resulting assemblied files, saving a previous versions for possible backup.

It works perfectly for me.

But this is not the answer. Maybe someday clang will not have such a problem right from the box.

这篇关于如何强制ang默认使用一些库?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆