2013-12-16 23 views
1

我已經寫了下面的Makefile重寫取決於的類型的Makefile變量使

INTERACTION=nonstopmode 

all: 
    make read.pdf > /dev/null 
    make clean > /dev/null 
diagnostic: 
    INTERACTION=batchmode 
    make read.pdf 
    make clean 
%.pdf: %.tex biblio.bib 
    bash makepdf.sh $(INTERACTION) $< 
clean: 
    rm -f *.aux *.log *.bbl *.bak *.blg *.toc *.out *.glg *.glo *.gls *.ist *~ *.*~* *.backup 

Makefile提供兩種模式:簡單的make文件,該文件不輸出錯誤和警告信息和診斷模式,以便pdflatex與用戶進行交互以找到問題。

makepdf.sh如下所示:

filename=$(basename $2) 
filename="${filename%.*}" 
pdflatex -interaction=$1 $2 
makeglossaries "$filename" 2 
makeindex "$filename" 2 
pdflatex -interaction=$1 $2 
echo $1 

不管事實makemake diagnostic是否被調用,程序總是在nonstopmode運行。一個Makefile變量不能被覆蓋?如果是這樣,這個問題怎麼解決?否則,這段代碼有什麼問題?

回答

2

這個makefile很奇怪。基本上,寫入不正確。

對於您的問題,最直接的答案是讓您意識到makefile配方中的每一行都在單獨的shell中調用,而在UNIX/POSIX系統中,進程無法影響其父級環境。這意味着對shell中的環境進行的調用對make過程或任何後續shell都沒有影響。因此,INTERACTION=batchmode在shell中運行並將INTERACTION變量設置爲batchmode,然後shell將退出並且該設置被遺忘,然後下一行將使用先前的設置運行。如果你想讓變量生效,你必須把它們放在配方中的同一條邏輯線上。

但是,這個makefile還有更多的基本問題。首先,你應該從不運行make來調用一個遞歸make。始終使用$(MAKE)變量。

其次,你不應該運行子製造。在makefile中列出先決條件的全部目的是強制執行規則調用的命令;在這裏你試圖通過遞歸地運行命令來接管make的工作。第三,假設你正在使用GNU,你可以使用特定於目標的變量來更容易地完成你想做的事情(參見GNU make手冊)。例如你的makefile,可以更準確地這樣寫的(注意,沒有遞歸在所有!):

INTERACTION = nonstopmode 

all: read.pdf 

diagnostic: INTERACTION = batchmode 
diagnostic: all 

%.pdf: %.tex biblio.bib 
     bash makepdf.sh $(INTERACTION) $< 

clean: 
     rm -f *.aux *.log *.bbl *.bak *.blg *.toc *.out *.glg *.glo *.gls *.ist *~ *.*~* *.backup 

它不會每個版本後自動運行clean規則。