34

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

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

私にはこの回避策があります:

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

しかし、それは非常に醜いです。makefileで「 pre-buildstep」を実行する他の方法はありますか?

4

5 に答える 5

36

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

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つ目は、EclipseIDEが生成するものによって引き起こされます。

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番目のステップでは、メインビルドの状態が最新の場合、ビルド後のステップは実行されません。ビルド前のステップは常に両方で実行されますが。

于 2009-10-25T21:45:41.137 に答える
13

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

CHEAT_ARG := $(shell myscript)

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

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

于 2009-10-23T09:19:49.173 に答える
5

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

run-script:
    myscript

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

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

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

于 2009-10-23T09:41:29.623 に答える
3

あなたが提案していることは、少し「作りたくない」ようです。以前に実行する必要のあるmakefileターゲットでコマンドを実行してみませんか?

たとえば、リンクする前に実行する必要がある場合foo

foo: ${OBJS}
    my-command-goes-here
    ${CC} -o $@ ${OBJS} ${LIBS}
于 2009-10-23T09:24:56.277 に答える
1

回答ありがとうございます。ndimは私を大いに助けてくれました、asveikau。最終的なファイルは1つのバイナリ実行可能ファイルなので、次のように使用できます。

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

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

all: run-script $(AXF_FILE)

これですべてです;)(もちろん、「すべて」の代わりに任意のターゲットを使用できます)


編集:このメソッドは、 $(AXF_FILE)も計算された後にスクリプトを実行します。そのため、AXF_FILEの値が間違っている可能性があります。これで、 ndimによる最初の回答だけが必要に応じて機能します。

于 2009-10-25T19:30:22.683 に答える