2011-04-13 5 views
5

나도 주어진 directiories에서 모든 파일을 팩 gnumake 또는 makepp와 실행 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 (예는, F) 내가 알고 어디에도 없습니다 dirs 또는 파일을 제외하고는 모든 행을 찾습니다. wildcard 지시어를 사용하여

+0

시도 : % .npk : $ (와일드 카드 %/*)하지만 작동하지 않습니다. 나는 또한 semafor에 대해서 생각했지만 target_dir/*에 의존 할 필요가있는 같은 문제를 겪었다. – Gavriel

답변

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

시도 :

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

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

편집 : 위는 wildcard를 사용하여 단지 예이고 다른 모든 폴더에있는 파일에 따라 각 .npk 파일을 만듭니다. 당신의 사용법은 약간 다를 것입니다.

나는 이것에 관해 더 쉬운 방법이 있을지도 모른다라고 생각한다. 왜 폴더의 모든 파일에 대한 의존성을 갖고 싶습니까? $^ 연산자를 사용하는 것입니까? 또는 파일이 변경된 경우 .npk를 다시 작성해야합니까?

한 대체 (및 청소기) 솔루션 대신 $^의 레시피에 find 유틸리티를 사용하여 항상 다시 할 .npk 파일을 강제로 .FORCE 지시어를 사용하는 것입니다. 단점은 .npk 파일이 불필요하게 재구성 될 수 있다는 것입니다.

편집 2 :make 명령을 깨끗하게 할 수있는 방법이 아니라면, 당신은 조리법이 항상 실행되어 있는지 확인하고 "이 파일을 다시해야한다"체크를 이동 .FORCE를 사용하여 해결할 수 있습니다

#!/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 

I 돈 :

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

check_for_rebuild.sh 이런 식으로 뭔가를 수행하는 쉘 스크립트입니다 조리법의 본문에 문제를 직접 해결하는 대신 문제를 해결하기 때문에 해결 방법이 마음에 들지만 실제로는 문제를 해결할 수 있습니다. 그 경로로 가려고한다면 쉘 스크립트에서 모든 것을 할 수 있고 makefile이 단순히 스크립트를 호출하거나 makefile을 완전히 제거하는 것이 더 깔끔하고 쉽습니다. 당신이이 단계에서이 작업을 수행 할 수 있습니다 makepp으로

+0

정확히 어떤 파일이 변경되거나 새 파일이 추가되면 npk 파일을 다시 작성해야합니다. .FORCE는 옵션이 아닙니다. (현재 저는 모든 것을 X.npk.tmp로 재 포장하는 쉘 스크립트를 가지고 있습니다.'cmp X.npk X.npk.tmp'가 변경된 것을 보여 주면 내가 이름을 바꿉니다. 그렇지 않으면 tmp 파일을 삭제합니다.하지만 더 많은 디렉토리와 파일을 가지고 있으므로 속도가 느려지고 있습니다. – Gavriel

0

의 VIA : foreach는 규칙 수정 :이 파일 목록의 변화가 그 안에있을 때마다 reexecutes 모든 하위 디렉토리에 대한 규칙을 제공

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

.