Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

experimental::filesystem linker error while using GCC6 after using -lstdc++fs option

Tags:

c++

gcc

c++17

While trying to use the current GCC for using some new/experimental stuff in C++, I am facing the linking error. It seems that similar question was already posted, however still getting the error.

Could somebody explain me what/where wrong I have done over here?. Hope I have provided all detailed information related to this.

test.cpp

#include<iostream>
#include<string>
#include<experimental/filesystem>
namespace fs = std::experimental::filesystem;

    int main(int argc, const char* argv[])
    {
        std::string s(argv[0]);
        fs::path p(s);
        std::cout << "p = " << p << std::endl;

        return 0;
    }

I have built(debug version) the new gcc version 6.0.0 20151122 (experimental) (GCC) as g++-6.0.0. Here I am using new -lstdc++fs option which is required for FS TS. I am able to use the other new stuff like C++ concept.

~/practice/gcc6$ g++-6.0.0 -v -g -lstdc++fs -o out test.cpp
Using built-in specs.
COLLECT_GCC=g++-6.0.0
COLLECT_LTO_WRAPPER=/usr/gcc_6_0/libexec/gcc/x86_64-linux-gnu/6.0.0/lto-wrapper
Target: x86_64-linux-gnu
Configured with: ../configure --build=x86_64-linux-gnu --prefix=/usr/gcc_6_0 --with-gmp=/usr/gcc_6_0 --with-mpfr=/usr/gcc_6_0 --with-mpc=/usr/gcc_6_0 --enable-languages=c,c++,fortran --disable-multilib --program-suffix=-6.0.0
Thread model: posix
gcc version 6.0.0 20151122 (experimental) (GCC) 
COLLECT_GCC_OPTIONS='-v' '-g' '-o' 'out' '-shared-libgcc' '-mtune=generic' '-march=x86-64'
 /usr/gcc_6_0/libexec/gcc/x86_64-linux-gnu/6.0.0/cc1plus -quiet -v -imultiarch x86_64-linux-gnu -D_GNU_SOURCE test.cpp -quiet -dumpbase test.cpp -mtune=generic -march=x86-64 -auxbase test -g -version -o /tmp/ccX3oTv2.s
GNU C++ (GCC) version 6.0.0 20151122 (experimental) (x86_64-linux-gnu)
    compiled by GNU C version 6.0.0 20151122 (experimental), GMP version 6.1.0, MPFR version 3.1.3, MPC version 1.0.3
GGC heuristics: --param ggc-min-expand=30 --param ggc-min-heapsize=4096
ignoring nonexistent directory "/usr/local/include/x86_64-linux-gnu"
ignoring nonexistent directory "/usr/gcc_6_0/lib/gcc/x86_64-linux-gnu/6.0.0/../../../../x86_64-linux-gnu/include"
#include "..." search starts here:
#include <...> search starts here:
 /usr/gcc_6_0/lib/gcc/x86_64-linux-gnu/6.0.0/../../../../include/c++/6.0.0
 /usr/gcc_6_0/lib/gcc/x86_64-linux-gnu/6.0.0/../../../../include/c++/6.0.0/x86_64-linux-gnu
 /usr/gcc_6_0/lib/gcc/x86_64-linux-gnu/6.0.0/../../../../include/c++/6.0.0/backward
 /usr/gcc_6_0/lib/gcc/x86_64-linux-gnu/6.0.0/include
 /usr/local/include
 /usr/gcc_6_0/include
 /usr/gcc_6_0/lib/gcc/x86_64-linux-gnu/6.0.0/include-fixed
 /usr/include/x86_64-linux-gnu
 /usr/include
End of search list.
GNU C++14 (GCC) version 6.0.0 20151122 (experimental) (x86_64-linux-gnu)
    compiled by GNU C version 6.0.0 20151122 (experimental), GMP version 6.1.0, MPFR version 3.1.3, MPC version 1.0.3
GGC heuristics: --param ggc-min-expand=30 --param ggc-min-heapsize=4096
Compiler executable checksum: 14452760b2e0f1df03cbd137364317c8
COLLECT_GCC_OPTIONS='-v' '-g' '-o' 'out' '-shared-libgcc' '-mtune=generic' '-march=x86-64'
 as -v --64 -o /tmp/ccMWw2R6.o /tmp/ccX3oTv2.s
