{"id":52,"date":"2016-06-15T15:48:00","date_gmt":"2016-06-15T07:48:00","guid":{"rendered":"http:\/\/blogs.gentoo.org\/gsoc2016-native-clang\/?p=52"},"modified":"2017-03-08T03:32:21","modified_gmt":"2017-03-07T19:32:21","slug":"the-invisible-_gnu_source-in-your-c-code","status":"publish","type":"post","link":"https:\/\/blogs.gentoo.org\/gsoc2016-native-clang\/2016\/06\/15\/the-invisible-_gnu_source-in-your-c-code\/","title":{"rendered":"The invisible _GNU_SOURCE in your C++ code"},"content":{"rendered":"<p>Recently two of my patches made their way into clang\/LLVM; now &#8216;musl&#8217; is a valid environment type in LLVM, and you can configure clang to build binaries against musl on Linux, without using fancy compiler flags like those shown in my previous blog posts. The &#8220;natural&#8221; next step of this\u00a0project is to build LLVM itself against musl, and this task\u00a0turns out to be tougher than I expected. Let&#8217;s now dive into the technical part.<\/p>\n<p>Briefly speaking, there&#8217;s a chunk of code like the following in LLVM:<\/p>\n<pre><code>namespace LibFunc {\r\nenum Func {\r\n    ...\r\n    fopen,\r\n    fopen64,\r\n    fprintf,\r\n    fputc,\r\n    ...\r\n};\r\n}<\/code><\/pre>\n<p>which defines a set of enumerators with the same names as various libc functions. This is totally valid since these enumerators are protected by a C++ namespace, so *ideally* won&#8217;t clash with raw libc function names.<\/p>\n<p>But the story goes a bit differently on musl&#8217;s side. Some of the functions, including <code>fopen64<\/code> listed in the code snippet, is actually non-POSIX, and somehow musl decides to define them as aliases to the non-64 versions. Here&#8217;s a code snippet from musl&#8217;s header stdio.h:<\/p>\n<pre><code>#if defined(_LARGEFILE64_SOURCE) || defined(_GNU_SOURCE)\r\n#define tmpfile64 tmpfile\r\n#define fopen64 fopen\r\n#define freopen64 freopen\r\n...\r\n#endif<\/code><\/pre>\n<p>You can see these 64-suffixed functions are defined as macros; the ugliness of macros is that they don&#8217;t respect C++&#8217;s scoping rules, thus\u00a0the inevitable name clashing with LLVM.<\/p>\n<p>Should we blame musl for this? Actually it does protect these symbols with another macro <code>_GNU_SOURCE<\/code>; the <code>fopen64<\/code> and stuff are exposed only when <code>_GNU_SOURCE<\/code> is defined. OTOH, I checked LLVM&#8217;s code and in fact it never explicitly defines _GNU_SOURCE, unless glibc is in use. Then why the clash? Unfortunately the ugliness doesn&#8217;t just end here. It turns out g++\/clang++ unconditionally predefines <code>_GNU_SOURCE<\/code> when compiling any C++ code on Linux, and that&#8217;s because libc++\/libstd++ won&#8217;t work on Linux without this macro defined. So the perfect fix for this incompatibility between LLVM and musl should be fixing the C++ compiler itself, but that&#8217;s another big story&#8230;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Recently two of my patches made their way into clang\/LLVM; now &#8216;musl&#8217; is a valid environment type in LLVM, and you can configure clang to build binaries against musl on Linux, without using fancy compiler flags like those shown in my previous blog posts. The &#8220;natural&#8221; next step of this\u00a0project is to build LLVM itself &hellip; <a href=\"https:\/\/blogs.gentoo.org\/gsoc2016-native-clang\/2016\/06\/15\/the-invisible-_gnu_source-in-your-c-code\/\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">The invisible _GNU_SOURCE in your C++ code<\/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\/52"}],"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=52"}],"version-history":[{"count":2,"href":"https:\/\/blogs.gentoo.org\/gsoc2016-native-clang\/wp-json\/wp\/v2\/posts\/52\/revisions"}],"predecessor-version":[{"id":54,"href":"https:\/\/blogs.gentoo.org\/gsoc2016-native-clang\/wp-json\/wp\/v2\/posts\/52\/revisions\/54"}],"wp:attachment":[{"href":"https:\/\/blogs.gentoo.org\/gsoc2016-native-clang\/wp-json\/wp\/v2\/media?parent=52"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.gentoo.org\/gsoc2016-native-clang\/wp-json\/wp\/v2\/categories?post=52"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.gentoo.org\/gsoc2016-native-clang\/wp-json\/wp\/v2\/tags?post=52"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}