Last active
February 14, 2025 10:21
-
-
Save mschubert/a0e4f3aeaf3558431890 to your computer and use it in GitHub Desktop.
Simple function to delegate target creation to another Makefile without losing dependency information
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Consider the following setup: | |
# | |
# root | |
# + a | |
# | + Makefile | |
# | + ..some other files.. | |
# + b | |
# + Makefile | |
# + ..some other files.. | |
# | |
# What if a target in directory `b` needs a file that is built | |
# by the Makefile in directory `a`? | |
# | |
# There is two options: | |
# * Use one common Makefile that tracks all dependencies | |
# * Add the dependency of the other Makefile in the current Makefile | |
# | |
# Both of them lead to huge, unreadable Makefiles. Why is there no | |
# easy way to delegate a target from one Makefile to another? | |
# | |
# Turns out, there is - but it requires programmatic creation of | |
# targets. An example of how this can work is shown below. | |
# | |
# Using this framwork, I can use | |
# | |
# @b/Makefile: | |
# $(call ext_dep,../a,target1 target2 etc.) | |
# | |
# to delegate the making of the targets in `a` to the Makefile in | |
# `a` and only rebuild downstream targets in `b` when `a` changes | |
# the corresponding files. | |
# Use `print-VARNAME` to print arbitrary variables | |
print-%: ; @echo $* = $($*) | |
# Always use "all" as default target | |
.DEFAULT_GOAL := all | |
# Delete targets on nonzero exit status | |
.DELETE_ON_ERROR: | |
# Create rules to help delegate recipes to other Makefiles | |
# | |
# There are two parts to this: | |
# (1) An empty, phony .FORCE target, that will cause | |
# external targets to always be built, so that the | |
# Makefile there will handle dependencies | |
# (2) A function that creates explicit rules for each | |
# external dependency | |
# | |
# Syntax to use this is: | |
# $(call ext_dep,DIR_OF_MAKEFILE,TARGETS) | |
# | |
# And it will call: | |
# make -C DIR_OF_MAKEFILE $(TARGETS) | |
.PHONY: .FORCE | |
.FORCE: ; | |
define EXT_DEP | |
$1/$2: .FORCE | |
make -C $(1) $(2) | |
endef | |
ifeq (n,$(findstring n,$(firstword -$(MAKEFLAGS)))) | |
ext_dep = $(NOOP) | |
else | |
ext_dep = $(foreach tt,$(2),$(eval $(call EXT_DEP,$(1),$(tt)))) | |
endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment