不要重新评估依赖变量

时间:2016-07-04 10:59:20

标签: makefile

我有一个Makefile,旨在构建一些不同的程序。我的SOURCESOBJECTS取决于PRODUCTPRODUCT应该是正在构建的产品。目前,我在列出每个规则OBJECTS的依赖关系之前设置CORE_LIB := libcore SCANNER := scanner FLETCHER := fletcher PRODUCT := $(SCANNER) SOURCE_DIR := ./src BUILD_DIR := ./build OBJECTS_DIR := $(BUILD_DIR)/intermediate PRODUCT_DIR := $(BUILD_DIR)/product SOURCES = $(wildcard $(SOURCE_DIR)/$(PRODUCT)/*.c) $(wildcard $(SOURCE_DIR)/$(PRODUCT)/*/*.c) OBJECTS = $(SOURCES:$(SOURCE_DIR)/%.c=$(OBJECTS_DIR)/%.o) # change PRODUCT based on rule being ran $(SCANNER): PRODUCT := $(SCANNER) $(SCANNER): $(OBJECTS) # link stuff $(CORE_LIB): PRODUCT := $(CORE_LIB) $(CORE_LIB): $(OBJECTS) # link stuff

OBJECTS

但是,PRODUCT会在设置A +----+------+--------------+ | id | age | +----+------+ | 1 | 10 | +----+------+ | 2 | 20 | +----+------+ | 3 | 30 | +----+------+ | 4 | 40 | +----+------+ B +----+ | id | +----+ | 1 | +---- | 2 | +----+ | 3 | +----+ 之前继续评估,并且永远不会根据规则进行更改。有什么我想念的吗?

1 个答案:

答案 0 :(得分:2)

你不能这样做。 GNU制作手册states,关于特定于目标的变量:

  

与自动变量一样,这些值仅在目标配方的上下文中可用(以及在其他特定于目标的分配中)。

这意味着在扩展先决条件期间,您无法使用特定于目标的变量值,例如$(OBJECTS)。或者更确切地说,您可以使用任何变量,但目标特定值不可用。由于您将全局PRODUCT的值设置为$(SCANNER) scanner,因此该值将用于所有先决条件。

您有多种选择。您可以定义多个变量,如下所示:

$(SCANNER)_SOURCES = $(wildcard $(SOURCE_DIR)/$(SCANNER)/*.c) $(wildcard $(SOURCE_DIR)/$(SCANNER)/*/*.c)
$(CORE_LIB)_SOURCES = $(wildcard $(SOURCE_DIR)/$(CORE_LIB)/*.c) $(wildcard $(SOURCE_DIR)/$(CORE_LIB)/*/*.c)

然后创建这样的规则:

$(SCANNER): $($(SCANNER)_SOURCES:$(SOURCE_DIR)/%.c=$(OBJECTS_DIR)/%.o)
        # link stuff
$(CORE_LIB): $($(CORE_LIB)_SOURCES:$(SOURCE_DIR)/%.c=$(OBJECTS_DIR)/%.o)
        # link stuff

如果你有更多这些,你可以创建一个宏并使用eval但我不会为复杂而烦恼,除非你真的会有一堆。

您可以使用Secondary Expansion稍微简化目标定义,如下所示:

OBJECTS = $$($$@_SOURCES:$(SOURCE_DIR)/%.c=$(OBJECTS_DIR)/%.o)

.SECONDEXPANSION:
$(SCANNER): $(OBJECTS)
        # link stuff
$(CORE_LIB): $(OBJECTS)
        # link stuff