1

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

2 回答 2

1

您正在规则的先决条件列表中使用特定于目标的变量值。 这是不允许的:特定于目标的变量只能在目标的配方中使用。OBJ_CURRENTMOD$(LIBDIR)%.so

另一个问题是您正在定义变量OBJ_MODULENAME,然后访问另一个$(OBJMOD_MODULENAME)尚未分配的变量。

于 2012-06-18T08:17:55.570 回答
1

正如我在我的一条评论中所说,我看不出该$(LIBDIR)%.so模式将如何匹配任何先决条件,modulename但假设metrics.so是这样,lib/metrics.so那么它将用于构建lib/metrics.so.

正如 interjay 指出的那样,“与自动变量一样,这些值仅在目标配方的上下文中可用(以及在其他特定于目标的分配中)。 ”它们不能用于目标模式或 pre 列表中-requisites,它解释了为什么当先决条件之一$(OBJ_MODULENAME)发生变化时目标不会被重建。

$(OBJ_CURRENTMOD)在先决条件列表中有效,您需要使用辅助扩展

.SECONDEXPANSION: 
$(LIBDIR)%.so: $$ (OBJ_CURRENTMOD)
        $(CXX) $(CXXLIBLINK) -o $@ $(OBJ_CURRENTMOD) $(LIB)
于 2012-06-18T15:54:08.760 回答