diff --git a/.gitignore b/.gitignore index 6edf09d5..c2fa58e8 100644 --- a/.gitignore +++ b/.gitignore @@ -70,8 +70,8 @@ doc/latexfiles/Makefile *.o *.a *.so -*/Depend -*/Depend*.tmp +# Per-file dependency fragments (in-tree they land in each source module dir; +# out-of-tree they are under the build dir). Replaces the old */Depend files. .deps/ database/database.h # autoconf config header, generated by ./configure (in-tree location; out-of-tree diff --git a/rules.mak b/rules.mak index 66f719d1..497f067a 100644 --- a/rules.mak +++ b/rules.mak @@ -2,31 +2,23 @@ module: lib${MODULE}.o -depend: ${DEPEND_FILE} - -# New Depend file generating line (Tim Edwards, 1/25/06). This gets around -# problems with gcc. The purpose of "make depend" is to generate a list of -# all local dependencies, but gcc insists that anything that is in, for -# example, the /usr/X11R6 path should also be included. The sed scripts -# (respectively) do: 1) remove comment lines generated by gcc, 2) remove -# any header (.h) files with an absolute path (beginning with "/"), and -# 3) remove isolated backslash-returns just to clean things up a bit. - -# The $$PPID allows this to be run on the same dir in parallel without -# corrupting the output, the final MV is transactional. If that is needed -# it indicates a missing dependency somewhere in a upstream/parent Makefile. -${DEPEND_FILE}: ${DEPSRCS} - ${CC} ${CFLAGS} ${CPPFLAGS} ${DFLAGS} ${DEPEND_FLAG} $(addprefix $(srcdir)/,${DEPSRCS}) > ${DEPEND_FILE}$$PPID.tmp - ${SED} -e "/#/D" -e "/ \//s/ \/.*\.h//" -e "/ \\\/D" -i ${DEPEND_FILE}$$PPID.tmp - ${MV} -f ${DEPEND_FILE}$$PPID.tmp ${DEPEND_FILE} - -# Original Depend file generating line: -# ${CC} ${CFLAGS} ${CPPFLAGS} ${DFLAGS} ${DEPEND_FLAG} ${SRCS} > ${DEPEND_FILE} +# Dependencies are now generated automatically as a side effect of each compile +# (see the %.o rule below); "make depend" is a no-op kept only so scripts/habits +# that still invoke it do not error. +.PHONY: depend +depend: +# Compile a source into an object. When the compiler supports it +# (AUTODEP_FLAGS = "-MMD -MP"), also write .deps/.d listing the non-system +# headers this object used -- generated as a side effect of the compile, so there +# is no separate serial "make depend" pass and it parallelises for free. -MMD +# already drops system headers (the job the old sed did), and -MP adds a phony +# target per header so a later removed/renamed header does not break the build. %.o: %.c @echo --- compiling ${MODULE}/$*.o + @test -z "${AUTODEP_FLAGS}" || mkdir -p .deps ${RM} $*.o - ${CC} ${CFLAGS} ${CPPFLAGS} ${DFLAGS} -c $< -o $@ + ${CC} ${CFLAGS} ${CPPFLAGS} ${DFLAGS} ${AUTODEP_FLAGS} $(if ${AUTODEP_FLAGS},-MF .deps/$*.d) -c $< -o $@ lib${MODULE}.o: ${OBJS} @echo --- linking lib${MODULE}.o @@ -53,12 +45,13 @@ ${DESTDIR}${BINDIR}/${MODULE}${EXEEXT}: ${MODULE}${EXEEXT} .PHONY: clean clean: ${RM} ${CLEANS} + ${RM} -r .deps tags: ${SRCS} ${LIB_SRCS} ctags $(addprefix $(srcdir)/,${SRCS} ${LIB_SRCS}) -# Depends are a somewhat optional part of the build process that are only useful when incremental -# building. If the file is here it's here, if not continue with build optimistically -ifneq (,$(wildcard ${DEPEND_FILE})) -include ${DEPEND_FILE} -endif +# Per-file dependency fragments written by the %.o rule above. Best effort: none +# exist on a first build (everything compiles anyway); on later builds they cause +# a recompile when a used header changes. `-include` tolerates their absence and +# the `-MP` phony header targets tolerate a removed/renamed header. +-include $(wildcard .deps/*.d) diff --git a/scripts/configure b/scripts/configure index 80f4988b..78de0bc1 100755 --- a/scripts/configure +++ b/scripts/configure @@ -636,7 +636,7 @@ MSED MCPP LD_RUN_PATH SHLIB_CFLAGS -DEPEND_FLAG +AUTODEP_FLAGS gr_hprog gr_hsrcs gr_srcs @@ -6349,7 +6349,7 @@ extra_defs="$extra_defs -DCAD_DIR=\\\"\${LIBDIR}\\\" -DBIN_DIR=\\\"\${BINDIR}\\\ X_LIBS= X_CFLAGS= INC_SPECS= -DEPEND_FLAG= +AUTODEP_FLAGS= SHLIB_CFLAGS="" LD_RUN_PATH="" WISH_EXE="" @@ -9435,9 +9435,36 @@ fi fi -if test "$GCC" = "yes" ; then - DEPEND_FLAG="-MM" +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC generates dependencies with -MMD -MP" >&5 +$as_echo_n "checking whether $CC generates dependencies with -MMD -MP... " >&6; } +magic_save_cflags="$CFLAGS" +CFLAGS="$CFLAGS -MMD -MP -MF conftest.autodep.d" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + if test -f conftest.autodep.d ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; }; AUTODEP_FLAGS="-MMD -MP" + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no (produced no .d)" >&5 +$as_echo "no (produced no .d)" >&6; } + fi +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f conftest.autodep.d +CFLAGS="$magic_save_cflags" diff --git a/scripts/configure.in b/scripts/configure.in index 95fe8038..224067e2 100644 --- a/scripts/configure.in +++ b/scripts/configure.in @@ -370,7 +370,7 @@ extra_defs="$extra_defs -DCAD_DIR=\\\"\${LIBDIR}\\\" -DBIN_DIR=\\\"\${BINDIR}\\\ X_LIBS= X_CFLAGS= INC_SPECS= -DEPEND_FLAG= +AUTODEP_FLAGS= SHLIB_CFLAGS="" LD_RUN_PATH="" WISH_EXE="" @@ -1987,9 +1987,25 @@ if test $usingTcl ; then fi -if test "$GCC" = "yes" ; then - DEPEND_FLAG="-MM" -fi +dnl Automatic per-file dependency generation. Compilers that support -MMD -MP +dnl write a .deps/.d listing the (non-system) headers a source used, as a +dnl side effect of compiling it -- replacing the old serial "make depend" pass +dnl and its sed post-processing, and parallelising with the compile. Best +dnl effort: empty if unsupported, and the build proceeds without incremental +dnl header tracking. Probed (not assumed from $GCC) so clang and others are +dnl covered only when they actually produce the file. +AC_MSG_CHECKING([whether $CC generates dependencies with -MMD -MP]) +magic_save_cflags="$CFLAGS" +CFLAGS="$CFLAGS -MMD -MP -MF conftest.autodep.d" +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [])], + [if test -f conftest.autodep.d ; then + AC_MSG_RESULT([yes]); AUTODEP_FLAGS="-MMD -MP" + else + AC_MSG_RESULT([no (produced no .d)]) + fi], + [AC_MSG_RESULT([no])]) +rm -f conftest.autodep.d +CFLAGS="$magic_save_cflags" dnl Substitute all variables @@ -2032,7 +2048,7 @@ AC_SUBST(CFLAGS) AC_SUBST(CPPFLAGS) AC_SUBST(CXX) AC_SUBST(CXXFLAGS) -AC_SUBST(DEPEND_FLAG) +AC_SUBST(AUTODEP_FLAGS) AC_SUBST(SHLIB_CFLAGS) AC_SUBST(LDFLAGS) AC_SUBST(LD_RUN_PATH) diff --git a/scripts/defs.mak.in b/scripts/defs.mak.in index 8f22f385..c8e8f49f 100755 --- a/scripts/defs.mak.in +++ b/scripts/defs.mak.in @@ -200,8 +200,10 @@ LDFLAGS = @LDFLAGS@ READLINE_DEFS = @rl_defs@ READLINE_LIBS = @rl_libs@ -DEPEND_FILE = Depend -DEPEND_FLAG = @DEPEND_FLAG@ +# Per-file dependency flags ("-MMD -MP" when the compiler supports it, else +# empty); used by the %.o rule in rules.mak to write .deps/.d as a compile +# side effect. Replaces the old serial "make depend" / Depend-file machinery. +AUTODEP_FLAGS = @AUTODEP_FLAGS@ EXEEXT = @EXEEXT@ GR_CFLAGS = @X_CFLAGS@ @gr_cflags@ @@ -214,12 +216,11 @@ GR_HELPER_PROG = @gr_hprog@ OA = @OA@ OA_LIBS = @OA_LIBS@ -DEPSRCS = ${SRCS} C_OBJS = ${SRCS:.c=.o} CXX_OBJS = ${CXXSRCS:.cpp=.o} OBJS = ${CXX_OBJS} ${C_OBJS} LIB_OBJS = ${LIB_SRCS:.c=.o} -CLEANS = Depend ${OBJS} ${LIB_OBJS} lib${MODULE}.a lib${MODULE}.o ${MODULE} +CLEANS = ${OBJS} ${LIB_OBJS} lib${MODULE}.a lib${MODULE}.o ${MODULE} # allows Makefile to be selective MAKE_TCL = @MAKE_TCL@