MikeMB
MikeMB

Reputation: 21156

Building and using a pure llvm toolchain for c++ on linux

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

The resulting compiler should

So far I have cloned

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"

Upvotes: 7

Views: 3003

Answers (1)

compor
compor

Reputation: 2329

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.

Upvotes: 4

Related Questions