How can I determine and change the version of the C++ standard library that g++ is using?

15,499

My program compiled but it won't link, and I suspect it's because I have multiple versions of the C++ standard library installed, one for g++ version 7 and one for g++ version 8. I need it to link with libstdc++-8-dev to get C++-17 features.

The reason your program won't link is because you are not passing the correct parameters during the compilation process. The compiler can see the function declarations but the linker cannot find the function implementations.

You need to tell the system which version / implementation to use by explicitly telling the version of the library you want to use and you do this with the -l parameter. In your case, you will probably need to preceed the -l parameter with the -L parameter.

Here is an example:

g++ myfile.cpp -L/usr/lib/gcc/x86_64-linux-gnu/7 -lstdc++

If you have v8 installed, unless the libs are installed somewhere else, you can do:

g++ myfile.cpp -L/usr/lib/gcc/x86_64-linux-gnu/8 -lstdc++

That should do it.

Do the following:

sudo updatedb
locate libstdc

and edit your question and post the output. I will try to build the exact command.

UPDATE: I can see you have:

/usr/lib/gcc/x86_64-linux-gnu/8/libstdc++.a  
/usr/lib/gcc/x86_64-linux-gnu/8/libstdc++.so  
/usr/lib/gcc/x86_64-linux-gnu/8/libstdc++fs.a  

Can you see if this works?

g++ test.cpp -std=c++11 -L/usr/lib/gcc/x86_64-linux-gnu/8 -lstdc++
Share:
15,499

Related videos on Youtube

user2596667
Author by

user2596667

Updated on September 18, 2022

