如何强制重新定义makefile中的变量

时间:2012-03-16 21:41:05

标签: makefile wildcard gnu

我有一个运行二进制文件的makefile来生成cpp文件。然后我编译cpp文件并为每个cpp文件生成.o文件。

问题是当首次调用makefile时,该文件夹为空,因为尚未调用二进制文件并且

CPP_FILES=$(wildcard $(MY_DIR)/inc/output/*.cpp) 

将是一个空变量。

所以我将行改为

CPPFILES=$$(wildcard $(MY_DIR)/inc/output/*.cpp) 
OBJFILES=$$(patsubst $(MY_DIR)/*.cpp,$(MY_DIR)/*.o,$(CPPFILES))

//运行二进制文件以生成cpp文件

.SECONDEXPANSION:
libEXP.so:$(CPPFILES),$(OBJFILES)
       $(CC) $(CFLAGS) -I(INC) -L(LIBS) -shared -o $(OBJFILES) $@

二级扩展失败,说shell无法找到通配符命令 我做错了什么?

5 个答案:

答案 0 :(得分:3)

你遇到的问题是make始终从最终目标BACKWARDS到源,然后再次开始构建和解决先决条件。从库开始,然后看看它的先决条件是什么,然后看看那些先决条件是什么,然后是THOSE的先决条件等等。

因此,当make扩展$(OBJFILES)值时,即使您通过第二次扩展延迟它,仍然会出现.cpp文件尚未创建的情况。

你必须解释一下,有一个规则可以生成.cpp文件。一旦了解了,它将为您调用您的规则。但是,您将无法使用通配符来确定要构建的.cpp文件,除非您想要首先构建所有.cpp文件,然后以递归方式调用make。

修改

你问为什么第二次扩张不起作用。我在第一段中提到过这一点,但可能还不够清楚。制作经历两个阶段的处理。首先它读取makefile,然后它运行规则并构建东西。二级扩展步骤会延迟解决,直到第二步......但在这种情况下,这不会对您有所帮助。

你要make make来构建libEXP.so。要做到这一点,它需要扩展libEXP.so的先决条件,以便它知道目标所依赖的内容。 THIS 是执行第二次扩展的时候,但是我们还没有构建任何.cpp文件,因为我们不知道我们需要它们,所以通配符扩展为空。 Make将不会创建那些.cpp文件,直到它知道它需要它们,并且它不知道它需要它们直到它已经拥有它们所以它可以为libEXP.so的先决条件生成.o文件列表。这显然不起作用:))

答案 1 :(得分:1)

要明确说明:不应对生成的文件使用$(wildcard )。如果你想要一个“所有生成文件的列表”,$(wildcard )只会通过运气给你这个列表(如果已经生成了所有文件)。

如果生成器文件和生成的文件之间存在一对一的对应关系,那么您可以在生成器文件上使用$(wildcard)并转换结果。

以Google的协议缓冲区为例(它可以从.proto文件生成.cc文件)

PROTOSS := $(wildcard *.proto)
GENERATED_SOURCES := ${PROTOSS:.proto=.cc}
GENERATED_HEADERS := ${PROTOSS:.proto=.h}

答案 2 :(得分:0)

CPPFILESOBJFILES保留为通常的递归变量:

CPPFILES = $(wildcard $(MY_DIR)/inc/output/*.cpp)
OBJFILES = $(CPPFILES:%.cpp=%.o)

并推迟扩展,使用双倍美元如下:

.SECONDEXPANSION:
libEXP.so: $$(OBJFILES)
    $(CC) $(CFLAGS) -I(INC) -L(LIBS) -shared -o $(OBJFILES) $@

但我想问题是在运行cpp文件生成器之前发生了扩展。你怎么调用它?是规则还是其他什么?

答案 3 :(得分:0)

我遇到了这种情况。我尝试了几层间接(使用一个称为使用wildcard的固定序列的固定序列),但是在执行生成文件的配方之前,make总是评估通配符。我的解决方案是编写一个Perl脚本来收集文件列表并执行我需要对它们执行的操作,然后从makefile调用脚本。我只希望我早点完成。我一直在想我想避免引入额外的文件,但总的来说,使用脚本比使用非常重要的makefile配方更容易,它可以节省大量时间来完成开始。

答案 4 :(得分:0)

另一种选择是在bash中使用for循环:

target: prereqs
    for file in files/*; do \
        ... \
    done