GNU assembler version 2.25.1 (x86_64-linux-gnu) using BFD version (GNU Binutils for Ubuntu) 2.25.1
COMPILER_PATH=/usr/gcc_6_0/libexec/gcc/x86_64-linux-gnu/6.0.0/:/usr/gcc_6_0/libexec/gcc/x86_64-linux-gnu/6.0.0/:/usr/gcc_6_0/libexec/gcc/x86_64-linux-gnu/:/usr/gcc_6_0/lib/gcc/x86_64-linux-gnu/6.0.0/:/usr/gcc_6_0/lib/gcc/x86_64-linux-gnu/
LIBRARY_PATH=/usr/gcc_6_0/lib/gcc/x86_64-linux-gnu/6.0.0/:/usr/gcc_6_0/lib/gcc/x86_64-linux-gnu/6.0.0/../../../../lib64/:/lib/x86_64-linux-gnu/:/lib/../lib64/:/usr/lib/x86_64-linux-gnu/:/usr/lib/../lib64/:/usr/gcc_6_0/lib/gcc/x86_64-linux-gnu/6.0.0/../../../:/lib/:/usr/lib/
COLLECT_GCC_OPTIONS='-v' '-g' '-o' 'out' '-shared-libgcc' '-mtune=generic' '-march=x86-64'
 /usr/gcc_6_0/libexec/gcc/x86_64-linux-gnu/6.0.0/collect2 -plugin /usr/gcc_6_0/libexec/gcc/x86_64-linux-gnu/6.0.0/liblto_plugin.so -plugin-opt=/usr/gcc_6_0/libexec/gcc/x86_64-linux-gnu/6.0.0/lto-wrapper -plugin-opt=-fresolution=/tmp/ccQOTKmb.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 --eh-frame-hdr -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o out /usr/lib/x86_64-linux-gnu/crt1.o /usr/lib/x86_64-linux-gnu/crti.o /usr/gcc_6_0/lib/gcc/x86_64-linux-gnu/6.0.0/crtbegin.o -L/usr/gcc_6_0/lib/gcc/x86_64-linux-gnu/6.0.0 -L/usr/gcc_6_0/lib/gcc/x86_64-linux-gnu/6.0.0/../../../../lib64 -L/lib/x86_64-linux-gnu -L/lib/../lib64 -L/usr/lib/x86_64-linux-gnu -L/usr/lib/../lib64 -L/usr/gcc_6_0/lib/gcc/x86_64-linux-gnu/6.0.0/../../.. -lstdc++fs /tmp/ccMWw2R6.o -lstdc++ -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc /usr/gcc_6_0/lib/gcc/x86_64-linux-gnu/6.0.0/crtend.o /usr/lib/x86_64-linux-gnu/crtn.o
/tmp/ccMWw2R6.o: In function `std::experimental::filesystem::v1::__cxx11::path::path<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::experimental::filesystem::v1::__cxx11::path>(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)':
/usr/gcc_6_0/include/c++/6.0.0/experimental/bits/fs_path.h:167: undefined reference to `std::experimental::filesystem::v1::__cxx11::path::_M_split_cmpts()'
collect2: error: ld returned 1 exit status

The below provides detailed version information of GCC installed on machine.

~/practice/gcc6$ g++-6.0.0 -v
Using built-in specs.
COLLECT_GCC=g++-6.0.0
COLLECT_LTO_WRAPPER=/usr/gcc_6_0/libexec/gcc/x86_64-linux-gnu/6.0.0/lto-wrapper
Target: x86_64-linux-gnu
Configured with: ../configure --build=x86_64-linux-gnu --prefix=/usr/gcc_6_0 --with-gmp=/usr/gcc_6_0 --with-mpfr=/usr/gcc_6_0 --with-mpc=/usr/gcc_6_0 --enable-languages=c,c++,fortran --disable-multilib --program-suffix=-6.0.0
Thread model: posix
gcc version 6.0.0 20151122 (experimental) (GCC)

Tried to extract the libstdc++fs.a. From below commands I could see that below method does exist in dir.o object file. However still linker is throwing the undefined reference error.

~/practice/gcc6$ ar t /usr/gcc_6_0/lib64/libstdc++fs.a
dir.o
ops.o
path.o
cow-dir.o
cow-ops.o
cow-path.o

~/practice/gcc6$ nm dir.o |grep "split"
                 U _ZNSt12experimental10filesystem2v17__cxx114path14_M_split_cmptsEv

~/practice/gcc6$ nm dir.o |c++filt |grep "split"
                 U std::experimental::filesystem::v1::__cxx11::path::_M_split_cmpts(

)

It seems that path has also been set correctly.

~/practice/gcc6$ which g++-6.0.0
/usr/gcc_6_o/bin/g++-6.0.0

This is debug version.

~/practice/gcc6$ file /usr/gcc_6_0/bin/g++-6.0.0
/usr/gcc_6_0/bin/g++-6.0.0: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, not stripped

Update

By putting the -lstdc++fs at the end of the command has worked fine as suggested by Galik in the comment. However I would like to know how did you identify that the command used by me is wrong?.

From all my analysis, I was not able to identify any clue from GCC which could have pointed towards this. It would be great is someone could provide some detailed input on the ordering of the new linker option(-lstdc++fs). There is no information in the GCC documentation regarding the ordering of this linker option.

like image 217
Mantosh Kumar Avatar asked Jan 04 '16 06:01

Mantosh Kumar


1 Answers

As written in the GCC documentation:

-llibrary
-l library
...
It makes a difference where in the command you write this option; the linker searches and processes libraries and object files in the order they are specified. Thus, ‘foo.o -lz bar.o’ searches library ‘z’ after file foo.o but before bar.o. If bar.o refers to functions in ‘z’, those functions may not be loaded.

Thus you have to put -lstdc++fs after test.cpp on the command line.

like image 151
Alexei Khlebnikov Avatar answered Oct 05 '22 05:10

Alexei Khlebnikov