2011-04-13 82 views
5

我想要做的運行要麼gnumake的或makepp是包下給出directiories的所有文件的Makefile:的Makefile:取決於目錄的每個文件

DIRS:=$(shell find . -mindepth 2 -maxdepth 2 -not -name mp3 -not -name ".*" -type d) 
PACKAGES = $(DIRS:%=%.npk) 

all: packages 

packages: $(PACKAGES) 

%.npk: %/* 
    npack c [email protected] @^ 

.PHONY: all packages 

的問題是,有沒有這樣的在依賴項中作爲%/ *。 我需要目標(X.npk)依賴目錄X中的每個文件,但我不知道當我編寫Makefile時文件是什麼,因爲它們是在稍後生成的。

一個例子:

./dirA/x 
./dirA/y 
./dirB/e 
./dirB/f 

我想創建./dirA.npk(取決於X,Y),./dirB.npk(E,F) 我沒有什麼瞭解目錄或文件,除了第一行中使用的查找找到所有目錄。

+0

我試過了:%.npk:$(通配符%/ *)但是不起作用。我也考慮過semafor,但遇到同樣的問題,我需要依賴target_dir/*。 – Gavriel 2011-04-14 00:00:55

回答

1

這是我找到的解決方案: 它基於makedepend的想法,帶有一些「元」腳本。不是很好,但工作。

PACKAGES := 

all: packages 

-include Makefile.depend 

packages: Makefile.depend $(PACKAGES) 

depend: clean Makefile.depend 

Makefile.depend: 
    @(PACKAGES= ; \ 
    for DIR in `find . -mindepth 2 -maxdepth 2 -not -name mp3 -not -name ".*" -type d` ; \ 
    do \ 
     PACKAGE=`basename $${DIR}.npk` ; \ 
     PACKAGES="$${PACKAGES} $${PACKAGE}" ; \ 
     DEPS=`find $${DIR} -not -type d | sed -e 's#\([: ]\)#\\\\\1#' -e 's#^\./\(.*\)# \1#' | tr -d "\n"` ; \ 
     SUBDIR=`echo $${DIR} | sed -e 's#^\./\([^/]\+\)/.*#\1#'` ; \ 
     FILES=`echo \ $${DEPS} | sed -e "s# $${SUBDIR}/# #g"` ; \ 
     echo "$${PACKAGE}:$${DEPS}" ; \ 
     echo " @cd $${SUBDIR} ; \\" ; \ 
     echo " npack c ../\[email protected] $${FILES} ; \\" ; \ 
     echo ; \ 
    done ; \ 
    echo "PACKAGES = $${PACKAGES}" \ 
    )>> Makefile.depend ; \ 

cleanall: clean 
    rm -f *.npk 

clean: 
    @rm -f Makefile.depend 

.PHONY: all packages depend clean 
2

嘗試使用wildcard指令:

DEPS := $(foreach dir, $(DIRS), $(wildcard $(dir)/*)) 

%.npk: $(DEPS) 
    npack c [email protected] $^ 

編輯: 以上只是使用wildcard的例子,使得依賴於所有其他文件夾的文件,每個文件.npk。您的使用情況會稍有不同。

我認爲可能有更簡單的方法來解決這個問題。你爲什麼想要依賴文件夾中的所有文件?是僅僅使用$^運算符嗎?或者如果任何文件改變了,你是否需要重建.npk?

一個備用(也可能是清潔劑)的解決方案是使用find工具在你的食譜,而不是$^和使用.FORCE指令總是迫使.npk文件重建。缺點是.npk文件可能會被不必要地重建。

編輯2: 要是沒有辦法與make命令乾淨做到這一點,你可以解決它通過使用.FORCE,以確保配方始終運行並移動「我應該重新生成此文件」檢查入配方的身體:

%.npk: .FORCE 
    check_for_rebuild.sh [email protected] && npack c [email protected] $^ 

其中check_for_rebuild.sh是一個shell腳本,它是這樣的:

#!/bin/bash 
# Returns non-zero if the archive needs to be rebuilt 
if [ -e $1 ]; then 
    folder_name=$(basename $1 .npk) 
    [ -z "$(find $folder_name -newer $1 -not -type d)" ] && return 0 
fi 
return 1 

我不真的不喜歡這個解決方案,因爲它解決了問題而不是直接解決問題,但它可能能夠讓你在此期間進行。如果你要走這條路線,那麼在shell腳本中做所有事情都可能更簡潔更容易,並且makefile只需調用腳本或完全去掉makefile即可。

+0

確切地說,我需要重建npk文件,如果任何文件改變或新文件被添加。 .FORCE是不是一個選項,我試圖做對立面(目前我有一個shell腳本,將所有東西重新裝入X.npk.tmp,然後如果'cmp X.npk X.npk.tmp'顯示更改,我重命名tmp文件,否則我刪除它,但由於我有更多的文件和目錄,因此速度變慢。 – Gavriel 2011-04-14 00:18:26

0

隨着makepp您可以在2個步驟做到這一點,通過:的foreach規則修改:

$(foreach).txt: $(foreach)/*: foreach */ 
    &echo $(inputs) -o $(output) 

這就爲每一個子目錄,這將重新執行只要有其中在文件列表中的變化規律。

相關問題