{"id":11,"date":"2016-05-05T09:26:49","date_gmt":"2016-05-05T01:26:49","guid":{"rendered":"http:\/\/blogs.gentoo.org\/gsoc2016-native-clang\/?p=11"},"modified":"2017-03-08T03:32:21","modified_gmt":"2017-03-07T19:32:21","slug":"build-a-freestanding-libcxx","status":"publish","type":"post","link":"https:\/\/blogs.gentoo.org\/gsoc2016-native-clang\/2016\/05\/05\/build-a-freestanding-libcxx\/","title":{"rendered":"Build a freestanding libc++"},"content":{"rendered":"<p>libc++ is the C++ standard library implemented by LLVM and an essential part of the clang-based\u00a0toolchain we&#8217;re going to build. In this post I&#8217;ll demonstrate\u00a0how to build a freestanding libc++ on Gentoo.<\/p>\n<p>A complete C++ runtime stack consists of three components, from top to bottom:<\/p>\n<ul>\n<li>a C++ standard library<\/li>\n<li>a C++ ABI library<\/li>\n<li>a stack unwinding library<\/li>\n<\/ul>\n<p>As stated in my introductory\u00a0post, in this GSoC project these roles will be taken by libc++, libc++abi and libunwind, respectively. As higher-level libraries depend on lower-level ones, we need to build them from bottom to top, i.e. :<\/p>\n<ol>\n<li>build libunwind<\/li>\n<li>build libc++abi against libunwind<\/li>\n<li>build libc++ against libc++abi<\/li>\n<\/ol>\n<p>All of the above, of course, should\u00a0be linked with musl instead of glibc. So first of all, we need a proper toolchain that can link binaries with musl. Luckily, Gentoo&#8217;s developers already prepared such a toolchain for us; just type the following commands:<br \/>\n<code><br \/>\n$ emerge layman crossdev &amp;&amp; layman -a musl &amp;&amp; \\<br \/>\ncrossdev -t x86_64-pc-linux-musl<br \/>\n<\/code><\/p>\n<p>Here we use <code>layman<\/code> to create a layout\u00a0for musl, and then use <code>crossdev<\/code> to auto-magically build the toolchain. Check out all needed respositories and we are ready to build the libraries:<br \/>\n<code><\/code><\/p>\n<p><code>$ cd $REPOS<br \/>\n$ svn co http:\/\/llvm.org\/svn\/llvm-project\/llvm\/trunk llvm<br \/>\n$ svn co http:\/\/llvm.org\/svn\/llvm-project\/libunwind\/trunk libunwind<br \/>\n$ svn co http:\/\/llvm.org\/svn\/llvm-project\/libcxxabi\/trunk libcxxabi<br \/>\n$ svn co http:\/\/llvm.org\/svn\/llvm-project\/libcxx\/trunk libcxx<br \/>\n<\/code><\/p>\n<p><strong>Build libunwind:<\/strong><br \/>\n<code><br \/>\n$ cd $REPOS\/libunwind &amp;&amp; mkdir build &amp;&amp; cd build<br \/>\n$ cmake -DCMAKE_C_COMPILER=x86_64-pc-linux-musl-gcc \\<br \/>\n-DCMAKE_CXX_COMPILER=x86_64-pc-linux-musl-g++ \\<br \/>\n-DLIBUNWIND_ENABLE_SHARED=0 \\<br \/>\n-DLLVM_PATH=\"$REPOS\/llvm\" ..<br \/>\n$ make<br \/>\n<\/code><\/p>\n<p>Note: I want to statically link libunwind into libc++abi, so I disable the building of\u00a0shared library through <code>LIBUNWIND_ENABLE_SHARED<\/code>. You may safely omit this option if you want a shared version.<\/p>\n<p><strong>Build libc++abi:<\/strong><br \/>\n<code><br \/>\n$ cd $REPOS\/libc++abi &amp;&amp; mkdir build &amp;&amp; cd build<br \/>\n$ cmake -DCMAKE_C_COMPILER=x86_64-pc-linux-musl-gcc \\<br \/>\n-DCMAKE_CXX_COMPILER=x86_64-pc-linux-musl-g++ \\<br \/>\n-DCMAKE_SHARED_LINKER_FLAGS=\"-L$REPOS\/libunwind\/build\/lib\"<br \/>\n-DLIBCXXABI_USE_LLVM_UNWINDER=1 \\<br \/>\n-DLIBCXXABI_LIBUNWIND_PATH=\"$REPOS\/libunwind\" \\<br \/>\n-DLIBCXXABI_LIBCXX_INCLUDES=\"$REPOS\/libcxx\/include\" \\<br \/>\n-DLLVM_PATH=\"$REPOS\/llvm\" ..<br \/>\n$ make<br \/>\n<\/code><\/p>\n<p><strong>Build libc++:<\/strong><br \/>\n<code><br \/>\n$ cd $REPOS\/libc++ &amp;&amp; mkdir build &amp;&amp; cd build<br \/>\n$ cmake -DCMAKE_C_COMPILER=x86_64-pc-linux-musl-gcc \\<br \/>\n-DCMAKE_CXX_COMPILER=x86_64-pc-linux-musl-g++ \\<br \/>\n-DLIBCXX_HAS_MUSL_LIBC=1 \\<br \/>\n-DLIBCXX_HAS_GCC_S_LIB=0 \\<br \/>\n-DLIBCXX_CXX_ABI=libcxxabi \\<br \/>\n-DLIBCXX_CXX_ABI_INCLUDE_PATHS=\"$REPOS\/libcxxabi\/include\" \\<br \/>\n-DLIBCXX_CXX_ABI_LIBRARY_PATH=\"$REPOS\/libcxxabi\/build\/lib\" \\<br \/>\n-DLLVM_PATH=\"$REPOS\/llvm\" \\<br \/>\n$ make<br \/>\n<\/code><\/p>\n<p>Note: libgcc is GCC&#8217;s stack unwinding library and should\u00a0not be used in our C++ runtime stack, so I explicitly disable it through <code>LIBCXX_HAS_GCC_S_LIB<\/code>\u00a0; otherwise it&#8217;ll sneak into our library.<\/p>\n<p>Now the C++ runtime stack is complete; it&#8217;s time to verify our work:<br \/>\n<code><br \/>\n$ readelf -d $REPOS\/libcxx\/build\/lib\/libc++.so.1 | grep NEEDED<br \/>\n0x0000000000000001 (NEEDED) Shared library: [libc++abi.so.1]<br \/>\n0x0000000000000001 (NEEDED) Shared library: [libc.so]<br \/>\n<\/code><\/p>\n<p>libunwind is statically linked so is not shown. Dependencies on libc++abi and libc (musl) look correct. So far, so good \ud83d\ude42<\/p>\n<p>In the following post, I&#8217;ll demonstrate how to link an actual C++ program with this freshly built libc++.\u00a0See you!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>libc++ is the C++ standard library implemented by LLVM and an essential part of the clang-based\u00a0toolchain we&#8217;re going to build. In this post I&#8217;ll demonstrate\u00a0how to build a freestanding libc++ on Gentoo. A complete C++ runtime stack consists of three components, from top to bottom: a C++ standard library a C++ ABI library a stack &hellip; <a href=\"https:\/\/blogs.gentoo.org\/gsoc2016-native-clang\/2016\/05\/05\/build-a-freestanding-libcxx\/\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">Build a freestanding libc++<\/span><\/a><\/p>\n","protected":false},"author":161,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[2],"tags":[],"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/blogs.gentoo.org\/gsoc2016-native-clang\/wp-json\/wp\/v2\/posts\/11"}],"collection":[{"href":"https:\/\/blogs.gentoo.org\/gsoc2016-native-clang\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.gentoo.org\/gsoc2016-native-clang\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.gentoo.org\/gsoc2016-native-clang\/wp-json\/wp\/v2\/users\/161"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.gentoo.org\/gsoc2016-native-clang\/wp-json\/wp\/v2\/comments?post=11"}],"version-history":[{"count":13,"href":"https:\/\/blogs.gentoo.org\/gsoc2016-native-clang\/wp-json\/wp\/v2\/posts\/11\/revisions"}],"predecessor-version":[{"id":46,"href":"https:\/\/blogs.gentoo.org\/gsoc2016-native-clang\/wp-json\/wp\/v2\/posts\/11\/revisions\/46"}],"wp:attachment":[{"href":"https:\/\/blogs.gentoo.org\/gsoc2016-native-clang\/wp-json\/wp\/v2\/media?parent=11"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.gentoo.org\/gsoc2016-native-clang\/wp-json\/wp\/v2\/categories?post=11"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.gentoo.org\/gsoc2016-native-clang\/wp-json\/wp\/v2\/tags?post=11"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}