2

foo_user.cpp が foo.h に依存している場合、foo_user.cpp がビルドされ、さらに foo.h の変更時刻が過去に設定されている場合、make は foo_user.cpp を再ビルドしません (foo.cpp が「新しい」ため)。make が依存関係の変更時間を記録し、それらが変更された場合 (新しいか古いか)、その依存関係のターゲットが古くなっていると見なすことをお勧めします。GNUはこれを行うことができますか? そうでない場合、簡単な代替手段はありますか?

この状況がどのように発生するのか興味がある場合: foo.h はシンボリックリンクされたフォルダーにあります。シンボリック リンクは、foolib-1.0 フォルダー、foolib-2.0 フォルダーなどを指している場合があります。シンボリック リンクが別のバージョンのライブラリを指している場合、古いバージョンであっても、foo_user.cpp を再構築する必要があります。単純に symlinkfolder/foo.h を foo_user.cpp の依存関係として指定すると、make は foo.h のタイムスタンプのみに注意を払い、foo.h がアクセスされるシンボリックリンクのディレクトリのタイムスタンプには注意を払いません。make ルールはコンパイラによって生成されるため、シンボリック リンク自体を依存関係として追加することはできません (GCC には、ソース ファイルが依存するすべてのヘッダーの make ルールを出力する特別なフラグがあります)。

4

4 に答える 4

3

シンボリックリンクを依存関係として追加できない理由を理解しようとしています。自動依存関係は 1 行にあると思いますが、必要な数だけ含めることができます。

x.o: a.h b.h    
x.o: c.h    
x.o: d.h

しかし、そうは言ってもmake、シンボリックリンク自体ではなく、シンボリックリンクのターゲットを統計する可能性が高いため、DTRTではない可能性があります。シンボリックリンクを作成するたびにどこかのファイルに触れることができると思いますが、すでに考えていると思います...

ls -id link/. > testリンク ターゲット ディレクトリの inode 番号を に配置する、 を実行するルールを作成できますtest。その後cmp test savesaveは最後の実行からできます。make clean && make targetそれらが異なる場合は、そのmakeルールを実行させることができます。

targetwrapper: 
    ls -id link/. > test
    cmp test save || make clean
    make realtarget
    cp test save

clean:
    echo cleaned

realtarget:
    echo made
于 2009-11-09T21:40:19.813 に答える
2

いいえ、Make はこれをサポートしていません。タイムスタンプだけに依存するのではなく、実際にソース ファイルの MD5 ハッシュを計算し、ハッシュに基づいて決定するSConsなどの別のビルド システムの使用を検討することをお勧めします。

「SConsをより良くするものは何ですか?」より その Web サイトで:

  • MD5 署名を使用したビルド変更の確実な検出。従来のタイムスタンプのオプションの構成可能なサポート。
于 2009-11-09T21:35:54.847 に答える
1

そのままではサポートされてmakeいませんが、プログラムすることはできます。

include more_deps

ifneq ($(MAKE_RESTARTS),)

more_deps:
  if (foolink.old differs from what foolink points to) ; then \
    readlink foolink > foolink.old ; \
    echo "foo_user: foolink_trigger" > more_deps ; \
    touch foolink_trigger ; \
  else \
    echo "" > more_deps ;\
  fi

endif

foo_user: foo_user.cpp
  g++ $^ -o $@

ここでは、シンボリック リンクのトリガーへの依存関係を含むことがあるmakefilemore_depsを含めます。トリガーは特別な中間ハエであり、そのタイムスタンプに含まれるすべての意味のある情報です。シンボリック リンクが変更されると、トリガーのタイムスタンプが現在の時刻に更新されるため (「参考文献」を参照)、foo_user が古くなり、再構築されます。touch

includeMAKE_RESTARTS上記の依存関係を計算した後、make を再起動する必要があります。インクルードされている makefile がターゲット自体である場合、ターゲットは再構築されたと見なされ、再構築されてから、make が再起動し、makefile を再度読み取ります。しかし、makefile を 2 回目に読み込むと、変数が空でない文字列に展開されるmore_depsため、ターゲットとして認識されません。MAKE_RESTARTS

実際、if の行は次のように聞こえます。

more_deps:
  if (any condition you want with $(VARIABLES) possible!) ; then \
     update a file that holds the previous state ;\ 
     ...
于 2009-11-09T21:50:56.590 に答える
0

どのプロセスでシンボリックリンクを変更しますか? make cleanシンボリックリンクを変更するアクションのタイプをスクリプトに追加できます。

「ヘッダー作業フォルダー」を設定して、ヘッダー ファイルをコピーすることもできます。コピーされたヘッダー ファイルは、元のファイルとシンボリック リンクに依存します。GCC によって生成された依存関係は、作業中のヘッダーのみを考慮しcopy headers into the working folder、Makefile の一部と衝突しません。

于 2009-11-09T21:51:33.860 に答える