#include <filesystem> alternative using Boost & Portability

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.
Last edited on
Ganado wrote:
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.

Edit: I read this: https://askubuntu.com/questions/1028601/install-gcc-8-only-on-ubuntu-18-04
And now I'm installing g++ 8 using: sudo apt-get install gcc-8

I'll set up the code using C++17 again and see if it works. Then will update this.

Edit 2: I'm using this code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// TESTING DIRECTORY ACCESS
#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
    std::string path = "../recipes/" + ver + '/';
    path += ver;
    
    for (const auto &entry : fs::directory_iterator(path)) {
        std::cout << entry.path() << std::endl;
    }
}


int main() {
    std::string version = "1.13";
    openRecipes(version);

    return 0;
}


and it gave these errors:
1
2
3
4
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.

Edit 4:
Tried running the code below using:
g++ -std=c++17 Main.cpp
g++ -std=c++17 -lstdc++fs Main.cpp

Error:
/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
Last edited on
"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?
Last edited on
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.

Ganado wrote:
"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?

No worries!

On g++ (Ubuntu 7.4.0-1ubuntu1~18.04) 7.4.0:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <iostream>
#include <string>
#include <experimental/filesystem>

namespace fs = std::experimental::filesystem;

void openRecipes(std::string &ver) {

    // Determines proper file path
    std::string path = "../recipes/" + ver + '/';
    path += ver;
    
    for (const auto &entry : fs::directory_iterator(path)) {
        std::cout << entry.path() << std::endl;
    }
}


int main() {
    std::string version = "1.13";
    openRecipes(version);

    return 0;
}

/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
Update: I managed to have it use v8 of g++ by default while also having v7 installed by following this tutorial:
https://askubuntu.com/a/1028656

Compiling using c++17 appears to work now. I'll update this if that proves to be wrong.


Thank you all for your responses!


Edit: Still doesn't work.

Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// Testing Directory Access
// 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
    std::string path = "../recipes/" + ver + '/';
    path += ver;
    
    for (const auto &entry : fs::directory_iterator(path)) {
        std::cout << entry.path() << std::endl;
    }
}


int main() {
    std::string version = "1.13";
    openRecipes(version);

    return 0;
}


Compiler Command: g++ -std=c++17 Main.cpp
Error:
1
2
3
4
5
6
7
8
9
10
11
/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.

g++ --version:
g++ (Ubuntu 8.3.0-6ubuntu1~18.04) 8.3.0
Last edited on
Is there a reason you selected gcc 8.3.0 instead of 9.1, your program seems to work if using 9.1.


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.
Last edited on
jlb wrote:
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.

And g++-9 still doesn't work.

Could this have to do with what I did in the tutorial:
https://askubuntu.com/a/1028656 and if so, how do I undo it?

I then tried doing:
1
2
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-8
800 --slave /usr/bin/g++ g++ /usr/bin/g++-8

And
1
2
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-9
900 --slave /usr/bin/g++ g++ /usr/bin/g++-9

update-alternatives: error: alternative path /usr/bin/gcc-9 doesn't exist


Then I tried sudo apt install gcc-9
Reading package lists... Done
Building dependency tree
Reading state information... Done
E: Unable to locate package gcc9


g++ -v
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.3.0-6ubuntu1~18.04' --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 --program-suffix=-8 --program-prefix=x86_64-linux-gnu- --enable-share
d --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --lib
dir=/usr/lib --enable-nls --enable-bootstrap --enable-clocale=gnu --enable-libstdcxx-debug --enable-libs
tdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --ena
ble-libmpx --enable-plugin --enable-default-pie --with-system-zlib --with-target-system-zlib --enable-ob
jc-gc=auto --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m
32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none --without-cuda-dri
ver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 8.3.0 (Ubuntu 8.3.0-6ubuntu1~18.04) 


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


Latest Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// 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 (const auto &entry : fs::directory_iterator(rPath)) {
        std::cout << entry.path() << std::endl;
    }
}


int main() {
    std::string version = "1.13";
    openRecipes(version);

    return 0;
}
Last edited on
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?



jlb wrote:
Do you know that you can compile gcc (practically any version) from source yourself?

Ah okay, I didn't know that. Thank you! Following a tutorial on YouTube now. :)

Will update this post when it's done regarding whether I get v9.1 to work & compile my program or not.

Update: Well, it didn't work.
https://youtu.be/odCi_U1XNQg

https://pastebin.com/XPLPhpi6

Just found and will now try: https://gcc.gnu.org/wiki/InstallingGCC
Last edited on
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:

https://solarianprogrammer.com/2016/10/07/building-gcc-ubuntu-linux/

You may want to read that page for more information.

^ 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.
jlb wrote:
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.


Folder System: https://gyazo.com/a5a934b4ae202d339ea9780112d93368

The steps I've been following from https://gcc.gnu.org/install/index.html:
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

If I try to run Step 8 anyways, I get this error:
make[1]: Entering directory '/mnt/c/Users/Tom/Downloads/gcc/objdir'
/bin/bash /mnt/c/Users/Tom/Downloads/gcc/objdir/../gcc-9.1.0/mkinstalldirs /GCC-9.1.0 /GCC-9.1.0
mkdir -p -- /GCC-9.1.0 /GCC-9.1.0
make[2]: Entering directory '/mnt/c/Users/Tom/Downloads/gcc/objdir/fixincludes'
make[2]: *** No rule to make target 'install'.  Stop.
make[2]: Leaving directory '/mnt/c/Users/Tom/Downloads/gcc/objdir/fixincludes'
Makefile:3815: recipe for target 'install-fixincludes' failed
make[1]: *** [install-fixincludes] Error 2
make[1]: Leaving directory '/mnt/c/Users/Tom/Downloads/gcc/objdir'
Makefile:2382: recipe for target 'install' failed
make: *** [install] Error 2


I'll try using instructions from https://solarianprogrammer.com/2016/10/07/building-gcc-ubuntu-linux/ this time.
-------------------------------
mbozzi wrote:
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"?
Last edited on
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.

See the section entitled "Building a native compiler"
https://gcc.gnu.org/install/build.html

To disable it (and build everything just once with the system GCC), pass --disable-bootstrap to the configure script.
Last edited on
Update:

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.

See the section entitled "Building a native compiler"
https://gcc.gnu.org/install/build.html

To disable it (and build everything just once with the system GCC), pass --disable-bootstrap to the configure script.

Ah okay, thanks for the information.
Last edited on
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.

I don't know how familiar you are with linkers, but if you need an introduction, see here:
http://www.lurklurk.org/linkers/linkers.html
Last edited on
mbozzi wrote:
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.

I don't know how familiar you are with linkers, but if you need an introduction, see here:
http://www.lurklurk.org/linkers/linkers.html

Apologies for the late reply. I've been busy with class. I normally program on Friday through Sunday. Then do school Monday to Thursday.

Anyways, using: g++ -std=c++17 Main.cpp -lstdc++fs works! I've updated my files (for reminders).

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.

I don't know how familiar you are with linkers, but if you need an introduction, see here:
http://www.lurklurk.org/linkers/linkers.html

Ahh okay. Thank you for explaining all of that! Post solved. :)
Last edited on
Topic archived. No new replies allowed.