Subject: clang: missing default include paths for C++
From: Tim Gesthuizen <[email-masked]>
To: [email-masked]
Date: Wed, 19 Sep 2018 20:23:14 +0200
List-Id: <debbugs-submit.debbugs.gnu.org>

Hi,
I noticed the following bug in clang when installed through guix:
Compiling C++ programs does not work because the include path is not set
correctly.

I will use the following test program for compling:

┌────
│ #include <iostream>
│
│ int
│ main()
│ {
│     std::cout << "Hello, World\n";
│ }
└────

When I now compile using clang I get the following error message:

┌────
│ which clang++
│ clang++ test.cc 2>&1
│ exit 0
└────

┌────
│ /home/tibbe/.guix-profile/bin/clang++
│ test.cc:1:10: fatal error: 'iostream' file not found
│ #include <iostream>
│ 	 ^~~~~~~~~~
│ 1 error generated.
└────

┌────
│ which g++
│ g++ test.cc 2>&1
│ exit 0
└────

┌────
│ /home/tibbe/.guix-profile/bin/g++
└────

As you can see g++ has no problem compiling the code, but clang++ cannot
find the `<iostream>' header. This is due to the already mentioned bad
include paths:

┌────
│ g++ -v test.cc 2>&1
│ clang++ -v test.cc 2>&1
│ exit 0
└────

┌────
│ Using built-in specs.
│ COLLECT_GCC=g++
│
COLLECT_LTO_WRAPPER=/gnu/store/758qfjvn4wnsrhrr08pmwfr77vmcq4q2-gcc-8.2.0/libexec/gcc/x86_64-unknown-linux-gnu/8.2.0/lto-wrapper
│ Target: x86_64-unknown-linux-gnu
│ Configured with:
│ Thread model: posix
│ gcc version 8.2.0 (GCC)
│ COLLECT_GCC_OPTIONS='-v' '-shared-libgcc' '-mtune=generic' '-march=x86-64'
│
/gnu/store/758qfjvn4wnsrhrr08pmwfr77vmcq4q2-gcc-8.2.0/libexec/gcc/x86_64-unknown-linux-gnu/8.2.0/cc1plus
-quiet -v -D_GNU_SOURCE test.cc -quiet -dumpbase test.cc -mtune=generic
-march=x86-64 -auxbase test -version -o /tmp/cceSqDtK.s
│ GNU C++14 (GCC) version 8.2.0 (x86_64-unknown-linux-gnu)
│ 	compiled by GNU C version 8.2.0, GMP version 6.1.2, MPFR version
4.0.1, MPC version 1.1.0, isl version isl-0.18-GMP
│
│ GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
│ ignoring nonexistent directory "/no-gcc-local-prefix/include"
│ ignoring nonexistent directory
"/gnu/store/bmaxmigwnlbdpls20px2ipq1fll36ncd-gcc-8.2.0-lib/lib/gcc/x86_64-unknown-linux-gnu/8.2.0/../../../../../../../x86_64-unknown-linux-gnu/include"
│ #include "..." search starts here:
│ #include <...> search starts here:
│  /home/tibbe/.guix-profile/include
│  /gnu/store/758qfjvn4wnsrhrr08pmwfr77vmcq4q2-gcc-8.2.0/include/c++
│
/gnu/store/758qfjvn4wnsrhrr08pmwfr77vmcq4q2-gcc-8.2.0/include/c++/x86_64-unknown-linux-gnu
│
/gnu/store/758qfjvn4wnsrhrr08pmwfr77vmcq4q2-gcc-8.2.0/include/c++/backward
│
/gnu/store/bmaxmigwnlbdpls20px2ipq1fll36ncd-gcc-8.2.0-lib/lib/gcc/x86_64-unknown-linux-gnu/8.2.0/include
│
/gnu/store/bmaxmigwnlbdpls20px2ipq1fll36ncd-gcc-8.2.0-lib/lib/gcc/x86_64-unknown-linux-gnu/8.2.0/include-fixed
│  /gnu/store/l4lr0f5cjd0nbsaaf8b5dmcw1a1yypr3-glibc-2.27/include
│ End of search list.
│ GNU C++14 (GCC) version 8.2.0 (x86_64-unknown-linux-gnu)
│ 	compiled by GNU C version 8.2.0, GMP version 6.1.2, MPFR version
4.0.1, MPC version 1.1.0, isl version isl-0.18-GMP
│
│ GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
│ Compiler executable checksum: 238b7d99644945f4ccaa2a89b02dcd25
│ COLLECT_GCC_OPTIONS='-v' '-shared-libgcc' '-mtune=generic' '-march=x86-64'
│  as -v --64 -o /tmp/ccZKb9XQ.o /tmp/cceSqDtK.s
│ GNU assembler version 2.30 (x86_64-unknown-linux-gnu) using BFD
version (GNU Binutils) 2.30
│
COMPILER_PATH=/gnu/store/758qfjvn4wnsrhrr08pmwfr77vmcq4q2-gcc-8.2.0/libexec/gcc/x86_64-unknown-linux-gnu/8.2.0/:/gnu/store/758qfjvn4wnsrhrr08pmwfr77vmcq4q2-gcc-8.2.0/libexec/gcc/x86_64-unknown-linux-gnu/8.2.0/:/gnu/store/758qfjvn4wnsrhrr08pmwfr77vmcq4q2-gcc-8.2.0/libexec/gcc/x86_64-unknown-linux-gnu/:/gnu/store/bmaxmigwnlbdpls20px2ipq1fll36ncd-gcc-8.2.0-lib/lib/gcc/x86_64-unknown-linux-gnu/8.2.0/:/gnu/store/bmaxmigwnlbdpls20px2ipq1fll36ncd-gcc-8.2.0-lib/lib/gcc/x86_64-unknown-linux-gnu/
│
LIBRARY_PATH=/home/tibbe/.guix-profile/lib/:/home/tibbe/.guix-profile/lib/:/gnu/store/bmaxmigwnlbdpls20px2ipq1fll36ncd-gcc-8.2.0-lib/lib/gcc/x86_64-unknown-linux-gnu/8.2.0/:/gnu/store/bmaxmigwnlbdpls20px2ipq1fll36ncd-gcc-8.2.0-lib/lib/gcc/x86_64-unknown-linux-gnu/8.2.0/../../../:/gnu/store/l4lr0f5cjd0nbsaaf8b5dmcw1a1yypr3-glibc-2.27/lib
│ COLLECT_GCC_OPTIONS='-v' '-shared-libgcc' '-mtune=generic' '-march=x86-64'
│
/gnu/store/758qfjvn4wnsrhrr08pmwfr77vmcq4q2-gcc-8.2.0/libexec/gcc/x86_64-unknown-linux-gnu/8.2.0/collect2
-plugin
/gnu/store/758qfjvn4wnsrhrr08pmwfr77vmcq4q2-gcc-8.2.0/libexec/gcc/x86_64-unknown-linux-gnu/8.2.0/liblto_plugin.so
-plugin-opt=/gnu/store/758qfjvn4wnsrhrr08pmwfr77vmcq4q2-gcc-8.2.0/libexec/gcc/x86_64-unknown-linux-gnu/8.2.0/lto-wrapper
-plugin-opt=-fresolution=/tmp/ccKNZuuX.res
-plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc
-plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lc
-plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc
--eh-frame-hdr -m elf_x86_64 -dynamic-linker
/gnu/store/l4lr0f5cjd0nbsaaf8b5dmcw1a1yypr3-glibc-2.27/lib/ld-linux-x86-64.so.2
/home/tibbe/.guix-profile/lib/crt1.o
/home/tibbe/.guix-profile/lib/crti.o
/gnu/store/bmaxmigwnlbdpls20px2ipq1fll36ncd-gcc-8.2.0-lib/lib/gcc/x86_64-unknown-linux-gnu/8.2.0/crtbegin.o
-L/home/tibbe/.guix-profile/lib -L/home/tibbe/.guix-profile/lib
-L/gnu/store/bmaxmigwnlbdpls20px2ipq1fll36ncd-gcc-8.2.0-lib/lib/gcc/x86_64-unknown-linux-gnu/8.2.0
-L/gnu/store/bmaxmigwnlbdpls20px2ipq1fll36ncd-gcc-8.2.0-lib/lib/gcc/x86_64-unknown-linux-gnu/8.2.0/../../..
-L/gnu/store/l4lr0f5cjd0nbsaaf8b5dmcw1a1yypr3-glibc-2.27/lib
/tmp/ccZKb9XQ.o -lstdc++ -lm -lgcc_s -lgcc
-L/gnu/store/l4lr0f5cjd0nbsaaf8b5dmcw1a1yypr3-glibc-2.27/lib
-rpath=/gnu/store/l4lr0f5cjd0nbsaaf8b5dmcw1a1yypr3-glibc-2.27/lib
-rpath=/gnu/store/bmaxmigwnlbdpls20px2ipq1fll36ncd-gcc-8.2.0-lib/lib
-lgcc_s -lc -lgcc_s -lgcc
/gnu/store/bmaxmigwnlbdpls20px2ipq1fll36ncd-gcc-8.2.0-lib/lib/gcc/x86_64-unknown-linux-gnu/8.2.0/crtend.o
/home/tibbe/.guix-profile/lib/crtn.o
│ COLLECT_GCC_OPTIONS='-v' '-shared-libgcc' '-mtune=generic' '-march=x86-64'
│ clang version 6.0.0 (tags/RELEASE_600/final)
│ Target: x86_64-unknown-linux-gnu
│ Thread model: posix
│ InstalledDir: /home/tibbe/.guix-profile/bin
│ Found candidate GCC installation:
/gnu/store/bgc2ckrkyz5fg4sp278msyzxs5a30pwa-gcc-5.5.0-lib/lib/gcc/x86_64-unknown-linux-gnu/5.5.0
│ Selected GCC installation:
/gnu/store/bgc2ckrkyz5fg4sp278msyzxs5a30pwa-gcc-5.5.0-lib/lib/gcc/x86_64-unknown-linux-gnu/5.5.0
│ Candidate multilib: .;@m64
│ Selected multilib: .;@m64
│
"/gnu/store/dy7lcm3d0dbh4510vkc0dv35g48pis50-clang-6.0.0/bin/clang-6.0"
-cc1 -triple x86_64-unknown-linux-gnu -emit-obj -mrelax-all
-disable-free -disable-llvm-verifier -discard-value-names
-main-file-name test.cc -mrelocation-model static -mthread-model posix
-mdisable-fp-elim -fmath-errno -masm-verbose -mconstructor-aliases
-munwind-tables -fuse-init-array -target-cpu x86-64 -dwarf-column-info
-debugger-tuning=gdb -v -resource-dir
/gnu/store/dy7lcm3d0dbh4510vkc0dv35g48pis50-clang-6.0.0/lib/clang/6.0.0
-I/home/tibbe/.guix-profile/include -internal-isystem /usr/local/include
-internal-isystem
/gnu/store/dy7lcm3d0dbh4510vkc0dv35g48pis50-clang-6.0.0/lib/clang/6.0.0/include
-internal-externc-isystem
/gnu/store/l4lr0f5cjd0nbsaaf8b5dmcw1a1yypr3-glibc-2.27/include
-fdeprecated-macro -fdebug-compilation-dir /home/tibbe/src/hello-world
-ferror-limit 19 -fmessage-length 0 -fobjc-runtime=gcc -fcxx-exceptions
-fexceptions -fdiagnostics-show-option -o /tmp/test-b83cb1.o -x c++ test.cc
│ clang -cc1 version 6.0.0 based upon LLVM 6.0.0 default target
x86_64-unknown-linux-gnu
│ #include "..." search starts here:
│ #include <...> search starts here:
│  /home/tibbe/.guix-profile/include
│  /usr/local/include
│
/gnu/store/dy7lcm3d0dbh4510vkc0dv35g48pis50-clang-6.0.0/lib/clang/6.0.0/include
│  /gnu/store/l4lr0f5cjd0nbsaaf8b5dmcw1a1yypr3-glibc-2.27/include
│ End of search list.
│ test.cc:1:10: fatal error: 'iostream' file not found
│ #include <iostream>
│ 	 ^~~~~~~~~~
│ 1 error generated.
└────

As you can see from the output, clang is missing some include paths that
gcc has. Specifying a custom `CPLUS_INCLUDE_PATH' fixes the problem:

┌────
│
CPLUS_INCLUDE_PATH=$HOME/.guix-profile/include/c++:$HOME/.guix-profile/include/c++/x86_64-unknown-linux-gnu/
clang++ test.cc
│ ./a.out
└────

┌────
│ Hello, World
└────

This is already done in the package definition for the
`C_INCLUDE_PATH'. It is not done for C++ because clang does not
implement a feature or build system variable for changing it.

Fixing this problem would probably include an upstream patch enabling a
similar feature for C++ for what is already done in C and configuring
this variable in build phase to add the same include paths that g++ has.

Tim.