2016-11-30 4 views
0

Ich habe eine Verzeichnisstruktur wiepatsubst mit mehreren Platzhalter

packages/ 
    foo/ 
    lib/ 
     a.js 
     b.js 
    bar/ 
    lib/ 
     c.js 
     d.js 

und ich versuche, eine einfache Makefile zu schreiben, um die Quelldateien über einen Compiler und geben das Ergebnis von laufen packages/foo/lib/a.js-packages/foo/build/a.js kompilieren. In der Vergangenheit habe ich etwas wie

JS = $(shell find packages/foo/lib -name "*.js") 
BUILD = $(patsubst packages/foo/lib/%.js, packages/foo/build/%.js, $(JS)) 

.PHONY: all 
all: $(BUILD) 

packages/foo/lib/%.js: packages/foo/build/%.js 
    # Compile $^ and output to [email protected] 

getan, das funktioniert super. Allerdings bin ich jetzt

JS = $(shell find packages/*/lib -name "*.js") 
BUILD = $(patsubst ...) 

Das Problem hier tun, ist, dass patsubst nicht zu mögen scheint mehrere % Platzhalter (dh packages/%/lib/%.js). Wenn ich jedoch packages/%.js verwende, kann ich nicht wissen, welches Verzeichnis in der Ersetzung verwendet werden soll. Ich bin überzeugt, dass es eine sehr einfache Möglichkeit gibt, dies zu tun, die ich in den make-Dokumenten nicht finden kann.

Antwort

1

BUILD zu definieren, könnten Sie die dumm, aber einfache Lösung verwenden:

BUILD = $(subst /lib/,/build/,$(JS)) 

solange man über zusätzliche „lib“ nicht besorgt sind, und „Build“ Pfadkomponenten in Ihrer Quelle.

Doch dies lässt Sie mit dem Problem, wie die tatsächlichen Makefile-Regeln zu definieren, es sei denn, Sie wollen für jedes Verzeichnis eine Regel manuell angeben foo, bar usw.

Stattdessen versuchen vielleicht so etwas wie diese (erinnern ersetzen Räume mit Tabs wieder gegebenenfalls, wenn Sie Ausschneiden und Einfügen):

PACKAGES = $(wildcard packages/*) 

ALL := 

define add_package 
JS := $$(shell find $(1)/lib -name "*.js") 
BUILD := $$(patsubst $(1)/lib/%.js, $(1)/build/%.js, $$(JS)) 
$(1)/build/%.js:: $(1)/lib/%.js 
     echo COMPILE $$^ '->' [email protected] 
     cp $$^ [email protected] # super fast compiler! 
ALL += $$(BUILD) 
endef 

$(foreach p, $(PACKAGES), \ 
    $(eval $(call add_package,$(p)))) 

all: $(ALL) 

Dies wertet eine Vorlage für jedes Paketverzeichnis, so dass Sie alles setzen dort, solange Sie die knifflig Verdoppelung erhalten von Dollarzeichen korrekt.

+0

Wow, schön! Vielen Dank. Und meine Güte der 'cp' Compiler scheint wirklich schnell im Vergleich zu anderen, die ich mir angesehen habe wie' babel' und 'traceur';) –