在 make 3.81 中尝试使用重新分配的变量作为依赖项时观察到的奇怪行为
Bizarre behavior observed in make 3.81 when attempting to use a reassigned variable as a dependancy
我在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 --version 表示 GNU make 3.81。 还有其他人可以证实这种奇怪的行为吗? 我只是在做一件非常愚蠢的事情吗? 我已经盯着它看了几个小时,我不会那么惊讶。
编辑:事实证明,这并没有真正修复它,它只是每次都将其困在运行中,无论它是否需要它。
要验证更改的值,请执行以下操作:
$(LIBDIR)%.so: $(OBJ_CURRENTMOD)
echo $(OBJ_CURRENTMOD)
$(CXX) $(CXXLIBLINK) -o $@ $(OBJ_CURRENTMOD) $(LIB)
正如我在一条评论中所说,我不明白$(LIBDIR)%.so
模式如何匹配modulename
的任何先决条件,但假设metrics.so
是要lib/metrics.so
那么它将用于构建lib/metrics.so
。
正如interjay指出的那样,"与自动变量一样,这些值仅在目标配方的上下文中可用(以及其他特定于目标的赋值)。它们不能在目标模式或先决条件列表中使用,这就解释了为什么当$(OBJ_MODULENAME)
中的先决条件之一发生更改时不会重新生成目标。
若要使$(OBJ_CURRENTMOD)
在先决条件列表中有效,需要使用辅助扩展
.二次扩展: $(LIBDIR)%.so: $$(OBJ_CURRENTMOD) $(CXX) $(CXXLIBLINK) -o $@ $(OBJ_CURRENTMOD) $(LIB)
您正在使用$(LIBDIR)%.so
规则的先决条件列表中OBJ_CURRENTMOD
的目标特定变量值。这是不允许的:特定于目标的变量只能在目标配方中使用。
另一个问题是您正在定义变量OBJ_MODULENAME
然后访问尚未分配给的其他变量$(OBJMOD_MODULENAME)
。
- 在 Windows 上,是否可以让 dll 在不使用 PATH 环境变量的情况下在另一个文件夹中查找依赖项?
- 是否可以依赖函数范围的静态变量来执行程序关闭期间调用的方法?
- 为什么内存屏障依赖于变量?
- 如何添加依赖于类本身的模板成员变量
- 如何转发声明依赖于变量定义的类,而变体定义又依赖于模板化类?
- 使用C 中的链接seam break static变量依赖关系
- 在不同翻译单元中具有静态存储持续时间的依赖非局部常量浮点变量的常量初始化
- 使用 INSTALLS 变量使用 Qmake 安装依赖项
- Visual Studio 中C++代码的变量依赖关系图
- 生成文件在变量中时不选取依赖项
- C++ 在超类构造函数中运行依赖于子类覆盖的大量变量的代码的正确方法是什么?
- 如何模拟依赖的成员变量
- 在多继承编译器的情况下访问成员变量是否依赖?如何正确地做
- C++使变量类型依赖于用户输入
- 在 make 3.81 中尝试使用重新分配的变量作为依赖项时观察到的奇怪行为
- Scons:如何在使用变量替换时创建 LIB 依赖项
- 如何正确修复对全局变量的循环依赖关系
- 使用依赖于类的类型和函数,在类的所有实例中具有相同值的c++变量
- C++std列表排序使用自定义比较器,该比较器依赖于对象实例的成员变量
- 文件间依赖变量的初始化顺序是什么?