The <cmath> and <cstdlib> headers need their counter parts <math.h> and <stdlib.h> from the libc respectively, but libstdc++ wraps these headers. Now <cmath> and <cstdlib> include these headers using
$ echo '#include <cstdlib>' | g++ -x c++ -E - -isystem /usr/include >/dev/null In file included from <stdin>:1: /usr/include/c++/9/cstdlib:75:15: fatal error: stdlib.h: No such file or directory 75 | #include_next <stdlib.h> | ^~~~~~~~~~ compilation terminated. $ What happens here is that g++ includes libstdc++-v3/include/c_global/cstdlib. That header temporarily #defines _GLIBCXX_INCLUDE_NEXT_C_HEADERS and then does #include_next <stdlib.h>. libstdc++-v3's replacement libstdc++-v3/include/c_comaptibility/stdlib.h happens to come earlier and is not considered. Unfortunately, the -isystem above inserted glibc's header before the location containing <cstdlib>, so the #include_next continues searching and fails to find <stdlib.h>. Now you are probably going to say that "-isystem /usr/include" is a bad idea and that you shouldn't do that. I'm inclined to agree. This isn't a problem just yet. Debian wants to move /usr/include/stdlib.h to /usr/include/<multiarch>/stdlib.h. After that move, the problematic flag becomes "-isystem /usr/include/<multiarch>". Unfortunately, around 30 Debian packages[1] do pass exactly that flag. Regardless whether doing so is a bad idea, I guess we will have to support that. I am proposing to replace those two #include_next with plain #include. That'll solve the problem described above, but it is not entirely obvious that doing so doesn't break something else. After switching those #include_next to #include, libstdc++-v3/include/c_global/cstdlib will continue to temporarily will #include <stdlib.h>. Now, it'll search all include directories. It may find libstdc++-v3/include/c_comaptibility/stdlib.h or the libc's version. We cannot tell which. If it finds the one from libstdc++-v3, the header will notice the _GLIBCXX_INCLUDE_NEXT_C_HEADERS macro and immediately #include_next <stdlib.h> skipping the rest of the header. That in turn will find the libc version. So in both cases, it ends up using the right one. Precisely what we wanted. #include_next is simply not useful here. The #include_next was originally added via PRs libstdc++/14608 and libstdc++/60401. At that time, the _GLIBCXX_INCLUDE_NEXT_C_HEADERS guard macro was also added. It seems like the #include_next was a meant as an extra safe-guard, but actually breaks a practical use case. For these reasons, I think that using #include_next here is harmful and that replacing it with plain #include solves the problem without introducing regressions. [1] Including but not limited chromium-browser, inkscape, various kde packages, opencv, and vtk. libstdc++-v3/ChangeLog: * include/c_global/cmath: Don't use #include_next. * include/c_global/cstdlib: Likewise. --- libstdc++-v3/include/c_global/cmath | 2 +- libstdc++-v3/include/c_global/cstdlib | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) Given the patch's size, I think that the copyright dance is not necessary. The issue affects at least gcc-8 to gcc-10. Please Cc me in replies. Helmut diff --git a/libstdc++-v3/include/c_global/cmath b/libstdc++-v3/include/c_global/cmath index b99aaf8df40..8b2bb7c0785 100644 --- a/libstdc++-v3/include/c_global/cmath +++ b/libstdc++-v3/include/c_global/cmath @@ -42,7 +42,7 @@ #include <bits/cpp_type_traits.h> #include <ext/type_traits.h> #define _GLIBCXX_INCLUDE_NEXT_C_HEADERS -#include_next <math.h> +#include <math.h> #undef _GLIBCXX_INCLUDE_NEXT_C_HEADERS #include <bits/std_abs.h> diff --git a/libstdc++-v3/include/c_global/cstdlib b/libstdc++-v3/include/c_global/cstdlib index f42db41fc51..80b39f6144f 100644 --- a/libstdc++-v3/include/c_global/cstdlib +++ b/libstdc++-v3/include/c_global/cstdlib @@ -72,7 +72,7 @@ namespace std // 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> +#include <stdlib.h> #undef _GLIBCXX_INCLUDE_NEXT_C_HEADERS #include <bits/std_abs.h> -- 2.26.0