{"id":55,"date":"2016-06-26T23:31:22","date_gmt":"2016-06-26T15:31:22","guid":{"rendered":"http:\/\/blogs.gentoo.org\/gsoc2016-native-clang\/?p=55"},"modified":"2017-03-08T03:32:21","modified_gmt":"2017-03-07T19:32:21","slug":"a-few-thoughts-on-libc-and-_gnu_source","status":"publish","type":"post","link":"https:\/\/blogs.gentoo.org\/gsoc2016-native-clang\/2016\/06\/26\/a-few-thoughts-on-libc-and-_gnu_source\/","title":{"rendered":"A few thoughts on libc++ and _GNU_SOURCE"},"content":{"rendered":"<p>This week I was trying to make\u00a0libc++ work without _GNU_SOURCE predefined, which causes me some trouble when compiling LLVM against musl. As mentioned\u00a0in my last post, g++\/clang++ unconditionally predefines _GNU_SOURCE for any C++ code, because libstdc++\/libc++ simply won&#8217;t work without it. This is an old and well-known issue [1], but unfortunately has never been fixed. This week I boldly tried to fix it for libc++, and failed \ud83d\ude41<\/p>\n<p>Simply put, libc++ depends on some non-standard C functions that are only available when _GNU_SOURCE is predefined. For example, strtoll_l() is a non-POSIX function hidden by _GNU_SOURCE in &lt;stdlib.h&gt;, and used by libc++&#8217;s header &lt;locale&gt;. A naive idea might be to define _GNU_SOURCE in &lt;locale&gt;. It doesn&#8217;t work because &lt;stdlib.h&gt; is possibly already included and expanded before &lt;locale&gt;, at which point defining _GNU_SOURCE is too late.<\/p>\n<p>To address the above problem,\u00a0we need\u00a0to define _GNU_SOURCE before any inclusion of &lt;stdlib.h&gt;. So a\u00a0straight-forward idea is putting _GNU_SOURCE in &lt;cstdlib&gt;, which is the only place in libc++\u00a0where &lt;stdlib.h&gt; is directly included (other C++ headers usually include &lt;cstdlib&gt; instead). Unfortunately this doesn&#8217;t work either. If you read glibc&#8217;s header, you&#8217;ll notice that symbols like strtoll_l are actually not directly protected by _GNU_SOURCE, but by another macro: __USE_GNU. __USE_GNU is defined in &lt;features.h&gt; only when _GNU_SOURCE is defined, so literally they have the same effect. But this leads to an unpleasant consequence: &lt;features.h&gt; might be included prior to &lt;cstdio&gt;, so defining _GNU_SOURCE doesn&#8217;t necessarily mean\u00a0__USE_GNU is defined; without __USE_GNU, the symbols we want in &lt;stdlib.h&gt; are still hidden.<\/p>\n<p>Then here comes the third idea: just define _GNU_SOURCE before any inclusion of &lt;features.h&gt;! Thus\u00a0we make sure __USE_GNU is properly defined this time. This works in theory; the problem is we don&#8217;t know when exactly &lt;features.h&gt; is to be included. Almost every C header implicitly includes &lt;features.h&gt; somewhere, which means we need to define _GNU_SOURCE before the inclusion of any C header in libc++&#8217;s headers: &lt;cstdio&gt;, &lt;cstdlib&gt;, &lt;cstring&gt;, etc.<\/p>\n<p>Defining _GNU_SOURCE in &lt;cstdio&gt;, &lt;cstdlib&gt;, etc seems no big deal. Doing that, we don&#8217;t need the C++ compiler to predefine _GNU_SOURCE for libc++, and user code won&#8217;t be polluted by _GNU_SOURCE anymore. Flawless, isn&#8217;t it? In fact, no. Let&#8217;s recall what&#8217;s the purpose of avoiding _GNU_SOURCE: to prevent user code from being polluted by non-standard symbols. With our &#8220;solution&#8221;, though _GNU_SOURCE is absent, those symbols hidden by it are still exposed in user code anyway. So this isn&#8217;t a &#8220;real&#8221; solution.<\/p>\n<p>This issue just doesn&#8217;t seem as trivial as it appears to be; no wonder it&#8217;s never fixed though frequently complained about. A large part of the\u00a0nastiness is due to the abuse of feature test macros in libc; perhaps when C++ module become a real deal [2], C++ library writers won&#8217;t be bothered by macro pollutions anymore.<\/p>\n<p>[1]\u00a0http:\/\/web.mit.edu\/darwin\/src\/modules\/gcc3\/libstdc++-v3\/docs\/html\/faq\/#3_5<br \/>\n[2]\u00a0http:\/\/clang.llvm.org\/docs\/Modules.html<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This week I was trying to make\u00a0libc++ work without _GNU_SOURCE predefined, which causes me some trouble when compiling LLVM against musl. As mentioned\u00a0in my last post, g++\/clang++ unconditionally predefines _GNU_SOURCE for any C++ code, because libstdc++\/libc++ simply won&#8217;t work without it. This is an old and well-known issue [1], but unfortunately has never been fixed. &hellip; <a href=\"https:\/\/blogs.gentoo.org\/gsoc2016-native-clang\/2016\/06\/26\/a-few-thoughts-on-libc-and-_gnu_source\/\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">A few thoughts on libc++ and _GNU_SOURCE<\/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\/55"}],"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=55"}],"version-history":[{"count":1,"href":"https:\/\/blogs.gentoo.org\/gsoc2016-native-clang\/wp-json\/wp\/v2\/posts\/55\/revisions"}],"predecessor-version":[{"id":56,"href":"https:\/\/blogs.gentoo.org\/gsoc2016-native-clang\/wp-json\/wp\/v2\/posts\/55\/revisions\/56"}],"wp:attachment":[{"href":"https:\/\/blogs.gentoo.org\/gsoc2016-native-clang\/wp-json\/wp\/v2\/media?parent=55"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.gentoo.org\/gsoc2016-native-clang\/wp-json\/wp\/v2\/categories?post=55"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.gentoo.org\/gsoc2016-native-clang\/wp-json\/wp\/v2\/tags?post=55"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}