Code:
DEST = <some-folder>
EXES = compiled1
SCRIPTS = script1
COPIED = $(addprefix $(DEST)/,$(EXES) $(SCRIPTS))
$(shell mkdir -p $(DEST))
all: $(COPIED)
$(EXES):
$(CXX) -o $@ $^ $(CXXFLAGS) $(LDFLAGS)
$(COPIED):
cp $< $@
chmod +x $@
$(DEST)/%: %
compiled1: compiled1.cpp
The idea is as follow: I have a folder with some scripts and source files. Source files are compiled to form 1 or more binary programs.
Then I need to copy both the scripts and the binary programs to a same destination folder. The scripts require, besides being copied, to be chmod
ed. Compiled programs don't but I did it anyway to merge rules.
all:
rule depends on the copied-files.
$(DEST)/%:
rule is meant to make sure each copied-file depends on my local version.
$(EXES):
rule generate the local binary programs.The problem is that, for some reason, the $(DEST)/%: %
prerequisite-only rule is not firing, so within the $(COPIED)
rule, $<
is empty, and cp
fails, and it should fire because $(COPIED)
follows the $(DEST)/%
pattern.
The problem is that, for some reason, the
$(DEST)/%: %
prerequisite-only rule is not firing, so within the$(COPIED)
rule,$<
is empty, andcp
fails, and it should fire because$(COPIED)
follows the$(DEST)/%
pattern.
Prerequisite-only implicit rules do not make much sense for adding prerequisites to targets (and they specifically do not have that effect). make
will consider implicit rules for a given target only if there is no explicit rule for the target, and it will select one implicit rule from among those applicable for building it. If no implicit rule matching a given target provides a recipe, and the target is not phony, then there must be an explicit rule that suffices to build it, and that moots all implicit rules for the same target.
One alternative would be to do the copying directly in the implicit rule, instead of having a separate rule for that:
# $(COPIED):
# cp $< $@
# chmod +x $@
$(DEST)/%: %
cp $< $@
chmod +x $@
All the files designated by $(COPIED)
are named as prerequisites for all
, so building all
will trigger the implicit rule (with its recipe) for each of them. You can also build any one of them explicitly, just as you could before. You can also get make
to try to build and copy other files, which is a potential weakness, but perhaps one you can live with.
Another alternative would be write a more conventional installation rule,* maybe something like this:
DEST = <some-folder>
EXES = compiled1
SCRIPTS = script1
all: $(EXES)
install: all
mkdir -p -m 0755 $(DEST)
cp $(EXES) $(SCRIPTS) $(DEST)
chmod 0755 $(SCRIPTS)
.PHONY: all install
* And if the copying is not well characterized as installation, then maybe rethink more deeply. If the copying does not require more privilege than the building does, then you probably shouldn't be doing it at all. Instead, build the EXEs directly to the location where you want them, and distribute the scripts (or copies of them) pre-installed in that location (which must be within the distribution if you can be sure that no extra privilege is required to copy files there).