7

Assuming this is possible, could someone tell me, how I have to configure the cmake build to create a "pure" llvm toolchain on ubuntu-16.04 consisting of

  • clang
  • lld
  • libc++
  • libc++abi
  • libunwind (llvm)
  • compiler-rt
  • any other pieces that might be relevant and are "production ready"

The resulting compiler should

  • be as fast as possible (optimizations turned on, no unnecessary asserts or other checks in the compiler binary itself)
  • be installed in a separate, local directory (lets call it <llvm_install>)
  • not have dependencies to the llvm tolchain provided by packet manager
  • use libc++, libc++abi etc by default.
  • support the sanitizers (ubsan, address, memory, thread) (which probably means that I have to compile libc++ a second time)

So far I have cloned

  • llvm from http://llvm.org/git/llvm.git into <llvm_root>
  • clang from http://llvm.org/git/clang.git into <llvm_root>/tools/clang
  • lld from http://llvm.org/git/lld.git into <llvm_root>/tools/lld
  • compiler-rt, libcxx, libcxxabi, libunwind from http://llvm.org/git/<project_name> into <llvm_root>/projects/<project_name>

Then run ccmake in a separate directory - I have tried various settings, but as soon as I try anything more fancy beyond turning optimizations on, I almost always get some sort of build error. Unfortunately, I have yet to find a way to export my changes from ccmake otherwise I'd give you an example with the settings and according error, but I'm more interested in a best practice than a fix to my test configs anyway.

Bonus points: By default, this should build with the default g++ toolchain, but I'd also be interested in a two stage build if that improves the performance of the final toolchain (e.g. by using LTO).

Btw.: The whole Idea came from watching chandler's talk
Pacific++ 2017: Chandler Carruth "LLVM: A Modern, Open C++ Toolchain"

MikeMB
  • 20,029
  • 9
  • 57
  • 102
  • I just compiled trunk (6.0) successfully with the commands mentioned in my answer below. The only unused variable was ```LLVM_ENABLE_LIBCXXABI```, but it didn't affect the build. – compor Nov 24 '17 at 20:49
  • I realize this isn't an answer, but a while ago I tried this because I wanted 17 features, my IDE uses clang for auto-completion etc, and clang didn't do well with compiling libstdc++ implementations of 17 features. I write C++ professionally and have been involved in sorting out various linker/ RPATH/RUNPATH/LD_LIBRARY kind of woes in the past. I couldn't find a pre-compiled version of libc++ newer than 3.8 for ubuntu. After multiple of hours of trying to get it all to work I quit in disgust. I ended up using libstdc++ 7.2, with clang 5.0 or something like that, it worked ok. – Nir Friedman Feb 26 '18 at 20:39

1 Answers1

4

My usual procedure is to build a small enough LLVM/Clang so that I have something working with libc++ and libc++abi. I guess you can use the system-provided LLVM, but I haven't tried it. For this step, what you have checked-out is probably enough. A sample script for this:

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]

Having the aforementioned clang in your PATH environment variable, you can use the below build script again and adjust based on your needs (sanitizers, etc). Apart from the main documentation page on the subject, poking around the CMakeLists.txt of each respective tool is also illuminating and helps adjust the build process from version to version.

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]

A note on performance: I haven't watched that talk yet, but my motivation behind this 2 step build was to have a toolchain that I can easily relocate between systems since the minimal system dependence that matters is libc.

Lastly, relevant to the above procedure is this older question of mine, which still bugs me. If you have any insight on this, please don't hesitate.

PS: Scripts have been tested with LLVM 3.7 through 3.9 and current trunk 6.0.0.

Update: I've also applied these suggestions, and there is marked improvement when using the gold linker instead of ld. LTO is also a boost.

compor
  • 2,239
  • 1
  • 19
  • 29
  • 1
    Thanks for the suggestion - I'll test your build script as soon as possible and report back. I general, SO prefers it, if you don't just link to an external site, but provide the important parts inline in your answer. So I'd recommend you add the build commands into your answer here. – MikeMB Nov 15 '17 at 13:23