C++17 executable size

So I have written some code that uses C++17 filesystem, and am dismayed at the size of the executable. I use the compile option -Os (Min Size Release)and link with -lstdc++fs and the executable size is 2.3MB. Is there some compile or linker or cmake option I need to set to improve this? KDevelop IDE has this as the verbose cmake output:

/home/TheIdeasMan/projects/kdev/c17fs/build> make -j8
/usr/bin/cmake -H/home/TheIdeasMan/projects/kdev/c17fs -B/home/TheIdeasMan/projects/kdev/c17fs/build --check-build-system CMakeFiles/Makefile.cmake 0
/usr/bin/cmake -E cmake_progress_start /home/TheIdeasMan/projects/kdev/c17fs/build/CMakeFiles /home/TheIdeasMan/projects/kdev/c17fs/build/CMakeFiles/progress.marks
/usr/bin/make -f CMakeFiles/Makefile2 all
make[1]: Entering directory '/home/TheIdeasMan/projects/kdev/c17fs/build'
/usr/bin/make -f CMakeFiles/c17fs.dir/build.make CMakeFiles/c17fs.dir/depend
make[2]: Entering directory '/home/TheIdeasMan/projects/kdev/c17fs/build'
cd /home/TheIdeasMan/projects/kdev/c17fs/build && /usr/bin/cmake -E cmake_depends "Unix Makefiles" /home/TheIdeasMan/projects/kdev/c17fs /home/TheIdeasMan/projects/kdev/c17fs /home/TheIdeasMan/projects/kdev/c17fs/build /home/TheIdeasMan/projects/kdev/c17fs/build /home/TheIdeasMan/projects/kdev/c17fs/build/CMakeFiles/c17fs.dir/DependInfo.cmake --color=
make[2]: Leaving directory '/home/TheIdeasMan/projects/kdev/c17fs/build'
/usr/bin/make -f CMakeFiles/c17fs.dir/build.make CMakeFiles/c17fs.dir/build
make[2]: Entering directory '/home/TheIdeasMan/projects/kdev/c17fs/build'
[ 50%] Building CXX object CMakeFiles/c17fs.dir/main.cpp.o
/usr/local/bin/g++-7.0 -std=c++1z -Wall -Wextra -pedantic-errors -Os -DNDEBUG -o CMakeFiles/c17fs.dir/main.cpp.o -c /home/TheIdeasMan/projects/kdev/c17fs/main.cpp
[100%] Linking CXX executable c17fs
/usr/bin/cmake -E cmake_link_script CMakeFiles/c17fs.dir/link.txt --verbose=1
/usr/local/bin/g++-7.0 -std=c++1z -Wall -Wextra -pedantic-errors -Os -DNDEBUG CMakeFiles/c17fs.dir/main.cpp.o -o c17fs -rdynamic -lstdc++fs
make[2]: Leaving directory '/home/TheIdeasMan/projects/kdev/c17fs/build'
[100%] Built target c17fs
make[1]: Leaving directory '/home/TheIdeasMan/projects/kdev/c17fs/build'
/usr/bin/cmake -E cmake_progress_start /home/TheIdeasMan/projects/kdev/c17fs/build/CMakeFiles 0
*** Finished ***


Here is the 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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#include <iostream>
#include <experimental/filesystem>

#include <string>
#include <regex>
#include <vector>


namespace fs = std::experimental::filesystem;

template<typename T, typename... Args>
void ListFiles ( std::vector<T>& Wildcards,
                 Args&&... args
               )
{
    std::size_t num_matches {0};

    ( Wildcards.emplace_back ( args ), ... );

    auto cwd = fs::current_path();

    for ( auto&& p: fs::directory_iterator ( cwd ) ) {

        if ( !fs::is_regular_file ( p ) ) {
            continue;
        }

        for ( auto&& pattern : Wildcards ) {
          
            auto CurrentFile = p.path().filename();

            if ( std::regex_match ( CurrentFile.c_str(), pattern ) ) {
                ++num_matches;
                std::cout << CurrentFile << "\n";
            }
        }
    }
    std::cout << "\nNumber of matches " << num_matches << "\n";
}

