在linux上为c ++构建和使用纯llvm工具链

Mik*_*eMB 5 c++ cmake llvm clang++

假设这是可能的,有人可以告诉我,我如何配置cmake构建以在ubuntu-16.04上创建一个"纯粹的"llvm工具链

  • LLD
  • 的libc ++
  • 的libc ++ ABI
  • libunwind(llvm)
  • 编译器RT
  • 任何其他可能相关并且"生产就绪"的部分

生成的编译器应该

  • 尽可能快(优化打开,编译器二进制本身没有不必要的断言或其他检查)
  • 安装在一个单独的本地目录中(让我们调用它<llvm_install>)
  • 不依赖于数据包管理器提供的llvm tolchain
  • 默认情况下使用libc ++,libc ++ abi等.
  • 支持清洁剂(ubsan,地址,内存,线程)(这可能意味着我必须第二次编译libc ++ )

到目前为止,我已经克隆了

  • llvm从http://llvm.org/git/llvm.git进入<llvm_root>
  • 铛从http://llvm.org/git/clang.git<llvm_root>/tools/clang
  • lld from http://llvm.org/git/lld.gitinto<llvm_root>/tools/lld
  • compile-rt,libcxx,libcxxabi,libunwind从http://llvm.org/git/<project_name>进入<llvm_root>/projects/<project_name>

然后在一个单独的目录中运行ccmake - 我尝试了各种设置,但是一旦我尝试了更多的花哨而不是转向优化,我几乎总会遇到某种构建错误.不幸的是,我还没有找到一种方法从ccmake导出我的更改,否则我会给你一个设置和错误的例子,但我对最佳实践更感兴趣,而不是修复我的测试配置.

加分点:默认情况下,这应该使用默认的g ++工具链构建,但如果能够提高最终工具链的性能(例如使用LTO),我也会对两阶段构建感兴趣.

顺便说一下:整个想法来自观看钱德勒的谈话
Pacific ++ 2017:Chandler Carruth"LLVM:一个现代的,开放的C++工具链"

com*_*por 4

我通常的程序是构建一个足够小的 LLVM/Clang,以便我可以使用libc++和进行工作libc++abi。我猜你可以使用系统提供的LLVM,但我没有尝试过。对于这一步,您签出的内容可能就足够了。一个示例脚本:

cmake
-G Ninja \
-DCMAKE_EXPORT_COMPILE_COMMANDS=On \
-DCMAKE_BUILD_TYPE=RelWithDebInfo \
-DBUILD_SHARED_LIBS=On \
-DLLVM_ENABLE_ASSERTIONS=Off \
-DLLVM_TARGETS_TO_BUILD="X86" \
-DLLVM_ENABLE_SPHINX=Off \
-DLLVM_ENABLE_THREADS=On \
-DLIBCXX_ENABLE_EXCEPTIONS=On \
-DLIBCXX_ENABLE_RTTI=On \
-DCMAKE_INSTALL_PREFIX=[path-to-install-dir] \
[path-to-source-dir]
Run Code Online (Sandbox Code Playgroud)

clang在环境变量中包含上述内容后PATH,您可以再次使用下面的构建脚本并根据您的需求(消毒剂等)进行调整。除了有关该主题的主要文档页面之外,浏览CMakeLists.txt每个相应工具也很有启发性,并有助于调整版本之间的构建过程。

LLVM_TOOLCHAIN_LIB_DIR=$(llvm-config --libdir)
LD_FLAGS=""
LD_FLAGS="${LD_FLAGS} -Wl,-L ${LLVM_TOOLCHAIN_LIB_DIR}"
LD_FLAGS="${LD_FLAGS} -Wl,-rpath-link ${LLVM_TOOLCHAIN_LIB_DIR}"
LD_FLAGS="${LD_FLAGS} -lc++ -lc++abi"

CXX_FLAGS=""
CXX_FLAGS="${CXX_FLAGS} -stdlib=libc++ -pthread"

CC=clang CXX=clang++ \
cmake -G Ninja \
-DCMAKE_EXPORT_COMPILE_COMMANDS=On \
-DBUILD_SHARED_LIBS=On \
-DLLVM_ENABLE_LIBCXX=On \
-DLLVM_ENABLE_LIBCXXABI=On \
-DLLVM_ENABLE_ASSERTIONS=On \
-DLLVM_TARGETS_TO_BUILD="X86" \
-DLLVM_ENABLE_SPHINX=Off \
-DLLVM_ENABLE_THREADS=On \
-DLLVM_INSTALL_UTILS=On \
-DLIBCXX_ENABLE_EXCEPTIONS=On \
-DLIBCXX_ENABLE_RTTI=On \
-DCMAKE_BUILD_TYPE=Debug \
-DCMAKE_CXX_FLAGS="${CXX_FLAGS}" \
-DCMAKE_SHARED_LINKER_FLAGS="${LD_FLAGS}" \
-DCMAKE_MODULE_LINKER_FLAGS="${LD_FLAGS}" \
-DCMAKE_EXE_LINKER_FLAGS="${LD_FLAGS}" \
-DCMAKE_POLICY_DEFAULT_CMP0056=NEW \
-DCMAKE_POLICY_DEFAULT_CMP0058=NEW \
-DCMAKE_INSTALL_PREFIX=${INSTALL_DIR} \
[path-to-source-dir]
Run Code Online (Sandbox Code Playgroud)

关于性能的说明:我还没有看过那个演讲,但是我在这个两步构建背后的动机是拥有一个可以在系统之间轻松重新定位的工具链,因为重要的最小系统依赖性是libc

最后,与上述过程相关的是我的这个旧问题,它仍然困扰着我。如果您对此有任何见解,请不要犹豫。

PS:脚本已经使用 LLVM 3.7 到 3.9 以及当前的 trunk 6.0.0 进行了测试。

更新:我也应用了这些建议,并且使用gold链接器而不是ld. LTO 也是一个推动因素。