3

入力/出力ファイルのペアがあります。スクリプトから出力ファイルの名前を生成します: output=$(generate input). たとえば、ペアは次のようになります。

in1.c      out1.o
in2.txt    data.txt
in3        config.sh
sub/in1.c  sub/out1.o

これらのペアはすべて、makefileの同じ一連の規則に従います。

$(out): $(in) $(common) 
    $(run) $< > $@

このような Makefile を簡潔かつ効率的に記述する方法は何ですか?

別のスクリプトから Makefile を生成することは避けたいと思います。

4

3 に答える 3

3

スクリプトから Makefile フラグメントを生成するつもりはありませんが、以下を使用できますinclude

INS := in1.c in2.txt in3 sub/in1.c

include rules.mk

rules.mk: Makefile
        rm -f $@
        for f in $(INS); do \
                out=`generate "$$f"`; \
                echo -e "$$out: $$f\n\t\$$(run) \$$<> > \$$@\n\n" >> $@; \
        done
于 2012-05-16T07:23:08.807 に答える
3

includeファイルを gmake が生成し、他のターゲットよりも先にインクルードしようとする場合。これをデフォルトのルールと組み合わせると、必要なものに近づくはずです

# makefile
gen=./generate.sh
source=a b c
run=echo

# Phony so the default rule doesn't match all
.PHONY:all
all:

# Update targets when makefile changes
targets.mk:makefile
    rm -f $@
    # Generate rules like $(target):$(source)
    for s in $(source); do echo "$$($(gen) $$s):$$s" >> $@; done
    # Generate rules like all:$(target)
    for s in $(source); do echo "all:$$($(gen) $$s)" >> $@; done

-include targets.mk

# Default pattern match rule
%:
    $(run) $< > $@

generate.shlikeでテストする

#!/bin/bash
echo $1 | md5sum | awk '{print $1}'

ください

$ make
rm -f targets.mk
for s in a b c; do echo "$(./generate.sh $s):$s" >> targets.mk; done
for s in a b c; do echo "all:$(./generate.sh $s)" >> targets.mk; done
echo a > 60b725f10c9c85c70d97880dfe8191b3
echo b > 3b5d5c3712955042212316173ccf37be
echo c > 2cd6ee2c70b0bde53fbe6cac3c8b8bb1
于 2012-05-16T07:30:39.617 に答える
1

このような Makefile を簡潔かつ効率的に記述する方法は何ですか?

入力のリストと、GNU make 機能を使用してターゲット、依存関係、およびルールを生成する出力ファイル名を生成するシェル スクリプトが与えられる可能性があります。

all :

inputs := in1.c in2.txt in3 sub/in1.c
outputs :=

define make_dependency
  ${1} : ${2}
  outputs += ${1}
endef

# replace $(shell echo ${in}.out) with your $(shell generate ${in})
$(foreach in,${inputs},$(eval $(call make_dependency,$(shell echo ${in}.out),${in})))

# generic rule for all outputs, and the common dependency
# replace "echo ..." with a real rule
${outputs} : % : ${common}
    @echo "making $@ from $<"

all : ${outputs}

.PHONY : all 

出力:

$ make
making in1.c.out from in1.c
making in2.txt.out from in2.txt
making in3.out from in3
making sub/in1.c.out from sub/in1.c

上記の makefile では、強力な GNU make 構造体によって少し使用されるものが使用されています: $(eval $(call ...)). マクロを展開してテキストの一部を生成し、そのテキストの一部を makefile の一部として評価するよう make に要求します。つまり、make はその場で makefile を生成します。

于 2012-05-16T08:09:13.657 に答える