How to build libc++ on Ubuntu 16.04
I had a similar issue as you do. While testing clang with libstdc++ worked fine with C++11 and C++14 there still might be licensing issues with libstdc++. So I ended up installing Clang toolchain from their repos and compiling libc++ on Ubuntu 16.04.
Disclaimer: This post is summary of long search on how to build the libc++
on Ubuntu Linux. Many of the posts I found in 2017 were either outdated or described a partial solution on other systems e.g. CentOS. Links to these posts are:
Here are the steps to build LLVM + Clang + libc++ from the 4.0 release branch:
Install the key of LLVM Repositories
# apt-get update && apt-get dist-upgrade -y && apt-get install -y vim curl &&
curl -q https://apt.llvm.org/llvm-snapshot.gpg.key |apt-key add -
Create a new new APT Repository File (you can also exclude 2 lines referring to v3.9 repos)
# cat > /etc/apt/sources.list.d/llvm-repos.list <<EOF
deb http://apt.llvm.org/xenial/ llvm-toolchain-xenial main
deb-src http://apt.llvm.org/xenial/ llvm-toolchain-xenial main
deb http://apt.llvm.org/xenial/ llvm-toolchain-xenial-3.9 main
deb-src http://apt.llvm.org/xenial/ llvm-toolchain-xenial-3.9 main
deb http://apt.llvm.org/xenial/ llvm-toolchain-xenial-4.0 main
deb-src http://apt.llvm.org/xenial/ llvm-toolchain-xenial-4.0 main
EOF
Install Clang and all Packages needed to build libc++ from LLVM repos
# apt-get update && apt-get install -y clang-4.0 clang-4.0-doc
libclang-common-4.0-dev libclang-4.0-dev libclang1-4.0 libclang1-4.0-dbg
libllvm4.0 libllvm4.0-dbg lldb-4.0 llvm-4.0 llvm-4.0-dev llvm-4.0-runtime
clang-format-4.0 python-clang-4.0 liblldb-4.0-dev lld-4.0 libfuzzer-4.0-dev
subversion cmake
Create an alternative for C++ compiler and linker. This is not a must, but lets you switch compilers or linkers if needed. Also some build files needed cc
or c++
or clang++
as far as I remember. Keep in mind, that we switch to LLD linker as default:
update-alternatives --install /usr/bin/cc cc /usr/bin/clang-4.0 100
&& update-alternatives --install /usr/bin/c++ c++ /usr/bin/clang++-4.0 100
&& update-alternatives --install /usr/bin/clang++ clang++ /usr/bin/clang++-4.0 100
&& update-alternatives --install /usr/bin/clang clang /usr/bin/clang-4.0 100
&& update-alternatives --install /usr/bin/ld ld /usr/bin/ld.lld-4.0 10
&& update-alternatives --install /usr/bin/ld ld /usr/bin/ld.gold 20
&& update-alternatives --install /usr/bin/ld ld /usr/bin/ld.bfd 30
&& ld --version && echo 3 | update-alternatives --config ld && ld --version
Checkout sources of libc++
and libc++abi
:
$ cd /tmp
$ svn co http://llvm.org/svn/llvm-project/libcxx/branches/release_40/ libcxx
$ svn co http://llvm.org/svn/llvm-project/libcxxabi/branches/release_40/ libcxxabi
$ mkdir -p libcxx/build libcxxabi/build
To run libc++
on Linux one needs ABI compatibility to the standard library, e.g. libstdc++. This is where libc++abi
comes into game. The only problem is that it needs libc++
to be on the system for which it is build. Thus libc++
is built in 2 steps. First: without any ABI compatibility. But it will be used for bootstrapping of ABI lib and than the second step is to recompile libc++
with the proper ABI present on system:
Bootstraping => build libc++
without proper ABI:
cd /tmp/libcxx/build
cmake -DCMAKE_BUILD_TYPE=Release -DLLVM_CONFIG_PATH=/usr/bin/llvm-config-4.0
-DCMAKE_INSTALL_PREFIX=/usr ..
&& make install
Building libc++abi
with libstdc++
compatible ABI:
cd /tmp/libcxxabi/build
CPP_INCLUDE_PATHS=echo | c++ -Wp,-v -x c++ - -fsyntax-only 2>&1
|grep ' /usr'|tr '
' ' '|tr -s ' ' |tr ' ' ';'
CPP_INCLUDE_PATHS="/usr/include/c++/v1/;$CPP_INCLUDE_PATHS"
cmake -G "Unix Makefiles" -DLIBCXX_CXX_ABI=libstdc++
-DLIBCXX_LIBSUPCXX_INCLUDE_PATHS="$CPP_INCLUDE_PATHS"
-DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr
-DLLVM_CONFIG_PATH=/usr/bin/llvm-config-4.0
-DLIBCXXABI_LIBCXX_INCLUDES=../../libcxx/include ..
make install
Rebuild libc++
with proper ABI lib deployed on system:
cd /tmp/libcxx/build
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr
-DLIBCXX_CXX_ABI=libcxxabi -DLLVM_CONFIG_PATH=/usr/bin/llvm-config-4.0
-DLIBCXX_CXX_ABI_INCLUDE_PATHS=../../libcxxabi/include ..
&& make install
Create a test file to check whether everything works fine. IMO you should also test cerr
stream, as previously it was not supported with the libc++abi
and there were some segfaults. Please refer to this question.
create a test.cpp file:
#include <iostream>
int main()
{
using namespace std;
cout << "[OK] Hello world to cout!" << endl;
cerr << "[OK] Hello world to cerr!" << endl;
clog << "[OK] Hello world to clog!" << endl;
return 0;
}
And compile it and run it using this command line:
clang++ -std=c++11 -stdlib=libc++ -lc++abi test.cpp && ./a.out
Reason there is no package
I found libc++ packages for Ubuntu but they are a bit behind recent version: https://packages.ubuntu.com/xenial/libc++-dev
Why they are not current, I can't answer, but my guess is that LLVM+Clang can work with mostly any Standard Library, whereas libc++ as you see must be linked to particular runtime ABI and might heavily depend on available C runtime library. I agree there should be a package which covers 90% of the cases. May be this is just the lack of resources. Searching the mailing archive did not bring up anything special.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…