Relink Makefile target when list of dependencies changes

梦想与她 提交于 2019-12-06 07:47:11

To do it properly, you'll probably have to resort to Paul Smith's Advanced Auto-Dependency Generation. Paul is the current maintainer of GNU make, and has described all the common problems (and their solutions!) concerning dependency generation.

The other white-papers on his website are recommended as well.

I use his tips and tricks for several years now, and - even if it gets complicated a little occasionally - studying them has been worth every second.

You need a smarter version of gmake. ElectricMake is a gmake-compatible replacement that includes a ledger feature that basically makes the up-to-date check more sophisticated than just checking that the output is newer than the inputs. In particular, the ledger will hash the list of inputs for the target and if that list changes, it will cause the output to be rebuilt:

# cat Makefile
out: a b c
        @echo out from $^
        @touch out
# emake --emake-ledger=timestamp
out from a b c
# emake --emake-ledger=timestamp
make: `out' is up to date.
# vi Makefile ;# Remove 'c' from the prereq list.
# cat Makefile
out: a b
        @echo out from $^
        @touch out
# emake --emake-ledger=timestamp
out from a b

If you want to give it a try, you can get an eval copy.

Ideally, the should be only one make pattern rule to do all the linking (okay, one for executables, one for shared libraries and one for archives). Something like:

# rules.mk
$(BUILD_DIR}/exe/% : rules.mk
    g++ -o $@ $(filter-out %.mk,$^)

Next, when you define build targets make them depend on its own makefile:

# project_a.mk
$(BUILD_DIR}/exe/a : project_a.mk ${a_obj}

Normally, this dependency would be wrapped in a macro:

define EXE_TARGET
  $(BUILD_DIR}/exe/${1} : ${2}
  $(BUILD_DIR}/exe/${1} : $(lastword $(MAKEFILE_LIST))
endef

so in project_a.mk it'd do:

# project_a.mk
$(eval $(call EXE_TARGET,a,${a_obj}))
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!