Makefile目标特定变量作为先决条件

10

相关文章:作为Makefile先决条件的特定目标变量

我正在尝试创建一个Makefile,使用特定于目标的变量来指定对象文件和最终可执行文件的输出目录。我的想法是维护两个不同的二进制版本,一个“发布”版本和一个带有额外调试信息的“调试”版本。

我的问题是,“make”每次都会进行干净的构建,即使我什么也没有改变。我很确定这是因为“make”在变量声明之前就评估了目标“corewars”的先决条件中的变量。

下面是Makefile的代码:

CXX=g++
LD=g++
LDFLAGS=
CXXFLAGS=-Iinclude -Wall -Wextra
OBJECTS=main.o Machine.o Core.o ProcessQueue.o Instruction.o
OUTPUT_DIR:=Test/

.PHONY: default
.PHONY: all
.PHONY: release
default: release
all: release
release: OUTPUT_DIR:=Release/
release: corewars

.PHONY: debug
debug: CXXFLAGS+=-DDEBUG -g
debug: OUTPUT_DIR:=Debug/
debug: corewars

corewars: $(OUTPUT_DIR) $(addprefix $(OUTPUT_DIR),$(OBJECTS))
    $(LD) -o $(addprefix $(OUTPUT_DIR),corewars) $(addprefix $(OUTPUT_DIR),$(OBJECTS))

Release:
    mkdir -p $@
Debug:
    mkdir -p $@

%.o: %.cpp include/%.h
    $(CXX) -c $(CXXFLAGS) $< -o $(OUTPUT_DIR)$@


.PHONY: clean
clean:
    $(RM) -r Release
    $(RM) -r Debug
2个回答

15
首先,一个非虚假的配方 必须 创建一个目标,$@,而不是 $(OUTPUT_DIR)$@。另外,考虑将目录依赖项转换为仅作顺序要求的前提条件。
为了在先决条件列表中获得正确的$(OUTPUT_DIR)值,您必须使用二次扩展,否则,在主要扩展期间,全局定义OUTPUT_DIR:=Test/将被用于特定于目标的定义。
不幸的是,我想不出一种理智的方法来使用特定于目标的变量使其工作,而不需要使用二次扩展和vpath魔法。个人而言,我宁愿先设置环境(找出OUTPUT_DIR的值等),然后使用正确的值重新执行Make。
ifndef OUTPUT_DIR

.PHONY: default all release debug

default all: release

release: export OUTPUT_DIR := Release/
debug:   export OUTPUT_DIR := Debug/
debug:   export EXTRA_CXXFLAGS := -DDEBUG -g

release debug:
    @$(MAKE)

else

# ...
CXXFLAGS := -Iinclude -Wall -Wextra $(EXTRA_CXXFLAGS)

PROGRAM := $(OUTPUT_DIR)corewars
OBJECTS := $(addprefix $(OUTPUT_DIR), \
    main.o Machine.o Core.o ProcessQueue.o Instruction.o)

# Default target.
$(PROGRAM): $(OBJECTS) | $(OUTPUT_DIR)
    $(LD) -o $@ $<

$(OUTPUT_DIR)%.o: %.cpp | $(OUTPUT_DIR)
    $(CXX) -c $(CXXFLAGS) $< -o $@

$(OUTPUT_DIR):
    mkdir -p $@

endif # OUTPUT_DIR

两个部分可以拆分成单独的 makefile,一个是根(起始)文件,另一个是真正执行工作的文件,以使整个过程更易管理。

这是我的构建系统的优秀清洁处理,非常感谢。我发现有必要在生成“.o”文件的规则的先决条件列表中添加“| $(OUTPUT_DIR)”,并添加了一个“clean”目标,但除此之外都按照引用工作。非常感谢。 - Chris Browne
@Chris,哦,是的,你说得对,我忘记了(已修复)。不客气!;-) - Eldar Abusalimov
谢谢提醒!我现在会修复它。 - Chris Browne

2

目标特定变量仅在目标的配方及其递归前提条件的上下文中可用。也就是说,目标特定变量不能用作目标或前提条件

一种解决方法是使用makefile there


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接