F
@HarteWare Danke, das scheint der Compiler des MSYS2-Projekts zu sein, bei denen schau ich auch immer gerne vorbei um zu sehen, ob ich vielleicht irgendwelche windows-spezifischen Patches vergessen habe. Mein GCC 8.2.0 sollte eigentlich auf dem selben Patch-Stand sein. Dort habe ich auch <filesystem> und die libstdc++fs. Bei obigem Code-Beispiel führt das aber bei meinem GCC wie erwähnt zu Linker-Fehlermeldungen. Ich werde deren GCC mal ausprobieren und schauen, ob es da läuft. Möglich, dass bei meinem Build irgendwas schiefgelaufen ist, oder es sich um Nebenwirkungen anderer Patches handelt.
Update: Habe jetzt mal den aktuellen GCC des MSYS2-Projekts getestet, leider läuft dieser auf die selben Linker-Fehler wie meine Version:
$ pacman -S mingw-w64-x86_64-gcc
...
$ g++ -v
Using built-in specs.
COLLECT_GCC=C:\msys64\mingw64\bin\g++.exe
COLLECT_LTO_WRAPPER=C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/8.2.1/lto-wrapper.exe
Target: x86_64-w64-mingw32
Configured with: ../gcc-8-20181123/configure --prefix=/mingw64 --with-local-prefix=/mingw64/local --build=x86_64-w64-mingw32 --host=x86_64-w64-mingw32 --target=x86_64-w64-mingw32 --with-native-system-header-dir=/mingw64/x86_64-w64-mingw32/include --libexecdir=/mingw64/lib --enable-bootstrap --with-arch=x86-64 --with-tune=generic --enable-languages=ada,c,lto,c++,objc,obj-c++,fortran --enable-shared --enable-static --enable-libatomic --enable-threads=posix --enable-graphite --enable-fully-dynamic-string --enable-libstdcxx-filesystem-ts=yes --enable-libstdcxx-time=yes --disable-libstdcxx-pch --disable-libstdcxx-debug --disable-isl-version-check --enable-lto --enable-libgomp --disable-multilib --enable-checking=release --disable-rpath --disable-win32-registry --disable-nls --disable-werror --disable-symvers --with-libiconv --with-system-zlib --with-gmp=/mingw64 --with-mpfr=/mingw64 --with-mpc=/mingw64 --with-isl=/mingw64 --with-pkgversion='Rev1, Built by MSYS2 project' --with-bugurl=https://sourceforge.net/projects/msys2 --with-gnu-as --with-gnu-ld
Thread model: posix
gcc version 8.2.1 20181123 (Rev1, Built by MSYS2 project)
$ cat test.cpp
#include <iostream>
#include <filesystem>
namespace fs = std::filesystem;
auto main() -> int
{
for (auto& entry : fs::directory_iterator("C:\\"))
std::cout << entry.path() << std::endl;
return 0;
}
$ g++ -std=c++17 -lstdc++fs -otest.exe test.cpp
C:\msys64\tmp\ccvfBIcq.o:test.cpp:(.text+0x1d9): undefined reference to `std::filesystem::__cxx11::directory_iterator::operator*() const'
C:\msys64\tmp\ccvfBIcq.o:test.cpp:(.text+0x213): undefined reference to `std::filesystem::__cxx11::directory_iterator::operator++()'
C:\msys64\tmp\ccvfBIcq.o:test.cpp:(.text$_ZNSt10filesystem7__cxx1116filesystem_errorC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESt10error_code[_ZNSt10filesystem7__cxx1116filesystem_errorC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESt10error_code]+0x93): undefined reference to `std::filesystem::__cxx11::filesystem_error::_M_gen_what()'
C:\msys64\tmp\ccvfBIcq.o:test.cpp:(.text$_ZNSt10filesystem7__cxx1118directory_iteratorC1ERKNS0_4pathE[_ZNSt10filesystem7__cxx1118directory_iteratorC1ERKNS0_4pathE]+0x28): undefined reference to `std::filesystem::__cxx11::directory_iterator::directory_iterator(std::filesystem::__cxx11::path const&, std::filesystem::directory_options, std::error_code*)'
C:\msys64\tmp\ccvfBIcq.o:test.cpp:(.text$_ZNSt10filesystem7__cxx114pathC1IA4_cS1_EERKT_NS1_6formatE[_ZNSt10filesystem7__cxx114pathC1IA4_cS1_EERKT_NS1_6formatE]+0x61): undefined reference to `std::filesystem::__cxx11::path::_M_split_cmpts()'
C:\msys64\tmp\ccvfBIcq.o:test.cpp:(.rdata$.refptr._ZNSt10filesystem7__cxx1116filesystem_errorD1Ev[.refptr._ZNSt10filesystem7__cxx1116filesystem_errorD1Ev]+0x0): undefined reference to `std::filesystem::__cxx11::filesystem_error::~filesystem_error()'
C:\msys64\tmp\ccvfBIcq.o:test.cpp:(.rdata$.refptr._ZTVNSt10filesystem7__cxx1116filesystem_errorE[.refptr._ZTVNSt10filesystem7__cxx1116filesystem_errorE]+0x0): undefined reference to `vtable for std::filesystem::__cxx11::filesystem_error'
collect2.exe: error: ld returned 1 exit status
Da scheint also nochwas im argen zu liegen. Ich würde mich sogar zu der Einschätzung hinreißen lassen, dass <filesystem> unter Windows von der libstdc++ derzeit noch nicht vollständg unterstützt wird ... selbst der aktuelle GCC-9-Entwicklungs-Branch hat dasselbe Problem. Es liegt also wahrscheinlich nicht daran, dass nur bei diesem Backport etwas nicht stimmt.
Update 2: Was mich jetzt wirklich stutzig macht, ist dass selbst mein Windows-zu-Linux-GCC ebenfalls diese Fehler ausspuckt:
$ x86_64-linux-musl-g++ -std=c++17 -lstdc++fs -otest.exe test.cpp
C:\Users\XXX~1\AppData\Local\Temp\ccT7c1r7.o: In function `main':
test.cpp:(.text+0xec): undefined reference to `std::filesystem::__cxx11::directory_iterator::operator*() const'
test.cpp:(.text+0x125): undefined reference to `std::filesystem::__cxx11::directory_iterator::operator++()'
C:\Users\XXX~1\AppData\Local\Temp\ccT7c1r7.o: In function `std::filesystem::__cxx11::directory_iterator::directory_iterator(std::filesystem::__cxx11::path const&)':
test.cpp:(.text._ZNSt10filesystem7__cxx1118directory_iteratorC2ERKNS0_4pathE[_ZNSt10filesystem7__cxx1118directory_iteratorC5ERKNS0_4pathE]+0x26): undefined reference to`std::filesystem::__cxx11::directory_iterator::directory_iterator(std::filesystem::__cxx11::path const&, std::filesystem::directory_options, std::error_code*)'
C:\Users\XXX~1\AppData\Local\Temp\ccT7c1r7.o: In function `std::filesystem::__cxx11::path::path<char [4], std::filesystem::__cxx11::path>(char const (&) [4], std::filesystem::__cxx11::path::format)':
test.cpp:(.text._ZNSt10filesystem7__cxx114pathC2IA4_cS1_EERKT_NS1_6formatE[_ZNSt10filesystem7__cxx114pathC5IA4_cS1_EERKT_NS1_6formatE]+0x5e): undefined reference to `std::filesystem::__cxx11::path::_M_split_cmpts()'
collect2.exe: error: ld returned 1 exit status
...muss nochmal weiter unter Linux testen. -lstdc++fs sollte doch eigentlich ausreichen, oder fehlt da noch irgendeine Compiler-Option?
Update 3: Lustig. Selbes Problem unter einer VM mit Alpine Linux (Edge):
alpine-vm:~$ g++ -v
Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-alpine-linux-musl/8.2.0/lto-wrapper
Target: x86_64-alpine-linux-musl
Configured with: /home/buildozer/aports/main/gcc/src/gcc-8.2.0/configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --build=x86_64-alpine-linux-musl --host=x86_64-alpine-linux-musl --target=x86_64-alpine-linux-musl --with-pkgversion='Alpine 8.2.0' --enable-checking=release --disable-fixed-point --disable-libstdcxx-pch --disable-multilib --disable-nls --disable-werror --disable-symvers --enable-__cxa_atexit --enable-default-pie --enable-default-ssp --enable-cloog-backend --enable-languages=c,c++,objc,fortran,ada --disable-libssp --disable-libmpx --disable-libmudflap --disable-libsanitizer --enable-shared --enable-threads --enable-tls --with-system-zlib --with-linker-hash-style=gnu
Thread model: posix
gcc version 8.2.0 (Alpine 8.2.0)
alpine-vm:~$ cat test.cpp
#include <iostream>
#include <filesystem>
namespace fs = std::filesystem;
auto main() -> int
{
for (auto& entry : fs::directory_iterator("/"))
std::cout << entry.path() << std::endl;
return 0;
}
alpine-vm:~$ g++ -std=c++17 -lstdc++fs -otest test.cpp
/usr/lib/gcc/x86_64-alpine-linux-musl/8.2.0/../../../../x86_64-alpine-linux-musl/bin/ld: /tmp/ccCcOCBM.o: in function `main':
test.cpp:(.text+0x100): undefined reference to `std::filesystem::__cxx11::directory_iterator::operator*() const'
/usr/lib/gcc/x86_64-alpine-linux-musl/8.2.0/../../../../x86_64-alpine-linux-musl/bin/ld: test.cpp:(.text+0x146): undefined reference to `std::filesystem::__cxx11::directory_iterator::operator++()'
/usr/lib/gcc/x86_64-alpine-linux-musl/8.2.0/../../../../x86_64-alpine-linux-musl/bin/ld: /tmp/ccCcOCBM.o: in function `std::filesystem::__cxx11::directory_iterator::directory_iterator(std::filesystem::__cxx11::path const&)':
test.cpp:(.text._ZNSt10filesystem7__cxx1118directory_iteratorC2ERKNS0_4pathE[_ZNSt10filesystem7__cxx1118directory_iteratorC5ERKNS0_4pathE]+0x26): undefined reference to `std::filesystem::__cxx11::directory_iterator::directory_iterator(std::filesystem::__cxx11::path const&, std::filesystem::directory_options, std::error_code*)'
/usr/lib/gcc/x86_64-alpine-linux-musl/8.2.0/../../../../x86_64-alpine-linux-musl/bin/ld: /tmp/ccCcOCBM.o: in function `std::filesystem::__cxx11::path::path<char [4], std::filesystem::__cxx11::path>(char const (&) [4], std::filesystem::__cxx11::path::format)':
test.cpp:(.text._ZNSt10filesystem7__cxx114pathC2IA4_cS1_EERKT_NS1_6formatE[_ZNSt10filesystem7__cxx114pathC5IA4_cS1_EERKT_NS1_6formatE]+0x6d): undefined reference to `std::filesystem::__cxx11::path::_M_split_cmpts()'
collect2: error: ld returned 1 exit status
So langsam glaube ich, dass ich etwas sehr triviales übersehe. GCC sollte doch eigentlich <filesystem> schon länger unterstützen, oder? Hat irgendjemand vielleicht eine Idee was hier schief läuft?
Update 4: Final facepalm! ... -lstdc++fs natürlich als letzte Compiler-Option. Link-Reihenfolge... zuerst die Libs/Objekte die eine Bibliotheksfunktion benötigen und danach die Bibliotheken linken, welche die Funktionen zur Verfügung stellen. Sorry Leute! So viel Text für so etwas triviales produziert. Jetzt funktionierts auch überall