2011-04-13 22 views
5

Ben de verilen Dizinler altındaki tüm dosyaları paketleri gnumake veya makepp ile çalışan bir Makefile yapmak istediğiniz bir dizinin her dosya bağlıdır: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 

sorun böyle var olmasıdır bağımlılıklarda%/* gibi bir şey. X dizinindeki her dosyaya bağlı olmak için hedeflere (X.npk) ihtiyacım var, ama Makefile yazarken dosyaların ne olduğunu bilmiyorum, çünkü daha sonra üretiliyorlar.

Bir örnek:

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

Ben ./dirA.npk (x bağlı, y) oluşturmak istiyorum, ./dirB.npk (e, f) Bilmem bir şey yok dirs veya dosyaları önceden, 1. satırda kullanılan buluntuların tüm dirsleri bulması dışında. wildcard yönergesini kullanarak

+0

Denedim:% .npk: $ (joker karakter%/*) ancak bu çalışmaz. Aynı zamanda bir semafor da düşündüm ama aynı soruna, hedef_dizine/* bağlı olmam gerek. – Gavriel

cevap

1

Bu bulduğum çözüm: , bazı "meta" komut dosyası ile makedepend fikrine dayanır. Çok hoş değil ama işe yarıyor.

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

Dene:

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

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

DÜZENLEME: yukarıda wildcard kullanarak sadece bir örnektir ve diğer klasörlerin tüm dosyaların bağımlı her .npk dosya yapar. Kullanımınız biraz farklı olacaktır. Bunun hakkında daha kolay bir yol olabileceğini düşünüyorum. Klasördeki tüm dosyalara neden bağımlı olmak istiyorsunuz? Sadece $^ operatörünü kullanmak mı? Ya da herhangi bir dosya değiştiyse .npk'yi yeniden oluşturmanız mı gerekiyor?

Bir alternatif (ve muhtemelen daha temiz) çözümü yerine $^ sizin tarifte find programı kullanın ve her zaman yeniden inşa edilecek .npk dosyasını zorlamak için .FORCE direktifini kullanmak olacaktır. Downside .npk dosyaları gereksiz şekilde yeniden oluşturulabilir.

DÜZENLEME 2:make komutlarla temiz bunu yapmanın bir yolu var değilse, sen tarifi her zaman çalıştırılır sağlamak ve "Ben bu dosyayı yeniden gerektiği" çek taşımak için .FORCE kullanarak etrafında çalışabilirsiniz

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

ı don:

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

check_for_rebuild.sh böyle bir şey yapar bir kabuk: tarifin vücuda Bu çözümü gerçekten çok seviyorum çünkü problemi doğrudan çözmektense problem çözüyor, ama bu arada size ulaşmanızı sağlayabilir. Bu rotayı gidecekseniz, muhtemelen kabuk betiğinde her şeyi yapmak daha kolay ve daha kolaydır ve ya makefile sadece betiği çağırır ya da makefile tamamen kurtulmak zorunda. Eğer 2 adımda bunu yapabilirsiniz makepp ile

+0

tam olarak, dosyalardan herhangi biri değiştirildiğinde veya yeni bir dosya eklendiyse npk dosyasını yeniden oluşturmam gerekiyor. .FORCE bir seçenek değil, ben opposit yapmaya çalışıyorum (şu anda X.npk.tmp içine her şeyi repacks bir kabuk betiği var, sonra cpm X.npk X.npk.tmp gösterir değişti eğer ben yeniden adlandırmak tmp dosyası yoksa siliyorum ama daha fazla dir ve dosyam olduğu için yavaşlıyor. – Gavriel

0

yoluyla: foreach kural değiştirici: Bu dosyalar listesine bir değişiklik oradaki olduğunda reexecutes her alt dizinin için kural sağlar

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

.