我有一个Makefile,旨在构建一些不同的程序。我的SOURCES
和OBJECTS
取决于PRODUCT
,PRODUCT
应该是正在构建的产品。目前,我在列出每个规则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 |
+----+
之前继续评估,并且永远不会根据规则进行更改。有什么我想念的吗?
答案 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