Makefile: how to declare a dependency for all targets that match a pattern?when multiple pattern rules match a targetmakefile pattern rules without recipesMakefile adds itself as targetRelink Makefile target when list of dependencies changesHow to makefile parseMakefile static rule syntax explainationAlternatives to pattern rules with .PHONY targets in a makefile?Is the first target in Makefile an implicit phony target?Makefile pattern rule with multiple targetsAdding a dependency to all uses of an implicit rulePattern rule for prerequisite regardless of targetMakefile : last resort match anything pattern
How could a sequence of random dates be generated, given year interval?
A partially ugly group with a casual secret
How to apply a macro for every single matching pattern
Is there any algorithm that runs faster in Mathematica than in C or Fortran?
What is more proper notation in piano sheet music to denote that the left hand should be louder?
Why are bagpipes tuned using just intonation?
Can I take the high-speed bullet train Beijing–Hong Kong under Chinese 144 h visa-free transit rules?
Should I do a regression analysis even if the variables do not seem to be associated at all?
Remove vertical space in gather enviroment
Is CR12 too difficult for two level 4 characters?
Novel in which space traders train a spearman army for a decaying medieval empire
More elegant way to express ((x == a and y == b) or (x == b and y == a))?
Intuition behind the paradox of instantaneous heat propagation
Modeling the Choose function
What's a good strategy for offering low on a house?
Why do microwaves use magnetron?
Tips for attracting more math majors in a liberal arts college mathematics department
Noise reduction using multiple recordings of the same signal
How to formulate a MIP that can minimize the costs with a combination of subsets given a set?
Why is Eastern Switzerland called Suisse orientale in French?
Novel about a woman who is transformed into an elf
How do I figure out how many hydrogens my compound actually has using a mass and NMR spectrum?
Why is Iceland Air's Saga Premium product classified as Business class?
How does AT-AT deploy troops?
Makefile: how to declare a dependency for all targets that match a pattern?
when multiple pattern rules match a targetmakefile pattern rules without recipesMakefile adds itself as targetRelink Makefile target when list of dependencies changesHow to makefile parseMakefile static rule syntax explainationAlternatives to pattern rules with .PHONY targets in a makefile?Is the first target in Makefile an implicit phony target?Makefile pattern rule with multiple targetsAdding a dependency to all uses of an implicit rulePattern rule for prerequisite regardless of targetMakefile : last resort match anything pattern
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty
margin-bottom:0;
Certain files in my target have dependencies on other targets. I can ensure a proper build by adding explicit rules like this:
static/app.mjs: js2/.legacy_app.built.mjs
static/admin_unit.mjs: js2/.legacy_admin.built.mjs
static/admin_source.mjs: js2/.legacy_admin.built.mjs
static/admin_module.mjs: js2/.legacy_admin.built.mjs
But this means changing my Makefile every time I add a new "admin_X" source to my project. What I would like to do is have a catch-all pattern rule like:
static/app.mjs: js2/.legacy_app.built.mjs
static/admin_%.mjs: js2/.legacy_admin.built.mjs
But this does not work, as explained by https://stackoverflow.com/a/3734705/179583:
Pattern rules with no recipes at all are documented as meaning something quite different [… :] they cancel any pre-existing implicit rule
Is there a clean way to specify that "any target matching a certain pattern" depends on some particular other target?
makefile
add a comment
|
Certain files in my target have dependencies on other targets. I can ensure a proper build by adding explicit rules like this:
static/app.mjs: js2/.legacy_app.built.mjs
static/admin_unit.mjs: js2/.legacy_admin.built.mjs
static/admin_source.mjs: js2/.legacy_admin.built.mjs
static/admin_module.mjs: js2/.legacy_admin.built.mjs
But this means changing my Makefile every time I add a new "admin_X" source to my project. What I would like to do is have a catch-all pattern rule like:
static/app.mjs: js2/.legacy_app.built.mjs
static/admin_%.mjs: js2/.legacy_admin.built.mjs
But this does not work, as explained by https://stackoverflow.com/a/3734705/179583:
Pattern rules with no recipes at all are documented as meaning something quite different [… :] they cancel any pre-existing implicit rule
Is there a clean way to specify that "any target matching a certain pattern" depends on some particular other target?
makefile
add a comment
|
Certain files in my target have dependencies on other targets. I can ensure a proper build by adding explicit rules like this:
static/app.mjs: js2/.legacy_app.built.mjs
static/admin_unit.mjs: js2/.legacy_admin.built.mjs
static/admin_source.mjs: js2/.legacy_admin.built.mjs
static/admin_module.mjs: js2/.legacy_admin.built.mjs
But this means changing my Makefile every time I add a new "admin_X" source to my project. What I would like to do is have a catch-all pattern rule like:
static/app.mjs: js2/.legacy_app.built.mjs
static/admin_%.mjs: js2/.legacy_admin.built.mjs
But this does not work, as explained by https://stackoverflow.com/a/3734705/179583:
Pattern rules with no recipes at all are documented as meaning something quite different [… :] they cancel any pre-existing implicit rule
Is there a clean way to specify that "any target matching a certain pattern" depends on some particular other target?
makefile
Certain files in my target have dependencies on other targets. I can ensure a proper build by adding explicit rules like this:
static/app.mjs: js2/.legacy_app.built.mjs
static/admin_unit.mjs: js2/.legacy_admin.built.mjs
static/admin_source.mjs: js2/.legacy_admin.built.mjs
static/admin_module.mjs: js2/.legacy_admin.built.mjs
But this means changing my Makefile every time I add a new "admin_X" source to my project. What I would like to do is have a catch-all pattern rule like:
static/app.mjs: js2/.legacy_app.built.mjs
static/admin_%.mjs: js2/.legacy_admin.built.mjs
But this does not work, as explained by https://stackoverflow.com/a/3734705/179583:
Pattern rules with no recipes at all are documented as meaning something quite different [… :] they cancel any pre-existing implicit rule
Is there a clean way to specify that "any target matching a certain pattern" depends on some particular other target?
makefile
makefile
edited Mar 29 at 7:45
Tsyvarev
32k5 gold badges37 silver badges73 bronze badges
32k5 gold badges37 silver badges73 bronze badges
asked Mar 28 at 21:37
natevwnatevw
10.2k5 gold badges52 silver badges71 bronze badges
10.2k5 gold badges52 silver badges71 bronze badges
add a comment
|
add a comment
|
3 Answers
3
active
oldest
votes
As you know, a pattern rule like:
static/admin_%.mjs: js2/.legacy_admin.built.mjs
recipe...
does not specify any targets, just a template for discovering
the prerequisites of targets that you specify otherwise,
with a recipe for making those targets from the prerequisites.
So there has to be something else in your makefile that determines
what the targets are. Let's suppose it is just a list as in:
$ cat Makefile
MJS_STEMS := app admin_unit admin_source admin_module
MJS_FILES := $(addprefix static/,$(MJS_STEMS:%=%.mjs))
.PHONY: all clean
all: $(MJS_FILES)
$(MJS_FILES): js2/.legacy_admin.built.mjs
static/%.mjs: | static
@echo $< > $@
@echo "$@ depends on $<"
js2/.legacy_admin.built.mjs: | js2
touch $@
static js2:
mkdir -p $@
clean:
$(RM) $(MJS_FILES) js2/.legacy_admin.built.mjs
Here,
$(MJS_FILES): js2/.legacy_admin.built.mjs
says that each of $(MJS_FILES)
depends on js2/.legacy_admin.built.mjs
.
That's the most concise way to do it without a pattern rule. The make runs like:
$ make
mkdir -p static
mkdir -p js2
touch js2/.legacy_admin.built.mjs
static/app.mjs depends on js2/.legacy_admin.built.mjs
static/admin_unit.mjs depends on js2/.legacy_admin.built.mjs
static/admin_source.mjs depends on js2/.legacy_admin.built.mjs
static/admin_module.mjs depends on js2/.legacy_admin.built.mjs
If you want you can move the maintenance of the MJS_STEMS
list out of the
makefile into another file:
$ cat ./mjs_stems
app
admin_unit
admin_source
admin_module
$ cat Makefile
MJS_STEMS := $(shell cat ./mjs_stems)
MJS_FILES := $(addprefix static/,$(MJS_STEMS:%=%.mjs))
.PHONY: all clean
all: $(MJS_FILES)
$(MJS_FILES): js2/.legacy_admin.built.mjs
static/%.mjs: | static
@echo $< > $@
@echo "$@ depends on $<"
js2/.legacy_admin.built.mjs: | js2
touch $@
static js2:
mkdir -p $@
clean:
$(RM) $(MJS_FILES) js2/.legacy_admin.built.mjs
$ make clean
rm -f static/app.mjs static/admin_unit.mjs static/admin_source.mjs static/admin_module.mjs js2/.legacy_admin.built.mjs
$ echo "admin_foobar" >> mjs_stems
$ make
touch js2/.legacy_admin.built.mjs
static/app.mjs depends on js2/.legacy_admin.built.mjs
static/admin_unit.mjs depends on js2/.legacy_admin.built.mjs
static/admin_source.mjs depends on js2/.legacy_admin.built.mjs
static/admin_module.mjs depends on js2/.legacy_admin.built.mjs
static/admin_foobar.mjs depends on js2/.legacy_admin.built.mjs
Or you can just get the MJS_STEMS
list from the environment:
$ cat Makefile
MJS_STEMS := $(strip $(MJS_STEMS))
MJS_FILES := $(addprefix static/,$(MJS_STEMS:%=%.mjs))
.PHONY: all clean
all: $(MJS_FILES)
$(MJS_FILES): js2/.legacy_admin.built.mjs
static/%.mjs: | static
@echo $< > $@
@echo "$@ depends on $<"
js2/.legacy_admin.built.mjs: | js2
touch $@
static js2:
mkdir -p $@
clean:
$(RM) $(MJS_FILES) js2/.legacy_admin.built.mjs
$ make clean
rm -f static/app.mjs static/admin_unit.mjs static/admin_source.mjs static/admin_module.mjs static/admin_foobar.mjs js2/.legacy_admin.built.mjs
$ export MJS_STEMS=$(cat ./mjs_stems)
$ make
touch js2/.legacy_admin.built.mjs
static/app.mjs depends on js2/.legacy_admin.built.mjs
static/admin_unit.mjs depends on js2/.legacy_admin.built.mjs
static/admin_source.mjs depends on js2/.legacy_admin.built.mjs
static/admin_module.mjs depends on js2/.legacy_admin.built.mjs
static/admin_foobar.mjs depends on js2/.legacy_admin.built.mjs
$ make clean
rm -f static/app.mjs static/admin_unit.mjs static/admin_source.mjs static/admin_module.mjs static/admin_foobar.mjs js2/.legacy_admin.built.mjs
$ export MJS_STEMS="aa bb cc"
$ make
touch js2/.legacy_admin.built.mjs
static/aa.mjs depends on js2/.legacy_admin.built.mjs
static/bb.mjs depends on js2/.legacy_admin.built.mjs
static/cc.mjs depends on js2/.legacy_admin.built.mjs
$ make clean
rm -f static/aa.mjs static/bb.mjs static/cc.mjs js2/.legacy_admin.built.mjs
But one way or another, somewhere, you have to specify the list of targets, and
to add new targets you have to update something.
Thanks for this. I don't think it directly answers my question but if not that's partly my fault for leaving out some of the background: I do already generate a list of target files viaappfiles = $(shell ls -1 js2/*.build.mjs)
andjs2: $(appfiles:js2/%.build.mjs=static/%.mjs)
[I forget if there was a reason for splitting it beyond readability.] So in this case I'm only trying to cleanly "call out" some of them as having an extra dependency. As @Matt reminds below, I should be able to use similarls -1
/substitution tricks to generate a sub-list.
– natevw
Apr 1 at 16:07
add a comment
|
If all those files already exist in the filesystem (i.e. not supposed to be built by make from scratch), you can use $(wildcard ...)
:
$(wildcard static/admin_*.mjs): js2/.legacy_admin.built.mjs
Unfortunately in my case thestatic/admin_*.mjs
targets are some of the final products of this Makefile, and won't always be present e.g. after mymake clean
.
– natevw
Apr 1 at 15:56
Ah, but as @MikeKinghan brings up in his answer — I can figure out what files should exist based on a different wildcard pattern (e.g.src/admin_*.build.mjs
) so I can probably combine this with a substitution.
– natevw
Apr 1 at 15:58
add a comment
|
I found another trick to do this, under the special case that all relevant files are built via their own particular recipe. I.e. this will not work in the general case, unless you have split out or can duplicate a separate recipe for the targets in question.
Granting that, it's a simple matter of tying in the common dependency via a phony target. This ADMIN
target depends on the shared intermediate file, and then in turn is specified as a prequisite of a pattern-matching recipe:
.PHONY: ADMIN
ADMIN: js2/.legacy_admin.built.mjs
static/admin_%.mjs static/admin_%.mjs.map: js2/admin_%.build.mjs ADMIN FORCE
node_modules/.bin/rollup --config rollup.config.js $< --format esm --sourcemap -o $@
# …also contains recipe to build "js2/.legacy_admin.built.mjs" itself
Now before any static/admin_%.mjs
file is built, make ensures that the common js2/.legacy_admin.built.mjs
helper file has been created.
(See when multiple pattern rules match a target for some background on how various versions of Make pick which recipe to use.)
add a comment
|
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/4.0/"u003ecc by-sa 4.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55407224%2fmakefile-how-to-declare-a-dependency-for-all-targets-that-match-a-pattern%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
As you know, a pattern rule like:
static/admin_%.mjs: js2/.legacy_admin.built.mjs
recipe...
does not specify any targets, just a template for discovering
the prerequisites of targets that you specify otherwise,
with a recipe for making those targets from the prerequisites.
So there has to be something else in your makefile that determines
what the targets are. Let's suppose it is just a list as in:
$ cat Makefile
MJS_STEMS := app admin_unit admin_source admin_module
MJS_FILES := $(addprefix static/,$(MJS_STEMS:%=%.mjs))
.PHONY: all clean
all: $(MJS_FILES)
$(MJS_FILES): js2/.legacy_admin.built.mjs
static/%.mjs: | static
@echo $< > $@
@echo "$@ depends on $<"
js2/.legacy_admin.built.mjs: | js2
touch $@
static js2:
mkdir -p $@
clean:
$(RM) $(MJS_FILES) js2/.legacy_admin.built.mjs
Here,
$(MJS_FILES): js2/.legacy_admin.built.mjs
says that each of $(MJS_FILES)
depends on js2/.legacy_admin.built.mjs
.
That's the most concise way to do it without a pattern rule. The make runs like:
$ make
mkdir -p static
mkdir -p js2
touch js2/.legacy_admin.built.mjs
static/app.mjs depends on js2/.legacy_admin.built.mjs
static/admin_unit.mjs depends on js2/.legacy_admin.built.mjs
static/admin_source.mjs depends on js2/.legacy_admin.built.mjs
static/admin_module.mjs depends on js2/.legacy_admin.built.mjs
If you want you can move the maintenance of the MJS_STEMS
list out of the
makefile into another file:
$ cat ./mjs_stems
app
admin_unit
admin_source
admin_module
$ cat Makefile
MJS_STEMS := $(shell cat ./mjs_stems)
MJS_FILES := $(addprefix static/,$(MJS_STEMS:%=%.mjs))
.PHONY: all clean
all: $(MJS_FILES)
$(MJS_FILES): js2/.legacy_admin.built.mjs
static/%.mjs: | static
@echo $< > $@
@echo "$@ depends on $<"
js2/.legacy_admin.built.mjs: | js2
touch $@
static js2:
mkdir -p $@
clean:
$(RM) $(MJS_FILES) js2/.legacy_admin.built.mjs
$ make clean
rm -f static/app.mjs static/admin_unit.mjs static/admin_source.mjs static/admin_module.mjs js2/.legacy_admin.built.mjs
$ echo "admin_foobar" >> mjs_stems
$ make
touch js2/.legacy_admin.built.mjs
static/app.mjs depends on js2/.legacy_admin.built.mjs
static/admin_unit.mjs depends on js2/.legacy_admin.built.mjs
static/admin_source.mjs depends on js2/.legacy_admin.built.mjs
static/admin_module.mjs depends on js2/.legacy_admin.built.mjs
static/admin_foobar.mjs depends on js2/.legacy_admin.built.mjs
Or you can just get the MJS_STEMS
list from the environment:
$ cat Makefile
MJS_STEMS := $(strip $(MJS_STEMS))
MJS_FILES := $(addprefix static/,$(MJS_STEMS:%=%.mjs))
.PHONY: all clean
all: $(MJS_FILES)
$(MJS_FILES): js2/.legacy_admin.built.mjs
static/%.mjs: | static
@echo $< > $@
@echo "$@ depends on $<"
js2/.legacy_admin.built.mjs: | js2
touch $@
static js2:
mkdir -p $@
clean:
$(RM) $(MJS_FILES) js2/.legacy_admin.built.mjs
$ make clean
rm -f static/app.mjs static/admin_unit.mjs static/admin_source.mjs static/admin_module.mjs static/admin_foobar.mjs js2/.legacy_admin.built.mjs
$ export MJS_STEMS=$(cat ./mjs_stems)
$ make
touch js2/.legacy_admin.built.mjs
static/app.mjs depends on js2/.legacy_admin.built.mjs
static/admin_unit.mjs depends on js2/.legacy_admin.built.mjs
static/admin_source.mjs depends on js2/.legacy_admin.built.mjs
static/admin_module.mjs depends on js2/.legacy_admin.built.mjs
static/admin_foobar.mjs depends on js2/.legacy_admin.built.mjs
$ make clean
rm -f static/app.mjs static/admin_unit.mjs static/admin_source.mjs static/admin_module.mjs static/admin_foobar.mjs js2/.legacy_admin.built.mjs
$ export MJS_STEMS="aa bb cc"
$ make
touch js2/.legacy_admin.built.mjs
static/aa.mjs depends on js2/.legacy_admin.built.mjs
static/bb.mjs depends on js2/.legacy_admin.built.mjs
static/cc.mjs depends on js2/.legacy_admin.built.mjs
$ make clean
rm -f static/aa.mjs static/bb.mjs static/cc.mjs js2/.legacy_admin.built.mjs
But one way or another, somewhere, you have to specify the list of targets, and
to add new targets you have to update something.
Thanks for this. I don't think it directly answers my question but if not that's partly my fault for leaving out some of the background: I do already generate a list of target files viaappfiles = $(shell ls -1 js2/*.build.mjs)
andjs2: $(appfiles:js2/%.build.mjs=static/%.mjs)
[I forget if there was a reason for splitting it beyond readability.] So in this case I'm only trying to cleanly "call out" some of them as having an extra dependency. As @Matt reminds below, I should be able to use similarls -1
/substitution tricks to generate a sub-list.
– natevw
Apr 1 at 16:07
add a comment
|
As you know, a pattern rule like:
static/admin_%.mjs: js2/.legacy_admin.built.mjs
recipe...
does not specify any targets, just a template for discovering
the prerequisites of targets that you specify otherwise,
with a recipe for making those targets from the prerequisites.
So there has to be something else in your makefile that determines
what the targets are. Let's suppose it is just a list as in:
$ cat Makefile
MJS_STEMS := app admin_unit admin_source admin_module
MJS_FILES := $(addprefix static/,$(MJS_STEMS:%=%.mjs))
.PHONY: all clean
all: $(MJS_FILES)
$(MJS_FILES): js2/.legacy_admin.built.mjs
static/%.mjs: | static
@echo $< > $@
@echo "$@ depends on $<"
js2/.legacy_admin.built.mjs: | js2
touch $@
static js2:
mkdir -p $@
clean:
$(RM) $(MJS_FILES) js2/.legacy_admin.built.mjs
Here,
$(MJS_FILES): js2/.legacy_admin.built.mjs
says that each of $(MJS_FILES)
depends on js2/.legacy_admin.built.mjs
.
That's the most concise way to do it without a pattern rule. The make runs like:
$ make
mkdir -p static
mkdir -p js2
touch js2/.legacy_admin.built.mjs
static/app.mjs depends on js2/.legacy_admin.built.mjs
static/admin_unit.mjs depends on js2/.legacy_admin.built.mjs
static/admin_source.mjs depends on js2/.legacy_admin.built.mjs
static/admin_module.mjs depends on js2/.legacy_admin.built.mjs
If you want you can move the maintenance of the MJS_STEMS
list out of the
makefile into another file:
$ cat ./mjs_stems
app
admin_unit
admin_source
admin_module
$ cat Makefile
MJS_STEMS := $(shell cat ./mjs_stems)
MJS_FILES := $(addprefix static/,$(MJS_STEMS:%=%.mjs))
.PHONY: all clean
all: $(MJS_FILES)
$(MJS_FILES): js2/.legacy_admin.built.mjs
static/%.mjs: | static
@echo $< > $@
@echo "$@ depends on $<"
js2/.legacy_admin.built.mjs: | js2
touch $@
static js2:
mkdir -p $@
clean:
$(RM) $(MJS_FILES) js2/.legacy_admin.built.mjs
$ make clean
rm -f static/app.mjs static/admin_unit.mjs static/admin_source.mjs static/admin_module.mjs js2/.legacy_admin.built.mjs
$ echo "admin_foobar" >> mjs_stems
$ make
touch js2/.legacy_admin.built.mjs
static/app.mjs depends on js2/.legacy_admin.built.mjs
static/admin_unit.mjs depends on js2/.legacy_admin.built.mjs
static/admin_source.mjs depends on js2/.legacy_admin.built.mjs
static/admin_module.mjs depends on js2/.legacy_admin.built.mjs
static/admin_foobar.mjs depends on js2/.legacy_admin.built.mjs
Or you can just get the MJS_STEMS
list from the environment:
$ cat Makefile
MJS_STEMS := $(strip $(MJS_STEMS))
MJS_FILES := $(addprefix static/,$(MJS_STEMS:%=%.mjs))
.PHONY: all clean
all: $(MJS_FILES)
$(MJS_FILES): js2/.legacy_admin.built.mjs
static/%.mjs: | static
@echo $< > $@
@echo "$@ depends on $<"
js2/.legacy_admin.built.mjs: | js2
touch $@
static js2:
mkdir -p $@
clean:
$(RM) $(MJS_FILES) js2/.legacy_admin.built.mjs
$ make clean
rm -f static/app.mjs static/admin_unit.mjs static/admin_source.mjs static/admin_module.mjs static/admin_foobar.mjs js2/.legacy_admin.built.mjs
$ export MJS_STEMS=$(cat ./mjs_stems)
$ make
touch js2/.legacy_admin.built.mjs
static/app.mjs depends on js2/.legacy_admin.built.mjs
static/admin_unit.mjs depends on js2/.legacy_admin.built.mjs
static/admin_source.mjs depends on js2/.legacy_admin.built.mjs
static/admin_module.mjs depends on js2/.legacy_admin.built.mjs
static/admin_foobar.mjs depends on js2/.legacy_admin.built.mjs
$ make clean
rm -f static/app.mjs static/admin_unit.mjs static/admin_source.mjs static/admin_module.mjs static/admin_foobar.mjs js2/.legacy_admin.built.mjs
$ export MJS_STEMS="aa bb cc"
$ make
touch js2/.legacy_admin.built.mjs
static/aa.mjs depends on js2/.legacy_admin.built.mjs
static/bb.mjs depends on js2/.legacy_admin.built.mjs
static/cc.mjs depends on js2/.legacy_admin.built.mjs
$ make clean
rm -f static/aa.mjs static/bb.mjs static/cc.mjs js2/.legacy_admin.built.mjs
But one way or another, somewhere, you have to specify the list of targets, and
to add new targets you have to update something.
Thanks for this. I don't think it directly answers my question but if not that's partly my fault for leaving out some of the background: I do already generate a list of target files viaappfiles = $(shell ls -1 js2/*.build.mjs)
andjs2: $(appfiles:js2/%.build.mjs=static/%.mjs)
[I forget if there was a reason for splitting it beyond readability.] So in this case I'm only trying to cleanly "call out" some of them as having an extra dependency. As @Matt reminds below, I should be able to use similarls -1
/substitution tricks to generate a sub-list.
– natevw
Apr 1 at 16:07
add a comment
|
As you know, a pattern rule like:
static/admin_%.mjs: js2/.legacy_admin.built.mjs
recipe...
does not specify any targets, just a template for discovering
the prerequisites of targets that you specify otherwise,
with a recipe for making those targets from the prerequisites.
So there has to be something else in your makefile that determines
what the targets are. Let's suppose it is just a list as in:
$ cat Makefile
MJS_STEMS := app admin_unit admin_source admin_module
MJS_FILES := $(addprefix static/,$(MJS_STEMS:%=%.mjs))
.PHONY: all clean
all: $(MJS_FILES)
$(MJS_FILES): js2/.legacy_admin.built.mjs
static/%.mjs: | static
@echo $< > $@
@echo "$@ depends on $<"
js2/.legacy_admin.built.mjs: | js2
touch $@
static js2:
mkdir -p $@
clean:
$(RM) $(MJS_FILES) js2/.legacy_admin.built.mjs
Here,
$(MJS_FILES): js2/.legacy_admin.built.mjs
says that each of $(MJS_FILES)
depends on js2/.legacy_admin.built.mjs
.
That's the most concise way to do it without a pattern rule. The make runs like:
$ make
mkdir -p static
mkdir -p js2
touch js2/.legacy_admin.built.mjs
static/app.mjs depends on js2/.legacy_admin.built.mjs
static/admin_unit.mjs depends on js2/.legacy_admin.built.mjs
static/admin_source.mjs depends on js2/.legacy_admin.built.mjs
static/admin_module.mjs depends on js2/.legacy_admin.built.mjs
If you want you can move the maintenance of the MJS_STEMS
list out of the
makefile into another file:
$ cat ./mjs_stems
app
admin_unit
admin_source
admin_module
$ cat Makefile
MJS_STEMS := $(shell cat ./mjs_stems)
MJS_FILES := $(addprefix static/,$(MJS_STEMS:%=%.mjs))
.PHONY: all clean
all: $(MJS_FILES)
$(MJS_FILES): js2/.legacy_admin.built.mjs
static/%.mjs: | static
@echo $< > $@
@echo "$@ depends on $<"
js2/.legacy_admin.built.mjs: | js2
touch $@
static js2:
mkdir -p $@
clean:
$(RM) $(MJS_FILES) js2/.legacy_admin.built.mjs
$ make clean
rm -f static/app.mjs static/admin_unit.mjs static/admin_source.mjs static/admin_module.mjs js2/.legacy_admin.built.mjs
$ echo "admin_foobar" >> mjs_stems
$ make
touch js2/.legacy_admin.built.mjs
static/app.mjs depends on js2/.legacy_admin.built.mjs
static/admin_unit.mjs depends on js2/.legacy_admin.built.mjs
static/admin_source.mjs depends on js2/.legacy_admin.built.mjs
static/admin_module.mjs depends on js2/.legacy_admin.built.mjs
static/admin_foobar.mjs depends on js2/.legacy_admin.built.mjs
Or you can just get the MJS_STEMS
list from the environment:
$ cat Makefile
MJS_STEMS := $(strip $(MJS_STEMS))
MJS_FILES := $(addprefix static/,$(MJS_STEMS:%=%.mjs))
.PHONY: all clean
all: $(MJS_FILES)
$(MJS_FILES): js2/.legacy_admin.built.mjs
static/%.mjs: | static
@echo $< > $@
@echo "$@ depends on $<"
js2/.legacy_admin.built.mjs: | js2
touch $@
static js2:
mkdir -p $@
clean:
$(RM) $(MJS_FILES) js2/.legacy_admin.built.mjs
$ make clean
rm -f static/app.mjs static/admin_unit.mjs static/admin_source.mjs static/admin_module.mjs static/admin_foobar.mjs js2/.legacy_admin.built.mjs
$ export MJS_STEMS=$(cat ./mjs_stems)
$ make
touch js2/.legacy_admin.built.mjs
static/app.mjs depends on js2/.legacy_admin.built.mjs
static/admin_unit.mjs depends on js2/.legacy_admin.built.mjs
static/admin_source.mjs depends on js2/.legacy_admin.built.mjs
static/admin_module.mjs depends on js2/.legacy_admin.built.mjs
static/admin_foobar.mjs depends on js2/.legacy_admin.built.mjs
$ make clean
rm -f static/app.mjs static/admin_unit.mjs static/admin_source.mjs static/admin_module.mjs static/admin_foobar.mjs js2/.legacy_admin.built.mjs
$ export MJS_STEMS="aa bb cc"
$ make
touch js2/.legacy_admin.built.mjs
static/aa.mjs depends on js2/.legacy_admin.built.mjs
static/bb.mjs depends on js2/.legacy_admin.built.mjs
static/cc.mjs depends on js2/.legacy_admin.built.mjs
$ make clean
rm -f static/aa.mjs static/bb.mjs static/cc.mjs js2/.legacy_admin.built.mjs
But one way or another, somewhere, you have to specify the list of targets, and
to add new targets you have to update something.
As you know, a pattern rule like:
static/admin_%.mjs: js2/.legacy_admin.built.mjs
recipe...
does not specify any targets, just a template for discovering
the prerequisites of targets that you specify otherwise,
with a recipe for making those targets from the prerequisites.
So there has to be something else in your makefile that determines
what the targets are. Let's suppose it is just a list as in:
$ cat Makefile
MJS_STEMS := app admin_unit admin_source admin_module
MJS_FILES := $(addprefix static/,$(MJS_STEMS:%=%.mjs))
.PHONY: all clean
all: $(MJS_FILES)
$(MJS_FILES): js2/.legacy_admin.built.mjs
static/%.mjs: | static
@echo $< > $@
@echo "$@ depends on $<"
js2/.legacy_admin.built.mjs: | js2
touch $@
static js2:
mkdir -p $@
clean:
$(RM) $(MJS_FILES) js2/.legacy_admin.built.mjs
Here,
$(MJS_FILES): js2/.legacy_admin.built.mjs
says that each of $(MJS_FILES)
depends on js2/.legacy_admin.built.mjs
.
That's the most concise way to do it without a pattern rule. The make runs like:
$ make
mkdir -p static
mkdir -p js2
touch js2/.legacy_admin.built.mjs
static/app.mjs depends on js2/.legacy_admin.built.mjs
static/admin_unit.mjs depends on js2/.legacy_admin.built.mjs
static/admin_source.mjs depends on js2/.legacy_admin.built.mjs
static/admin_module.mjs depends on js2/.legacy_admin.built.mjs
If you want you can move the maintenance of the MJS_STEMS
list out of the
makefile into another file:
$ cat ./mjs_stems
app
admin_unit
admin_source
admin_module
$ cat Makefile
MJS_STEMS := $(shell cat ./mjs_stems)
MJS_FILES := $(addprefix static/,$(MJS_STEMS:%=%.mjs))
.PHONY: all clean
all: $(MJS_FILES)
$(MJS_FILES): js2/.legacy_admin.built.mjs
static/%.mjs: | static
@echo $< > $@
@echo "$@ depends on $<"
js2/.legacy_admin.built.mjs: | js2
touch $@
static js2:
mkdir -p $@
clean:
$(RM) $(MJS_FILES) js2/.legacy_admin.built.mjs
$ make clean
rm -f static/app.mjs static/admin_unit.mjs static/admin_source.mjs static/admin_module.mjs js2/.legacy_admin.built.mjs
$ echo "admin_foobar" >> mjs_stems
$ make
touch js2/.legacy_admin.built.mjs
static/app.mjs depends on js2/.legacy_admin.built.mjs
static/admin_unit.mjs depends on js2/.legacy_admin.built.mjs
static/admin_source.mjs depends on js2/.legacy_admin.built.mjs
static/admin_module.mjs depends on js2/.legacy_admin.built.mjs
static/admin_foobar.mjs depends on js2/.legacy_admin.built.mjs
Or you can just get the MJS_STEMS
list from the environment:
$ cat Makefile
MJS_STEMS := $(strip $(MJS_STEMS))
MJS_FILES := $(addprefix static/,$(MJS_STEMS:%=%.mjs))
.PHONY: all clean
all: $(MJS_FILES)
$(MJS_FILES): js2/.legacy_admin.built.mjs
static/%.mjs: | static
@echo $< > $@
@echo "$@ depends on $<"
js2/.legacy_admin.built.mjs: | js2
touch $@
static js2:
mkdir -p $@
clean:
$(RM) $(MJS_FILES) js2/.legacy_admin.built.mjs
$ make clean
rm -f static/app.mjs static/admin_unit.mjs static/admin_source.mjs static/admin_module.mjs static/admin_foobar.mjs js2/.legacy_admin.built.mjs
$ export MJS_STEMS=$(cat ./mjs_stems)
$ make
touch js2/.legacy_admin.built.mjs
static/app.mjs depends on js2/.legacy_admin.built.mjs
static/admin_unit.mjs depends on js2/.legacy_admin.built.mjs
static/admin_source.mjs depends on js2/.legacy_admin.built.mjs
static/admin_module.mjs depends on js2/.legacy_admin.built.mjs
static/admin_foobar.mjs depends on js2/.legacy_admin.built.mjs
$ make clean
rm -f static/app.mjs static/admin_unit.mjs static/admin_source.mjs static/admin_module.mjs static/admin_foobar.mjs js2/.legacy_admin.built.mjs
$ export MJS_STEMS="aa bb cc"
$ make
touch js2/.legacy_admin.built.mjs
static/aa.mjs depends on js2/.legacy_admin.built.mjs
static/bb.mjs depends on js2/.legacy_admin.built.mjs
static/cc.mjs depends on js2/.legacy_admin.built.mjs
$ make clean
rm -f static/aa.mjs static/bb.mjs static/cc.mjs js2/.legacy_admin.built.mjs
But one way or another, somewhere, you have to specify the list of targets, and
to add new targets you have to update something.
edited Mar 29 at 16:14
answered Mar 29 at 12:12
Mike KinghanMike Kinghan
35.9k8 gold badges80 silver badges127 bronze badges
35.9k8 gold badges80 silver badges127 bronze badges
Thanks for this. I don't think it directly answers my question but if not that's partly my fault for leaving out some of the background: I do already generate a list of target files viaappfiles = $(shell ls -1 js2/*.build.mjs)
andjs2: $(appfiles:js2/%.build.mjs=static/%.mjs)
[I forget if there was a reason for splitting it beyond readability.] So in this case I'm only trying to cleanly "call out" some of them as having an extra dependency. As @Matt reminds below, I should be able to use similarls -1
/substitution tricks to generate a sub-list.
– natevw
Apr 1 at 16:07
add a comment
|
Thanks for this. I don't think it directly answers my question but if not that's partly my fault for leaving out some of the background: I do already generate a list of target files viaappfiles = $(shell ls -1 js2/*.build.mjs)
andjs2: $(appfiles:js2/%.build.mjs=static/%.mjs)
[I forget if there was a reason for splitting it beyond readability.] So in this case I'm only trying to cleanly "call out" some of them as having an extra dependency. As @Matt reminds below, I should be able to use similarls -1
/substitution tricks to generate a sub-list.
– natevw
Apr 1 at 16:07
Thanks for this. I don't think it directly answers my question but if not that's partly my fault for leaving out some of the background: I do already generate a list of target files via
appfiles = $(shell ls -1 js2/*.build.mjs)
and js2: $(appfiles:js2/%.build.mjs=static/%.mjs)
[I forget if there was a reason for splitting it beyond readability.] So in this case I'm only trying to cleanly "call out" some of them as having an extra dependency. As @Matt reminds below, I should be able to use similar ls -1
/substitution tricks to generate a sub-list.– natevw
Apr 1 at 16:07
Thanks for this. I don't think it directly answers my question but if not that's partly my fault for leaving out some of the background: I do already generate a list of target files via
appfiles = $(shell ls -1 js2/*.build.mjs)
and js2: $(appfiles:js2/%.build.mjs=static/%.mjs)
[I forget if there was a reason for splitting it beyond readability.] So in this case I'm only trying to cleanly "call out" some of them as having an extra dependency. As @Matt reminds below, I should be able to use similar ls -1
/substitution tricks to generate a sub-list.– natevw
Apr 1 at 16:07
add a comment
|
If all those files already exist in the filesystem (i.e. not supposed to be built by make from scratch), you can use $(wildcard ...)
:
$(wildcard static/admin_*.mjs): js2/.legacy_admin.built.mjs
Unfortunately in my case thestatic/admin_*.mjs
targets are some of the final products of this Makefile, and won't always be present e.g. after mymake clean
.
– natevw
Apr 1 at 15:56
Ah, but as @MikeKinghan brings up in his answer — I can figure out what files should exist based on a different wildcard pattern (e.g.src/admin_*.build.mjs
) so I can probably combine this with a substitution.
– natevw
Apr 1 at 15:58
add a comment
|
If all those files already exist in the filesystem (i.e. not supposed to be built by make from scratch), you can use $(wildcard ...)
:
$(wildcard static/admin_*.mjs): js2/.legacy_admin.built.mjs
Unfortunately in my case thestatic/admin_*.mjs
targets are some of the final products of this Makefile, and won't always be present e.g. after mymake clean
.
– natevw
Apr 1 at 15:56
Ah, but as @MikeKinghan brings up in his answer — I can figure out what files should exist based on a different wildcard pattern (e.g.src/admin_*.build.mjs
) so I can probably combine this with a substitution.
– natevw
Apr 1 at 15:58
add a comment
|
If all those files already exist in the filesystem (i.e. not supposed to be built by make from scratch), you can use $(wildcard ...)
:
$(wildcard static/admin_*.mjs): js2/.legacy_admin.built.mjs
If all those files already exist in the filesystem (i.e. not supposed to be built by make from scratch), you can use $(wildcard ...)
:
$(wildcard static/admin_*.mjs): js2/.legacy_admin.built.mjs
answered Mar 29 at 6:02
MattMatt
5,8661 gold badge6 silver badges13 bronze badges
5,8661 gold badge6 silver badges13 bronze badges
Unfortunately in my case thestatic/admin_*.mjs
targets are some of the final products of this Makefile, and won't always be present e.g. after mymake clean
.
– natevw
Apr 1 at 15:56
Ah, but as @MikeKinghan brings up in his answer — I can figure out what files should exist based on a different wildcard pattern (e.g.src/admin_*.build.mjs
) so I can probably combine this with a substitution.
– natevw
Apr 1 at 15:58
add a comment
|
Unfortunately in my case thestatic/admin_*.mjs
targets are some of the final products of this Makefile, and won't always be present e.g. after mymake clean
.
– natevw
Apr 1 at 15:56
Ah, but as @MikeKinghan brings up in his answer — I can figure out what files should exist based on a different wildcard pattern (e.g.src/admin_*.build.mjs
) so I can probably combine this with a substitution.
– natevw
Apr 1 at 15:58
Unfortunately in my case the
static/admin_*.mjs
targets are some of the final products of this Makefile, and won't always be present e.g. after my make clean
.– natevw
Apr 1 at 15:56
Unfortunately in my case the
static/admin_*.mjs
targets are some of the final products of this Makefile, and won't always be present e.g. after my make clean
.– natevw
Apr 1 at 15:56
Ah, but as @MikeKinghan brings up in his answer — I can figure out what files should exist based on a different wildcard pattern (e.g.
src/admin_*.build.mjs
) so I can probably combine this with a substitution.– natevw
Apr 1 at 15:58
Ah, but as @MikeKinghan brings up in his answer — I can figure out what files should exist based on a different wildcard pattern (e.g.
src/admin_*.build.mjs
) so I can probably combine this with a substitution.– natevw
Apr 1 at 15:58
add a comment
|
I found another trick to do this, under the special case that all relevant files are built via their own particular recipe. I.e. this will not work in the general case, unless you have split out or can duplicate a separate recipe for the targets in question.
Granting that, it's a simple matter of tying in the common dependency via a phony target. This ADMIN
target depends on the shared intermediate file, and then in turn is specified as a prequisite of a pattern-matching recipe:
.PHONY: ADMIN
ADMIN: js2/.legacy_admin.built.mjs
static/admin_%.mjs static/admin_%.mjs.map: js2/admin_%.build.mjs ADMIN FORCE
node_modules/.bin/rollup --config rollup.config.js $< --format esm --sourcemap -o $@
# …also contains recipe to build "js2/.legacy_admin.built.mjs" itself
Now before any static/admin_%.mjs
file is built, make ensures that the common js2/.legacy_admin.built.mjs
helper file has been created.
(See when multiple pattern rules match a target for some background on how various versions of Make pick which recipe to use.)
add a comment
|
I found another trick to do this, under the special case that all relevant files are built via their own particular recipe. I.e. this will not work in the general case, unless you have split out or can duplicate a separate recipe for the targets in question.
Granting that, it's a simple matter of tying in the common dependency via a phony target. This ADMIN
target depends on the shared intermediate file, and then in turn is specified as a prequisite of a pattern-matching recipe:
.PHONY: ADMIN
ADMIN: js2/.legacy_admin.built.mjs
static/admin_%.mjs static/admin_%.mjs.map: js2/admin_%.build.mjs ADMIN FORCE
node_modules/.bin/rollup --config rollup.config.js $< --format esm --sourcemap -o $@
# …also contains recipe to build "js2/.legacy_admin.built.mjs" itself
Now before any static/admin_%.mjs
file is built, make ensures that the common js2/.legacy_admin.built.mjs
helper file has been created.
(See when multiple pattern rules match a target for some background on how various versions of Make pick which recipe to use.)
add a comment
|
I found another trick to do this, under the special case that all relevant files are built via their own particular recipe. I.e. this will not work in the general case, unless you have split out or can duplicate a separate recipe for the targets in question.
Granting that, it's a simple matter of tying in the common dependency via a phony target. This ADMIN
target depends on the shared intermediate file, and then in turn is specified as a prequisite of a pattern-matching recipe:
.PHONY: ADMIN
ADMIN: js2/.legacy_admin.built.mjs
static/admin_%.mjs static/admin_%.mjs.map: js2/admin_%.build.mjs ADMIN FORCE
node_modules/.bin/rollup --config rollup.config.js $< --format esm --sourcemap -o $@
# …also contains recipe to build "js2/.legacy_admin.built.mjs" itself
Now before any static/admin_%.mjs
file is built, make ensures that the common js2/.legacy_admin.built.mjs
helper file has been created.
(See when multiple pattern rules match a target for some background on how various versions of Make pick which recipe to use.)
I found another trick to do this, under the special case that all relevant files are built via their own particular recipe. I.e. this will not work in the general case, unless you have split out or can duplicate a separate recipe for the targets in question.
Granting that, it's a simple matter of tying in the common dependency via a phony target. This ADMIN
target depends on the shared intermediate file, and then in turn is specified as a prequisite of a pattern-matching recipe:
.PHONY: ADMIN
ADMIN: js2/.legacy_admin.built.mjs
static/admin_%.mjs static/admin_%.mjs.map: js2/admin_%.build.mjs ADMIN FORCE
node_modules/.bin/rollup --config rollup.config.js $< --format esm --sourcemap -o $@
# …also contains recipe to build "js2/.legacy_admin.built.mjs" itself
Now before any static/admin_%.mjs
file is built, make ensures that the common js2/.legacy_admin.built.mjs
helper file has been created.
(See when multiple pattern rules match a target for some background on how various versions of Make pick which recipe to use.)
edited Sep 3 at 17:51
answered Sep 3 at 17:45
natevwnatevw
10.2k5 gold badges52 silver badges71 bronze badges
10.2k5 gold badges52 silver badges71 bronze badges
add a comment
|
add a comment
|
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55407224%2fmakefile-how-to-declare-a-dependency-for-all-targets-that-match-a-pattern%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown