Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Very slow build because of system.hh header file bottleneck #2339

Open
riastradh opened this issue Apr 27, 2024 · 5 comments
Open

Very slow build because of system.hh header file bottleneck #2339

riastradh opened this issue Apr 27, 2024 · 5 comments
Assignees
Labels
build Build problems

Comments

@riastradh
Copy link

Just about every .cc file includes system.hh, and system.hh includes 84 header files including STL and boost.

Just the boost header files that are directly included alone, not counting STL header files or transitive inclusions, bring in half a megabyte of C++ code.

When I pass one of the smallest files in the build, mask.cc, through c++ -E to find the C preprocessor expansion, it turns out at 7.5 MB of C++ source code -- with no comments.

This makes builds very slow, because the compiler has to slog through megabytes of heavy-weight C++ declarations and templates that mostly aren't used by most of the .cc files. That, in turn, makes iterating development very slow -- takes minutes on my laptop to build ledger, which isn't a very large piece of software, even when I parallelize it to the maximum degree of my CPU (4-core/8-thread Kaby Lake 1.9 GHz).

It would be nice if each .cc file included only the header files it needs to speed up the build.

@afh
Copy link
Member

afh commented Apr 28, 2024

I'd like to believe that precompiled headers should mitigate some the compile performance issues. Could it be that precompiled headers aren't working anymore / for you, @riastradh?

@afh afh self-assigned this Apr 28, 2024
@afh afh added the build Build problems label Apr 28, 2024
@riastradh
Copy link
Author

riastradh commented Apr 28, 2024

It looks like, in ledger, precompiled headers are enabled only for debug builds:

if (CMAKE_BUILD_TYPE STREQUAL "Debug")

What I've been running locally in my ledger development tree, and in pkgsrc, has not been debug builds.

I tried a debug build, and it is spewing warning messages about pch files:

$ mkdir -p build/x86_64--netbsd9
$ cd build/x86_64--netbsd9
$ cmake -DUSE_PYTHON:BOOL=ON -DBUILD_DEBUG:BOOL=ON ../../master
...
$ make -j4
...
[  1%] Building CXX object src/CMakeFiles/libledger.dir/cmake_pch.hxx.gch
[  2%] Building CXX object src/CMakeFiles/libledger.dir/generate.cc.o
[  3%] Building CXX object src/CMakeFiles/libledger.dir/stats.cc.o
[  5%] Building CXX object src/CMakeFiles/libledger.dir/csv.cc.o
[  6%] Building CXX object src/CMakeFiles/libledger.dir/convert.cc.o
cc1plus: warning: /home/riastradh/misc/ledger/build/x86_64--netbsd9/src/CMakeFiles/libledger.dir/cmake_pch.hxx.gch: had text segment at different address
cc1plus: warning: /home/riastradh/misc/ledger/build/x86_64--netbsd9/src/CMakeFiles/libledger.dir/cmake_pch.hxx.gch: had text segment at different address
cc1plus: warning: /home/riastradh/misc/ledger/build/x86_64--netbsd9/src/CMakeFiles/libledger.dir/cmake_pch.hxx.gch: had text segment at different address
...

The debug build appears to be just as slow as the release build. Does this precompiled header mechanism rely on something kooky like disabling ASLR in the system?

(I don't think I've ever seen precompiled headers work, over decades of encountering them in various build systems, compilers, and operating systems. I still have -no-cpp-precomp wired into my fingers from two decades ago when it was needed to make just about any software build in an Apple environment...)

@afh
Copy link
Member

afh commented Apr 28, 2024

Unfortunately I cannot answer your question about disabling ASLR, my expertise in the area is too little and the pch mechanism was added before I started contributing to ledger.
Can you think of other ways to improve compile times to resolve this issue?

@riastradh
Copy link
Author

Can you think of other ways to improve compile times to resolve this issue?

It would likely be much faster if each .cc file included only the header files it uses. For example, .cc files that don't handle pathnames or do file I/O probably don't need to include anything under boost/filesystem/.

Inside ledger, if a class A is declared in A.hh, and a class B is declared in B.hh with members or parameters that are pointers or references to A, you can also use forward declarations to reduce interdependencies between header files, which can help speed things up too:

/* B.hh */
class A;    // no need to #include "A.hh"
...
class B {
public:
  A *a;
...
};

@afh
Copy link
Member

afh commented Apr 29, 2024

Could the ledger API documentation be helpful here in order to find which classes depend on/use which other classes?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
build Build problems
Projects
None yet
Development

No branches or pull requests

2 participants