0

これは少し複雑なので、ここに例をアップロードしました。

テスト方法:

  • tarball をダウンロードして展開します
  • cd make_problem/make
  • きれいにする(アーカイブからアーカイブを削除するのを忘れた;))
  • make alib (削除したばかりの単純でばかげたアーカイブを再作成します)
  • ./weird.sh

odd.sh が行うことは、単純に、ソース ファイルに触れて再作成し、別のソース ファイルに触れて再作成を数回繰り返すだけです。

GNU Make 3.81 を使用した Linux システムでの出力は次のようになります。

$ ./weird.sh
#### 1 ####
gcc -c -g -Wall -Wextra -o ../swu/1/src/foo1.o ../swu/1/src/foo1.c

ar cr ../make/libmine.a ../swu/1/src/foo1.o
==== 1 ====
gcc -c -g -Wall -Wextra -o ../swu/1/src/bar1.o ../swu/1/src/bar1.c

ar cr ../make/libmine.a ../swu/1/src/bar1.o
#### 2 ####
gcc -c -g -Wall -Wextra -o ../swu/1/src/foo2.o ../swu/1/src/foo2.c

==== 2 ====
gcc -c -g -Wall -Wextra -o ../swu/1/src/bar2.o ../swu/1/src/bar2.c

#### 3 ####
gcc -c -g -Wall -Wextra -o ../swu/1/src/foo3.o ../swu/1/src/foo3.c

==== 3 ====
gcc -c -g -Wall -Wextra -o ../swu/1/src/bar3.o ../swu/1/src/bar3.c

#### 4 ####
gcc -c -g -Wall -Wextra -o ../swu/1/src/foo4.o ../swu/1/src/foo4.c

==== 4 ====
gcc -c -g -Wall -Wextra -o ../swu/1/src/bar4.o ../swu/1/src/bar4.c

#### 5 ####
gcc -c -g -Wall -Wextra -o ../swu/1/src/foo5.o ../swu/1/src/foo5.c

==== 5 ====
gcc -c -g -Wall -Wextra -o ../swu/1/src/bar5.o ../swu/1/src/bar5.c

#### 6 ####
gcc -c -g -Wall -Wextra -o ../swu/1/src/foo6.o ../swu/1/src/foo6.c

==== 6 ====
gcc -c -g -Wall -Wextra -o ../swu/1/src/bar6.o ../swu/1/src/bar6.c

#### 7 ####
gcc -c -g -Wall -Wextra -o ../swu/1/src/foo7.o ../swu/1/src/foo7.c

==== 7 ====
gcc -c -g -Wall -Wextra -o ../swu/1/src/bar7.o ../swu/1/src/bar7.c

ar cr ../make/libmine.a ../swu/1/src/bar7.o
#### 8 ####
gcc -c -g -Wall -Wextra -o ../swu/1/src/foo8.o ../swu/1/src/foo8.c

==== 8 ====
gcc -c -g -Wall -Wextra -o ../swu/1/src/bar8.o ../swu/1/src/bar8.c

$

ソースにアクセスするたびにアーカイブが再構築されることを期待していましたが、明らかにそうではありませんでした。

誰でもこれを説明できますか?そして、それが常に期待どおりに機能することを確認する方法を説明してください?

4

1 に答える 1

2

ここでの問題は、ファイル変更タイムスタンプの解像度が比較的低いことです。これにより、make を 2 回続けて実行すると、非常に迅速に実行すると混乱が生じますweird.sh

具体的には、次のことを行いweird.shます。

  1. 接するfoo1.c
  2. make を実行します。
    1. 再構築foo1.oし、
    2. 再構築しますlibmine.a
  3. 接するbar1.c
  4. make を実行します。
    1. 再構築しますbar1.o
    2. たぶん(以下を参照)再構築libmine.a

ステップ 2.2 とステップ 4.2 の間の時間がファイルシステムのタイムスタンプの解決よりも短い場合、make はlibmine.a既に と同じタイムスタンプを持っていると認識しbar1.o、再構築しません。

Linux ext3 ファイル システムのタイムスタンプの精度は 1 秒です。make のメンテナーからのこの説明では、問題がより詳細に説明されており、Solaris の方がタイムスタンプの解決が優れていることにも言及しています。

これが実際のアプリケーションで問題になる場合は、ナノ秒単位のタイムスタンプを持つ ext4 ファイルシステムを試すことができます。それ以外の場合は、sleep 1各 make コマンドの後に を追加するだけweird.shで、問題は解決します :-)

于 2010-07-11T23:42:54.310 に答える