termux / termux-packages

A package build system for Termux.
https://termux.dev
Other
13.34k stars 3.07k forks source link

DRAFT: ccache support experiment #22305

Open pipcet opened 4 days ago

pipcet commented 4 days ago

I've looked into using ccache to speed up (re)compilation of termux packages, and I think I've got something that works, so I'll leave it here, if nothing else, for the next person to search for "ccache" to find.

The basic idea is, of course, to use ccache /path/to/clang instead of /path/to/clang and everything works automatically. It's not quite that easy, for these reasons:

  1. clang, unfortunately, depends on the name of the executable that is invoked to determine its behavior. This requires us to create a new symlink clang++-18 so we can still properly exec the compiler.
  2. Some build systems (ninja? cmake?) auto-detect the presence of a ccache binary in the path. We don't want that, so we rename our ccache binary to ccache.local
  3. The default configuration of ccache limits cache size to 5GB, and includes compression which reduces performance; the current version of this PR also includes debugging flags.
  4. cmake, by default, uses pre-compiled headers, which is a bad idea for many reasons; one of the reasons is that it busts ccache. Disable that.
  5. This patch also includes unrelated changes to mount more volumes when running the Docker container, which I'll remove in a bit.

Sorry for the code drop, but I think the benefits are quite noticeable and probably worth the trouble...

TomJo2000 commented 4 days ago

Maybe @thunder-coding can have a look at this one, time permitting of course.

thunder-coding commented 3 days ago

Some build systems (ninja? cmake?) auto-detect the presence of a ccache binary in the path. We don't want that, so we rename our ccache binary to ccache.local

Ninja is a very minimal build system (the authors call it meta-build system) and does not try to be smart in anyway and just follows the rules defined in build.ninja. Talking of CMake, yes it can be told to use ccache in CMakeLists.txt but by default it will not try to use ccache unless specified in command line arguments to cmake

cmake, by default, uses pre-compiled headers, which is a bad idea for many reasons; one of the reasons is that it busts ccache. Disable that.

No, cmake does not use pre-compiled headers by default unless using target_precompile_headers in CMakeLists.txt. Also CMAKE_DISABLE_PRECOMPILE_HEADERS=ON might have negative effects when not using ccaache

pipcet commented 2 days ago

Some build systems (ninja? cmake?) auto-detect the presence of a ccache binary in the path. We don't want that, so we rename our ccache binary to ccache.local

Ninja is a very minimal build system (the authors call it meta-build system) and does not try to be smart in anyway and just follows the rules defined in build.ninja. Talking of CMake, yes it can be told to use ccache in CMakeLists.txt but by default it will not try to use ccache unless specified in command line arguments to cmake

cmake, by default, uses pre-compiled headers, which is a bad idea for many reasons; one of the reasons is that it busts ccache. Disable that.

No, cmake does not use pre-compiled headers by default unless using target_precompile_headers in CMakeLists.txt. Also CMAKE_DISABLE_PRECOMPILE_HEADERS=ON might have negative effects when not using ccaache

If you want you can look at the PR linked by @TomJo2000 for somethings missing from this PR

Thanks! I've looked at that, and making ccache usage a build-package.sh option seems like a really good idea to me.

pipcet commented 2 days ago

Some build systems (ninja? cmake?) auto-detect the presence of a ccache binary in the path. We don't want that, so we rename our ccache binary to ccache.local

Ninja is a very minimal build system (the authors call it meta-build system) and does not try to be smart in anyway and just follows the rules defined in build.ninja. Talking of CMake, yes it can be told to use ccache in CMakeLists.txt but by default it will not try to use ccache unless specified in command line arguments to cmake

As we have no control over the CMakeLists.txt files used to build packages, I see no way around renaming the binary or taking it out of the PATH for now.

cmake, by default, uses pre-compiled headers, which is a bad idea for many reasons; one of the reasons is that it busts ccache. Disable that.

No, cmake does not use pre-compiled headers by default unless using target_precompile_headers in CMakeLists.txt.

In the package I looked at, the string target_precompile_headers doesn't appear, but it still manages to somehow enable generation and usage of PCH files.

Since, again, we cannot control the CMakeLists.txt, we need to work around the problem by passing a flag to CMake, even if the misbehavior is due to a package bug.

Also CMAKE_DISABLE_PRECOMPILE_HEADERS=ON might have negative effects when not using ccaache

Absolutely, but it does appear to be required when using ccache.

TomJo2000 commented 2 days ago

As we have no control over the CMakeLists.txt files used to build packages, I see no way around renaming the binary or taking it out of the PATH for now.

We can, and frequently do patch CMakeLists.txt files for packages. So we do have some degree of control.

But sidestepping the issue is absolutely preferable to some jury rigged autopatcher.

Also CMAKE_DISABLE_PRECOMPILE_HEADERS=ON might have negative effects when not using ccaache

Absolutely, but it does appear to be required when using ccache.

That could be made a toggle. So TERMUX_PKG_USE_CCACHE=true also turns off precompiled headers