web-dev-qa-db-ja.com

makefileの事前構築ステップ

他のすべてのmakefileコマンドの前に実行する必要があるスクリプトを実行するにはどうすればよいですか?そして、ビルドするものが何もない場合、スクリプトが実行されないのはいいことです(必須ではありません)。

SOとGoogleを検索しましたが、何も見つかりません。

私はこの回避策を持っています:

# myscript.bat output is empty
CHEAT_ARGUMENT = (Shell myscript.bat)
CFLAGS += -DCHEAT_ARGUMENT=$(CHEAT_ARGUMENT)
AFLAGS += -DCHEAT_ARGUMENT=$(CHEAT_ARGUMENT)

しかし、それは非常に醜いです。 makefileで「ビルド前のステップ」を実行する他の方法はありますか?

28
zxcat

2つの解決策を提案します。 1つ目は、NetBeans IDEが生成するものを模倣しています。

CC=gcc

.PHONY: all clean

all: post-build

pre-build:
    @echo PRE

post-build: main-build
    @echo POST

main-build: pre-build
    @$(MAKE) --no-print-directory target

target: $(OBJS)
    $(CC) -o $@ $(OBJS)

clean:
    rm -f $(OBJS) target

2番目のものは、Eclipse IDEが生成するものによって刺激されます。

CC=gcc

.PHONY: all clean
.SECONDARY: main-build

all: pre-build main-build

pre-build:
    @echo PRE

post-build:
    @echo POST

main-build: target

target: $(OBJS)
    $(CC) -o $@ $(OBJS)
    @$(MAKE) --no-print-directory post-build

clean:
    rm -f $(OBJS) target

最初のビルドでは、メインビルドが最新であるかどうかに関係なく、プリビルドとポストビルドが常に呼び出されることに注意してください。

2番目の例では、メインビルドの状態が最新の場合、ビルド後のステップは実行されません。一方、事前構築ステップは常に両方で実行されます。

27
Amro

makeバージョンによっては、CFLAGSとAFLAGSが数十回評価される場合、次のようなものは少なくとも数十回は実行しないようにする必要があります。

CHEAT_ARG := $(Shell myscript)

コロンに注意してください。

これは1回だけ実行されます。 1回を超えることはありませんが、1回を超えることはありません。独自のトレードオフを選択してください。

11
ndim

Makefileに特別なターゲットを追加し、すべてのビルドルールをそれに依存させることができます。

run-script:
    myscript

.o.c: run-script
     $(CC) $(CFLAGS) -o $@ $<

.o.S: run-script
     $(AS) $(AFLAGS) -o $@ $<

スクリプトが実際に何をするかに応じて、Makefile(autoconfの用語ではconfigureステージ)の前のステージでスクリプトを1回実行すると、さらに意味をなす(そして作業が少なくなる)可能性があります。

5
ndim

あなたが提案しているものは、少し「un-make-like」のようです。以前に必要なmakefileターゲットでコマンドを実行しないのはなぜですか?

例、fooをリンクする前に実行する必要がある場合:

foo: ${OBJS}
    my-command-goes-here
    ${CC} -o $@ ${OBJS} ${LIBS}
3
asveikau

回答ありがとうございます。 ndimは大いに役立ちましたasveika。最終的なファイルは1つのバイナリ実行可能ファイルなので、次のように使用できます。

run-script:
    myscript
$(AXF_FILE): run-script $(OBJ_DIRS) $(OBJ_FILES)
    $(LINK) #......

Myscriptを1回実行します。 {AXF_FILE}の値はmyscriptに依存するため、実行する必要がありますbefore。そしてこの場合、再構築が必要なときだけでなく、myscriptは常に実行されます。その後、最も単純な答えが思い浮かびました。

all: run-script $(AXF_FILE)

それはall;)(もちろん、 "all"の代わりに任意のターゲットを使用できます)


編集:このメソッドは$(AXF_FILE)の計算後にスクリプトを実行します。したがって、AXF_FILEの誤った値を取得する可能性があります。 ndimによる最初の回答のみが必要に応じて機能します。

1
zxcat