我在使用 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)