web-dev-qa-db-ja.com

メイクファイルにターゲットを再構築させる方法

ビルドして別のメイクファイルを呼び出すメイクファイルがあります。このmakefileは、作業を行うより多くのmakefileを呼び出すため、実際には変更されません。したがって、プロジェクトが構築され、最新の状態にあると考え続けます。

dnetdev11 ~ # make
make: `release' is up to date.

メイクファイルにターゲットを再構築させるにはどうすればよいですか?

clean = $(MAKE) -f ~/xxx/xxx_compile.workspace.mak clean


build = svn up ~/xxx                                                       \
        $(clean)                                                                \
        ~/cbp2mak/cbp2mak -C ~/xxx ~/xxx/xxx_compile.workspace        \
        $(MAKE) -f ~/xxx/xxx_compile.workspace.mak $(1)                    \


release:
        $(build )

debug:
        $(build DEBUG=1)

clean:
        $(clean)

install:
        cp ~/xxx/source/xxx_utility/release/xxx_util /usr/local/bin
        cp ~/xxx/source/xxx_utility/release/xxxcore.so /usr/local/lib

注:無実の人を保護するために削除された名前

編集:最終修正バージョン:

clean = $(MAKE) -f xxx_compile.workspace.mak clean;


build = svn up;                                         \
        $(clean)                                        \
        ./cbp2mak/cbp2mak -C . xxx_compile.workspace;   \
        $(MAKE) -f xxx_compile.workspace.mak    $(1);   \


.PHONY: release debug clean install

release:
        $(call build,)

debug:
        $(call build,DEBUG=1)

clean:
        $(clean)

install:
        cp ./source/xxx_utillity/release/xxx_util /usr/bin
        cp ./dlls/Release/xxxcore.so /usr/lib
152
Lodle

1つ以上のターゲットを phony として宣言できます。

偽のターゲットとは、実際にはファイルの名前ではないターゲットです。むしろ、明示的な要求を行ったときに実行されるレシピの単なる名前です。偽のターゲットを使用する理由は2つあります。同じ名前のファイルとの競合を回避するためと、パフォーマンスを向上させるためです。

...

偽のターゲットは、実際のターゲットファイルの前提条件ではありません。そうである場合、そのレシピはmakeがそのファイルを更新するたびに実行されます。偽のターゲットが実際のターゲットの前提条件にならない限り、偽のターゲットレシピは、偽のターゲットが指定された目標である場合にのみ実行されます

26
Dave

長い形式が-Bである--always-makeスイッチは、makeにタイムスタンプを無視して指定されたターゲットを作成するように指示します。これはmakeを使用する目的に反する場合がありますが、必要な場合があります。

641
sykora

makeのSunマニュアルに文書化されていたトリックの1つは、(存在しない)ターゲット '.FORCE'を使用することです。これを行うには、次を含むforce.mkファイルを作成します。

.FORCE:
$(FORCE_DEPS): .FORCE

次に、既存のメイクファイルの名前がmakefileであると仮定すると、次を実行できます。

make FORCE_DEPS=release -f force.mk -f makefile release

.FORCEは存在しないため、それに依存するものはすべて古くなり、再構築されます。

これはすべてのバージョンのmakeで機能します。 Linuxでは、GNU Makeがあるため、説明したように.PHONYターゲットを使用できます。

makeがリリースが最新であると考える理由も検討する価値があります。これは、実行されたコマンドの中にtouch releaseコマンドがあるためです。 「リリース」と呼ばれるファイルまたはディレクトリが存在し、依存関係がなく、最新であることが原因である可能性があります。次に、実際の理由があります...

15

他の誰かが、間違いなく正しい.PHONYを提案しました。 .PHONYは、入力と出力の間の日付比較が無効であるルールに使用する必要があります。 output: inputという形式のターゲットはないため、それらすべてに.PHONYを使用する必要があります!

とはいえ、おそらく、さまざまなファイル名に対してmakefileの先頭にいくつかの変数を定義し、入力セクションと出力セクションの両方を持つ実際のmakeルールを定義して、makeの利点を活用できるようにする必要があります。つまり、実際にコンパイルするだけですコピーするために必要なもの!

編集:例を追加しました。未テストですが、これがあなたのやり方です。

.PHONY: clean    
clean:
    $(clean)
13
easel

この単純な手法により、強制が望ましくない場合にメイクファイルが正常に機能するようになります。 makefileの最後にforceという新しいターゲットを作成します。 forceターゲットは、デフォルトのターゲットが依存するファイルにタッチします。以下の例では、touch myprogram.cppを追加しています。 makeへの再帰呼び出しも追加しました。これにより、make forceと入力するたびにデフォルトのターゲットが作成されます。

yourProgram: yourProgram.cpp
       g++ -o yourProgram yourProgram.cpp 

force:
       touch yourProgram.cpp
       make
4
groko

正しく思い出せば、「make」はタイムスタンプ(ファイル変更時刻)を使用して、ターゲットが最新かどうかを判断します。再ビルドを強制する一般的な方法は、「touch」コマンドを使用してそのタイムスタンプを更新することです。 makefileで 'touch'を呼び出して、ターゲットの1つ(おそらくそれらのサブmakefileの1つ)のタイムスタンプを更新し、Makeにそのコマンドを強制的に実行させることができます。

4
poundifdef

私はこれを試してみましたが、うまくいきました

これらの行をMakefileに追加します

clean:
    rm *.o output

new: clean
    $(MAKE)     #use variable $(MAKE) instead of make to get recursive make calls

保存して電話する

make new 

そして、それは再びすべてを再コンパイルします

どうした?

1)「新規」はクリーンを呼び出します。 「clean」は「rm」を実行し、「。o」の拡張子を持つすべてのオブジェクトファイルを削除します。

2)「new」は「make」を呼び出します。 「make」は「.o」ファイルがないことを確認するため、すべての「.o」を再度作成します。その後、リンカはすべての.oファイルを1つの実行可能出力にリンクします

幸運を

3
hamaney

すでに正常にコンパイルされた出力を保存する必要がない場合

nmake /A 

すべてを再構築

1
CZahrobsky

Millerの 再帰的に有害と見なされる に従って、$(MAKE)!を呼び出さないでください。示している場合、これは無害です。これは実際にはメイクファイルではなく、単なるラッパースクリプトであり、シェルで作成されている可能性があるためです。しかし、あなたはより深い再帰レベルでそのように続けると言うので、おそらくあなたはその目を見張るようなエッセイで示された問題に遭遇したでしょう。

もちろん、GNUを使用すると、避けるのが面倒です。そして、彼らはこの問題を認識していても、文書化された方法です。

OTOH、 makepp はこの問題の解決策として作成されました。メイクファイルはディレクトリごとに作成できますが、プロジェクトの完全なビューにまとめられます。

ただし、レガシーメイクファイルは再帰的に書き込まれます。そのため、$(MAKE)がサブリクエストをメインのmakeppプロセスに戻す以外の何もしない回避策があります。サブメイク間で冗長な、またはさらに悪いことに矛盾することを行う場合にのみ、--traditional-recursive-makeを要求する必要があります(もちろんmakeppのこの利点を無効にします)。私はあなたの他のメイクファイルを知りませんが、それらがきれいに書かれていれば、makeppで必要な再構築が自動的に行われるはずです。

1
Daniel

make cleanは、すでにコンパイルされているすべてのオブジェクトファイルを削除します。

0
0
abernier

すでに言及しましたが、touchの使用に追加できると考えました

コンパイルするすべてのソースファイルをtouchすると、touchコマンドはファイルのタイムスタンプをtouchコマンドが実行されたシステム時刻に変更します。

ソースファイルのtimstampは、makeがファイルが変更され、再コンパイルする必要があることを「知る」ために使用するものです

例:プロジェクトがc ++プロジェクトの場合、touch *.cppを実行してからmakeを再度実行すると、makeはプロジェクト全体を再コンパイルする必要があります。

0
mrflash818

実際にはターゲットが何であるかに依存します。それが偽のターゲットである場合(つまり、ターゲットがファイルに関連していない場合)、. PHONYとして宣言する必要があります。

ただし、ターゲットが偽のターゲットではなく、何らかの理由でそれを再構築する場合(例:__TIME__前処理マクロを使用する場合)、ここの回答で説明されているFORCEスキームを使用する必要があります。

0
Kostas