2011-04-13 81 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) 

这就为每一个子目录,这将重新执行只要有其中在文件列表中的变化规律。

相关问题