I want to open each file in a directory, read the file, store the data into my program, and close the file. Then repeat until all files have done this process.
My initial plan was to use C++17's awesome feature #include <filesystem> but g++ doesn't fully support C++17 so I decided I'd stick with C++14 features. I then tried the experimental filesystem for C++14 but that gave errors:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
/tmp/ccwH4ctR.o: In function `openRecipes(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&)':
Main.cpp:(.text+0x2ae): undefined reference to `std::experimental::filesystem::v1::__cxx11::directory_iterator::operator*() co
nst'
Main.cpp:(.text+0x2f7): undefined reference to `std::experimental::filesystem::v1::__cxx11::directory_iterator::operator++()'
/tmp/ccwH4ctR.o: In function `std::experimental::filesystem::v1::__cxx11::directory_iterator::directory_iterator(std::experime
ntal::filesystem::v1::__cxx11::path const&)':
Main.cpp:(.text._ZNSt12experimental10filesystem2v17__cxx1118directory_iteratorC2ERKNS2_4pathE[_ZNSt12experimental10filesystem2
v17__cxx1118directory_iteratorC5ERKNS2_4pathE]+0x26): undefined reference to `std::experimental::filesystem::v1::__cxx11::dire
ctory_iterator::directory_iterator(std::experimental::filesystem::v1::__cxx11::path const&, std::experimental::filesystem::v1:
:directory_options, std::error_code*)'
/tmp/ccwH4ctR.o: In function `std::experimental::filesystem::v1::__cxx11::path::path<std::__cxx11::basic_string<char, std::cha
r_traits<char>, std::allocator<char> >, std::experimental::filesystem::v1::__cxx11::path>(std::__cxx11::basic_string<char, std
::char_traits<char>, std::allocator<char> > const&)':
Main.cpp:(.text._ZNSt12experimental10filesystem2v17__cxx114pathC2INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES3_EERKT
_[_ZNSt12experimental10filesystem2v17__cxx114pathC5INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES3_EERKT_]+0x70): unde
fined reference to `std::experimental::filesystem::v1::__cxx11::path::_M_split_cmpts()'
collect2: error: ld returned 1 exit status
So... I looked for alternatives. That's when I came across this post: https://stackoverflow.com/a/612112. It uses Boost to make a cross-platform way to do what I want (I think..). So here's my question:
If I were to use boost, would I need to include it's files (Boost) in my program 's .exe if I were to distribute it to other people? Basically I'd like people to be able to just download the program and run it (no compiling or programming knowledge required) and for it to be cross-platform preferably.
If you're talking about boost's source code, no, a compiled executable has no use for the source code used to create it. This applies whether it's your own source code, or the source/object code of another library you're using.
What platform/version of g++ are you using? https://stackoverflow.com/questions/45867379/why-does-gcc-not-seem-to-have-the-filesystem-standard-library
It sounds like you're on Windows, so unfortunately I would assume that your version of MinGW doesn't have the latest features of <filesystem> implemented. You can try <experimental/filesystem>, but not sure if the latest builds support it, you would need to check changelogs of wherever your'e downloading from. If that's too much of a pain or not successful, then yep you can use boost.
If you're talking about boost's source code, no, a compiled executable has no use for the source code used to create it. This applies whether it's your own source code, or the source/object code of another library you're using.
Thanks for your reply!
Ah okay. Right, I forgot compiled means it's in machine code. I was thinking of how Jar files, for example, can have their source files extracted from them using an unzipping program. Forgot about the conversion to machine code step.
Ganado wrote:
What platform/version of g++ are you using? https://stackoverflow.com/questions/45867379/why-does-gcc-not-seem-to-have-the-filesystem-standard-library
It sounds like you're on Windows, so unfortunately I would assume that your version of MinGW doesn't have the latest features of <filesystem> implemented. You can try <experimental/filesystem>, but not sure if the latest builds support it, you would need to check changelogs of wherever your'e downloading from. If that's too much of a pain, then yep you can use boost.
I use Windows 10 but I use the Linux Sub System feature to also have Ubuntu.
g++ --version says: g++ (Ubuntu 7.4.0-1ubuntu1~18.04) 7.4.0. And as mentioned in my original post, I tried the experimental version but it gave errors unfortunately.
Main.cpp:5:10: fatal error: filesystem: No such file or directory
#include <filesystem>
^~~~~~~~~~~~
compilation terminated.
Edit 3: The gcc version is now g++ (Ubuntu 7.4.0-1ubuntu1~18.04) 7.4.0 (I guess it can't install 8..? Idk) and it needs to be version 8 to use filesystem apparently. Will try with experimental now.
/tmp/cceHHbnF.o: In function `openRecipes(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&)':
Main.cpp:(.text+0x284): undefined reference to `std::experimental::filesystem::v1::__cxx11::directory_iterator::operator*() co
Main.cpp:(.text+0x2cd): undefined reference to `std::experimental::filesystem::v1::__cxx11::directory_iterator::operator++()'
/tmp/cceHHbnF.o: In function `std::experimental::filesystem::v1::__cxx11::directory_iterator::directory_iterator(std::experime
Main.cpp:(.text._ZNSt12experimental10filesystem2v17__cxx1118directory_iteratorC2ERKNS2_4pathE[_ZNSt12experimental10filesystem2
perimental::filesystem::v1::__cxx11::directory_iterator::directory_iterator(std::experimental::filesystem::v1::__cxx11::path c
/tmp/cceHHbnF.o: In function `std::experimental::filesystem::v1::__cxx11::path::path<std::__cxx11::basic_string<char, std::cha
ath>(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)':
Main.cpp:(.text._ZNSt12experimental10filesystem2v17__cxx114pathC2INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES3_EERKT
ar_traitsIcESaIcEEES3_EERKT_]+0x70): undefined reference to `std::experimental::filesystem::v1::__cxx11::path::_M_split_cmpts(
collect2: error: ld returned 1 exit status
"g++" might still be pointing to your older, original version of g++.
What happens if you do "gcc-8 --version" or "g++-8 --version"?
I can't test out this with ubuntu myself right now, sorry. But what happens if, on 7.4, you #include <experimental/filesystem> , and use std::experimental::filesystem instead of just std::filesystem?
"g++" might still be pointing to your older, original version of g++.
What happens if you do "gcc-8 --version" or "g++-8 --version"?
Oh that's interesting. When I did "gcc-8 --version" it said:
gcc-8 (Ubuntu 8.3.0-6ubuntu1~18.04) 8.3.0
How do I uninstall the older version or redirect it so it points to version 8?
Ganado wrote:
I can't test out this with ubuntu myself right now, sorry. But what happens if, on 7.4, you #include <experimental/filesystem> , and use std::experimental::filesystem instead of just std::filesystem?
/tmp/cckcOOPt.o: In function `openRecipes(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&)':
Main.cpp:(.text+0x284): undefined reference to `std::experimental::filesystem::v1::__cxx11::directory_iterator::operator*() co
Main.cpp:(.text+0x2cd): undefined reference to `std::experimental::filesystem::v1::__cxx11::directory_iterator::operator++()'
/tmp/cckcOOPt.o: In function `std::experimental::filesystem::v1::__cxx11::directory_iterator::directory_iterator(std::experime
Main.cpp:(.text._ZNSt12experimental10filesystem2v17__cxx1118directory_iteratorC2ERKNS2_4pathE[_ZNSt12experimental10filesystem2
perimental::filesystem::v1::__cxx11::directory_iterator::directory_iterator(std::experimental::filesystem::v1::__cxx11::path c
/tmp/cckcOOPt.o: In function `std::experimental::filesystem::v1::__cxx11::path::path<std::__cxx11::basic_string<char, std::cha
ath>(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)':
Main.cpp:(.text._ZNSt12experimental10filesystem2v17__cxx114pathC2INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES3_EERKT
ar_traitsIcESaIcEEES3_EERKT_]+0x70): undefined reference to `std::experimental::filesystem::v1::__cxx11::path::_M_split_cmpts(
collect2: error: ld returned 1 exit status
jlb wrote:
You may need to link with the -lstdc++fs library as well, depending on the compiler version.
Also depending on version you may not need to use "experimental". Check the documentation for your particular compiler to be sure.
Apologies if my previous posts were not clear. You don't need "experimental" on g++ version 8 and higher. I currently have g++ 7.4 and 8.3 installed. But it appears to only be compiling programs using 7.4 at the moment.
I tried adding -lstdc++fs in my previous post but it gave the same error (or very similar) as without including it.
When using: g++ -std=c++17 -lstdc++fs Main.cpp
/tmp/ccsaa224.o: In function `openRecipes(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&)':
Main.cpp:(.text+0x284): undefined reference to `std::experimental::filesystem::v1::__cxx11::directory_iterator::operator*() co
Main.cpp:(.text+0x2cd): undefined reference to `std::experimental::filesystem::v1::__cxx11::directory_iterator::operator++()'
/tmp/ccsaa224.o: In function `std::experimental::filesystem::v1::__cxx11::directory_iterator::directory_iterator(std::experime
Main.cpp:(.text._ZNSt12experimental10filesystem2v17__cxx1118directory_iteratorC2ERKNS2_4pathE[_ZNSt12experimental10filesystem2
perimental::filesystem::v1::__cxx11::directory_iterator::directory_iterator(std::experimental::filesystem::v1::__cxx11::path c
/tmp/ccsaa224.o: In function `std::experimental::filesystem::v1::__cxx11::path::path<std::__cxx11::basic_string<char, std::cha
ath>(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)':
Main.cpp:(.text._ZNSt12experimental10filesystem2v17__cxx114pathC2INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES3_EERKT
ar_traitsIcESaIcEEES3_EERKT_]+0x70): undefined reference to `std::experimental::filesystem::v1::__cxx11::path::_M_split_cmpts(
collect2: error: ld returned 1 exit status
/tmp/cc1ox09U.o: In function `openRecipes(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&)':
Main.cpp:(.text+0x17e): undefined reference to `std::filesystem::__cxx11::directory_iterator::operator*() const'
Main.cpp:(.text+0x1c7): undefined reference to `std::filesystem::__cxx11::directory_iterator::operator++()'
/tmp/cc1ox09U.o: In function `std::filesystem::__cxx11::directory_iterator::directory_iterator(std::filesystem::__cxx11::path const&)':
Main.cpp:(.text._ZNSt10filesystem7__cxx1118directory_iteratorC2ERKNS0_4pathE[_ZNSt10filesystem7__cxx1118directory_iteratorC5ERKNS0_4pathE]+0x26): undefined reference to `std::filesystem::__cxx11::directory_iter
tor::directory_iterator(std::filesystem::__cxx11::path const&, std::filesystem::directory_options, std::error_code*)'
/tmp/cc1ox09U.o: In function `std::filesystem::__cxx11::path::path<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::filesystem::__cxx11::path>(std::__cxx11::basic_string<cha
, std::char_traits<char>, std::allocator<char> > const&, std::filesystem::__cxx11::path::format)':
Main.cpp:(.text._ZNSt10filesystem7__cxx114pathC2INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES1_EERKT_NS1_6formatE[_ZNSt10filesystem7__cxx114pathC5INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES1
EERKT_NS1_6formatE]+0x73): undefined reference to `std::filesystem::__cxx11::path::_M_split_cmpts()'
collect2: error: ld returned 1 exit status
Note: If I try to comment out the openRecipes() function entirely and the call for it in main(), it runs without errors.
Is there a reason you selected gcc 8.3.0 instead of 9.1, your program seems to work if using 9.1.
I looked it up and it said I needed to use v8 or higher for it to work. And if I recall correctly it said 8 was the highest Ubuntu supports, but I guess that post was outdated.
I tried installing g++ version 9 and it seemed to work until I tried doing g++-9 in bash. The result was:
Command 'g++-9' not found, did you mean:
command 'g++-6' from deb g++-6
command 'g++-7' from deb g++-7
command 'g++-8' from deb g++-8
command 'g++-5' from deb g++-5
Try: sudo apt install <deb name>
So I tried sudo apt install g++-9 and put in my password. Then it said:
Reading package lists... Done
Building dependency tree
Reading state information... Done
Note, selecting 'libconfig9' for regex 'g++9'
Note, selecting 'librope-ocaml-dev-ig916' for regex 'g++9'
Note, selecting 'libjpeg9-dbg' for regex 'g++9'
Note, selecting 'libjpeg9-dev' for regex 'g++9'
Note, selecting 'librope-ocaml-ig916' for regex 'g++9'
Note, selecting 'libjpeg9' for regex 'g++9'
Note, selecting 'libgettext-ocaml-dev-0xdg9' for regex 'g++9'
Note, selecting 'libgettext-ocaml-0xdg9' for regex 'g++9'
Note, selecting 'golang-github-xiang90-probing-dev' for regex 'g++9'
Note, selecting 'libnppig9.1' for regex 'g++9'
Note, selecting 'libgettext-ocaml' instead of 'libgettext-ocaml-0xdg9'
Note, selecting 'libgettext-ocaml-dev' instead of 'libgettext-ocaml-dev-0xdg9'
Note, selecting 'librope-ocaml' instead of 'librope-ocaml-ig916'
Note, selecting 'librope-ocaml-dev' instead of 'librope-ocaml-dev-ig916'
golang-github-xiang90-probing-dev is already the newest version (0.0.1-1).
libconfig9 is already the newest version (1.5-0.4).
libgettext-ocaml is already the newest version (0.3.7-1build2).
libgettext-ocaml-dev is already the newest version (0.3.7-1build2).
libjpeg9 is already the newest version (1:9b-2).
libjpeg9-dbg is already the newest version (1:9b-2).
libjpeg9-dev is already the newest version (1:9b-2).
librope-ocaml is already the newest version (0.6-1).
librope-ocaml-dev is already the newest version (0.6-1).
libnppig9.1 is already the newest version (9.1.85-3ubuntu1).
0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
So I have no idea how to install v9 of g++.
-------------------------------------------------------------------------
mbozzi wrote:
You need to pass -lstdc++fs to link the C++ filesystem library.
Consider fs::path over std::string.
fs::path is like std::string, except that it has special support for manipulating filesystem paths.
Thanks for your reply! I tried that & changed std::string to fs::path like you suggested.
g++ -std=c++17 -lstdc++fs Main.cpp
/tmp/ccmCklwv.o: In function `openRecipes(std::__cxx11::basic_string<char, std::char_traits<char>, std::
allocator<char> >&)':
Main.cpp:(.text+0x187): undefined reference to `std::filesystem::__cxx11::directory_iterator::operator*(
) const'
Main.cpp:(.text+0x1d0): undefined reference to `std::filesystem::__cxx11::directory_iterator::operator++
()'
/tmp/ccmCklwv.o: In function `std::filesystem::__cxx11::path::path(std::__cxx11::basic_string<char, std:
:char_traits<char>, std::allocator<char> >&&, std::filesystem::__cxx11::path::format)':
Main.cpp:(.text._ZNSt10filesystem7__cxx114pathC2EONSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEENS
1_6formatE[_ZNSt10filesystem7__cxx114pathC5EONSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEENS1_6fo
rmatE]+0x4f): undefined reference to `std::filesystem::__cxx11::path::_M_split_cmpts()'
/tmp/ccmCklwv.o: In function `std::filesystem::__cxx11::path::operator+=(std::__cxx11::basic_string<char
, std::char_traits<char>, std::allocator<char> > const&)':
Main.cpp:(.text._ZNSt10filesystem7__cxx114pathpLERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE[
_ZNSt10filesystem7__cxx114pathpLERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE]+0x2b): undefine
d reference to `std::filesystem::__cxx11::path::_M_split_cmpts()'
/tmp/ccmCklwv.o: In function `std::filesystem::__cxx11::directory_iterator::directory_iterator(std::file
system::__cxx11::path const&)':
Main.cpp:(.text._ZNSt10filesystem7__cxx1118directory_iteratorC2ERKNS0_4pathE[_ZNSt10filesystem7__cxx1118
directory_iteratorC5ERKNS0_4pathE]+0x26): undefined reference to `std::filesystem::__cxx11::directory_it
erator::directory_iterator(std::filesystem::__cxx11::path const&, std::filesystem::directory_options, st
d::error_code*)'
collect2: error: ld returned 1 exit status
// Trying to get program to work with filesystem.
#include <iostream>
#include <string>
#include <filesystem>
namespace fs = std::filesystem; // Shortens the amount I need to type below.
void openRecipes(std::string &ver) {
// Determines proper file path
fs::path rPath = "../recipes/" + ver + '/';
rPath += ver;
for (constauto &entry : fs::directory_iterator(rPath)) {
std::cout << entry.path() << std::endl;
}
}
int main() {
std::string version = "1.13";
openRecipes(version);
return 0;
}
Continuing on last comment (hit max comment length):
I then tried: g++ -lstdc++fs Main.cpp
Main.cpp:7:21: error: ‘filesystem’ is not a namespace-name
namespace fs = std::filesystem; // Shortens the amount I need to type below.
^~~~~~~~~~
Main.cpp:7:31: error: expected namespace-name before ‘;’ token
namespace fs = std::filesystem; // Shortens the amount I need to type below.
^
Main.cpp: In function ‘void openRecipes(std::__cxx11::string&)’:
Main.cpp:13:5: error: ‘fs’ has not been declared
fs::path rPath = "../recipes/" + ver + '/';
^~
Main.cpp:14:5: error: ‘rPath’ was not declared in this scope
rPath += ver;
^~~~~
Main.cpp:14:5: note: suggested alternative: ‘rpmatch’
rPath += ver;
^~~~~
rpmatch
Main.cpp:16:30: error: ‘fs’ has not been declared
for (const auto &entry : fs::directory_iterator(rPath)) {
^~
I looked it up and it said I needed to use v8 or higher for it to work. And if I recall correctly it said 8 was the highest Ubuntu supports, but I guess that post was outdated.
Do you know that you can compile gcc (practically any version) from source yourself?
Be careful trying to compile gcc, you don't want to overwrite the "system gcc" so you need to be sure to specify the prefix flag to some other directory. I usually place it in the opt/gcc-Whateverversion directory.
This is what I've used to compile gcc (after downloading the source in tar.gz format:
Replace the file name with the file you downloaded.
tar xzf gcc-9.1.0.tar.gz
cd gcc-9.1.0
./contrib/download_prerequisites
cd ..
mkdir objdir
cd objdir
../gcc-9.1.0/configure --prefix=/opt/gcc-9.1.0
make -j 8
make install
Notes: Notice you need to build the compiler from a directory outside the source directory.
The download_prerequisites command retrieves and downloads everything that is needed to compile the source.
Notice the creation of the object directory and that you moved into that download directory.
Here you run configure with whatever option you select.
Run make on the source:
Now, we are ready to build GCC, you typically want to pass twice the number of your computer cores to the make command in order to speed up the build. I have a quad-core system, so I will use 8 parallel jobs to build GCC:
Run make install as su/sudo to install the compiler in the directory you specified in the --prefix option.
The make can take a while so be patient.
Here is a link to the page where the above quote originated:
^ Strongly recommend configuring the build carefully, else you'll be waiting for quite a while.
At very least, you probably only want to build the C and C++ compilers. And you most likely don't want to 3-stage bootstrap, though you can, if you wish.
Be careful trying to compile gcc, you don't want to overwrite the "system gcc" so you need to be sure to specify the prefix flag to some other directory. I usually place it in the opt/gcc-Whateverversion directory.
This is what I've used to compile gcc (after downloading the source in tar.gz format:
Replace the file name with the file you downloaded.
tar xzf gcc-9.1.0.tar.gz
cd gcc-9.1.0
./contrib/download_prerequisites
cd ..
mkdir objdir
cd objdir
../gcc-9.1.0/configure --prefix=/opt/gcc-9.1.0
make -j 8
make install
Notes: Notice you need to build the compiler from a directory outside the source directory.
The download_prerequisites command retrieves and downloads everything that is needed to compile the source.
Notice the creation of the object directory and that you moved into that download directory.
Here you run configure with whatever option you select.
Run make on the source:
Now, we are ready to build GCC, you typically want to pass twice the number of your computer cores to the make command in order to speed up the build. I have a quad-core system, so I will use 8 parallel jobs to build GCC:
Thanks for your response. I did all of that I think except for the part about doubling your number of cores, I used 6 because that's the number of cores I have. I will change that in future attempts. Also the tutorial I used had different stuff for the line: ../gcc-9.1.0/configure --prefix=/opt/gcc-9.1.0. I will try that line you mentioned next.
Step 0: tar xzf gcc-9.1.0.tar.gz
Step 1: cd gcc-9.1.0
Step 2: ./contrib/download_prerequisites
Step 3: cd ..
Step 4: mkdir objdir
Step 5: cd objdir
Step 6: $PWD/../gcc-9.1.0/configure --prefix=$HOME/GCC-9.1.0 --enable-languages=c,c++,fortran,go
Step 7: make -j 6 (Can never get to the "make install" step without errors). Will use -j 12 next time.
Step 8: make install
There's way too many lines to put into a pastebin, but the ending lines after Step 7 are: https://pastebin.com/7XhrdDEX
At very least, you probably only want to build the C and C++ compilers. And you most likely don't want to 3-stage bootstrap, though you can, if you wish.
Thanks for your reply. How would I go about not installing "3-stage bootstrap"?
Bootstrapping is a build process:
Step 1. Build the GCC sources with the system compiler
Step 2. Build the GCC sources again with the newest GCC compiled;
Step 3. Build the GCC sources again with the newest GCC compiled;
Finally, compare the results of stage 2 and stage 3 for equality.
I tried following the https://solarianprogrammer.com/2016/10/07/building-gcc-ubuntu-linux/ instructions. When I tried doing the line ../gcc-9.1.0/configure -v --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu --prefix=/usr/local/gcc-9.1 --enable-checking=release --enable-languages=c,c++,fortran --disable-multilib --program-suffix=-9.1 it gave an error msg saying it didn't exist or something. Then I tried following your instructions jlb and got another error: https://pastebin.com/wy1NykK9.
So at this point I have no clue why it's not working.
------------------------
mbozzi wrote:
Bootstrapping is a build process:
Step 1. Build the GCC sources with the system compiler
Step 2. Build the GCC sources again with the newest GCC compiled;
Step 3. Build the GCC sources again with the newest GCC compiled;
Finally, compare the results of stage 2 and stage 3 for equality.
Whoops, I didn't notice your prior reply, so this is about building the filesystem example with GCC 8:
You tried g++ -std=c++17 -lstdc++fs Main.cpp, but linking order matters. Say g++ -std=c++17 Main.cpp -lstdc++fs instead.
The linker looks at code in the order specified on the command line (the link line). As it goes, it records references to any symbols whose definition it hasn't encountered yet (i.e., undefined references or unresolved (external) symbols). If a library later on in the sequence provides that symbol, that symbol is considered resolved, or defined.
Since Main.cpp depends on functions defined in stdc++fs, stdc++fs must go afterMain.cpp on the command line.
Whoops, I didn't notice your prior reply, so this is about building the filesystem example with GCC 8:
You tried g++ -std=c++17 -lstdc++fs Main.cpp, but linking order matters. Say g++ -std=c++17 Main.cpp -lstdc++fs instead.
The linker looks at code in the order specified on the command line (the link line). As it goes, it records references to any symbols whose definition it hasn't encountered yet (i.e., undefined references or unresolved (external) symbols). If a library later on in the sequence provides that symbol, that symbol is considered resolved, or defined.
Since Main.cpp depends on functions defined in stdc++fs, stdc++fs must go after Main.cpp on the command line.
The linker looks at code in the order specified on the command line (the link line). As it goes, it records references to any symbols whose definition it hasn't encountered yet (i.e., undefined references or unresolved (external) symbols). If a library later on in the sequence provides that symbol, that symbol is considered resolved, or defined.
Since Main.cpp depends on functions defined in stdc++fs, stdc++fs must go after Main.cpp on the command line.