Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

stdlib.h: No such file or directory #22

Closed
ghost opened this issue Aug 22, 2017 · 12 comments
Closed

stdlib.h: No such file or directory #22

ghost opened this issue Aug 22, 2017 · 12 comments

Comments

@ghost
Copy link

ghost commented Aug 22, 2017

This is currently a TagParser issue, but I bet it bubbles up to TagEditor - I posted this here thinking it was GCC issue, but it seems some *.cmake files here might need to be reworked:

[  7%] Building CXX object CMakeFiles/tagparser_static.dir/mp4/mp4tagfield.cpp.o
In file included from
/usr/lib/gcc/x86_64-w64-mingw32/6.3.0/include/c++/ext/string_conversions.h:41:0,
from /usr/lib/gcc/x86_64-w64-mingw32/6.3.0/include/c++/bits/basic_string.h:5402,
from /usr/lib/gcc/x86_64-w64-mingw32/6.3.0/include/c++/string:52,
from /usr/lib/gcc/x86_64-w64-mingw32/6.3.0/include/c++/stdexcept:39,
from /usr/lib/gcc/x86_64-w64-mingw32/6.3.0/include/c++/array:39,
from /usr/lib/gcc/x86_64-w64-mingw32/6.3.0/include/c++/tuple:39,
from /usr/lib/gcc/x86_64-w64-mingw32/6.3.0/include/c++/functional:55,
from /usr/x86_64-w64-mingw32/sys-root/mingw/include/c++utilities/chrono/timespan.h:7,
from /usr/x86_64-w64-mingw32/sys-root/mingw/include/c++utilities/chrono/datetime.h:4,
from /var/cache/glade/tagparser/notification.h:6,
from /var/cache/glade/tagparser/statusprovider.h:4,
from /var/cache/glade/tagparser/abstracttrack.h:4,
from /var/cache/glade/tagparser/mp4/mp4track.h:4,
from /var/cache/glade/tagparser/mp4/mp4atom.cpp:1:
/usr/lib/gcc/x86_64-w64-mingw32/6.3.0/include/c++/cstdlib:75:25: fatal error:
stdlib.h: No such file or directory
#include_next <stdlib.h>

http://cygwin.com/ml/cygwin/2017-08/msg00192.html

Here is possible fix:

http://github.com/opencv/opencv/pull/7390/files

@Martchus
Copy link
Owner

Martchus commented Aug 22, 2017

Ok, so this issue occurs after upgrading GCC to 6.3.0. However, it only seems to occur under certain conditions. At least here I haven't had any trouble using GCC 6.x (at the time it was the current release). https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70936 might be the relevant GCC issue.

Note that I can only take the effort to test with latest GCC (currently 7.1.1) and Clang (4.0.1) and not various configurations. Patches to support different versions/configurations are welcome of course.

I'm wondering why I'm not affected by this issue. Even cross-compilation works for me (some comments in the GCC issue state they have the bug in their cross tool-chain).


However, it could also be a CMake bug or something wrong with my build scripts (eg. incorrect use of -isystem). Which version of CMake do you use? (I use CMake 3.9.1.)


Since I can not reproduce myself, I can only give hints and suspicions. That's what I would try to find a workaround:

  1. Execute make VERBOSE=1 to get the failing line. (This important information is missing in your log.)
  2. Execute the failing line manually. The error should be reproducible.
  3. Check for obvious mistakes in the line.
  4. Fix obvious mistakes and verify the result by executing the line manually. If there are no obvious mistakes, I would play around with the flags (especially the include flags in this case) to find a workaround. Sometimes it is also useful, to add -v to display spawned subprocesses.
  5. Adjust the CMake project so the fixed line is produced. If it is only a workaround for a specific CMake/compiler/library version, make it conditional. The best place is likely the build script of c++utilities so all projects can benefit from the fix.

Of course I can help with that (especially the last point).

@Martchus Martchus added the bug label Aug 30, 2017
@Martchus
Copy link
Owner

Martchus commented Sep 19, 2017

And, did you do any of the mentioned steps?


I have just checked build scripts of tageditor and its dependencies and I see nowhere use of include_directories or target_include_directories with SYSTEM argument so the system includes shouldn't be messed. But that would be the most likely explanation for this issue. Maybe a CMake toolchain file or wrong CLI arguments passed to CMake cause this behavior?

@ghost
Copy link
Author

ghost commented Sep 19, 2017

Which version of CMake do you use? (I use CMake 3.9.1.)

$ cmake --version
cmake version 3.6.2

Execute make VERBOSE=1 to get the failing line. (This important information is
missing in your log.)

x86_64-w64-mingw32-g++.exe -DCPP_UTILITIES_STATIC \
-DCPP_UTILITIES_USE_NATIVE_FILE_BUFFER -DLEGACY_API -DTAG_PARSER_STATIC \
-I/var/cache/glade/tagparser/.. -I/var/cache/glade/tagparser \
-isystem /usr/x86_64-w64-mingw32/sys-root/mingw/include -std=gnu++14 \
-o CMakeFiles/tagparser_static.dir/mp4/mp4tagfield.cpp.o \
-c /var/cache/glade/tagparser/mp4/mp4tagfield.cpp

