{"id":49,"date":"2016-05-31T17:08:33","date_gmt":"2016-05-31T09:08:33","guid":{"rendered":"http:\/\/blogs.gentoo.org\/gsoc2016-native-clang\/?p=49"},"modified":"2017-03-08T03:32:21","modified_gmt":"2017-03-07T19:32:21","slug":"build-gnu-free-executables-with-clang","status":"publish","type":"post","link":"https:\/\/blogs.gentoo.org\/gsoc2016-native-clang\/2016\/05\/31\/build-gnu-free-executables-with-clang\/","title":{"rendered":"Build GNU-free executables with clang"},"content":{"rendered":"<p>Previously we discussed how to build a LLVM\u00a0C++ runtime stack with libc++, libc++abi and libunwind. Along with musl, we now\u00a0have a GNU-free C\/C++ runtime environment. But an\u00a0unfortunate fact\u00a0is, clang is used to living\u00a0with GCC and glibc, and it takes\u00a0some extra effort\u00a0to make clang\u00a0work with our new environment. In my last post, I demonstrated how to make a wrapper of clang to build GNU-free executables. As the name of this project implies, we want a native clang, not an ugly wrapper. So in this post, I&#8217;m going to show you how to build a native clang that works &#8220;out of the box&#8221;.<\/p>\n<p>Before getting into it, let&#8217;s first analyze what dependencies a program built by clang typically has. For C programs, it&#8217;s of course glibc; and for C++ programs there&#8217;s also libstdc++. Yet there&#8217;s a lesser known library that every program relies on: libgcc. Sometimes it&#8217;s statically linked into the executable, other times dynamically linked in the form of &#8220;libgcc_s&#8221;. libgcc is a low-level runtime library provided by GCC. More information can be found at:\u00a0<a href=\"https:\/\/gcc.gnu.org\/onlinedocs\/gccint\/Libgcc.html\" target=\"_blank\">https:\/\/gcc.gnu.org\/onlinedocs\/gccint\/Libgcc.html<\/a>.\u00a0LLVM also has a replacement for it: compiler-rt; and we&#8217;ll need this later.<\/p>\n<p>The biggest obstacle preventing clang from working with musl is that musl has its own dynamic linker which could not be recognized by clang. A naive workaround is to rename musl&#8217;s linker to the same name as glibc&#8217;s, but that would obviously mess up the whole system. We&#8217;ll have to take a alternative approach (which I&#8217;m personally resistant to): modify clang\/LLVM&#8217;s source code.<\/p>\n<p>Two rudimentary patches that work on x86_64 platforms\u00a0could be found here:\u00a0<a href=\"https:\/\/github.com\/zzlei\/musl-clang\">https:\/\/github.com\/zzlei\/musl-clang<\/a>. As their names imply, one patch is for the LLVM source root, and the other for clang. Assume you&#8217;ve already checked out LLVM, clang and compiler-rt to the right location, say $LLVM, $LLVM\/tools\/clang and $LLVM\/projects\/compiler-rt respectively. After applying the patches, issue the following command to build them all together:<br \/>\n<code><br \/>\n$ mkdir $LLVM\/build &amp;&amp; cd $LLVM\/build<br \/>\n$ cmake -DGCC_INSTALL_PREFIX=\/usr \\<br \/>\n-DDEFAULT_SYSROOT=\/usr\/x86_64-pc-linux-musl \\<br \/>\n-DCLANG_DEFAULT_CXX_STDLIB=libc++ \\<br \/>\n-DLLVM_DEFAULT_TARGET_TRIPLE=x86_64-pc-linux-musl ..<br \/>\n$ make<br \/>\n<\/code><\/p>\n<p>Some explanations:<br \/>\n<strong>DEFAULT_SYSROOT<\/strong> tells clang where to find musl&#8217;s headers and libraries. It&#8217;s pointed to the location where the musl toolchain is installed.<br \/>\n<strong>GCC_INSTALL_PREFIX<\/strong> specifies where GCC is installed. clang needs this to find crtbegin.o and crtend.o. This part is a bit thorny, as neither musl or clang provides these files. We&#8217;ll need to replace them with some other vendor&#8217;s later in this project.<br \/>\n<strong>CLANG_DEFAULT_CXX_STDLIB<\/strong> tells clang to use libc++ by default. A vanilla clang on Linux always uses libstdc++ by default.<br \/>\n<strong>LLVM_DEFAULT_TARGET_TRIPLE<\/strong> informs clang that we&#8217;re targeting on musl-libc; without this clang won&#8217;t find the correct dynamic linker.<\/p>\n<p>After putting the freestanding C++ runtime libraries we previously built under \/usr\/x86_64-pc-linux-musl\/usr\/lib, we should have a native clang that &#8220;almost&#8221; works out of the box. Why &#8220;almost&#8221;? Because we still need to feed\u00a0one\u00a0option to\u00a0clang: &#8220;-rtlib=compiler-rt&#8221;, indicating the use of compiler-rt instead of libgcc. I&#8217;m still struggling to set this option permanently at build time; hopefully I don&#8217;t have to modify too much of clang&#8217;s code to achieve this&#8230;<\/p>\n<p>Now, let&#8217;s take a final look of our product:<br \/>\n<code><br \/>\n$ .\/bin\/clang++ hello.cc -rtlib=compiler-rt<br \/>\n$ readelf -d a.out | grep NEEDED<br \/>\n0x0000000000000001 (NEEDED) Shared library: [libc++.so.1]<br \/>\n0x0000000000000001 (NEEDED) Shared library: [libc++abi.so.1]<br \/>\n0x0000000000000001 (NEEDED) Shared library: [libc.so]<br \/>\n<\/code><\/p>\n<p>Great!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Previously we discussed how to build a LLVM\u00a0C++ runtime stack with libc++, libc++abi and libunwind. Along with musl, we now\u00a0have a GNU-free C\/C++ runtime environment. But an\u00a0unfortunate fact\u00a0is, clang is used to living\u00a0with GCC and glibc, and it takes\u00a0some extra effort\u00a0to make clang\u00a0work with our new environment. In my last post, I demonstrated how to &hellip; <a href=\"https:\/\/blogs.gentoo.org\/gsoc2016-native-clang\/2016\/05\/31\/build-gnu-free-executables-with-clang\/\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">Build GNU-free executables with clang<\/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\/49"}],"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=49"}],"version-history":[{"count":1,"href":"https:\/\/blogs.gentoo.org\/gsoc2016-native-clang\/wp-json\/wp\/v2\/posts\/49\/revisions"}],"predecessor-version":[{"id":50,"href":"https:\/\/blogs.gentoo.org\/gsoc2016-native-clang\/wp-json\/wp\/v2\/posts\/49\/revisions\/50"}],"wp:attachment":[{"href":"https:\/\/blogs.gentoo.org\/gsoc2016-native-clang\/wp-json\/wp\/v2\/media?parent=49"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.gentoo.org\/gsoc2016-native-clang\/wp-json\/wp\/v2\/categories?post=49"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.gentoo.org\/gsoc2016-native-clang\/wp-json\/wp\/v2\/tags?post=49"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}