Subject: bug#30756: gcc7 doesn't find stdlib.h

From: Giel van Schijndel <[email-masked]>
Date: Fri, 4 May 2018 18:03:38 +0200

On 04-05-18 17:28, Ludovic Courtès wrote:
> That’s probably because your package still includes gcc@5 as an implicit
> input via ‘cmake-build-system’.
>
> You could use a procedure like this to remove implicit inputs and add
> your own GCC variant:
>
> --8<---------------cut here---------------start------------->8---
> (define (package-with-specific-compiler p compiler)
>   "Return P modified to be built with COMPILER."
>   (package
>     (inherit p)
>     (arguments
>      `(#:implicit-inputs? #f ,@(package-arguments p)))
>     (native-inputs `(("compiler" ,compiler)
>                      ,@(package-native-inputs p)))
>     (inputs (append (package-inputs p)
>                     (alist-delete "gcc" (standard-packages))))))
> --8<---------------cut here---------------end--------------->8---
>
> … where ‘standard-packages’ comes from (guix build-system gnu).
This gives me:
> guix/build-system/cmake.scm:93:0: In procedure cmake-build:
> guix/build-system/cmake.scm:93:0: Unrecognized keyword: #:implicit-inputs?

>> Would it be possible to filter the list of directories added to these
>> environment variables to exclude those already present in GCC's default
>> search path?
> I still don’t fully understand the issue actually.  What’s wrong with
> having these directories appear several times in the search path?
>
> The difficulty here will be that search path environment variables in
> Guix are populated automatically based on their specifications, so it’s
> not all that clear to me where that filtering would happen.

The problem seems to be triggered by glibc appearing on the search path.

I'm not sure about GCC's internals exactly so I'm making one assumption
that causes all of this to make sense to me: if a directory appears
multiples times in the search path it will be searched only the first
time that it's encountered.

So in short: <cstdlib> contains an "#include_next <stdlib.h>"
preprocessor directive. That's a GCC extension that tells the
preprocessor it should only search directories appearing in the search
path _after_ the directory containing the file currently being processed.

Now this is the trimmed down search path that gets produced for g++:

 *
/gnu/store/4sqaib7c2dfjv62ivrg9b8wa7bh226la-glibc-2.26.105-g0890d5379c/include

 * /gnu/store/f9wi8xs84b29f5igp578hnqfpjnfn4gh-gcc-7.3.0/include/c++
 *
/gnu/store/f9wi8xs84b29f5igp578hnqfpjnfn4gh-gcc-7.3.0/include/c++/x86_64-unknown-linux-gnu
 *
/gnu/store/f9wi8xs84b29f5igp578hnqfpjnfn4gh-gcc-7.3.0/include/c++/backward
 *
/gnu/store/8jp0v7q1g4g87ay94i7h7p54mcw48mf3-gcc-7.3.0-lib/lib/gcc/x86_64-unknown-linux-gnu/7.3.0/include
 *
/gnu/store/8jp0v7q1g4g87ay94i7h7p54mcw48mf3-gcc-7.3.0-lib/lib/gcc/x86_64-unknown-linux-gnu/7.3.0/include-fixed
 *
/gnu/store/4sqaib7c2dfjv62ivrg9b8wa7bh226la-glibc-2.26.105-g0890d5379c/include

The first item gets there through CPLUS_INCLUDE_PATH. The rest of the
list are GCC's defaults. Because the first item is a duplicate of the
last, under the previously stated assumption, this will prevent the
preprocessor from searching it a second time for the last. This means
that <cstdlib>, which is found in .../include/c++ cannot find <stdlib.h>
in the list of directories left to search. Because that list, at that
point, starts at .../c++/x86_64-unknown-linux-gnu and ends at
*-glibc-*/include _but_ because that's a duplicate of a previously seen
item it gets eliminated.

I'm guessing the slow down they claim a workaround would cause that GCC
bug report is caused by having to deal with cycle detection becoming
more complicated if you cannot just remove duplicate entries from the
include path.

-- 
Met vriendelijke groet,
With kind regards,
Giel van Schijndel