我正在尝试制作一个Makefile,它使用特定于目标的变量来指定目标文件和最终可执行文件的输出目录.我们的想法是维护两个独立的二进制版本,一个'发布'版本和一个带有额外调试信息的'debug'版本.
我的问题是'make'每次都做一个干净的构建,即使我没有改变一件事.我很确定这是因为'make'是在'debug'或'release'目标的先决条件中的变量声明之前评估目标'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
Run Code Online (Sandbox Code Playgroud)
Eld*_*mov 12
至少你的编译规则被破坏了.非虚假配方必须创建目标$@,而不是$(OUTPUT_DIR)$@.
还要考虑将目录依赖项转换为仅限订单的先决条件.
最后,要获得$(OUTPUT_DIR)必备条件列表中的正确值,必须使用辅助扩展,否则,将使用全局定义OUTPUT_DIR:=Test/而不是特定于目标的定义.
我不知道,如何在没有二次扩展和vpath魔法的情况下修复你的Makefile.我个人首先设置环境(找出值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
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
7409 次 |
| 最近记录: |