Bug 70129 - [6 Regression] stdlib.h: No such file or directory when using -isystem /usr/include
Summary: [6 Regression] stdlib.h: No such file or directory when using -isystem /usr/...
Status: RESOLVED WONTFIX
Alias: None
Product: gcc
Classification: Unclassified
Component: libstdc++ (show other bugs)
Version: 6.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2016-03-07 20:11 UTC by Markus Trippelsdorf
Modified: 2018-06-19 23:02 UTC (History)
5 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Markus Trippelsdorf 2016-03-07 20:11:08 UTC
markus@x4 tmp % echo "#include<algorithm>" | g++ -x c++ -isystem /usr/include -
In file included from /usr/lib/gcc/x86_64-pc-linux-gnu/6.0.0/include/g++-v6/bits/stl_algo.h:59:0,
                 from /usr/lib/gcc/x86_64-pc-linux-gnu/6.0.0/include/g++-v6/algorithm:62,
                 from <stdin>:1:
/usr/lib/gcc/x86_64-pc-linux-gnu/6.0.0/include/g++-v6/cstdlib:75:25: fatal error: stdlib.h: No such file or directory
 #include_next <stdlib.h>
                         ^
compilation terminated.

gcc-5 and older is fine.
Comment 1 Jakub Jelinek 2016-03-07 20:23:43 UTC
Yeah, this is known, but I'm afraid there is nothing that can be done easily about it.  Just don't do it.
Well, in theory, we could slow everything down by adding yet another default include directory that would come after /usr/include in the default search scope, and would contain some fallback stdlib.h and math.h for these cases, but that would be too ugly.  So, IMHO just the packages that use this should either know what they are doing and put the C++ STL system headers first, or don't use STL, or don't mess with -isystem for the default directories.  The last one preferred.
Comment 2 Markus Trippelsdorf 2016-03-07 20:27:02 UTC
OK. Thanks.
Comment 3 chuck cranor 2017-10-31 18:33:48 UTC
If the only difference between "-isystem" and "-I" was the change in the
handling of warnings, the #include_next of stdlib.h in libstdc++ would not be
a problem.

The real problem here is that "-isystem /usr/include" changes the include
search path in a way that is incompatible with "-I /usr/include" e.g.

% cat try.cc
#include <cstdlib>
% g++ -c try.cc
% g++ -I /usr/include -c try.cc
% g++ -isystem /usr/include -c try.cc
In file included from try.cc:1:0:
/proj/testbed/data/travis/cache/gcc/include/c++/6.2.0/cstdlib:75:25: fatal error: stdlib.h: No such file or directory
 #include_next <stdlib.h>
                         ^
compilation terminated.
% 

I think you'll find most build systems that do "-isystem /usr/include"
instead of "-I /usr/include" are only using "-isystem" for the change
in the warning behavior.  The change in the include path order is not
wanted...
Comment 4 Jonathan Wakely 2017-10-31 18:36:30 UTC
Why do you need to use either option? /usr/include is already a system include dir, so -isystem /usr/include serves no useful purpose.
Comment 5 chuck cranor 2017-10-31 19:04:17 UTC
I don't think anyone would manually add "-isystem /usr/include" ...
but build systems that provide variables for third party headers that
may or may not be installed in /usr/include often trigger this.

e.g. if boost is installed in prefix /pkg, then you want to include
/pkg/include in the search path.   if boost is installed in /usr
then you want /usr/include in the search path.  if you have 
"-isystem ${BOOST_PREFIX}/include" in your CXXFLAGS and BOOST_PREFIX
happens to be set to /usr somewhere earlier, you lose.


For what it's worth, this definitely crops up in cmake-based builds:

https://gitlab.kitware.com/cmake/cmake/issues/16291

I triggered it with cmake and Boost on a Cray.  It is partly cmake's
fault too.  Its handling of CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES
isn't correct.
Comment 6 fiesh 2018-02-01 10:21:12 UTC
For what it's worth, I'd like to mention that what chuck mentions in the previous post can be used to circumvent the issue:

Setting
CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES
and
CMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES
manually serves as a workaround until the CMake ticket is closed.

This took me quite a while to understand, so hopefully it helps someone else.
Comment 7 Shaun Jackman 2018-06-19 22:36:31 UTC
Thanks for reporting and trouble shooting this issue, Markus. This issue also affects the Linuxbrew package manager. See the downstream issue at https://github.com/Linuxbrew/brew/issues/724. It'd be great if this issue were addressed by GCC. Thanks to the trouble shooting here, we can work around the issue in the mean time.

Cheers,
Shaun
Comment 8 Jonathan Wakely 2018-06-19 23:02:16 UTC
(In reply to chuck cranor from comment #3)
> I think you'll find most build systems that do "-isystem /usr/include"
> instead of "-I /usr/include" are only using "-isystem" for the change
> in the warning behavior.  The change in the include path order is not
> wanted...

Then they should stop (mis)using -isystem, since it's clearly documented to affect the order directories are searched:

  If a standard system include directory, or a directory specified with
  -isystem, is also specified with -I, the -I option is ignored.  The directory
  is still searched but as a system directory at its normal position in the
  system include chain.  This is to ensure that GCC's procedure to fix buggy
  system headers and the ordering for the "#include_next" directive are not
  inadvertently changed.  If you really need to change the search order for
  system directories, use the -nostdinc and/or -isystem options.

The corollary is that you shouldn't use it unless you really need to change the search order for system directories!