2012-08-24 54 views
4

我有以下代碼解開目錄中的所有文件並將其移動到構建目錄。如果我多次調用make,即使build目錄已經存在,它也會嘗試每次執行「build」目標。有沒有人遇到過這個?爲什麼以下makefile重建目標「build」

我發現這個問題,但它是不一樣的。 Makefile always running target

操作系統:Ubuntu的12.04 計劃:GNU使3.81

build: mkBuildDir untar 
    chmod 700 build 

.PHONY: mkBuildDir untar 

mkBuildDir: 
    mkdir build 

untar: *.tar.gz 
    for prefix in *.tar.gz; do \ 
     tar xvf $$prefix --directory=build; \ 
    done 

clean: 
    rm -Rf build 

回答

7

幾乎是一樣的,你所鏈接的問題。你永遠不會創建一個名爲mkBuildDir的文件,所以它總是過時的,所以build總是過期。

您的mkBuildDir目標沒有做任何有用的事情(雖然我認爲這是一個縮減的makefile)。如果您改爲

# it'd be better to list the TARFILES explicitly, though this will probably work 
TARFILES=`ls *.tar.gz` 

all: build untar 

build: $(TARFILES) 
    test -d build || mkdir build 
    chmod 700 build 
    for prefix in $(TARFILES); do \ 
     tar xvf $$prefix --directory=build; \ 
    done 

clean: 
    rm -Rf build 

這可能會完成您正在尋找的內容。

Makefile中有太多假目標通常是makefile的代碼異味。他們很少是做事最好的/慣用的方式。

+0

謝謝。這很有幫助。 – Parth

+0

我認爲最好使用'TARFILES = $(通配符* .tar.gz)'。在原始情況下,如果沒有匹配的文件名,那麼'TARFILES'將是'* .tar.gz'而不是一個空列表。更重要的是,一個流程的創造得以倖免。 – TrueY

+0

確實如此,但通配符行爲僅適用於某些shell中的某些設置。另外,'$(通配符...)'是一個GNU Make擴展,所以不會是可移植的(這可能是也可能不是問題)。最後,每一個行動路線都會創建一個新的流程,因此在這裏保存一個流程並不會真正獲益。 –