2017-08-09 14 views
0

複数のディレクトリからビルドディレクトリにpdfファイルをコピーし、pdfuniteを使って1つのpdfファイルにコンパイルします。次のレシピの作成はできますが、初めての場合は、pdfuniteからエラーが表示されるため、2回実行する必要があります。以前のバージョンではコピーされたにもかかわらず、ビルドディレクトリ(PDFS変数は空です)ライン。これを修正して1回のパスで動作させるにはどうすればよいですか?わかりやすくするためにレシピを簡略化しました。私は実際に様々なフォルダから引っ張って、その場でいくつかのpdfを作っているので、pdfuniteに渡すために、さまざまなサブフォルダ(この例ではfolder1とfolder2)のファイルの完全なリストを簡単に連結することはできません。ワイルドカードでコピーしたファイルが見つかりません

notebook: 
    mkdir -p $(out) 
    mkdir -p $(build)/notebook 
    $(eval PR := $(sort $(wildcard $(data)/folder1/*.pdf))) 
    cp $(PR) $(build)/notebook 
    $(eval SR := $(sort $(wildcard $(data)/folder2/*.pdf))) 
    cp $(SR) $(build)/notebook 
    $(eval PDFS := $(sort $(wildcard $(build)/notebook/*.pdf))) 
    pdfunite $(PDFS) $(out)/notebook.pdf 
+0

は、ビルド時に生成これらのPDFファイルはありますか? – fukanchik

+0

はい、そのうちのいくつかは(pandocを使用していますが)一部はコピーされたばかりです。 –

答えて

0

あなたのMakefileは、makeの理念に沿ったものではありません。 makeは別のスクリプト言語としてmakeを使用していますが、makeはこれ以上です。ターゲットと前提条件の日付を比較し、これに基づいてビルドまたは再構築が必要なものを決定し、レシピをシェルに渡します。その名前が言うように、文字列を代入し、patsubst:変数の定義は合理的に簡単である

PR := $(wildcard $(data)/folder1/*.pdf) 
SR := $(wildcard $(data)/folder2/*.pdf) 
PDFS1 := $(patsubst $(data)/folder1/%.pdf,$(build)/notebook/%.pdf,$(PR)) 
PDFS2 := $(patsubst $(data)/folder2/%.pdf,$(build)/notebook/%.pdf,$(SR)) 
PDFS := $(sort $(PDFS1) $(PDFS2)) 

.PHONY: notebook 

notebook: $(out)/notebook.pdf 

$(PDFS1): $(build)/notebook/%.pdf: $(data)/folder1/%.pdf | $(build)/notebook 
    cp $< [email protected] 

$(PDFS2): $(build)/notebook/%.pdf: $(data)/folder2/%.pdf | $(build)/notebook 
    cp $< [email protected] 

$(build)/notebook $(out): 
    mkdir -p [email protected] 

$(out)/notebook.pdf: $(PDFS) | $(out) 
    pdfunite $(PDFS) [email protected] 

:だから、あなたの特定の問題のために、あなたはかなりのようなものを試してみてください。 target: pattern: prerequisitesstatic pattern ruleです。 |の後の前提条件はorder-only prerequisitesです。このメイクファイルが言う

は、基本的には、$(out)/notebook.pdf$(build)/notebook/でPDFファイルのセットに依存し、これらのPDFファイルは$(data)/folder1/$(data)/folder2/で同じベース名とソースのPDFファイルに依存していることということです。また、ディレクトリを作成する前に作成する必要があります。このすべてのおかげで、実行する必要があるものだけが実行されます。それはmakeの哲学に沿ったものです。

あなたは多くのソースフォルダを持っており、コピールールを複製したくない場合は、あなたのような、より高度な機能を使用することができます。

FOLDERS := folder1 folder2 

.PHONY: notebook 

notebook: $(out)/notebook.pdf 

define MY_rule 
$(1)_SRCS := $$(wildcard $$(data)/$(1)/*.pdf) 
$(1)_DSTS := $$(patsubst $$(data)/$(1)/%.pdf,$$(build)/notebook/%.pdf,$$($(1)_SRCS)) 
PDFS  += $$($(1)_DSTS) 

$(1)_DSTS: $$(build)/notebook/%.pdf: $$(data)/$(1)/%.pdf | $$(build)/notebook 
    cp $$< [email protected] 
endef 

$(foreach f,$(FOLDERS),$(eval $(call MY_rule,$(f)))) 

$(build)/notebook $(out): 
    mkdir -p [email protected] 

$(out)/notebook.pdf: $(PDFS) | $(out) 
    pdfunite $(PDFS) [email protected] 
0

私は別のやり方をします。

PR:=$(sort $(wildcard $(data)/folder1/*.pdf)) 
SR:=$(sort $(wildcard $(data)/folder2/*.pdf)) 
PDFS=$(sort $(wildcard $(build)/notebook/*.pdf)) 

all: copy 
    pdfunite $(PDFS) $(out)/notebook.pdf 

copy: 
    mkdir -p $(out) 
    mkdir -p $(build)/notebook 
    cp $(PR) $(build)/notebook 
    cp $(SR) $(build)/notebook 

.PHONY: all copy 

確認してください:PDFS=ないPDFS:=を。単純な=を使用すると、変数の値が必要なときに計算されます(より早く!)。

makeを実行すると、allをビルドします。 allの要件はcopyです。したがって、makeは、mkdircpです。それはallを返した後:PDFSの値がそれほど必要とされることになりましたをevaluteます - 私たちは$(build)/notebookに多く、多くのPDFファイルを持っている:)

関連する問題