34770b218ef5c3100da392a3119a3b0d50d99bfb markd Thu Feb 20 17:56:46 2025 -0800 Implement old make behavior were programs will be remade after a make clean removing the .o, even though actually program is not out of date with respect to the .c diff --git src/inc/userApp.mk src/inc/userApp.mk index f0dd531e6e3..14d5d37e813 100644 --- src/inc/userApp.mk +++ src/inc/userApp.mk @@ -1,66 +1,78 @@ ######################################################################## # user App rules, typical three-line makefile to use this rule set, # -# the one or more program file name is specified by the 'A' variable: +# the one program file name is specified by the 'A' variable: # kentSrc = ../.. # A = aveCols # include ${kentSrc}/inc/userApp.mk # +# If multiple programs are required, recursive make is needed, see +# hg/makeDb/hgLoadWiggle/makefile for an example. +# # Other variables that can be defined, which needs to be done # before including userApp.mk # # for more than one object file for the resulting 'A' program, use # extraObjects = second.o third.o fourth.o etc.o # # and for extra header files for depenencies # extraHeaders = second.h third.h fourth.h etc.h # # to use object files built elsewhere: # externObjects = ../path/other.o # # use other libraries BEFORE jkweb.a # preMyLibs += path/to/lib/other.a # +# Note: Reason for restriction on compiling one program.: +# Due to the non-standard use of make, the expected behavor is that the +# program gets rebuilt if the .o is missing (after make clean), even if the +# program in the destination is current with the C file. This doesn't work +# with make pattern rules, as it will not rebuild the target in this case. +# +ifneq ($(words ${A}),1) + $(error The A variable should contain only one word, found '${A}') +endif + include ${kentSrc}/inc/localEnvironment.mk include ${kentSrc}/inc/common.mk # with SEMI_STATIC, this makes sure only allow shared lirbaries are used userAppsCheckLinking=${kentSrc}/utils/qa/weeklybld/userAppsCheckLinking DEPLIBS = ${preMyLibs} ${kentSrc}/lib/${MACHTYPE}/jkweb.a ifeq ($(findstring src/hg/,${CURDIR}),src/hg/) DEPLIBS = ${preMyLibs} ${kentSrc}/lib/${MACHTYPE}/jkhgap.a ${kentSrc}/lib/${MACHTYPE}/jkweb.a endif LINKLIBS = ${STATIC_PRE} ${DEPLIBS} ${MYSQLLIBS} -objects = ${extraObjects} ${externObjects} +default:: ${DESTBINDIR}/${A}${EXE} +compile:: ${A} -default:: ${A:%=${DESTBINDIR}/%${EXE}} +objects = ${A}.o ${extraObjects} ${externObjects} ${extraObjects}: ${extraHeaders} -${DESTBINDIR}/%${EXE}: %.o ${objects} ${DEPLIBS} +${DESTBINDIR}/${A}${EXE}: ${objects} ${DEPLIBS} @${MKDIR} $(dir $@) - ${CC} ${COPT} -o $@ $*.o ${objects} ${LINKLIBS} ${L} - ${STRIP} ${DESTDIR}${BINDIR}/${A}${EXE} + ${CC} ${COPT} -o $@ ${objects} ${LINKLIBS} ${L} + ${STRIP} $@ ifeq (${SEMI_STATIC},yes) ${userAppsCheckLinking} $@ endif -compile:: ${A:%=%${EXE}} - -%${EXE}: ${DEPLIBS} %.o ${objects} - ${CC} ${COPT} -o $@ $*.o ${objects} ${LINKLIBS} ${L} +${A}${EXE}: ${objects} ${DEPLIBS} + ${CC} ${COPT} -o $@ ${objects} ${LINKLIBS} ${L} install:: ${A:%=${DESTBINDIR}/%${EXE}} clean:: - rm -f ${O} ${extraObjects} ${A:%=%${EXE}} + rm -f ${A}.o ${extraObjects} ${A:%=%${EXE}} @if test -d tests -a -s tests/makefile; then cd tests && ${MAKE} clean; fi test:: @if test -d tests -a -s tests/makefile; then (cd tests && ${MAKE} test); \ else echo "# no tests directory (or perhaps no tests/makefile) in $(CURDIR)"; fi ${extraObjects}: ${extraHeaders}