web-dev-qa-db-ja.com

GNU makeで部分的にシリアル化するにはどうすればよいですか?

特定のターゲットを別のターゲットより先に作成する必要があるmakeタスクがある場合、並列モードでは、SunPro Make(dmake)を使用すると簡単です。次のメイクファイル:

install:  dir dir/file

dir:
    mkdir dir

dir/file:
    cp source dir/file

最初の行を次のように変更することで、並列化して安全にすることができます。

install: dir .WAIT dir/file

または使用して:

.NO_PARALLEL: install

Makefileの残りの部分は引き続きパラレルモードで処理され、.WAITの左側または右側のターゲットがパラレルモードで処理される場合でもリストは処理されます。

参照: http://schilytools.sourceforge.net/man/man1/make.1s.html および http://schilytools.sourceforge.net/man/man1/dmake.1 .html

しかしGNU makeには同様のオプションがないようです。GNU makeでこれを行う方法は本当にありませんか?

より具体的に言うと、ソリューションは、メイクファイルを他のmake実装で処理できるように記述する必要があります。

特別なターゲット.WAITは、たとえば呼び出されるmakeプログラム依存マクロにある$(待機)

役に立たない明らかな解決策があることに注意してください:

理論的には、dir/fileにコピーする前にdirの作成を強制するために、dirdir/file,の依存関係にすることができますが、後で別のファイルをdir,にコピーすると、dirdir/fileよりも新しくなります。その結果、makeを複数回呼び出すと、dir/fileagainに何度もコピーされます。ソースがdir/file.よりも新しい場合にのみ、コピーを行うmakeからの期待される結果はありません。

makeaにdir/fileの依存関係を作成せずに、dir/file.にコピーする前にdirを強制的に作成してdirを強制する依存関係のトポロジがあるかどうかという別の質問が発生します

4
schily

これは、フィリッペブランデンブルガーによって提示されたアイデアと、Schily Makefileシステムで使用されている一般的な方法から得られた私の独自の回答です。

Makefileシステムは、次の_make macros_がこのように設定されていることを確認します。

_WAIT=       # empty with GNU make
WAIT= .WAIT # .WAIT special target with SunPro Make

MAKEPROG= <name of the make program> # This is from: smake, gmake, sunpro

_UNIQ= .XxZzy-
_

上記のマクロ定義を利用するmakefile:

__NORULE=    $(_UNIQ)$(MAKEPROG)
__NORULE=   $(_NORULE:$(_UNIQ)gmake=)
NORULE=     $(__NORULE:$(_UNIQ)%=%)

install: dir $(WAIT) dir/file

dir/file: source
        cp source dir/file

dir:
        mkdir -p dir

$(NORULE)dir/file: | dir
_

$(NORULE)は、gmakeでは何も展開せず、SunPro Makeではsunproに展開されます。

Gmakeの場合、makefile全体が次のように展開されます。

_install: dir dir/file

dir/file: source
        cp source dir/file

dir:
        mkdir -p dir

dir/file: | dir
_

SunPro Makeの場合、makefile全体が次のように展開されます。

_install: dir .WAIT dir/file

dir/file: source
        cp source dir/file

dir:
        mkdir -p dir

sunprodir/file: | dir
_

最後の行は関連性のないジャンクルールと見なされます。

1
schily

GNU makeでは、order-only-prerequisitesを使用してdirが作成されていることを確認できますdir/fileを作成するルールが実行される前。

詳細は このページ を参照してください。

GNU make's manualの例から、ディレクトリの下にファイルを作成する前に、作成中のディレクトリに依存関係を追加するように調整されていることがわかります。

あなたの具体的な例の場合、このような何かがそれをするはずです:

dir/file: | dir
        cp source dir/file

既存のルールを変更する必要はありませんが、Makefileの他の場所にその依存関係を追加するだけです...

より具体的に言うと、ソリューションは、メイクファイルを他のmake実装で処理できるように記述する必要があります。

これが他のmakeの実装では機能しないと思います...可能な解決策の1つは、GNUmakefileを作成することです include 実際のMakefileおよびGNUを追加して、特定の拡張を行います。

GNUをGNUmakefileのダミールールとして定義することにより、.WAITなどのルールを無視させることもできます。

これらのポインタがお役に立てば幸いです。

6
filbranden

依存関係を追加して、その下のファイルの前にディレクトリが作成されるようにする必要があります。

ディレクトリへの依存関係に「マーカー」ファイルを使用することが可能です。その方法で、その下にファイルを作成しても、ディレクトリのタイムスタンプには影響しません。 GNU特定の機能を作成する必要もありません。

あなたの例では:

install: dir/file

dir/.marker:
        mkdir -p dir
        touch dir/.marker

dir/file: dir/.marker
        cp source dir/file

マーカーファイルには.directoryまたは.dirまたは.folderなどを使用できます...

4
filbranden