Skip to content

Instantly share code, notes, and snippets.

@mschubert
Last active May 3, 2023 18:51
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mschubert/a0e4f3aeaf3558431890 to your computer and use it in GitHub Desktop.
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
# 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