0

makeの問題をデバッグしようとして髪を引っ張っています。make は特定の前提条件を順序のみの前提条件としてランダムに扱っているようで、それらに依存する静的ライブラリ ターゲットから除外されています。ほとんどの場合、ビルドは機能しますが、.cpp ファイルがビルドされても .a ファイルに含まれないことがあります。--debug を指定して Make を実行すると、疑わしい前提条件に関する次の出力が表示されます。

Prerequisite `blah.o' is newer than target `/path/to/foo.a`
Prerequisite `blah1.o' is newer than target `/path/to/foo.a`
Prerequisite `blah2.o' is newer than target `/path/to/foo.a`
No need to remake target `/path/to/foo.a'

.a に含まれる前提条件のすべてについて、最後の行は、予想どおり、「ターゲット /path/to/foo.a をリメートする必要があります」です。

make は複数のサブディレクトリで呼び出されるため、ターゲット /path/to/foo.a が数回更新されます。make を並行して実行していないので、ファイルの更新が互いに踏みつけられているとは思いません。.o の方が新しいにもかかわらず、make は意図的に .a ファイルを更新していないようです。foo.a を作成するためのレシピは次のとおりです。

$(OBJLIB): $(OBJS)
    $(AR)     $(ARFLAGS) $(OBJLIB) $?

ARFLAGS=rv と OBJLIB は /path/to/foo.a になります。

.o ファイルが順序のみの依存関係として扱われていると考えるのは正しいですか? 私がここで見逃しているものは他にありますか?$(info) を使用して OBJLIB と OBJS の内容を出力していますが、順序のみの依存関係を引き起こす変数の内容に間違ったパイプ ('|') 文字が入り込むことはありません。

4

3 に答える 3

1

残念ながら、答えはmakeとは何の関係もありませんでした。私が知る限り、ファイルシステムが本当の犯人です。何人かはこのビルドで成功を経験していましたが、私はそうではありませんでした。共通のビルド環境を使用していた私たちのシステムの違いは、私が ext3 ファイルシステムでビルドしていたのに対し、それらのシステムでは ext4 ファイルシステムを使用していたことです。

ext3 は sub-1s タイムスタンプをサポートしない (ext4 はサポートする) ため、少数の CPP ファイルのみを使用してルールが呼び出された場合、アーカイブが以前の呼び出しによって更新されたのと同じ秒でコンパイルされ、すべてが終了していました。同じタイムスタンプ。ディレクトリをext4ファイルシステムにコピーすると、問題が修正されました。

本当の解決策は、適切な一連の make ルールを作成することですが、少なくとも、私以外のすべてのユーザーにとって機能していた理由については答えがあります。

于 2013-06-11T02:07:15.600 に答える
0

make はさまざまなサブディレクトリで呼び出されるため、.a ファイルに対するいくつかの更新について言及しました。おそらくそのメッセージ

No need to remake target `/path/to/foo.a'

はあるサブディレクトリからのものであり、is newer- 別のサブディレクトリからのものです。1 つのステップですべてのオブジェクトから lib を構築することを検討してください。

于 2013-06-10T20:14:13.037 に答える