C++ makefile で奇妙な問題が発生しています。使っていた古いものは自殺したくなったので、今日の午後に書き直しました。変数の再割り当てと動的依存関係に関する奇妙な問題に直面しています。
この質問の目的のために、次の値を想定します。
OBJMOD_MODULENAME = obj/lib/foo.o obj/lib/bar.o obj/lib/quux.o
LIBDIR = lib/
CXX = g++
CXXLIBLINK = -shared
LIB = -lm -lpt
次の形式のターゲットがあります。
modulename: OBJ_CURRENTMOD = $(OBJMOD_MODULENAME)
modulename: $(OBJMOD_MODULENAME) lib/metrics.so
その後、次の別の形式:
$(LIBDIR)%.so: $(OBJ_CURRENTMOD)
$(CXX) $(CXXLIBLINK) -o $@ $(OBJ_CURRENTMOD) $(LIB)
コード ブロック内の行は、常にコード ブロック内に表示されている順序で表示されますが、デバッグの過程でブロックの相対的な位置を変更しました。
この問題は、ソース ファイルを変更して「make modulename」で再コンパイルしようとすると発生します。オブジェクト ファイルの構築は期待どおりに機能しますが、ファイルが既に存在する場合、ライブラリの再構築は行われません。つまり、 で指定された依存関係$(OBJ_CURRENTMOD)
は無視されます。$(OBJMOD_MODULENAME)
ライブラリの依存関係で使用すると、期待どおりに機能します。の値が$(OBJ_CURRENTMOD)
期待どおりであることをさまざまな方法で確認しました(たとえば、ライブラリターゲットの最初の行に固執echo
$(OBJ_CURRENTMOD)
します)が、何を試しても、再コンパイルをトリガーするのに間に合うように変数が更新されないようです依存関係のチェックに。
これを入力していると、回避策が見つかりました。
OBJMOD_MODULENAME = obj/lib/foo.o obj/lib/bar.o obj/lib/quux.o
LIBDIR = lib/
CXX = g++
CXXLIBLINK = -shared
LIB = -lm -lpt
modulename: OBJ_CURRENTMOD = $(OBJMOD_MODULENAME)
modulename: $(OBJMOD_MODULENAME) lib/metrics.so
$(LIBDIR)%.so: herp $(OBJ_CURRENTMOD)
$(CXX) $(CXXLIBLINK) -o $@ $(OBJ_CURRENTMOD) $(LIB)
herp: $(OBJ_CURRENTMOD)
このダミーターゲットは、変数参照が強制的に更新され、私の問題を解決する前に追加されました。これはmakeのバグか何かですか?make --version は GNU make 3.81 を示します。他の誰かがこの奇妙な動作を確認できますか? 私はひどく愚かなことをしているだけですか?私は何時間もそれを見つめていましたが、それほど驚かないでしょう。
編集:実際には修正されていないことが判明しました。必要かどうかに関係なく、毎回実行するようにトラップしていました。
変更された値を確認するには:
$(LIBDIR)%.so: $(OBJ_CURRENTMOD)
echo $(OBJ_CURRENTMOD)
$(CXX) $(CXXLIBLINK) -o $@ $(OBJ_CURRENTMOD) $(LIB)