Main content of a makefile: rules
targets … : prerequisites …
recipe
…
…
TAB character at the beginning of every recipe line!
$ cd /to/the/git/repo
Normally you should call your makefile either makefile
or Makefile
.
If not, use -f
or --file
option.
makefile_test1:
test1_double.txt : test1.txt
cp test1.txt test1_double.txt
$ make -f makefile_test1
Run again:
$ make -f makefile_test1
Let's try to create a pipeline.
makefile_test2:
test1_double.txt : test1.txt
cp test1.txt test1_double.txt
test2_double.txt : test2.txt
cp test2.txt test2_double.txt
$ make -f makefile_test2
By default, make starts with the first target which is called the default_goal and processes only rules whose targets are prerequisits of the goal.
Makefiles are usually written so that the first target is for compiling the entire program.
Or you can tell make which targets to update:
$ make -f makefile_test2 test2_double.txt
makefile_test2b:
.PHONY: all
all : test1_double.txt test2_double.txt
test1_double.txt : test1.txt
cp test1.txt test1_double.txt
test2_double.txt : test2.txt
cp test2.txt test2_double.txt
$ make -f makefile_test2b
makefile_test2c:
.PHONY: all
all : test1_double.txt test2_double.txt
%_double.txt : %.txt
cp $*.txt $*_double.txt
$ make -f makefile_test2c
To make your life simpler.
makefile_cool1:
VAR := Gosia
.PHONY: one
one:
echo "$(VAR) is coool!"
$ make -f makefile_cool1
$ make -f makefile_cool1 VAR="Helen"
VAR := Gosia
VARS := Gosia Padu Cate Luka
.PHONY: all one multiple
all: one multiple
one:
echo "$(VAR) is coool!"
multiple: $(foreach i,$(VARS),multiple_$(i))
define print_name
multiple_$(1):
echo "$(1) is coool!"
endef
$(foreach i,$(VARS),$(eval $(call print_name,$(i))))
$ make -f makefile_cool2 VAR="Helen Lukas"
$ make -f makefile_cool2 VARS="Helen Lukas"
Other useful functions:
- returns the n-th word of text
$(word n,text)
SERVERS := penticton taupo
$(word, 1, $(SERVERS))
makefile_r1:
RWD := .
RCODE := rcode
ROUT := rout
FILES := test1 test2
### Define the default rule
.PHONY: all
all: mkdir_rout plot_barplot_goal
### Make sure no intermediate files are deleted
.SECONDARY:
.PHONY: mkdir_rout
mkdir_rout:
mkdir -p $(ROUT)
define calculate_sum
$(1)_sum.txt: $(1).txt $(RCODE)/01_calculate_sum.R
R CMD BATCH --no-restore --no-save "--args rwd='$(RWD)' outdir='.' \
path_file='$(1).txt' prefix='$(1)_'" \
$(RCODE)/01_calculate_sum.R $(ROUT)/01_calculate_sum.Rout
endef
$(foreach i,$(FILES),$(eval $(call calculate_sum,$(i))))
.PHONY: plot_barplot_goal
plot_barplot_goal: $(foreach i,$(FILES),$(i)_barplot.pdf)
define plot_barplot
$(1)_barplot.pdf: $(1)_sum.txt $(RCODE)/02_barplot.R
R CMD BATCH --no-restore --no-save "--args rwd='$(RWD)' \
outdir='.' path_file='$(1)_sum.txt' prefix='$(1)_' color='red'" \
$(RCODE)/02_barplot.R $(ROUT)/02_barplot.Rout
endef
$(foreach i,$(FILES),$(eval $(call plot_barplot,$(i))))
$ make -f makefile_r1
Make sure no intermediate files are deleted.
.SECONDARY:
Marks targets as up to date without actually changing them.
rjson
package
to import jason files into R.