Reputation: 345
I have the following Makefile, with a rule which checks for dependencies:
#!/usr/bin/make -f
dependencies:
$(info START-info)
@echo "START-echo"
$(call assert-command-present,fastqc)
$(call assert-command-present,cutadapt)
$(call assert-command-present,bowtie2)
$(call assert-command-present,samtools)
$(call assert-command-present,bedtools)
$(call assert-command-present,fetchChromSizes)
$(call assert-command-present,bedGraphToBigWig)
$(info END-info)
@echo "END-echo"
pipeline: dependencies
assert-command-present = $(info Checking for $1) && $(if $(shell which $1),$(info OK.),$(error ERROR: could not find '$1'. Exiting))
The user-defined function assert-command-present checks for a command in the path, and returns an error if it is not found. When I run this Makefile, the echo and info commands are not returned in the order I expect:
START-info
Checking for fastqc
OK.
Checking for cutadapt
OK.
Checking for bowtie2
OK.
Checking for samtools
OK.
Checking for bedtools
OK.
Checking for fetchChromSizes
OK.
Checking for bedGraphToBigWig
OK.
END-info
START-echo
END-echo
The START-echo and START-info commands should run before any assert-command-presents functions run, but the echo command runs after the function calls.
Upvotes: 2
Views: 1402
Reputation: 7098
Eugeniu Rosca is correct. More generally, "make" built-in functions are evaluated first, then the entire command sequence is run.
One way to see this is to use the GNU make debugger remake. You can stop at the target "dependencies", and write out the commands that would be run in a shell.
For example:
$ remake -X -f /tmp/Makefile dependencies
GNU Make 4.1+dbg0.91
...
Updating goal targets....
-> (/tmp/Makefile:3)
dependencies:
remake<0> write
START-info
END-info
File "/tmp/dependencies.sh" written.
remake<1>
Look at file /tmp/dependencies.sh
and you will see all of the Make functions removed or expanded with whatever value they returned which in my case was empty lines.
Upvotes: 4