gcc compilation terminated with "fatal error: string: No such file or directory #include <string>"

37,202

Solution 1

That's looking for a C++ header file, normally part of a development package such as libstdc++ (with a version and "-dev" or "-devel" as part of the package name).

For instance in Debian (where Ubuntu gets most of its packages), I have a "libstdc++6-4.6-dev" on my Debian 7 machine, which has this file:

/usr/include/c++/4.6/string

The C header files have a .h suffix; C++ as a rule does not (though on some systems you may see .hh).

When you configured the add-on compiler, it used settings (see your logs...) which told it where to expect to find libraries. You'll probably have to build your own libstdc++ for compatibility with the newer compiler. Again, you'll have to set the --prefix option when configuring, so the compiler and library work together.

Addressing a followup: if your compiler is looking in /usr/local, then you could work around this by amending your CPPFLAGS variable, adding /usr/include (and possibly /usr/include/c++/4.8, etc.), though there's also the library path in LDFLAGS to consider). To see the pathnames used by your libstdc++ package, use

dpkg -L $(dpkg -l | awk '{print $2}' |grep -E 'libstdc++.*dev')

Solution 2

What follows is one avenue to a solution. I am indebted to Thomas Dickey answer for having put me in the right direction.

Issue

The problem is that the custom-installed compiler gcc 6.3.0 cannot find the files of the libstdc++ family contained within /usr/include/ in the Ubuntu distribution.

Cause

At point of installation, the configure file for gcc 6.3.0 itself silently followed the default specification as for the target directory where to find local (previously installed) header files. This default is /usr/local/include/. See https://gcc.gnu.org/install/configure.html for details.

Fix

The compiler reinstalled with the ./configure --with-local-prefix=/usr has created a new gcc that is able to fetch the required files where Ubuntu has put them. No further adjustement of the CPPFLAGS is needed with respect to what has been shown in the question. However, the setting --with-local-prefix=/usr is discouraged (see quote in https://unix.stackexchange.com/a/348868/132913), so this is a workaround.

Check

The empirical test for this strategy is that the make of HDF 1.8.18 proceeds where it once got stranded. All tests in the make check are passed successfully.

Alternatives

I have note explored (yet) the other avenue of installing a fresh libstdc++ library that serves specifically the custom install of gcc (switch --enable-version-specific-runtime-libs). I have raised this possibility in the question frame above in search of cues. That might well be a more robust solution. The thread remains open for the moment. Thanks for contributing/editing

Share:
37,202

Related videos on Youtube

XavierStuvw
Author by

XavierStuvw

Proficiency, competence and ambitions of an educated layman, interested in much, expert in little Some experience with programming in FORTRAN, C++, Matlab/Octave, Python and R. Using Linux since 2014 and committed to it I like it when a computer does what I want. It's a creative accomplishment where knowing what I want and wanting what I know come together Happy to help and to be corrected

Updated on September 18, 2022

Comments

  • XavierStuvw
    XavierStuvw over 1 year

    My situation. uname -a gives Linux computer2 4.4.0-62-generic #83~14.04.1-Ubuntu SMP Wed Jan 18 18:10:30 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux

    I am trying to install HDF5 1.8.18 with GNU make 3.81 invoking gcc 6.3.0. I have successfully installed this gcc 6.3.0 alongside the version 4.8.4 that is shipped with the Ubuntu distribution.

    My gcc 6.3.0 lives in /opt/gcc/6_3_0/. I use the following script to configure and pass on the commands, libraries and headers in non-standard directories:

    export FC='/opt/gcc/6_3_0/bin/gfortran-6.3.0'   # probably unnecessary
    export CC='/opt/gcc/6_3_0/bin/gcc-6.3.0'  
    export CXX='/opt/gcc/6_3_0/bin/g++-6.3.0' 
    export CPP='/opt/gcc/6_3_0/bin/cpp-6.3.0'
    export LDFLAGS='-L/opt/gcc/6_3_0/lib -L/opt/gcc/6_3_0/lib64' 
    export CPPFLAGS='-I/opt/gcc/6_3_0/include -I/opt/gcc/6_3_0/lib/gcc/x86_64-pc-linux-gnu/6.3.0/include'
    
    ./configure \
    --prefix=${insdir} \
    --with-zlib=${zlibdir}/include,${zlibdir}/lib \
    --enable-fortran \
    --enable-cxx
    

    where ${insdir} is an installation directory, ${zlibdir} is where zlib lives and the other switches are standards as per the installation guidelines

    The configure step goes well. The make step fails with the error:

    make[2]: Entering directory `<the source directory>/hdf5-1.8.18/c++/src'
    CXX      H5Exception.lo
    H5Exception.cpp:16:18: fatal error: string: No such file or directory
    #include <string>
                    ^
    compilation terminated
    

    If I understand it correctly, some header file is missing, and of a basic nature.

    • Where should I get it from?
    • Is there any flaw in the names and values of the environment variables?

    StackExchange contains a host of posts on this error, but they seem to be mostly related to coding exercises. My aim is not to edit codes, rather to compile source codes successfully with my vanilla gcc 6.3.0.

    Updated question

    In the light of the helpful comments and Thomas Dickey's answer below, it appears that a promising avenue is to install matching versions of libstdc++ and gcc. I have searched around in the GCC website and it appears that one can configure gcc with the following switch

    --enable-version-specific-runtime-libs

    Specify that runtime libraries should be installed in the compiler specific subdirectory (libdir/gcc) rather than the usual places. In addition, libstdc++'s include files will be installed into libdir unless you overruled it by using --with-gxx-include-dir=dirname. Using this option is particularly useful if you intend to use several versions of GCC in parallel. This is currently supported by ‘libgfortran’, ‘libstdc++’, and ‘libobjc’.

    • Is this pointing in the right direction?
    • Where would I be supposed to find the libstdc++'s include files that are distributed alongside the source of gcc, if this is switch is not used?
    • smw
      smw about 7 years
      Are you sure you can chain -I include directives in your CPPFLAGS like that (i.e. comma separated)? I've always thought you need a separate -I for each path. FWIW you might consider using gcc's CPATH instead - which does take a list of (colon separated) paths.
    • Kusalananda
      Kusalananda about 7 years
      The -I flag takes exactly one directory. If you have multiple include directories, specify each of them separately with -I.
    • XavierStuvw
      XavierStuvw about 7 years
      Thx @Kusalananda @steeldriver -- I have edited the line in the post and in my script alike. This does not solve the issue. Also adding -I/usr/include to gain access to the header file string.h does not help.
  • smw
    smw about 7 years
    @XavierStuvw string.h would be a C header file; your issue appears to concern the C++ header file string
  • XavierStuvw
    XavierStuvw about 7 years
    @steeldriver I stand corrected also in the light of Thomas Dickey's note. In my computer the header file string lives in the directories /usr/include/c++/4.4 and /usr/include/c++/4.8. Either way setting the CPPFLAG to search for string is no plain sailing since it asks for more and more files. I am editing my questions to adjust to the insights gained so far,
  • XavierStuvw
    XavierStuvw about 7 years
    @ThomasDickey Would you please consider the updated question in my post? It seems that there are ways (hints) to combine the installation of gcc and of libstdc++ in one go. The avenue of working around with CPPFLAGS looks like a quagmire.
  • Marius
    Marius about 7 years
    That looks promising, but it's been a while since I built those - good luck :-)