Date post: | 15-Jan-2015 |
Category: |
Technology |
Upload: | pierre-lindenbaum |
View: | 434 times |
Download: | 1 times |
MakePierre Lindenbaum
http://plindenbaum.blogspot.com@yokofakun(http://twitter.com/yokofakun)
INSERM-UMR1087 NantesJanuary 2013
https://github.com/lindenb/courses/tree/master/about.make
Problem
Build a C program
Make a protein
#!/bin/bashTRANSCRIPT=catTRANSLATE=catrm -f merge.proteinfor DNA in file1.dna file2.dna file3.dnado echo "ATGCTAGTAGATGC" > ${DNA} ${TRANSCRIPT} ${DNA} > ${DNA/%.dna/.rna} ${TRANSLATE} ${DNA/%.dna/.rna} > ${DNA/%.dna/.pep} cat ${DNA/%.dna/.pep} >> merge.proteindone
What if file1.pep already exists ?
Solution: Test if file exists
#!/bin/bashTRANSCRIPT=catTRANSLATE=catrm -f merge.proteinfor DNA in file1.dna file2.dna file3.dnado echo "ATGCTAGTAGATGC" > ${DNA} ${TRANSCRIPT} ${DNA} > ${DNA/%.dna/.rna} if [ ! -f ${DNA/%.dna/.pep} ] then ${TRANSLATE} ${DNA/%.dna/.rna} > ${DNA/%.dna/.pep} fi cat ${DNA/%.dna/.pep} >> merge.proteindone
What if file1.pep is outdated ?
Parallelization ?
GNU make
"a utility that automaticallybuilds executable programs and
libraries from source code byreading files called makefiles"
1977
TARGET1: DEPENDENCIES COMMAND-LINES1 COMMAND-LINES2 COMMAND-LINES3
Makefile
TRANSCRIPT=catTRANSLATE=cat
merged.protein: file1.pep file2.pep file3.pep cat file1.pep file2.pep \ file3.pep > merged.protein
file1.pep: file1.rna ${TRANSLATE} file1.rna > file1.pep
file1.rna : file1.dna ${TRANSCRIPT} file1.dna > file1.rna
file1.dna: echo "ATGCTAGTAGATGC" > file1.dna
file2.pep: file2.rna ${TRANSLATE} file2.rna > file2.pep
file2.rna : file2.dna ${TRANSCRIPT} file2.dna > file2.rna
file2.dna: echo "ATGCTAGTAGATGC" > file2.dna
file3.pep: file3.rna ${TRANSLATE} file3.rna > file3.pep
file3.rna : file3.dna ${TRANSCRIPT} file3.dna > file3.rna
file3.dna: echo "ATGCTAGTAGATGC" > file3.dna
Output
echo "ATGCTAGTAGATGC" > file1.dnacat file1.dna > file1.rnacat file1.rna > file1.pepecho "ATGCTAGTAGATGC" > file2.dnacat file2.dna > file2.rnacat file2.rna > file2.pepecho "ATGCTAGTAGATGC" > file3.dnacat file3.dna > file3.rnacat file3.rna > file3.pepcat file1.pep file2.pep \ file3.pep > merged.protein
If one file is removed
$ rm file2.rna$ make
cat file2.dna > file2.rnacat file2.rna > file2.pepcat file1.pep file2.pep \ file3.pep > merged.protein
If one file is changed
$ touch file1.dna file3.pep$ make
cat file1.dna > file1.rnacat file1.rna > file1.pepcat file1.pep file2.pep \ file3.pep > merged.protein
Special variables
"name of the target" : $@
TRANSCRIPT=catTRANSLATE=cat
merged.protein: file1.pep file2.pep file3.pep cat file1.pep file2.pep \ file3.pep > $@
file1.pep: file1.rna ${TRANSLATE} file1.rna > $@
file1.rna : file1.dna ${TRANSCRIPT} file1.dna > $@
file1.dna: echo "ATGCTAGTAGATGC" > $@
file2.pep: file2.rna ${TRANSLATE} file2.rna > $@
file2.rna : file2.dna ${TRANSCRIPT} file2.dna > $@
file2.dna: echo "ATGCTAGTAGATGC" > $@
file3.pep: file3.rna ${TRANSLATE} file3.rna > $@
file3.rna : file3.dna ${TRANSCRIPT} file3.dna > $@
file3.dna: echo "ATGCTAGTAGATGC" > $@
"name of the first dependency" : $<
TRANSCRIPT=catTRANSLATE=cat
merged.protein: file1.pep file2.pep file3.pep cat file1.pep file2.pep \ file3.pep > $@
file1.pep: file1.rna ${TRANSLATE} $< > $@
file1.rna : file1.dna ${TRANSCRIPT} $< > $@
file1.dna: echo "ATGCTAGTAGATGC" > $@
file2.pep: file2.rna ${TRANSLATE} $< > $@
file2.rna : file2.dna ${TRANSCRIPT} $< > $@
file2.dna: echo "ATGCTAGTAGATGC" > $@
file3.pep: file3.rna ${TRANSLATE} $< > $@
file3.rna : file3.dna ${TRANSCRIPT} $< > $@
file3.dna: echo "ATGCTAGTAGATGC" > $@
"all the dependencies" : $^
TRANSCRIPT=catTRANSLATE=cat
merged.protein: file1.pep file2.pep file3.pep cat $^ > $@
file1.pep: file1.rna ${TRANSLATE} $< > $@
file1.rna : file1.dna ${TRANSCRIPT} $< > $@
file1.dna: echo "ATGCTAGTAGATGC" > $@
file2.pep: file2.rna ${TRANSLATE} $< > $@
file2.rna : file2.dna ${TRANSCRIPT} $< > $@
file2.dna: echo "ATGCTAGTAGATGC" > $@
file3.pep: file3.rna ${TRANSLATE} $< > $@
file3.rna : file3.dna ${TRANSCRIPT} $< > $@
file3.dna: echo "ATGCTAGTAGATGC" > $@
Rules
How to create a *.pep or a *.rna ?
TRANSCRIPT=catTRANSLATE=cat
%.pep:%.rna ${TRANSLATE} $< > $@%.rna:%.dna ${TRANSCRIPT} $< > $@
merged.protein: file1.pep file2.pep file3.pep cat $^ > $@
file1.dna: echo "ATGCTAGTAGATGC" > [email protected]: echo "ATGCTAGTAGATGC" > [email protected]: echo "ATGCTAGTAGATGC" > $@
Output
echo "ATGCTAGTAGATGC" > file1.dnacat file1.dna > file1.rnacat file1.rna > file1.pepecho "ATGCTAGTAGATGC" > file2.dnacat file2.dna > file2.rnacat file2.rna > file2.pepecho "ATGCTAGTAGATGC" > file3.dnacat file3.dna > file3.rnacat file3.rna > file3.pepcat file1.pep file2.pep file3.pep > merged.protein
Useful options
-B "Unconditionally make all targets"
-f FILE "Read FILE as a makefile"
-j [N] "Allow N jobs at once"
-n "Don't actually run any commands; just print them"
.PHONY targets
.PHONY: all clean
all: file1.dna
file1.dna: echo "ATGCTAGTAGATGC" > $@clean: rm -f file1.dna
Function Call Syntax
$(function arg1,arg2,arg3...)
Loops: $(foreach var,list,...)
merged.protein: \ $(foreach INDEX,1 2 3,file${INDEX}.pep ) cat $^ > $@
$(eval )
TRANSCRIPT=catTRANSLATE=catINDEXES=1 2 3%.pep:%.rna ${TRANSLATE} $< > $@%.rna:%.dna ${TRANSCRIPT} $< > $@
merged.protein: $(foreach INDEX,${INDEXES},file${INDEX}.pep ) cat $^ > $@
$(foreach INDEX,${INDEXES},$(eval \file${INDEX}:\ echo "ATGCTAGTAGATGC" > $$@ \))
$(subst ee,EE,feet on the street) ‘fEEt on the strEEt’.
$(patsubst %.c,%.o,x.c.c bar.c) ‘x.c.o bar.o’.
$(strip a b c )‘a b c’
$(filter %.c,src1.c src2.c src3.c file.txt) $(filter-out %.c,src1.c src2.c src3.c file.txt) $(sort foo bar lose)
$(word 2, foo bar baz) 'bar' $(wordlist 2, 3, foo bar baz)‘bar baz’.
$(firstword foo bar)‘foo’.
$(lastword foo bar)‘bar’.
$(dir src/foo.c hacks)‘src/ ./’
$(notdir src/foo.c hacks)‘foo.c hacks’
$(suffix src/foo.c src-1.0/bar.c hacks)‘.c .c’
$(basename src/foo.c src-1.0/bar hacks)‘src/foo src-1.0/bar hacks’
$(addsuffix .c,foo bar)‘foo.c bar.c’.
$(addprefix src/,foo bar)‘src/foo src/bar’
(join a b,.c .o)‘a.c b.o’
$(shell cat file1.txt)
END