Makefile: lazily compute header dependencies
Use the gcc -MMD -MP -MF options to generate dependency rules as a byproduct when building .o files if the COMPUTE_HEADER_DEPENDENCIES variable is defined. That variable is left undefined by default for now. As each object file is built, write a makefile fragment containing its dependencies in the deps/ subdirectory of its containing directory. The deps/ directories should be generated if they are missing at the start of each build. So let each object file depend on $(missing_dep_dirs), which lists only the directories of this kind that are missing to avoid needlessly regenerating files when the directories' timestamps change. gcc learned the -MMD -MP -MF options in version 3.0, so most gcc users should have them by now. The dependencies this option computes are more specific than the rough estimates hard-coded in the Makefile, greatly speeding up rebuilds when only a little-used header file has changed. Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
This commit is contained in:
parent
c373991375
commit
dfea575017
1
.gitignore
vendored
1
.gitignore
vendored
@ -177,6 +177,7 @@
|
|||||||
*.exe
|
*.exe
|
||||||
*.[aos]
|
*.[aos]
|
||||||
*.py[co]
|
*.py[co]
|
||||||
|
*.o.d
|
||||||
*+
|
*+
|
||||||
/config.mak
|
/config.mak
|
||||||
/autom4te.cache
|
/autom4te.cache
|
||||||
|
49
Makefile
49
Makefile
@ -217,6 +217,10 @@ all::
|
|||||||
# DEFAULT_EDITOR='~/bin/vi',
|
# DEFAULT_EDITOR='~/bin/vi',
|
||||||
# DEFAULT_EDITOR='$GIT_FALLBACK_EDITOR',
|
# DEFAULT_EDITOR='$GIT_FALLBACK_EDITOR',
|
||||||
# DEFAULT_EDITOR='"C:\Program Files\Vim\gvim.exe" --nofork'
|
# DEFAULT_EDITOR='"C:\Program Files\Vim\gvim.exe" --nofork'
|
||||||
|
#
|
||||||
|
# Define COMPUTE_HEADER_DEPENDENCIES if your compiler supports the -MMD option
|
||||||
|
# and you want to avoid rebuilding objects when an unrelated header file
|
||||||
|
# changes.
|
||||||
|
|
||||||
GIT-VERSION-FILE: FORCE
|
GIT-VERSION-FILE: FORCE
|
||||||
@$(SHELL_PATH) ./GIT-VERSION-GEN
|
@$(SHELL_PATH) ./GIT-VERSION-GEN
|
||||||
@ -1677,14 +1681,48 @@ ASM_SRC := $(wildcard $(OBJECTS:o=S))
|
|||||||
ASM_OBJ := $(ASM_SRC:S=o)
|
ASM_OBJ := $(ASM_SRC:S=o)
|
||||||
C_OBJ := $(filter-out $(ASM_OBJ),$(OBJECTS))
|
C_OBJ := $(filter-out $(ASM_OBJ),$(OBJECTS))
|
||||||
|
|
||||||
|
ifdef COMPUTE_HEADER_DEPENDENCIES
|
||||||
|
dep_dirs := $(addsuffix deps,$(sort $(dir $(OBJECTS))))
|
||||||
|
$(dep_dirs):
|
||||||
|
mkdir -p $@
|
||||||
|
|
||||||
|
missing_dep_dirs := $(filter-out $(wildcard $(dep_dirs)),$(dep_dirs))
|
||||||
|
else
|
||||||
|
dep_dirs =
|
||||||
|
missing_dep_dirs =
|
||||||
|
endif
|
||||||
|
|
||||||
.SUFFIXES:
|
.SUFFIXES:
|
||||||
|
|
||||||
$(C_OBJ): %.o: %.c GIT-CFLAGS
|
$(C_OBJ): %.o: %.c GIT-CFLAGS $(missing_dep_dirs)
|
||||||
$(QUIET_CC)$(CC) -o $*.o -c $(ALL_CFLAGS) $<
|
$(QUIET_CC)$(CC) -o $*.o -c $(dep_args) $(ALL_CFLAGS) $<
|
||||||
%.s: %.c GIT-CFLAGS FORCE
|
%.s: %.c GIT-CFLAGS FORCE
|
||||||
$(QUIET_CC)$(CC) -S $(ALL_CFLAGS) $<
|
$(QUIET_CC)$(CC) -S $(ALL_CFLAGS) $<
|
||||||
$(ASM_OBJ): %.o: %.S GIT-CFLAGS
|
$(ASM_OBJ): %.o: %.S GIT-CFLAGS $(missing_dep_dirs)
|
||||||
$(QUIET_CC)$(CC) -o $*.o -c $(ALL_CFLAGS) $<
|
$(QUIET_CC)$(CC) -o $*.o -c $(dep_args) $(ALL_CFLAGS) $<
|
||||||
|
|
||||||
|
ifdef COMPUTE_HEADER_DEPENDENCIES
|
||||||
|
# Take advantage of gcc's on-the-fly dependency generation
|
||||||
|
# See <http://gcc.gnu.org/gcc-3.0/features.html>.
|
||||||
|
dep_files := $(wildcard $(foreach f,$(OBJECTS),$(dir f)deps/$(notdir $f).d))
|
||||||
|
ifneq ($(dep_files),)
|
||||||
|
include $(dep_files)
|
||||||
|
endif
|
||||||
|
|
||||||
|
dep_file = $(dir $@)deps/$(notdir $@).d
|
||||||
|
dep_args = -MF $(dep_file) -MMD -MP
|
||||||
|
else
|
||||||
|
dep_args =
|
||||||
|
|
||||||
|
# Dependencies on header files, for platforms that do not support
|
||||||
|
# the gcc -MMD option.
|
||||||
|
#
|
||||||
|
# Dependencies on automatically generated headers such as common-cmds.h
|
||||||
|
# should _not_ be included here, since they are necessary even when
|
||||||
|
# building an object for the first time.
|
||||||
|
#
|
||||||
|
# XXX. Please check occasionally that these include all dependencies
|
||||||
|
# gcc detects!
|
||||||
|
|
||||||
$(GIT_OBJS): $(LIB_H)
|
$(GIT_OBJS): $(LIB_H)
|
||||||
builtin-branch.o builtin-checkout.o builtin-clone.o builtin-reset.o branch.o transport.o: branch.h
|
builtin-branch.o builtin-checkout.o builtin-clone.o builtin-reset.o branch.o transport.o: branch.h
|
||||||
@ -1700,10 +1738,10 @@ builtin-pack-objects.o: thread-utils.h
|
|||||||
http-fetch.o http-walker.o remote-curl.o transport.o walker.o: walker.h
|
http-fetch.o http-walker.o remote-curl.o transport.o walker.o: walker.h
|
||||||
http.o http-walker.o http-push.o remote-curl.o: http.h
|
http.o http-walker.o http-push.o remote-curl.o: http.h
|
||||||
|
|
||||||
|
|
||||||
xdiff-interface.o $(XDIFF_OBJS): \
|
xdiff-interface.o $(XDIFF_OBJS): \
|
||||||
xdiff/xinclude.h xdiff/xmacros.h xdiff/xdiff.h xdiff/xtypes.h \
|
xdiff/xinclude.h xdiff/xmacros.h xdiff/xdiff.h xdiff/xtypes.h \
|
||||||
xdiff/xutils.h xdiff/xprepare.h xdiff/xdiffi.h xdiff/xemit.h
|
xdiff/xutils.h xdiff/xprepare.h xdiff/xdiffi.h xdiff/xemit.h
|
||||||
|
endif
|
||||||
|
|
||||||
exec_cmd.s exec_cmd.o: ALL_CFLAGS += \
|
exec_cmd.s exec_cmd.o: ALL_CFLAGS += \
|
||||||
'-DGIT_EXEC_PATH="$(gitexecdir_SQ)"' \
|
'-DGIT_EXEC_PATH="$(gitexecdir_SQ)"' \
|
||||||
@ -2011,6 +2049,7 @@ clean:
|
|||||||
$(RM) $(ALL_PROGRAMS) $(BUILT_INS) git$X
|
$(RM) $(ALL_PROGRAMS) $(BUILT_INS) git$X
|
||||||
$(RM) $(TEST_PROGRAMS)
|
$(RM) $(TEST_PROGRAMS)
|
||||||
$(RM) -r bin-wrappers
|
$(RM) -r bin-wrappers
|
||||||
|
$(RM) -r $(dep_dirs)
|
||||||
$(RM) *.spec *.pyc *.pyo */*.pyc */*.pyo common-cmds.h TAGS tags cscope*
|
$(RM) *.spec *.pyc *.pyo */*.pyc */*.pyo common-cmds.h TAGS tags cscope*
|
||||||
$(RM) -r autom4te.cache
|
$(RM) -r autom4te.cache
|
||||||
$(RM) config.log config.mak.autogen config.mak.append config.status config.cache
|
$(RM) config.log config.mak.autogen config.mak.append config.status config.cache
|
||||||
|
Loading…
Reference in New Issue
Block a user