Execute the failing line manually. The error should be reproducible.

same error if executed manually

Check for obvious mistakes in the line.

If I change this:

-isystem /usr/x86_64-w64-mingw32/sys-root/mingw/include

to this:

-I /usr/x86_64-w64-mingw32/sys-root/mingw/include

it fixes it - not sure what to change at a higher level to make that happen

@Martchus
Copy link
Owner

Martchus commented Sep 20, 2017

man g++:

       -I dir
       -iquote dir
       -isystem dir
       -idirafter dir
           Add the directory dir to the list of directories to be searched
           for header files during preprocessing.  If dir begins with =, then
           the = is replaced by the sysroot prefix; see --sysroot and
           -isysroot.

           Directories specified with -iquote apply only to the quote form of
           the directive, "#include "file"".  Directories specified with -I,
           -isystem, or -idirafter apply to lookup for both the
           "#include "file"" and "#include <file>" directives.

           You can specify any number or combination of these options on the
           command line to search for header files in several directories.
           The lookup order is as follows:

           1.  For the quote form of the include directive, the directory of
               the current file is searched first.

           2.  For the quote form of the include directive, the directories
               specified by -iquote options are searched in left-to-right
               order, as they appear on the command line.

           3.  Directories specified with -I options are scanned in left-to-
               right order.

           4.  Directories specified with -isystem options are scanned in
               left-to-right order.

           5.  Standard system directories are scanned.

           6.  Directories specified with -idirafter options are scanned in
               left-to-right order.

           You can use -I to override a system header file, substituting your
           own version, since these directories are searched before the
           standard system header file directories.  However, you should not
           use this option to add directories that contain vendor-supplied
           system header files; use -isystem for that.

           The -isystem and -idirafter options also mark the directory as a
           system directory, so that it gets the same special treatment that
           is applied to the standard system directories.

           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.