Comments

  • user2596667
    user2596667 almost 2 years

    I have a C++ program that I'm trying to update to use the std::filesystem library which is in the standard library of the new C++-17. I had to install g++ version 8 to get C++-17 features. My program compiled but it won't link, and I suspect it's because I have multiple versions of the C++ standard library installed, one for g++ version 7 and one for g++ version 8. I need it to link with libstdc++-8-dev to get C++-17 features.

    How can I determine which version of libstdc++ is being used by g++? Is it possible to switch the version? Ideally I do want multiple versions on my computer, because some Ubuntu packages compile C++ code and might need the older version, but I want my program to use g++ 8 and Ubuntu to use whatever it usually uses.

    UPDATE: The errors I've been getting described below have been resolved (see comments). But I'm still curious about the questions I ask above.

    The errors I'm getting are similar to these: https://stackoverflow.com/questions/51252829/stdfilesystemdirectory-iterator-linker-issue-c17

    However I tried their solution of adding the -lstdc++fs option and it made no difference.

    EDIT: I found the static library file for std::filesystem and linked with it explicitly by adding it to the g++ linking command, and the errors went away:

    g++ $(CXXFLAGS) $(obj) /usr/lib/gcc/x86_64-linux-gnu/8/libstdc++fs.a
    

    This suggests that it is indeed unable to find the correct version of the standard library when linking. Why?

    EDIT: As requested below, this is the result of locate libstdc:

    /snap/core/5328/usr/lib/x86_64-linux-gnu/libstdc++.so.6  
    /snap/core/5328/usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21  
    /snap/core/5328/usr/share/doc/libstdc++6  
    /snap/core/5328/usr/share/gcc-5/python/libstdcxx  
    /snap/core/5328/usr/share/gcc-5/python/libstdcxx/__init__.py  
    /snap/core/5328/usr/share/gcc-5/python/libstdcxx/v6  
    /snap/core/5328/usr/share/gcc-5/python/libstdcxx/v6/__init__.py  
    /snap/core/5328/usr/share/gcc-5/python/libstdcxx/v6/printers.py  
    /snap/core/5328/usr/share/gcc-5/python/libstdcxx/v6/xmethods.py  
    /snap/core/5328/usr/share/gdb/auto-load/usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21-gdb.py  
    /usr/lib/gcc/x86_64-linux-gnu/7/libstdc++.a  
    /usr/lib/gcc/x86_64-linux-gnu/7/libstdc++.so  
    /usr/lib/gcc/x86_64-linux-gnu/7/libstdc++fs.a  
    /usr/lib/gcc/x86_64-linux-gnu/8/libstdc++.a  
    /usr/lib/gcc/x86_64-linux-gnu/8/libstdc++.so  
    /usr/lib/gcc/x86_64-linux-gnu/8/libstdc++fs.a  
    /usr/lib/i386-linux-gnu/libstdc++.so.6  
    /usr/lib/i386-linux-gnu/libstdc++.so.6.0.25  
    /usr/lib/x86_64-linux-gnu/libstdc++.so.6  
    /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25  
    /usr/lib32/libstdc++.so.6  
    /usr/lib32/libstdc++.so.6.0.25  
    /usr/share/doc/libstdc++-7-dev  
    /usr/share/doc/libstdc++-8-dev  
    /usr/share/doc/libstdc++6  
    /usr/share/doc/gcc-7-base/C++/README.libstdc++-baseline.amd64  
    /usr/share/doc/gcc-7-base/C++/changelog.libstdc++.gz  
    /usr/share/doc/gcc-7-base/C++/libstdc++_symbols.txt.amd64  
    /usr/share/doc/gcc-8-base/C++/README.libstdc++-baseline.amd64  
    /usr/share/doc/gcc-8-base/C++/changelog.libstdc++.gz  
    /usr/share/doc/gcc-8-base/C++/libstdc++_symbols.txt.amd64  
    /usr/share/gcc-8/python/libstdcxx  
    /usr/share/gcc-8/python/libstdcxx/__init__.py  
    /usr/share/gcc-8/python/libstdcxx/v6  
    /usr/share/gcc-8/python/libstdcxx/v6/__init__.py  
    /usr/share/gcc-8/python/libstdcxx/v6/printers.py  
    /usr/share/gcc-8/python/libstdcxx/v6/xmethods.py  
    /usr/share/gdb/auto-load/usr/lib/i386-linux-gnu/libstdc++.so.6.0.25-gdb.py  
    /usr/share/gdb/auto-load/usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25-gdb.py  
    /usr/share/gdb/auto-load/usr/lib32/libstdc++.so.6.0.25-gdb.py  
    /usr/share/locale-langpack/en_GB/LC_MESSAGES/libstdc++.mo  
    /var/cache/apt/archives/libstdc++-7-dev_7.3.0-16ubuntu3_amd64.deb  
    /var/cache/apt/archives/libstdc++6_8-20180414-1ubuntu2_i386.deb  
    /var/lib/dpkg/info/libstdc++-7-dev:amd64.list  
    /var/lib/dpkg/info/libstdc++-7-dev:amd64.md5sums  
    /var/lib/dpkg/info/libstdc++-8-dev:amd64.list  
    /var/lib/dpkg/info/libstdc++-8-dev:amd64.md5sums  
    /var/lib/dpkg/info/libstdc++6:amd64.list  
    /var/lib/dpkg/info/libstdc++6:amd64.md5sums  
    /var/lib/dpkg/info/libstdc++6:amd64.postinst  
    /var/lib/dpkg/info/libstdc++6:amd64.prerm  
    /var/lib/dpkg/info/libstdc++6:amd64.shlibs  
    /var/lib/dpkg/info/libstdc++6:amd64.symbols  
    /var/lib/dpkg/info/libstdc++6:amd64.triggers  
    /var/lib/dpkg/info/libstdc++6:i386.list  
    /var/lib/dpkg/info/libstdc++6:i386.md5sums  
    /var/lib/dpkg/info/libstdc++6:i386.postinst  
    /var/lib/dpkg/info/libstdc++6:i386.prerm  
    /var/lib/dpkg/info/libstdc++6:i386.shlibs  
    /var/lib/dpkg/info/libstdc++6:i386.symbols  
    /var/lib/dpkg/info/libstdc++6:i386.triggers  
    

    EDIT: Here is a simple sample program that exhibits the problem on my machine:

    #include <filesystem>
    #include <iostream>
    
    int main()
    {
        std::filesystem::path p = "/";
        std::cout << p;
    }
    

    EDIT: I compiled the sample program with

    g++ -v -Wall -std=c++1z test.cpp
    

    and got this output:

    Using built-in specs.
    COLLECT_GCC=g++
    COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/8/lto-wrapper
    OFFLOAD_TARGET_NAMES=nvptx-none
    OFFLOAD_TARGET_DEFAULT=1
    Target: x86_64-linux-gnu
    Configured with: ../src/configure -v --with-pkgversion='Ubuntu 8-20180414-1ubuntu2' --with-bugurl=file:///usr/share/doc/gcc-8/README.Bugs --enable-languages=c,ada,c++,go,brig,d,fortran,objc,obj-c++ --prefix=/usr --with-gcc-major-version-only --with-as=/usr/bin/x86_64-linux-gnu-as --with-ld=/usr/bin/x86_64-linux-gnu-ld --program-suffix=-8 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-libmpx --enable-plugin --enable-default-pie --with-system-zlib --with-target-system-zlib --enable-objc-gc=auto --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
    Thread model: posix
    gcc version 8.0.1 20180414 (experimental) [trunk revision 259383] (Ubuntu 8-20180414-1ubuntu2) 
    COLLECT_GCC_OPTIONS='-v' '-Wall' '-std=c++17' '-shared-libgcc' '-mtune=generic' '-march=x86-64'
     /usr/lib/gcc/x86_64-linux-gnu/8/cc1plus -quiet -v -imultiarch x86_64-linux-gnu -D_GNU_SOURCE test.cpp -quiet -dumpbase test.cpp -mtune=generic -march=x86-64 -auxbase test -Wall -std=c++17 -version -fstack-protector-strong -Wformat-security -o /tmp/cchNMFhq.s
    GNU C++17 (Ubuntu 8-20180414-1ubuntu2) version 8.0.1 20180414 (experimental) [trunk revision 259383] (x86_64-linux-gnu)
        compiled by GNU C version 8.0.1 20180414 (experimental) [trunk revision 259383], GMP version 6.1.2, MPFR version 4.0.1, MPC version 1.1.0, isl version isl-0.19-GMP
    
    GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
    ignoring duplicate directory "/usr/include/x86_64-linux-gnu/c++/8"
    ignoring nonexistent directory "/usr/local/include/x86_64-linux-gnu"
    ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/8/../../../../x86_64-linux-gnu/include"
    #include "..." search starts here:
    #include <...> search starts here:
     /usr/include/c++/8
     /usr/include/x86_64-linux-gnu/c++/8
     /usr/include/c++/8/backward
     /usr/lib/gcc/x86_64-linux-gnu/8/include
     /usr/local/include
     /usr/lib/gcc/x86_64-linux-gnu/8/include-fixed
     /usr/include/x86_64-linux-gnu
     /usr/include
    End of search list.
    GNU C++17 (Ubuntu 8-20180414-1ubuntu2) version 8.0.1 20180414 (experimental) [trunk revision 259383] (x86_64-linux-gnu)
        compiled by GNU C version 8.0.1 20180414 (experimental) [trunk revision 259383], GMP version 6.1.2, MPFR version 4.0.1, MPC version 1.1.0, isl version isl-0.19-GMP
    
    GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
    Compiler executable checksum: 3e256d94cf1a8afbef1b441ddb5fe0dc
    COLLECT_GCC_OPTIONS='-v' '-Wall' '-std=c++17' '-shared-libgcc' '-mtune=generic' '-march=x86-64'
     /usr/bin/x86_64-linux-gnu-as -v --64 -o /tmp/cc4KG8eJ.o /tmp/cchNMFhq.s
    GNU assembler version 2.30 (x86_64-linux-gnu) using BFD version (GNU Binutils for Ubuntu) 2.30
    COMPILER_PATH=/usr/lib/gcc/x86_64-linux-gnu/8/:/usr/lib/gcc/x86_64-linux-gnu/8/:/usr/lib/gcc/x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/8/:/usr/lib/gcc/x86_64-linux-gnu/
    LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/8/:/usr/lib/gcc/x86_64-linux-gnu/8/../../../x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/8/../../../../lib/:/lib/x86_64-linux-gnu/:/lib/../lib/:/usr/lib/x86_64-linux-gnu/:/usr/lib/../lib/:/usr/lib/gcc/x86_64-linux-gnu/8/../../../:/lib/:/usr/lib/
    COLLECT_GCC_OPTIONS='-v' '-Wall' '-std=c++17' '-shared-libgcc' '-mtune=generic' '-march=x86-64'
     /usr/lib/gcc/x86_64-linux-gnu/8/collect2 -plugin /usr/lib/gcc/x86_64-linux-gnu/8/liblto_plugin.so -plugin-opt=/usr/lib/gcc/x86_64-linux-gnu/8/lto-wrapper -plugin-opt=-fresolution=/tmp/ccoQuLk2.res -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc --sysroot=/ --build-id --eh-frame-hdr -m elf_x86_64 --hash-style=gnu --as-needed -dynamic-linker /lib64/ld-linux-x86-64.so.2 -pie -z now -z relro /usr/lib/gcc/x86_64-linux-gnu/8/../../../x86_64-linux-gnu/Scrt1.o /usr/lib/gcc/x86_64-linux-gnu/8/../../../x86_64-linux-gnu/crti.o /usr/lib/gcc/x86_64-linux-gnu/8/crtbeginS.o -L/usr/lib/gcc/x86_64-linux-gnu/8 -L/usr/lib/gcc/x86_64-linux-gnu/8/../../../x86_64-linux-gnu -L/usr/lib/gcc/x86_64-linux-gnu/8/../../../../lib -L/lib/x86_64-linux-gnu -L/lib/../lib -L/usr/lib/x86_64-linux-gnu -L/usr/lib/../lib -L/usr/lib/gcc/x86_64-linux-gnu/8/../../.. /tmp/cc4KG8eJ.o -lstdc++ -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc /usr/lib/gcc/x86_64-linux-gnu/8/crtendS.o /usr/lib/gcc/x86_64-linux-gnu/8/../../../x86_64-linux-gnu/crtn.o
    /tmp/cc4KG8eJ.o: In function `std::filesystem::__cxx11::path::path<char [2], std::filesystem::__cxx11::path>(char const (&) [2], std::filesystem::__cxx11::path::format)':
    test.cpp:(.text._ZNSt10filesystem7__cxx114pathC2IA2_cS1_EERKT_NS1_6formatE[_ZNSt10filesystem7__cxx114pathC5IA2_cS1_EERKT_NS1_6formatE]+0x6d): undefined reference to `std::filesystem::__cxx11::path::_M_split_cmpts()'
    collect2: error: ld returned 1 exit status
    
    • user2596667
      user2596667 almost 6 years
      Oddly, I tried using clang++ instead to compile my code, but I got the same linking errors. So the standard library might not be the problem. But I would still like to know how to determine the standard library version to help narrow down the problem.
    • muru
      muru almost 6 years
      How did you install G++8?
    • abu_bua
      abu_bua almost 6 years
      Post the ouput of the g++ command with -v -Wall flags. (g++ -v -Wall ........)
    • user2596667
      user2596667 almost 6 years
      @muru I installed g++8 with sudo apt install g++-8 @abu_bua Added the output as requested.
    • muru
      muru almost 6 years
      @user2596667 your pasted output doesn't seem to include the -lstdc++fs flag. Also, are you sure that you included that flag at the end? Note that libstdc++fs.a is a static library, so it should come after the source code file itself.
    • user2596667
      user2596667 almost 6 years
      @muru: Thanks! That was my problem: I was putting the -lstdc++fs flag in the beginning of the command line options. When I put it at the end it works without needing to use -L to specify the library location. So in terms of my original question: is it accurate to say that g++ automatically selects the version of the standard library that's associated with the version of g++, and there's no way to change it?
  • user2596667
    user2596667 almost 6 years
    That didn't work: the linking errors came back when I replaced the library file with the -L and -l options, even when I also added -lstdc++fs. -L and -l shouldn't be needed for the standard library, should they? I thought they're for linking with external libraries. I edited the question as requested.
  • user2596667
    user2596667 almost 6 years
    One thing I notice in the above output is that there's a libstdc++fs.a but no libstdc++fs.so. Could that be related to the cause?
  • marko
    marko almost 6 years
    I have modified my response, please see if it works (see the Update section)
  • user2596667
    user2596667 almost 6 years
    The command you posted didn't work; filesystem is in C++-17, so using -std=c++11 prevents it from compiling. However, I've now got it working using the comment from @muru above - the problem was I had to put -lstdc++fs at the end of the command line options.