int main()
{
    auto cwd = fs::current_path();
    std::cout << "The current directory is " << cwd << "\n" ;

    for ( auto&& p: fs::directory_iterator ( cwd ) ) {
        std::cout << p.path().filename() << '\n';
    }

    std::cout << "\n";

    std::vector< std::regex > Wildcards;



    ListFiles ( Wildcards, "\\w*\\.txt", "\\w*\\.cpp", "\\w*\\.json" );

    return 0;
}


Last edited on
Try building in Release mode, rather than Debug.
I just compiled with g++ 6.3 and the executable was ~ 279KB.

Am having trouble with compiling with clang++ 5.0 - compile errors

Tried on Coliru Stacked, clang 3.8:

clang++ -Os -std=c++1z -Wall -Wextra -pedantic-errors main.cpp -lstdc++fs && ls -l a.out

clang: error: unable to execute command: File size limit exceeded (core dumped)

clang: error: linker command failed due to signal (use -v to see invocation)


On Coliru with g++ 6.3.1, the executable is ~2.3MB

-rwxr-xr-x 1 2001 2000 2326624 Apr 26 05:04 a.out
Try building in Release mode, rather than Debug.



Thanks for your reply

TheIdeaman wrote:
I use the compile option -Os (Min Size Release)and link with -lstdc++fs and the executable size is 2.3MB
.

There is the -DNDEBUG option, which I am guessing is a cmake thing, does it mean "No Debug" ? I am trying to look for documentation for that now. It is a default setting in KDevelop for the release builds.

If I do a debug build the size is ~2.6MB.

Thanks :+)

Edit:

maybe the -DNDEBUG is not making it to cmake?
Last edited on
% g++ -std=c++17 -Wall -Wextra -pedantic-errors -Os -fdata-sections -ffunction-sections -fwhole-program -flto fstest.cxx -lstdc++fs -Wl,--gc-sections
% ls -lh a.out
-rwxr-xr-x 1 mbozzi mbozzi 2.1M Apr 26 01:28 a.out
% g++ --version
g++ (GCC) 7.0.1 20170305 (experimental)
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
% uname -srm
Linux 4.10.8-1-ARCH x86_64


On my system at least, libstdc++fs.a is built with debug symbols. Stripping those symbols from an executable built using the above command line leaves a 161K executable.

Edit: You can strip the debug symbols using objcopy -g a.out:
% objcopy -g a.out
% ls -lh a.out
-rwxr-xr-x 1 mbozzi mbozzi 161K Apr 26 01:42 a.out


Defining the macro NDEBUG at least removes assertions during the pre-processing step.
http://en.cppreference.com/w/c/error/assert
Last edited on
Cheers Max :+D

ThingsLearnt += 3;

That worked really well, I have a 152K executable now.

My system has a shared library libstdc++fs.la , is there any way to link that instead? I guess there is , I don't have much experience with that .

Edit: Never mind, it seems there isn't one.
https://gcc.gnu.org/onlinedocs/libstdc++/manual/using_dynamic_or_shared.html

Thanks again for your help :+)
Last edited on
Glad that helped. Maybe once the filesystem library gets integrated into libstdc++ they'll strip the debugging symbols by default.

My system has a shared library libstdc++fs.la, is there any way to link that instead

Not really, because the la file is an artifact of the build process and is ideally transparent to you as a library user. It's not a shared library itself, but a bunch of metadata that helps keep track of different library versions and dependencies of that library. It comes from libtool, which is supposed to help write portable code. If you're curious, open it up -- it's human readable.

https://www.gnu.org/software/libtool/manual/libtool.html#Motivation
https://blog.flameeyes.eu/2008/04/what-about-those-la-files/
Last edited on
Topic archived. No new replies allowed.