So the search order for includes should be the same, regardless whether -I or -isystem is used:

  1. /var/cache/glade/tagparser/.. (used for the Building this straight approach in case you're wondering about it)
  2. /var/cache/glade/tagparser
  3. /usr/x86_64-w64-mingw32/sys-root/mingw/include
  4. Standard system directories (which may contain /usr/x86_64-w64-mingw32/sys-root/mingw/include already)

So the only difference between those options is (as far as I see it) the "special treatment that is applied to the standard system directories".


Regardless why it makes a difference, you should be able to convince CMake to omit -isystem and maybe use -I by passing the following arguments to it:

cmake \
  -DCMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES:PATH='/usr/x86_64-w64-mingw32/sys-root/mingw/include' \
  -DCMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES:PATH='/usr/x86_64-w64-mingw32/sys-root/mingw/include' \
  -DCMAKE_CXX_FLAGS:STRING='-I/usr/x86_64-w64-mingw32/sys-root/mingw/include'

The first ones cause CMake to omit -isystem /usr/x86_64-w64-mingw32/sys-root/mingw/include. The last one should add -I/usr/x86_64-w64-mingw32/sys-root/mingw/include. Note that adding -I... is maybe not required (it looks like a default directory).

@ghost
Copy link
Author

ghost commented Sep 20, 2017

hm - so you are saying -isystem dir should be the same as -I dir - so maybe it is a GCC issue after all - I will check again with Cygwin GCC maintainer - thanks

@Martchus
Copy link
Owner

Martchus commented Sep 20, 2017

so you are saying -isystem dir should be the same as -I dir

Yes, in this particular case and only concerning the order in which the search paths are being used. Not exactly sure which difference this "special treatment that is applied to the standard system directories" makes. Apparently more than what's in the documentation.


Is the -isystem ... actually required in your case? If not, I wouldn't consider telling CMake to omit it a workaround. That's what the IMPLICIT_INCLUDE_DIRECTORIES variables are for.

I suppose that specifying a directory which is already default again explicitly via -isystem is a thing that one just shouldn't do. I'm able to reproduce the issue by compiling a simple program which just includes cstdlib:

# using default g++, version 7.2.0 as provided by Arch Linux
g++ -isystem /usr/include test.cpp -o /dev/null
In file included from /usr/include/c++/7.2.0/ext/string_conversions.h:41:0,
                 from /usr/include/c++/7.2.0/bits/basic_string.h:6159,
                 from /usr/include/c++/7.2.0/string:52,
                 from /usr/include/c++/7.2.0/bits/locale_classes.h:40,
                 from /usr/include/c++/7.2.0/bits/ios_base.h:41,
                 from /usr/include/c++/7.2.0/ios:42,
                 from /usr/include/c++/7.2.0/ostream:38,
                 from /usr/include/c++/7.2.0/iostream:39,
                 from dynamic_cast.cpp:1:
/usr/include/c++/7.2.0/cstdlib:75:15: fatal error: stdlib.h: No such file or directory
 #include_next <stdlib.h>
               ^~~~~~~~~~
compilation terminated.

So if specifying a default include dir again with -isystem messes things (for whatever reason), why not just don't do it?


However, if you then still need -I ... (because the directory is not in the defaults) I would also say it might be a GCC issue after all.

@ghost
Copy link
Author

ghost commented Sep 21, 2017

Your suggestion for:

-DCMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES:PATH=/usr/x86_64-w64-mingw32/sys-root/mingw/include
-DCMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES:PATH=/usr/x86_64-w64-mingw32/sys-root/mingw/include

Makes sense - we shouldnt be letting Cmake include that explicitly if we dont
need to - however I feel it should still work even if we do explicitly include
it - that is how it worked with 5.4.0:

$ cat alfa.cpp
#include <cstdio>
#include <functional>
int main() {
 puts("hello world");
}

$ x86_64-w64-mingw32-g++ --version
x86_64-w64-mingw32-g++ (GCC) 5.4.0

$ x86_64-w64-mingw32-g++ \
-I /usr/x86_64-w64-mingw32/sys-root/mingw/include alfa.cpp

$ x86_64-w64-mingw32-g++ \
-isystem /usr/x86_64-w64-mingw32/sys-root/mingw/include alfa.cpp

Running the last command with GCC 6.3.0 causes the problem. So for now I think I
will continue to use the "broken" 6.3.0 with the IMPLICIT option you suggest -
at least until if/when 6.3.0 is "fixed" - thanks

@ghost ghost closed this as completed Sep 23, 2017
@Martchus Martchus added out of scope and removed bug labels Sep 25, 2017
@lslavkov
Copy link

lslavkov commented Dec 3, 2017

Sorry to post off topic but I'm experiencing the similar issue at Linux from Scratch. When I do a cmd 'make tooldir/=usr' for Binutilus (chapter 6.16 for version 8.1) it gives me the error:

In file included from ../../gold/gold.h:30:0,
from ../../gold/archive.cc:23:
/usr/include/c++/7/cstdlib:75:15: fatal error: stdlib.h: No such file or directory
#include_next <stdlib.h>

I posted this on linuxquestions.org but the answer I received is to start all over again which unlikely.

@Martchus
Copy link
Owner

Martchus commented Dec 3, 2017

I can summarize for you what this issue was about:

  • The issue was triggered by updating to GCC >= 6
  • which doesn't like when you explicitly specify an include search path with -isystem which is implicitly present anyways.
  • The workaround is to simply stop the build system from adding such an include path to the compiler invocation.

If your issue has the same source, you could apply the same workaround. For further investigation, you could also try to follow the steps in my first comment on this issue being aware that the gold linker is likely not using the CMake build system and verbose output is hence likely enabled in a slightly different way. I assume the project you want to build is the gold linker of the GNU binutils?

@lslavkov
Copy link

lslavkov commented Dec 3, 2017

@Martchus thank you for replying. I was trying to do with -isystem(-I) but that could not work at my side. While did some research on internet the problem showed at /usr/include/c++/7/cstdlib and /usr/include/c++/7/bits/std_abs.h. Only thing was to remove the '_next' from #include_next <stdlib.h> and #include_next <math.h>(located on second file).

@changshen
Copy link

changshen commented Aug 29, 2018

I got the same problem when I have two version of gcc/g++ installed. Old version is in /usr/include and new version is in =/usr/local/include/c++/8.2.0.

>locate stdlib.h 
return results:
/opt/rh/devtoolset-3/root/usr/include/c++/4.9.2/tr1/stdlib.h
/usr/include/stdlib.h
/usr/include/bits/stdlib.h
/usr/include/boost/cstdlib.hpp
/usr/include/c++/4.4.4/tr1/stdlib.h
/usr/include/freetype2/freetype/config/ftstdlib.h
/usr/local/include/c++/8.2.0/stdlib.h
/usr/local/include/c++/8.2.0/tr1/stdlib.h

change the order of CPLUS_INCLUDE_PATH will solve the problem.

export CPLUS_INCLUDE_PATH=/usr/local/include/c++/8.2.0:/usr/local/include:/usr/include:$CPLUS_INCLUDE_PATH

put this in your ~/.bashrc

@Martchus
Copy link
Owner

Martchus commented Aug 29, 2018

@changshen Thanks for sharing your findings. Keep in mind that you've just hardcoded the GCC version into your ~/.bashrc. So after updating GCC the problem is likely to reoccur.

Reminds me of something hacky I had to do for cross compiling with mingw-w64 while using native clang tooling. To make it at least a little bit robust, I avoided hardcoding the GCC version: https://github.com/Martchus/PKGBUILDs/blob/master/tageditor/mingw-w64-static/PKGBUILD#L40

This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants