[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

How to deal with gcc's <cstdlib> with multiarch glibc headers?



Hi,

I was offered some CPU cycles to research the impact of #798955 (moving
glibc's headers to /usr/include/<triplet>). I'll post another mail with
a summary, but there is already one quite obvious issue affecting
multiple packages. The implications are not quite clear to me, so maybe
someone else can chime in?

/usr/include/c++/8/cstdlib contains the following code:

| // Need to ensure this finds the C library's <stdlib.h> not a libstdc++
| // wrapper that might already be installed later in the include search path.
| #define _GLIBCXX_INCLUDE_NEXT_C_HEADERS
| #include_next <stdlib.h>
| #undef _GLIBCXX_INCLUDE_NEXT_C_HEADERS

After fixing #798955, glibc's stdlib.h will live in
/usr/include/<triplet>. One can figure out the default include search
path with "gcc -E -Wp,-v - </dev/null". Notably, /usr/include/<triplet>
comes before /usr/include. Adding -x c++ gives the search path for C++.
Notably /usr/include/c++/8 comes before both others.

Now most of the time, that works, but some packages (such as
chromium-browser, fcitx-qt5, fw4spl, or gemma) insist on adding some
-isystem /usr/include/<triplet>.  That changes order and one can get:

| /usr/include/c++/8/cstdlib:75:15: fatal error: stdlib.h: No such file or directory
|  #include_next <stdlib.h>
|                ^~~~~~~~~~
| compilation terminated.

You can trigger the very same error on a standard sid system using
-isystem /usr/include:

| echo '#include <cstdlib>' | g++ -isystem /usr/include -x c++ -E - >/dev/null

After messing with system include order, that's a little expected, but I
wonder whether it should work anyway.

Now gcc also ships /usr/include/c++/8/stdlib.h which starts with:

| #if !defined __cplusplus || defined _GLIBCXX_INCLUDE_NEXT_C_HEADERS
| # include_next <stdlib.h>
| #else

So it seems that if we replaced the #include_next in cstdlib with a
plain #include, it should always work, regardless of the search order:
If glibc's header comes first, all is fine. Otherwise, the
_GLIBCXX_INCLUDE_NEXT_C_HEADERS macro will instruct gcc's stdlib.h to
#include_next glibc's stdlib.h, so it should also be fine. What I don't
understand is: why does cstdlib use #include_next at all? What problem
is solved by not using plain #include?

Then the question arises whether adding /usr/include/<triplet> via
-isystem is something that should work. Should we fix chromium-browser
et al here?

Thanks in advance

Helmut


Reply to: