* [PATCH 0/4] make: precompile "git-compat-util.h"
@ 2026-09-09 19:50 SZEDER Gábor
2026-09-09 19:50 ` [PATCH 1/4] Makefile: remove XDIFF_OBJS initialization SZEDER Gábor
` (3 more replies)
0 siblings, 4 replies; 7+ messages in thread
From: SZEDER Gábor @ 2026-09-09 19:50 UTC (permalink / raw)
To: git; +Cc: SZEDER Gábor
Update our Makefile to make use of the recently introduced precompiled
header to make builds faster (on my setup by about 35%).
SZEDER Gábor (4):
Makefile: remove XDIFF_OBJS initialization
cmake: remove any "$(*_OBJS)" variables when parsing Makefile for
sources
Makefile: reintroduce REFTABLE_OBJS
Makefile: precompile "git-compat-util.h"
.gitignore | 1 +
Makefile | 59 +++++++++++++++++++----------
contrib/buildsystems/CMakeLists.txt | 6 ++-
3 files changed, 45 insertions(+), 21 deletions(-)
--
2.55.0.1193.g1b994e35de
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 1/4] Makefile: remove XDIFF_OBJS initialization
2026-09-09 19:50 [PATCH 0/4] make: precompile "git-compat-util.h" SZEDER Gábor
@ 2026-09-09 19:50 ` SZEDER Gábor
2026-09-09 19:50 ` [PATCH 2/4] cmake: remove any "$(*_OBJS)" variables when parsing Makefile for sources SZEDER Gábor
` (2 subsequent siblings)
3 siblings, 0 replies; 7+ messages in thread
From: SZEDER Gábor @ 2026-09-09 19:50 UTC (permalink / raw)
To: git; +Cc: SZEDER Gábor
Object files under 'xlib/' used to be listed in the XDIFF_OBJS
Makefile variable so we could build a static library from them. This
static library was removed in cf680cdb95 (make: delete XDIFF_LIB, add
xdiff to LIB_OBJS, 2025-10-02), along with filling XDIFF_OBJS with
object files.
But the initial empty initalization of XDIFF_OBJS remained, so remove
it now.
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
---
Makefile | 1 -
1 file changed, 1 deletion(-)
diff --git a/Makefile b/Makefile
index d4b775953d..7d9ac15c74 100644
--- a/Makefile
+++ b/Makefile
@@ -695,7 +695,6 @@ BUILTIN_OBJS =
BUILT_INS =
COMPAT_CFLAGS =
COMPAT_OBJS =
-XDIFF_OBJS =
GENERATED_H =
EXTRA_CPPFLAGS =
FUZZ_OBJS =
--
2.55.0.1193.g1b994e35de
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 2/4] cmake: remove any "$(*_OBJS)" variables when parsing Makefile for sources
2026-09-09 19:50 [PATCH 0/4] make: precompile "git-compat-util.h" SZEDER Gábor
2026-09-09 19:50 ` [PATCH 1/4] Makefile: remove XDIFF_OBJS initialization SZEDER Gábor
@ 2026-09-09 19:50 ` SZEDER Gábor
2026-09-09 19:50 ` [PATCH 3/4] Makefile: reintroduce REFTABLE_OBJS SZEDER Gábor
2026-09-09 19:50 ` [PATCH 4/4] Makefile: precompile "git-compat-util.h" SZEDER Gábor
3 siblings, 0 replies; 7+ messages in thread
From: SZEDER Gábor @ 2026-09-09 19:50 UTC (permalink / raw)
To: git; +Cc: SZEDER Gábor
To get various lists of files, CMake parses our Makefile looking for
lines matching e.g. "list_var += ...". In case of LIB_OBJS this
picks up the line "LIB_OBJS += $(COMPAT_OBJS)" as well, so the parsing
macro has a specific instruction to remove "$(COMPAT_OBJS)" from the
resulting list.
Currently this is the only such Makefile variable to be removed from
the list, but the next patches will (re)introduce more variables
containing lists of object files, so let's generalize that removing
instruction to remove any "$(*_OBJS)" Makefile variable as well.
Note that we can't make the pattern matching the Makefile variable too
general, e.g. to match any "$(VARIABLE)", because some lines of our
Makefile do contain variables as directory prefixes, e.g.
"UNIT_TEST_OBJS += $(UNIT_TEST_DIR)/test-lib.o", and we must
definitely keep those.
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
---
I rarely do CMake, so it's quite possible that this is not the most
straightforward or idiomatic approach.
contrib/buildsystems/CMakeLists.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/contrib/buildsystems/CMakeLists.txt b/contrib/buildsystems/CMakeLists.txt
index 8f56203f34..241da0d43a 100644
--- a/contrib/buildsystems/CMakeLists.txt
+++ b/contrib/buildsystems/CMakeLists.txt
@@ -102,7 +102,7 @@ project(git
macro(parse_makefile_for_sources list_var makefile regex)
file(STRINGS ${makefile} ${list_var} REGEX "^${regex} \\+=(.*)")
string(REPLACE "${regex} +=" "" ${list_var} ${${list_var}})
- string(REPLACE "$(COMPAT_OBJS)" "" ${list_var} ${${list_var}}) #remove "$(COMPAT_OBJS)" This is only for libgit.
+ string(REGEX REPLACE "\\$\\([^)]*_OBJS\\)" "" ${list_var} ${${list_var}}) # remove any "$(*_OBJS)" variables
string(STRIP ${${list_var}} ${list_var}) #remove trailing/leading whitespaces
string(REPLACE ".o" ".c;" ${list_var} ${${list_var}}) #change .o to .c, ; is for converting the string into a list
list(TRANSFORM ${list_var} STRIP) #remove trailing/leading whitespaces for each element in list
--
2.55.0.1193.g1b994e35de
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 3/4] Makefile: reintroduce REFTABLE_OBJS
2026-09-09 19:50 [PATCH 0/4] make: precompile "git-compat-util.h" SZEDER Gábor
2026-09-09 19:50 ` [PATCH 1/4] Makefile: remove XDIFF_OBJS initialization SZEDER Gábor
2026-09-09 19:50 ` [PATCH 2/4] cmake: remove any "$(*_OBJS)" variables when parsing Makefile for sources SZEDER Gábor
@ 2026-09-09 19:50 ` SZEDER Gábor
2026-09-09 21:07 ` Junio C Hamano
2026-09-09 19:50 ` [PATCH 4/4] Makefile: precompile "git-compat-util.h" SZEDER Gábor
3 siblings, 1 reply; 7+ messages in thread
From: SZEDER Gábor @ 2026-09-09 19:50 UTC (permalink / raw)
To: git; +Cc: SZEDER Gábor
Object files under "reftable/" used to be listed in the REFTABLE_OBJS
Makefile variable so we could build a static library from them. This
static library was removed in f3b4c89d59 (make: delete REFTABLE_LIB,
add reftable to LIB_OBJS, 2025-10-02), along with filling
REFTALBE_OBJS with object files.
However, the reftable source files are kind of special, because the
reftable implementation is supposed to be easily includable in other
projects. Therefore, the reftable source files don't include
"git-compat-util.h", with the sole exception of the purposefully
project-specific "reftable/system.c". Consequently, they shouldn't be
compiled with our precompiled header, as it does include
"git-compat-util.h".
Resurrect listing object files under "reftable/" in REFTABLE_OBJS (but
not the static library), so in the next commit we'll be able to easily
filter them out and keep building them the old way, without the
precompiled header.
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
---
Makefile | 32 ++++++++++++++++-------------
contrib/buildsystems/CMakeLists.txt | 4 ++++
2 files changed, 22 insertions(+), 14 deletions(-)
diff --git a/Makefile b/Makefile
index 7d9ac15c74..2c4d6f4d4a 100644
--- a/Makefile
+++ b/Makefile
@@ -707,6 +707,7 @@ OBJECTS =
OTHER_PROGRAMS =
PROGRAM_OBJS =
PROGRAMS =
+REFTABLE_OBJS =
RUST_SOURCES =
EXCLUDED_PROGRAMS =
SCRIPT_PERL =
@@ -1284,20 +1285,6 @@ LIB_OBJS += refs/iterator.o
LIB_OBJS += refs/packed-backend.o
LIB_OBJS += refs/ref-cache.o
LIB_OBJS += refspec.o
-LIB_OBJS += reftable/basics.o
-LIB_OBJS += reftable/block.o
-LIB_OBJS += reftable/blocksource.o
-LIB_OBJS += reftable/error.o
-LIB_OBJS += reftable/fsck.o
-LIB_OBJS += reftable/iter.o
-LIB_OBJS += reftable/merged.o
-LIB_OBJS += reftable/pq.o
-LIB_OBJS += reftable/record.o
-LIB_OBJS += reftable/stack.o
-LIB_OBJS += reftable/system.o
-LIB_OBJS += reftable/table.o
-LIB_OBJS += reftable/tree.o
-LIB_OBJS += reftable/writer.o
LIB_OBJS += remote.o
LIB_OBJS += repack.o
LIB_OBJS += repack-cruft.o
@@ -1386,6 +1373,23 @@ LIB_OBJS += xdiff/xpatience.o
LIB_OBJS += xdiff/xprepare.o
LIB_OBJS += xdiff/xutils.o
+REFTABLE_OBJS += reftable/basics.o
+REFTABLE_OBJS += reftable/block.o
+REFTABLE_OBJS += reftable/blocksource.o
+REFTABLE_OBJS += reftable/error.o
+REFTABLE_OBJS += reftable/fsck.o
+REFTABLE_OBJS += reftable/iter.o
+REFTABLE_OBJS += reftable/merged.o
+REFTABLE_OBJS += reftable/pq.o
+REFTABLE_OBJS += reftable/record.o
+REFTABLE_OBJS += reftable/stack.o
+REFTABLE_OBJS += reftable/system.o
+REFTABLE_OBJS += reftable/table.o
+REFTABLE_OBJS += reftable/tree.o
+REFTABLE_OBJS += reftable/writer.o
+
+LIB_OBJS += $(REFTABLE_OBJS)
+
BUILTIN_OBJS += builtin/add.o
BUILTIN_OBJS += builtin/am.o
BUILTIN_OBJS += builtin/annotate.o
diff --git a/contrib/buildsystems/CMakeLists.txt b/contrib/buildsystems/CMakeLists.txt
index 241da0d43a..462c1eb5ec 100644
--- a/contrib/buildsystems/CMakeLists.txt
+++ b/contrib/buildsystems/CMakeLists.txt
@@ -668,6 +668,10 @@ include_directories(${CMAKE_BINARY_DIR})
#libgit
parse_makefile_for_sources(libgit_SOURCES ${CMAKE_SOURCE_DIR}/Makefile "LIB_OBJS")
+#reftable
+parse_makefile_for_sources(reftable_SOURCES ${CMAKE_SOURCE_DIR}/Makefile "REFTABLE_OBJS")
+list(APPEND libgit_SOURCES ${reftable_SOURCES})
+
list(TRANSFORM libgit_SOURCES PREPEND "${CMAKE_SOURCE_DIR}/")
list(TRANSFORM compat_SOURCES PREPEND "${CMAKE_SOURCE_DIR}/")
--
2.55.0.1193.g1b994e35de
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 4/4] Makefile: precompile "git-compat-util.h"
2026-09-09 19:50 [PATCH 0/4] make: precompile "git-compat-util.h" SZEDER Gábor
` (2 preceding siblings ...)
2026-09-09 19:50 ` [PATCH 3/4] Makefile: reintroduce REFTABLE_OBJS SZEDER Gábor
@ 2026-09-09 19:50 ` SZEDER Gábor
2026-09-09 19:57 ` SZEDER Gábor
3 siblings, 1 reply; 7+ messages in thread
From: SZEDER Gábor @ 2026-09-09 19:50 UTC (permalink / raw)
To: git; +Cc: SZEDER Gábor
This patch follows the idea of 671df48df8 (meson: precompile
"git-compat-util.h", 2026-03-19) to make it faster to build Git using
"make". The notable differences are the boilerplate needed to wire up
the precompiled header with "make", and the selection of object files
that are built using the precompiled header:
- Add a new rule to precompile "tools/precompiled.h" into
"tools/precompiled.h.gch".
This rule and its dependencies are basically the same as our
existing rule and its dependencies for compiling object files from
our source files and, except that in this rule we don't use the
EXTRA_CPPFLAGS target-specific variable. This is partly because
any compiler flags in that target-specific variable can't possibly
make sense for the project-wide "git-compat-util.h", and partly
because it could run afoul of "make"'s quirks with target-specific
variables and GCC's "-Winvalid-pch" compiler option [1].
Our Makefile always writes object files next to the source files
they were compiled from. Since a precompiled header is in many
ways similar to an object file, let's follow suit and write it
next to the header file it was created from as well. 671df48df8
doesn't mention why "precompiled.h" was placed in "tools/".
Use the ".gch" suffix for the precompiled header file, because
that's the only suffix GCC looks for when searching for a
precompiled header. Clang apparently looks for both ".pch" and
".gch" suffixes. If we ever encounter a compiler which only
supports a different precompiled header suffix, then we might make
the suffix configurable via a Makefile knob; but until then it
remains hard-coded for the sake of simplicity.
- Declare the precompiled header's dependencies, so it gets rebuilt
when any of our header files it includes is modified.
When using computed header dependencies, then the compiler can
generate the Makefile snippet containing the header files inlcuded
by the precompiled header, just like when compiling a C source
file into an object file.
When not using computed header dependencies, then make the
precompiled header depend on the same header files that our object
files depend on, i.e. those listed in LIB_H and GENERATED_H. This
is not ideal, because the precompiled header will be rebuilt even
when a header file it doesn't actually depend on changes; but in
that case all object files will be rebuilt as well anyway.
- List the object files that are built using the precompiled header
in the PRECOMPILED_HEADER_USERS variable:
- The precompiled header should not change what actually gets
compiled. Therefore, use the precompiled header only when
compiling source files that start with including
"git-compat-util.h" (directly or indirectly, e.g. via
"builtin.h"), or its inclusion is only preceeded by #define
directives that don't influence "git-compat-util.h" between its
include guards [2] (currently DISABLE_SIGN_COMPARE_WARNINGS,
USE_THE_REPOSITORY_VARIABLE or GIT_TEST_PROGRESS_ONLY). [3]
Several (but not all) object or source files listed in the
COMPAT_OBJS, REFTABLE_OBJS and THIRD_PARTY_SOURCES variables
don't include "git-compat-util.h", therefore, for the sake of
simplicity, none of the files listed in these variables are
built with the precompiled header. [4]
Since 671df48df8 the Meson build uses the precompiled header
even when compiling those reftable source files that don't
include "git-compat-util.h" at all, although this change is not
mentioned in the commit message.
- But other than that, use the precompiled header when compiling
all other source files, including e.g. source files for
standalone executables (e.g. "daemon.c" for "git-daemon"), or
those in the directories "t/helper/" and "t/unit-tests/" as
well.
The Meson build, however, only uses the precompiled header for
compiling objects in "libgit_sources" and "builtin_sources",
despite 671df48df8 giving the impression that the precompiled
header is included in all compilation units.
- In short, PRECOMPILED_HEADER_USERS contains all object files
listed in OBJECTS, except those that are listed in COMPAT_OBJS,
REFTABLE_OBJS or THIRD_PARTY_SOURCES as well.
- Add a new rule to build object files listed in
PRECOMPILED_HEADER_USERS with the precompiled header.
This rule and its dependencies are basically the same as our
existing rule and its dependencies compiling object files from our
source files, except:
- This rule depends on the precompiled header as well, to make
sure that it's built before it is used.
- Use the "-include tools/precompiled.h" option to make the
precompiled header the first header in the compilation unit,
because only then is it used to speed things up.
- Use the "-Winvalid-pch" option to catch any issues when the
precompiled header is present but can't be used for whatever
reason. While being unable to use the precompiled header would
normally only result in a slower build, it is probably better
that developers are made aware that simething is not quite
right. Meson uses this option as well when compiling a source
file using the precompiled header.
Note, that in case of such an issue with "-Winvalid-pch" we
would get a warning for each object file that is build using the
precompiled header, but together with "-Werror" (e.g. with
DEVELOPER=1) it would fail the build.
Object files not listed in PRECOMPILED_HEADER_USERS are built with
the existing (and unchanged) rule for object files.
- This way the precompiled header is compiled only once during
the whole build process.
The Meson build, however, currently compiles the precompiled
header twice: once for "libgit_sources" and once for
"builtin_sources", despite 671df48df8 giving the impression that
it's compiled only once. And, by the looks of it, it would have
to be compiled once more for each new library or executable where
we declare the use of the precompiled header.
- Add the Makefile knob NO_PRECOMPILED_HEADER to make it possible to
build without using the precompiled header for testing purposes,
or for any compiler that might be out there that doesn't support
the "-Winvalid-pch" option.
Note, that when this knob is set then we merely leave
PRECOMPILED_HEADER_USERS empty: this way nothing is built with the
precompiled header, but "make clean NO_PRECOMPILED_HEADER=1" would
still remove a leftover precompiled header file.
With this patch series on top of v2.55.0 I got the following build
time improvement:
Benchmark 1: make -j12 (rev = v2.55.0)
Time (mean ± σ): 29.414 s ± 0.031 s [User: 254.786 s, System: 47.447 s]
Range (min … max): 29.370 s … 29.470 s 10 runs
Benchmark 2: make -j12 (rev = precompile)
Time (mean ± σ): 21.725 s ± 0.047 s [User: 186.047 s, System: 35.109 s]
Range (min … max): 21.643 s … 21.768 s 10 runs
Summary
'make -j12 (rev = precompile)' ran
1.35 ± 0.00 times faster than 'make -j12 (rev = v2.55.0)'
[1] "make" applies target-specific variables to the first target's
dependencies as well. So, if the rule creating the precompiled
header included $(EXTRA_CPPFLAGS) as well, then we could get this:
$ make -s clean
$ make V=1 git
gcc -o tools/precompiled.h.gch -c -MF [...] -DSHELL_PATH='"/bin/sh"' '-DGIT_HTML_PATH="share/doc/git-doc"' '-DGIT_MAN_PATH="share/man"' '-DGIT_INFO_PATH="share/info"' tools/precompiled.h
gcc -o git.o -c -include tools/precompiled.h -Winvalid-pch -MF [...] -DSHELL_PATH='"/bin/sh"' '-DGIT_HTML_PATH="share/doc/git-doc"' '-DGIT_MAN_PATH="share/man"' '-DGIT_INFO_PATH="share/info"' git.c
gcc -o builtin/add.o -c -include tools/precompiled.h -Winvalid-pch -MF [...] -DSHELL_PATH='"/bin/sh"' builtin/add.c
cc1: error: ./tools/precompiled.h.gch: not used because `GIT_MAN_PATH' not defined [-Werror=invalid-pch]
cc1: all warnings being treated as errors
make: *** [Makefile:2940: builtin/add.o] Error 1
So in this case "git.o" is the first object file to be build, and
since it has a target-specific EXTRA_CPPFLAGS and since it depends
on the precompiled header, the precompiled header is built with
the same EXTRA_CPPFLAGS as well. But then "builtin/add.o" is
built with empty EXTRA_CPPFLAGS, and GCC's sanity checks for the
-Winvalid-pch option complain. Clang apparently doesn't consider
this to be an issue, and builds "git" just fine.
Note, however, that if the first object file to be built is not
"git.o" (or one of the other object files with target-specific
EXTRA_CPPFLAGS), which is usually the case with e.g. "make all",
then the precompiled header is built with empty EXTRA_CPPFLAGS,
and then all is well. Weird. We already had issues with "make"
and target-specific variables in the past, see a673cfede6
(Makefile: Fix occasional GIT-CFLAGS breakage, 2010-03-19).
The Meson build doesn't use target-specific variables, and the
whole project needs to be rebuilt when e.g. "mandir" is changed,
although this is not mentioned in 904339edbd (Introduce support
for the Meson build system, 2024-12-06).
[2] See baa61e46da (git-compat-util.h: move warning infra to prepare
for PCHs, 2026-03-19).
[3] This can be verified by simply scanning through the output of:
{
printf '%s\n' 'print-%:'
printf '\t%s\n' '@printf "%s\n" $($*)'
} >/tmp/printvars.mak
for f in $(make -f /tmp/printvars.mak -f Makefile print-PRECOMPILED_HEADER_USERS)
do
f="${f%o}c"
sed -n -E -e "s%# *(define|include).*%& $f%p" -e '/# *include/q' "$f"
done | sort
[4] "make"'s flexibility would allow us to separately list those
object files that don't include "git-compat-util.h", but then on
my (I assume fairly typical) Linux box the number of object files
built using the precompiled header increases only by 9 (from 536
to 545), which reduces the build time by about 1% (0.2s).
Therefore, I don't think it's worth the churn.
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
---
.gitignore | 1 +
Makefile | 26 +++++++++++++++++++++-----
2 files changed, 22 insertions(+), 5 deletions(-)
diff --git a/.gitignore b/.gitignore
index 4da58c6754..0209bd16f2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -233,6 +233,7 @@
/.vscode/
/tags
/TAGS
+/tools/precompiled.h.gch
/cscope*
/compile_commands.json
/.cache/
diff --git a/Makefile b/Makefile
index 2c4d6f4d4a..02162719db 100644
--- a/Makefile
+++ b/Makefile
@@ -321,6 +321,9 @@ include shared.mak
# dependency rules. The default is "auto", which means to use computed header
# dependencies if your compiler is detected to support it.
#
+# Define NO_PRECOMPILED_HEADER if you want to build Git without precompiling
+# "git-compat-util.h".
+#
# Define NATIVE_CRLF if your platform uses CRLF for line endings.
#
# Define GIT_USER_AGENT if you want to change how git identifies itself during
@@ -2905,8 +2908,15 @@ endif
.PHONY: objects
objects: $(OBJECTS)
-dep_files := $(foreach f,$(OBJECTS),$(dir $f).depend/$(notdir $f).d)
-dep_dirs := $(addsuffix .depend,$(sort $(dir $(OBJECTS))))
+PRECOMPILED_HEADER := tools/precompiled.h
+PRECOMPILED_HEADER_GCH := $(addsuffix .gch,$(PRECOMPILED_HEADER))
+
+ifndef NO_PRECOMPILED_HEADER
+PRECOMPILED_HEADER_USERS := $(filter-out $(COMPAT_OBJS) $(REFTABLE_OBJS) $(patsubst %.c,%.o,$(THIRD_PARTY_SOURCES)),$(OBJECTS))
+endif
+
+dep_files := $(foreach f,$(OBJECTS) $(PRECOMPILED_HEADER_GCH),$(dir $f).depend/$(notdir $f).d)
+dep_dirs := $(addsuffix .depend,$(sort $(dir $(OBJECTS) $(PRECOMPILED_HEADER_GCH))))
ifeq ($(uname_S),Darwin)
dep_dirs += $(addsuffix .depend,$(sort $(dir contrib/credential/osxkeychain/git-credential-osxkeychain.o)))
@@ -2940,7 +2950,13 @@ missing_compdb_dir =
compdb_args =
endif
-$(OBJECTS): %.o: %.c GIT-CFLAGS $(missing_dep_dirs) $(missing_compdb_dir)
+$(PRECOMPILED_HEADER_GCH): %.gch: % GIT-CFLAGS $(missing_dep_dirs) $(missing_compdb_dir)
+ $(QUIET_CC)$(CC) -o $@ -c $(dep_args) $(compdb_args) $(ALL_CFLAGS) $<
+
+$(PRECOMPILED_HEADER_USERS): %.o: %.c $(PRECOMPILED_HEADER_GCH) GIT-CFLAGS $(missing_dep_dirs) $(missing_compdb_dir)
+ $(QUIET_CC)$(CC) -o $*.o -c -include $(PRECOMPILED_HEADER) -Winvalid-pch $(dep_args) $(compdb_args) $(ALL_CFLAGS) $(EXTRA_CPPFLAGS) $<
+
+$(filter-out $(PRECOMPILED_HEADER_USERS),$(OBJECTS)): %.o: %.c GIT-CFLAGS $(missing_dep_dirs) $(missing_compdb_dir)
$(QUIET_CC)$(CC) -o $*.o -c $(dep_args) $(compdb_args) $(ALL_CFLAGS) $(EXTRA_CPPFLAGS) $<
%.s: %.c GIT-CFLAGS FORCE
@@ -2954,7 +2970,7 @@ ifneq ($(dep_files_present),)
include $(dep_files_present)
endif
else
-$(OBJECTS): $(LIB_H) $(GENERATED_H)
+$(OBJECTS) $(PRECOMPILED_HEADER_GCH): $(LIB_H) $(GENERATED_H)
endif
ifeq ($(GENERATE_COMPILATION_DATABASE),yes)
@@ -3908,7 +3924,7 @@ clean: profile-clean coverage-clean cocciclean
$(RM) GIT-TEST-SUITES
$(RM) po/git.pot po/git-core.pot
$(RM) git.rc git.res
- $(RM) $(OBJECTS)
+ $(RM) $(OBJECTS) $(PRECOMPILED_HEADER_GCH)
$(RM) headless-git.o
$(RM) $(LIB_FILE)
$(RM) $(ALL_PROGRAMS) $(SCRIPT_LIB) $(BUILT_INS) $(OTHER_PROGRAMS)
--
2.55.0.1193.g1b994e35de
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH 4/4] Makefile: precompile "git-compat-util.h"
2026-09-09 19:50 ` [PATCH 4/4] Makefile: precompile "git-compat-util.h" SZEDER Gábor
@ 2026-09-09 19:57 ` SZEDER Gábor
0 siblings, 0 replies; 7+ messages in thread
From: SZEDER Gábor @ 2026-09-09 19:57 UTC (permalink / raw)
To: git
On Wed, Sep 09, 2026 at 09:50:06PM +0200, SZEDER Gábor wrote:
> - List the object files that are built using the precompiled header
> in the PRECOMPILED_HEADER_USERS variable:
>
> - The precompiled header should not change what actually gets
> compiled. Therefore, use the precompiled header only when
> compiling source files that start with including
> "git-compat-util.h" (directly or indirectly, e.g. via
> "builtin.h"), or its inclusion is only preceeded by #define
> directives that don't influence "git-compat-util.h" between its
> include guards [2] (currently DISABLE_SIGN_COMPARE_WARNINGS,
> USE_THE_REPOSITORY_VARIABLE or GIT_TEST_PROGRESS_ONLY). [3]
>
> Several (but not all) object or source files listed in the
> COMPAT_OBJS, REFTABLE_OBJS and THIRD_PARTY_SOURCES variables
> don't include "git-compat-util.h", therefore, for the sake of
> simplicity, none of the files listed in these variables are
> built with the precompiled header. [4]
> - In short, PRECOMPILED_HEADER_USERS contains all object files
> listed in OBJECTS, except those that are listed in COMPAT_OBJS,
> REFTABLE_OBJS or THIRD_PARTY_SOURCES as well.
> [4] "make"'s flexibility would allow us to separately list those
> object files that don't include "git-compat-util.h", but then on
> my (I assume fairly typical) Linux box the number of object files
> built using the precompiled header increases only by 9 (from 536
> to 545), which reduces the build time by about 1% (0.2s).
> Therefore, I don't think it's worth the churn.
For reference, a change to do that would look like that patch below,
but, as mentioned above, the benefit is rather small:
Benchmark 1: make -j12 (rev = precompile)
Time (mean ± σ): 21.747 s ± 0.048 s [User: 186.120 s, System: 35.032 s]
Range (min … max): 21.650 s … 21.802 s 10 runs
Benchmark 2: make -j12 (rev = precompile-all)
Time (mean ± σ): 21.556 s ± 0.062 s [User: 184.584 s, System: 35.016 s]
Range (min … max): 21.477 s … 21.675 s 10 runs
Summary
'make -j12 (rev = precompile-all)' ran
1.01 ± 0.00 times faster than 'make -j12 (rev = precompile)'
--- >8 ---
diff --git a/Makefile b/Makefile
index 7d9dac83c4..b5d75dc75f 100644
--- a/Makefile
+++ b/Makefile
@@ -698,6 +698,7 @@ BUILTIN_OBJS =
BUILT_INS =
COMPAT_CFLAGS =
COMPAT_OBJS =
+COMPAT_NOPCH_OBJS =
GENERATED_H =
EXTRA_CPPFLAGS =
FUZZ_OBJS =
@@ -711,6 +712,7 @@ OTHER_PROGRAMS =
PROGRAM_OBJS =
PROGRAMS =
REFTABLE_OBJS =
+REFTABLE_NOPCH_OBJS =
RUST_SOURCES =
EXCLUDED_PROGRAMS =
SCRIPT_PERL =
@@ -721,6 +723,7 @@ TEST_BUILTINS_OBJS =
TEST_OBJS =
TEST_PROGRAMS_NEED_X =
THIRD_PARTY_SOURCES =
+THIRD_PARTY_NOPCH_SOURCES =
UNIT_TEST_PROGRAMS =
UNIT_TEST_DIR = t/unit-tests
UNIT_TEST_BIN = $(UNIT_TEST_DIR)/bin
@@ -1376,20 +1379,22 @@ LIB_OBJS += xdiff/xpatience.o
LIB_OBJS += xdiff/xprepare.o
LIB_OBJS += xdiff/xutils.o
-REFTABLE_OBJS += reftable/basics.o
-REFTABLE_OBJS += reftable/block.o
-REFTABLE_OBJS += reftable/blocksource.o
-REFTABLE_OBJS += reftable/error.o
-REFTABLE_OBJS += reftable/fsck.o
-REFTABLE_OBJS += reftable/iter.o
-REFTABLE_OBJS += reftable/merged.o
-REFTABLE_OBJS += reftable/pq.o
-REFTABLE_OBJS += reftable/record.o
-REFTABLE_OBJS += reftable/stack.o
REFTABLE_OBJS += reftable/system.o
-REFTABLE_OBJS += reftable/table.o
-REFTABLE_OBJS += reftable/tree.o
-REFTABLE_OBJS += reftable/writer.o
+REFTABLE_NOPCH_OBJS += reftable/basics.o
+REFTABLE_NOPCH_OBJS += reftable/block.o
+REFTABLE_NOPCH_OBJS += reftable/blocksource.o
+REFTABLE_NOPCH_OBJS += reftable/error.o
+REFTABLE_NOPCH_OBJS += reftable/fsck.o
+REFTABLE_NOPCH_OBJS += reftable/iter.o
+REFTABLE_NOPCH_OBJS += reftable/merged.o
+REFTABLE_NOPCH_OBJS += reftable/pq.o
+REFTABLE_NOPCH_OBJS += reftable/record.o
+REFTABLE_NOPCH_OBJS += reftable/stack.o
+REFTABLE_NOPCH_OBJS += reftable/table.o
+REFTABLE_NOPCH_OBJS += reftable/tree.o
+REFTABLE_NOPCH_OBJS += reftable/writer.o
+
+REFTABLE_OBJS += $(REFTABLE_NOPCH_OBJS)
LIB_OBJS += $(REFTABLE_OBJS)
@@ -1535,11 +1540,13 @@ THIRD_PARTY_SOURCES += compat/inet_ntop.c
THIRD_PARTY_SOURCES += compat/inet_pton.c
THIRD_PARTY_SOURCES += compat/obstack.%
THIRD_PARTY_SOURCES += compat/poll/%
-THIRD_PARTY_SOURCES += compat/regex/%
-THIRD_PARTY_SOURCES += sha1collisiondetection/%
-THIRD_PARTY_SOURCES += sha1dc/%
-THIRD_PARTY_SOURCES += $(UNIT_TEST_DIR)/clar/%
-THIRD_PARTY_SOURCES += $(UNIT_TEST_DIR)/clar/clar/%
+THIRD_PARTY_NOPCH_SOURCES += compat/regex/%
+THIRD_PARTY_NOPCH_SOURCES += sha1collisiondetection/%
+THIRD_PARTY_NOPCH_SOURCES += sha1dc/%
+THIRD_PARTY_NOPCH_SOURCES += $(UNIT_TEST_DIR)/clar/%
+THIRD_PARTY_NOPCH_SOURCES += $(UNIT_TEST_DIR)/clar/clar/%
+
+THIRD_PARTY_SOURCES += $(THIRD_PARTY_NOPCH_SOURCES)
CLAR_TEST_SUITES += u-ctype
CLAR_TEST_SUITES += u-dir
@@ -1959,7 +1966,7 @@ ifdef SNPRINTF_RETURNS_BOGUS
endif
ifdef FREAD_READS_DIRECTORIES
COMPAT_CFLAGS += -DFREAD_READS_DIRECTORIES
- COMPAT_OBJS += compat/fopen.o
+ COMPAT_NOPCH_OBJS += compat/fopen.o
endif
ifdef OPEN_RETURNS_EINTR
COMPAT_CFLAGS += -DOPEN_RETURNS_EINTR
@@ -2063,7 +2070,7 @@ ifdef NO_TRUSTABLE_FILEMODE
endif
ifdef NEEDS_MODE_TRANSLATION
COMPAT_CFLAGS += -DNEEDS_MODE_TRANSLATION
- COMPAT_OBJS += compat/stat.o
+ COMPAT_NOPCH_OBJS += compat/stat.o
endif
ifdef NO_IPV6
BASIC_CFLAGS += -DNO_IPV6
@@ -2229,7 +2236,7 @@ ifdef SHA1_MAX_BLOCK_SIZE
endif
ifdef NO_HSTRERROR
COMPAT_CFLAGS += -DNO_HSTRERROR
- COMPAT_OBJS += compat/hstrerror.o
+ COMPAT_NOPCH_OBJS += compat/hstrerror.o
endif
ifdef NO_MEMMEM
COMPAT_CFLAGS += -DNO_MEMMEM
@@ -2282,7 +2289,7 @@ ifdef UNRELIABLE_FSTAT
endif
ifdef NO_REGEX
COMPAT_CFLAGS += -Icompat/regex
- COMPAT_OBJS += compat/regex/regex.o
+ COMPAT_NOPCH_OBJS += compat/regex/regex.o
else
ifdef USE_ENHANCED_BASIC_REGULAR_EXPRESSIONS
COMPAT_CFLAGS += -DUSE_ENHANCED_BASIC_REGULAR_EXPRESSIONS
@@ -2387,17 +2394,17 @@ endif
ifdef FILENO_IS_A_MACRO
COMPAT_CFLAGS += -DFILENO_IS_A_MACRO
- COMPAT_OBJS += compat/fileno.o
+ COMPAT_NOPCH_OBJS += compat/fileno.o
endif
ifdef NEED_ACCESS_ROOT_HANDLER
COMPAT_CFLAGS += -DNEED_ACCESS_ROOT_HANDLER
- COMPAT_OBJS += compat/access.o
+ COMPAT_NOPCH_OBJS += compat/access.o
endif
ifdef FSMONITOR_DAEMON_BACKEND
COMPAT_CFLAGS += -DHAVE_FSMONITOR_DAEMON_BACKEND
- COMPAT_OBJS += compat/fsmonitor/fsm-listen-$(FSMONITOR_DAEMON_BACKEND).o
+ COMPAT_NOPCH_OBJS += compat/fsmonitor/fsm-listen-$(FSMONITOR_DAEMON_BACKEND).o
COMPAT_OBJS += compat/fsmonitor/fsm-health-$(FSMONITOR_DAEMON_BACKEND).o
endif
@@ -2531,6 +2538,7 @@ endif
LIBS = $(filter-out %.o, $(GITLIBS)) $(EXTLIBS)
BASIC_CFLAGS += $(COMPAT_CFLAGS)
+COMPAT_OBJS += $(COMPAT_NOPCH_OBJS)
LIB_OBJS += $(COMPAT_OBJS)
# Quote for C
@@ -2912,7 +2920,7 @@ PRECOMPILED_HEADER := tools/precompiled.h
PRECOMPILED_HEADER_GCH := $(addsuffix .gch,$(PRECOMPILED_HEADER))
ifndef NO_PRECOMPILED_HEADER
-PRECOMPILED_HEADER_USERS := $(filter-out $(COMPAT_OBJS) $(REFTABLE_OBJS) $(patsubst %.c,%.o,$(THIRD_PARTY_SOURCES)),$(OBJECTS))
+PRECOMPILED_HEADER_USERS := $(filter-out $(COMPAT_NOPCH_OBJS) $(REFTABLE_NOPCH_OBJS) $(patsubst %.c,%.o,$(THIRD_PARTY_NOPCH_SOURCES)),$(OBJECTS))
endif
dep_files := $(foreach f,$(OBJECTS) $(PRECOMPILED_HEADER_GCH),$(dir $f).depend/$(notdir $f).d)
diff --git a/config.mak.uname b/config.mak.uname
index 95ef6e64dc..c51ebadc40 100644
--- a/config.mak.uname
+++ b/config.mak.uname
@@ -152,7 +152,7 @@ ifeq ($(uname_S),Darwin)
NO_MEMMEM = YesPlease
USE_ST_TIMESPEC = YesPlease
HAVE_DEV_TTY = YesPlease
- COMPAT_OBJS += compat/precompose_utf8.o
+ COMPAT_NOPCH_OBJS += compat/precompose_utf8.o
BASIC_CFLAGS += -DPRECOMPOSE_UNICODE
BASIC_CFLAGS += -DPROTECT_HFS_DEFAULT=1
HAVE_BSD_SYSCTL = YesPlease
@@ -535,7 +535,8 @@ endif
AR = compat/vcbuild/scripts/lib.pl
CFLAGS =
BASIC_CFLAGS = -nologo -I. -Icompat/vcbuild/include -DWIN32 -D_CONSOLE -DHAVE_STRING_H -D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_DEPRECATE
- COMPAT_OBJS = compat/msvc.o compat/winansi.o \
+ COMPAT_NOPCH_OBJS = compat/winansi.o
+ COMPAT_OBJS = compat/msvc.o \
compat/win32/flush.o \
compat/win32/path-utils.o \
compat/win32/pthread.o compat/win32/syslog.o \
@@ -735,7 +736,8 @@ ifeq ($(uname_S),MINGW)
BASIC_LDFLAGS += -municode
COMPAT_CFLAGS += -DNOGDI -Icompat -Icompat/win32
COMPAT_CFLAGS += -DSTRIP_EXTENSION=\".exe\"
- COMPAT_OBJS += compat/mingw.o compat/winansi.o \
+ COMPAT_NOPCH_OBJS += compat/winansi.o
+ COMPAT_OBJS += compat/mingw.o \
compat/win32/trace2_win32_process_info.o \
compat/win32/flush.o \
compat/win32/path-utils.o \
diff --git a/contrib/buildsystems/CMakeLists.txt b/contrib/buildsystems/CMakeLists.txt
index 462c1eb5ec..d96a4ebd84 100644
--- a/contrib/buildsystems/CMakeLists.txt
+++ b/contrib/buildsystems/CMakeLists.txt
@@ -101,7 +101,7 @@ project(git
#macros for parsing the Makefile for sources and scripts
macro(parse_makefile_for_sources list_var makefile regex)
file(STRINGS ${makefile} ${list_var} REGEX "^${regex} \\+=(.*)")
- string(REPLACE "${regex} +=" "" ${list_var} ${${list_var}})
+ string(REGEX REPLACE "${regex} \\+=" "" ${list_var} ${${list_var}})
string(REGEX REPLACE "\\$\\([^)]*_OBJS\\)" "" ${list_var} ${${list_var}}) # remove any "$(*_OBJS)" variables
string(STRIP ${${list_var}} ${list_var}) #remove trailing/leading whitespaces
string(REPLACE ".o" ".c;" ${list_var} ${${list_var}}) #change .o to .c, ; is for converting the string into a list
@@ -669,7 +669,7 @@ include_directories(${CMAKE_BINARY_DIR})
parse_makefile_for_sources(libgit_SOURCES ${CMAKE_SOURCE_DIR}/Makefile "LIB_OBJS")
#reftable
-parse_makefile_for_sources(reftable_SOURCES ${CMAKE_SOURCE_DIR}/Makefile "REFTABLE_OBJS")
+parse_makefile_for_sources(reftable_SOURCES ${CMAKE_SOURCE_DIR}/Makefile "REFTABLE_(|NOPCH_)OBJS")
list(APPEND libgit_SOURCES ${reftable_SOURCES})
list(TRANSFORM libgit_SOURCES PREPEND "${CMAKE_SOURCE_DIR}/")
--
2.55.0.1193.g1b994e35de
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH 3/4] Makefile: reintroduce REFTABLE_OBJS
2026-09-09 19:50 ` [PATCH 3/4] Makefile: reintroduce REFTABLE_OBJS SZEDER Gábor
@ 2026-09-09 21:07 ` Junio C Hamano
0 siblings, 0 replies; 7+ messages in thread
From: Junio C Hamano @ 2026-09-09 21:07 UTC (permalink / raw)
To: SZEDER Gábor; +Cc: git
SZEDER Gábor <szeder.dev@gmail.com> writes:
> Object files under "reftable/" used to be listed in the REFTABLE_OBJS
> Makefile variable so we could build a static library from them. This
> static library was removed in f3b4c89d59 (make: delete REFTABLE_LIB,
> add reftable to LIB_OBJS, 2025-10-02), along with filling
> REFTALBE_OBJS with object files.
>
> However, the reftable source files are kind of special, because the
> reftable implementation is supposed to be easily includable in other
> projects. Therefore, the reftable source files don't include
> "git-compat-util.h", with the sole exception of the purposefully
> project-specific "reftable/system.c". Consequently, they shouldn't be
> compiled with our precompiled header, as it does include
> "git-compat-util.h".
This is the first mention of "our precompiled header" in this
series, and the first hint that "our precompiled header" would
include "git-compat-util.h". It may probably give us a better
organization to state it upfront at the beginning of the proposed
log message of this commit. It is of secondary importance that once
in the past we used to have REFTABLE_OBJS Makefile variable that
listed some files (but for completely different purposes). How
about explaining it along this line...
The ultimate endgame of this series is to use the precompiled
header facility to speed up compilation, and the plan is to have
Git specific headers including git-compat-util.h precompiled.
The reftable sources are largely designed to be independent from
the Git source proper, and except for reftable/system.c they do
not include <git-compat-util.h>.
Move the object files in the subsystem from the LIB_OBJS to the
REFTABLE_OBJS Makefile variable, so that we can use LIB_OBJS as
list of files compiled with precompiled header files and others
without
... or something like that, perhaps?
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2026-09-09 21:07 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-09 19:50 [PATCH 0/4] make: precompile "git-compat-util.h" SZEDER Gábor
2026-09-09 19:50 ` [PATCH 1/4] Makefile: remove XDIFF_OBJS initialization SZEDER Gábor
2026-09-09 19:50 ` [PATCH 2/4] cmake: remove any "$(*_OBJS)" variables when parsing Makefile for sources SZEDER Gábor
2026-09-09 19:50 ` [PATCH 3/4] Makefile: reintroduce REFTABLE_OBJS SZEDER Gábor
2026-09-09 21:07 ` Junio C Hamano
2026-09-09 19:50 ` [PATCH 4/4] Makefile: precompile "git-compat-util.h" SZEDER Gábor
2026-09-09 19:57 ` SZEDER Gábor
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.