いつ .ONESHELL
は使用されません。Makefileは、各シェルコマンドを個別のシェルで実行します。これの利点は何ですか? makefileが同じシェルを使用しないのはなぜですか?
1つの理由は、レシピコマンドの1つでの失敗がGNU make
によって検出されないことです。シェルの最終的な終了ステータスのみがmake
。.SHELLFLAGS
を-e
にさらに設定して、エラー時にシェルを早期に終了させる必要があります(これは、.ONESHELL
がなくても、マルチコマンドシェルの呼び出しで必要です need 最初のエラーで失敗する)。
これは、Shell
がPOSIXシェルである場合に適しています。 MakefileはShell
をたとえばに設定することもできます。 /usr/bin/Perl
またはその他のコマンドインタープリタ。次に、.ONESHELL
を使用することが適切かどうかは不明です。
.ONESHELL
をmake
のデフォルトの動作にすると、古いMakefileが壊れる可能性があります。
これはPOSIX標準またはGNU make
によるその標準への準拠に関する質問ではありませんが、 (make
は、当面の問題についてこれを述べています:
make
の一部の拡張バージョンのデフォルトでは、ターゲットのすべてのコマンドラインをグループ化し、単一のシェル呼び出しを使用してそれらを実行します。 System Vの方法では、各行を個別のシェルに個別に渡します。シングルシェル方式には、パフォーマンスの点で有利であり、多くの継続的なラインに対する要件がありません。ただし、この新しいメソッドに変換すると、多くの従来のメイクファイルで移植性の問題が発生します。したがって、POSIXメイクファイルの動作は、System Vの動作と同じになるように指定されています。特別なターゲット.ONESHELL
を実装拡張として使用して、ターゲットまたはターゲットのグループの単一シェルグループ化を実現することをお勧めします。
GNU make
は、System Vの動作を実装しているため、この点でPOSIXに準拠していますおよびは、必要に応じて代替動作を有効にする.ONESHELL
ターゲットを提供します。 ... GNU make
が現在の動作を維持するもう1つの理由です。
.ONESHELL
は、GNU移植性がなく、POSIX標準の一部ではないベンダー固有の拡張機能です。
これがPOSIX標準にない理由は、これをサポートする実装が今のところ1つしかないためです。
これが標準のデフォルトではない理由は、説明するのが簡単です。
POSIXは既存の動作を標準化しようとしますが、POSIXは既存のオリジナルのUNIX実装を標準と矛盾させたくありません-特定の動作が明確な設計バグとして見られる場合を除きます。
1977年のスチュアートフェルドマンによる元のmake
実装は、sh -ce cmdline
を使用して別のシェルのアクションリストの各行を呼び出し、これがすべての以降のmake
実装のマスターになりました。
ただし、.ONESHELL
が有効な場合、GNU実装(個別に表示)でも問題はありません。GNU makeは、コマンドを呼び出すときのシェルの-e
フラグこれにより、.ONESHELL
が原因で発生する複数行のシェルスクリプトがエラー発生時に終了しなくなります。
それ以外の場合、.ONESHELL
にはいくつかのメリットがあります。
複数行のシェルスクリプトは、メイクファイル内のバックスラッシュ改行シーケンスによってmake
内で使用できます。
コマンドラインにシェル固有のメタ文字が含まれていない場合、最新の実装ではシェルを呼び出さないようにするため、パフォーマンス引数は最新のmake
実装には適用されません。
私のsmake
実装は、echo
コマンドのインラインサポートも実装しています。これは、行の最初のコマンドがecho
で、セミコロンが1つだけで、その他の単純なコマンドが続く場合です。これにより、すべてのケースの90%以上にわたってシェルを呼び出す必要がなくなります。