How can I determine and change the version of the C++ standard library that g++ is using?
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++
Related videos on Youtube
user2596667
Updated on September 18, 2022Comments
-
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 almost 6 yearsOddly, 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 almost 6 yearsHow did you install G++8?
-
abu_bua almost 6 yearsPost the ouput of the g++ command with -v -Wall flags. (
g++ -v -Wall ........
) -
user2596667 almost 6 years@muru I installed g++8 with
sudo apt install g++-8
@abu_bua Added the output as requested. -
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 thatlibstdc++fs.a
is a static library, so it should come after the source code file itself. -
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 almost 6 yearsThat 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 almost 6 yearsOne 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 almost 6 yearsI have modified my response, please see if it works (see the Update section)
-
user2596667 almost 6 yearsThe 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.