オブジェクト拡張が変更されたときのmakefileのパターンルール

オブジェクト拡張が変更されたときのmakefileのパターンルール

私はそれぞれ.pngまたは.pdfを生成する.asyファイルのリストを持つmakefileを作成しようとしています。

ファイルを表示して正しい拡張子を取得したので、生成されたソースとオブジェクトのリストがあります。

asy_to_ext = $(shell sed -n \
    's#^settings.outformat *= *"\([a-z]*\)" *;#\1#p' \
    $(file) | tail -1)
ASY_SRC := $(wildcard *.asy)
ASY_EXT := $(foreach file,$(ASY_SRC),$(asy_to_ext))
ASY_OBJ := $(ASY_SRC:.asy=.$(ASY_EXT))

私の質問は次のとおりです。では、各オブジェクトがそのソースに依存していることをどのように知ることができますか?単一の拡張を使用すると、静的パターンルールがトリックを実行します。

$(ASY_OBJ) : %.png: %.asy
    asy -noView -nointeractiveView $<

ただし、マニュアルでは、ワイルドカードを含むパターンルールのように見えるものが見つかりません。たとえば、$(ASY_OBJ) : %.*: %.asy私が好むソースリストを使用しているとします $(ASY_OBJ) : $(ASY_SRC)

二重コロンルールも試しましたが、ルールの1つが一致しなくなるまで最初のオブジェクトのみを処理し、理想的にはASY_OBJが.pdfまたは.pngと同じ値を持っていても探しています。

$(ASY_OBJ) :: %.png: %.asy
    asy -noView -nointeractiveView $<
$(ASY_OBJ) :: %.pdf: %.asy
    asy -noView -nointeractiveView $<

答え1

ついに方法を見つけたので、自分で答えてみましょう。解決策は2番目の拡張、前提条件リストから自動変数を使用できます。これにより、ターゲットの拡張子を削除して.asyに置き換えることができます。

また、ASY_EXTをインポートする機能が正しく機能しないことも認識していません。この問題は、次に示すマッピング機能を使用して解決されました。手動

# function returning the extension of the generated file
asy_to_ext = $(shell sed -n \
    's#^settings.outformat *= *"\([a-z]*\)" *;#\1#p' \
    $(1) | tail -1)
map = $(foreach a,$(2),$(call $(1),$(a)))

ASY_SRC := $(wildcard *.asy)
ASY_EXT := $(call map,asy_to_ext,$(ASY_SRC))
# build the target list by adding the computed extension to the basename of the sources
ASY_OBJ := $(join $(basename $(ASY_SRC)),$(addprefix .,$(ASY_EXT)))

.PHONY: asy
asy : $(ASY_OBJ)

# compute the prerequisite by adding .asy to the basename of the target
.SECONDEXPANSION:
$(ASY_OBJ) : $$(addsuffix .asy,$$(basename $$@))
    asy -noView -nointeractiveView $<

関連情報