1. ホーム
  2. makefile

[解決済み] makefileで別のターゲットを実行する

2022-04-24 05:16:01

質問

以下のような構成のmakefileがあります。

all : 
    compile executable

clean :
    rm -f *.o $(EXEC)

私は、"make all" を実行する前に、ターミナルで "make clean" と "clear" を一貫して実行していたことに気づきました。私は、厄介な C++ のコンパイルエラーを調べ上げる前に、ターミナルをクリーンな状態にしておきたいのです。そこで、3番目のターゲットを追加しようとしました。

fresh :
    rm -f *.o $(EXEC)
    clear
    make all

これは動作しますが、これはmakeの2番目のインスタンスを実行します(と私は信じています)。2番目のmakeインスタンスを実行せずに同じ機能を得るための正しい方法はあるのでしょうか?

解決方法は?

実際、あなたの言う通り、makeの別のインスタンスが実行されています。 可能な解決策は、次のとおりです。

.PHONY : clearscr fresh clean all

all :
    compile executable

clean :
    rm -f *.o $(EXEC)

fresh : clean clearscr all

clearscr:
    clear

を呼び出すことで make fresh を取得すると、まず clean ターゲット、そして clearscreen を実行する clear で、最後に all を実行します。

編集部 8月4日

makeの並列ビルドの場合はどうなるのでしょうか? -j というオプションがあります。 順番を固定する方法があります。makeのマニュアル、4.2項より。

しかし、時には、起動するルールに特定の順序を課し、それらのルールのいずれかが実行された場合にターゲットを強制的に更新させたくないという状況が発生します。そのような場合、順序のみの前提条件を定義します。順序のみの前提条件は、前提条件リスト内にパイプ記号(|)を配置することで指定できます。パイプ記号の左側にある前提条件は通常、右側にある前提条件は順序のみです: targets : normal-prerequisites | order-only-prequisites

もちろん、通常の前提条件セクションは空でもかまいません。また、同じターゲットに対して複数行の前提条件を宣言することも可能です:それらは適切に追加されます。同じファイルを通常の前提条件と順序のみの前提条件の両方に宣言した場合、通常の前提条件が優先されることに注意してください(順序のみの前提条件の動作の厳密なスーパーセットであるため)。

したがって、makefileは次のようになります。

.PHONY : clearscr fresh clean all

all :
    compile executable

clean :
    rm -f *.o $(EXEC)

fresh : | clean clearscr all

clearscr:
    clear

EDIT 12月5日

複数のmakefileインスタンスを実行しても、タスク内の各コマンドが サブシェル ということです。しかし、再利用可能なメソッドを持つには 呼び出し機能 .

log_success = (echo "\x1B[32m>> $1\x1B[39m")
log_error = (>&2 echo "\x1B[31m>> $1\x1B[39m" && exit 1)

install:
  @[ "$(AWS_PROFILE)" ] || $(call log_error, "AWS_PROFILE not set!")
  command1  # this line will be a subshell
  command2  # this line will be another subshell
  @command3  # Use `@` to hide the command line
  $(call log_error, "It works, yey!")

uninstall:
  @[ "$(AWS_PROFILE)" ] || $(call log_error, "AWS_PROFILE not set!")
  ....
  $(call log_error, "Nuked!")