2
votes

I am trying to get some dependent install targets to work in my Makefile as follows:

.PHONY: install-everything install-part1 install-part2

install-everything: install-part1 install-part2

install-part1:
    $(call part1-function)

install-part2:
    $(call part2-function)

This is very similar to that described in the GNU Make manual here: https://www.gnu.org/software/make/manual/html_node/Phony-Targets.html

I did

make install-part1

first, then manually (i.e. rm -rf) removed the $(DESTDIR) directory that got created.

Now, every time I try to run any of the targets listed above, I get e.g:

make: nothing to be done for 'install-everything'.

I get the same answer if I try to force make with the '-B' flag. If I add debug info (make --debug) I get

File 'install-everything' does not exist.
Must remake target 'install-everything'.

I thought that using the .PHONY directive would fix this problem - can anyone help?

1
It could be that your $(call partX-function) expand to nothing. If it is the case, all recipes are empty and the message you get is correct: there is nothing to be done. Please show an example of your partX-function macros.Renaud Pacalet
It's just creating some directories and then copying stuff in: define install-part1: $(mkdir -p $(1)) $(cp -r files $(1)) endefuser12066

1 Answers

4
votes

Your partX-function macros, as you explain in your comment, expand to the empty string. What they do when called and how they expand are two different things. As a consequence your recipes are all empty and make tells you this with its nothing to be done message. It is not smart enough to analyze your macros and discover that they do something. Your use of GNU make and of its call function is unconventional. For the example you show, it would be much better to use plain make (unless you have a lot of files to install and performance matters):

.PHONY: install-everything install-part1 install-part2

install-everything: install-part1 install-part2

install-part1: $(addprefix $(DIR1)/,$(FILES1))

$(DIR1):
    mkdir -p $@

$(addprefix $(DIR1)/,$(FILES1)): $(DIR1)/%: $(SRCDIR)/% | $(DIR1)
    cp -f $< $@

install-part2:...

(assuming make variables SRCDIR, DIR1 and FILES1 define the source directory, the destination directory for install-part1 and the list of files to copy for install-part1, respectively).

In order to fully understand this example makefile, you will need to understand static pattern rules and order-only prerequisites.

If you have a lot of files to install and performance matters it is better to group the copy (cp) and thus reduce the number of shell invocations:

install-part1: $(addprefix $(SRCDIR)/,$(FILES1)) | $(DIR1)
    for f in $(FILES1); do \
         cp -f $(SRCDIR)/$$f $(DIR1);\
    done

or even:

install-part1: $(addprefix $(SRCDIR)/,$(FILES1)) | $(DIR1)
    cp -f $^ $(DIR1)

It is less elegant because all dependencies are not properly declared. And all files will be copied each time you invoke make install-part1, even if they are already installed and up-to-date, but it should be much faster than with the other solution.

Last but not least: under GNU/Linux installation frequently uses the install utility instead of cp...