4

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
6
  • 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. Sep 22, 2018 at 20:16
  • 1
    How did you install G++8?
    – muru
    Sep 23, 2018 at 14:41
  • Post the ouput of the g++ command with -v -Wall flags. (g++ -v -Wall ........)
    – abu_bua
    Sep 23, 2018 at 19:07
  • @muru I installed g++8 with sudo apt install g++-8 @abu_bua Added the output as requested. Sep 24, 2018 at 0:49
  • 1
    @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.
    – muru
    Sep 24, 2018 at 2:15

1 Answer 1

1

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++
4
  • 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. Sep 23, 2018 at 14:00
  • 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? Sep 23, 2018 at 14:35
  • I have modified my response, please see if it works (see the Update section)
    – marko
    Sep 24, 2018 at 8:29
  • 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. Sep 24, 2018 at 12:41

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .