我有一个项目的makefile,我想用于调试和发布版本。对于调试版本,我必须包含一个包含所有单元测试的额外cpp文件。我已经在makefile中添加了一个调试选项,除了一行之外,一切似乎都有效。
我的makefile很长,但有问题的行在这个块中:
debug: CXXFLAGS+=-DDEBUG_TEST
debug: CXXFLAGS+=-DTEST_DIRECTORY='"$(subst /makefile,,$(abspath $(lastword $(MAKEFILE_LIST))))/tests"'
debug: SRCS+=src/test.cpp
debug: flex bison $(SRCS) $(EXE)
成功解析添加到CXXFLAGS的前两行,以及执行编译的最后一行。但是,似乎无论我做什么,SRCS都不会将测试文件附加到它上面。我甚至在前后打印了内容,但没有显示任何变化。我做错了什么?
我在Windows上使用GNU Make 3.81。
编辑:我决定添加整个makefile以帮助回答。
CXX=g++
CXXFLAGS+=-std=c++11 -U__STRICT_ANSI__
FLEX=win_flex.exe
BISON=win_bison.exe
FLEXBISONSRCS=src/parser.cpp src/tokens.cpp src/math_parser.cpp src/math_tokens.cpp
SRCS=$(FLEXBISONSRCS) src/main.cpp src/assembler.cpp src/instruction.cpp src/util.cpp
OBJS=$(SRCS:.cpp=.o)
EXE=bin/yasa
debug: CXXFLAGS+=-DDEBUG_TEST
debug: CXXFLAGS+=-DTEST_DIRECTORY='"$(subst /makefile,,$(abspath $(lastword $(MAKEFILE_LIST))))/tests"'
debug: SRCS+=src/test.cpp
all debug: flex bison $(SRCS) $(EXE)
@echo ' $$^: $^'
@echo ' $$(SRCS): $(SRCS)'
$(EXE): $(OBJS)
$(CXX) $(OBJS) -o $@
.cpp.o:
$(CXX) $(CXXFLAGS) $< -c -o $@
flex:
$(FLEX) -o src/tokens.cpp src/65c816.l
$(FLEX) -o src/math_tokens.cpp src/math.l
bison:
$(BISON) -d -o src/parser.cpp src/65c816.y
$(BISON) -d -o src/math_parser.cpp src/math.y
rebuild: clean all
clean:
rm src/*.o
答案 0 :(得分:1)
target-specific variable assignments的范围仅限于该目标的配方以及该目标的任何先决条件的配方。
具体而言,范围不会扩展到先决条件列表本身。
所以举例this makefile:
SRCS := a.c b.c c.c
debug: SRCS+=d.c
all debug: $(SRCS)
@echo ' $$^: $^'
@echo ' $$(SRCS): $(SRCS)'
运行时生成此输出:
$ make
$^: a.c b.c c.c
$(SRCS): a.c b.c c.c
$ make debug
$^: a.c b.c c.c
$(SRCS): a.c b.c c.c d.c
您可以在本手册的How make
Reads a Makefile部分阅读有关如何生成读取makefile以及何时在makefile的不同部分中扩展变量的所有内容。
如上所示,这意味着在$(SRCS)
目标的配方中使用debug
可以在这里工作(因为它具有正确的值),但使用自动变量不会,而是使用debug
。不完全是一个好的(或者甚至是可能的)解决方案。
另一种方法是将赋值设置为全局,但仅在ifneq (,$(filter debug,$(MAKECMDGOALS)))
SRCS += src/test.cpp
endif
是正在构建的目标时执行。像这样:
make all debug
这不允许你运行flex
来构建两者(例如),但不会这样做。
关于makefile的一些一般性评论。通过教导如何在这些输入和输出对上运行这些命令并让它做到这一点,你会比那些bison
和src/tokens.cpp: src/65c816.l
$(FLEX) -o $@ $^
src/math_tokens.cpp: src/math.l
$(FLEX) -o $@ $^
src/parser.cpp: src/65c816.y
$(BISON) -d -o $@ $^
src/math_parser.cpp: src/math.y
$(BISON) -d -o $@ $^
目标做得更好。
这样的事情:
flex
并从bison
和all
先决条件中删除debug
和.cpp
。不需要添加任何其他东西,make已经知道它需要那些all
文件,现在它知道如何从源生成它们,以便它可以在需要的时候。
此外,debug
和$(SRCS)
并不想依赖$(EXE)
而且他们不需要。 (他们已经通过$(OBJS)
和SRCS
进行了传递。
但这些都没有解决问题。不幸的是,这个问题没有一个简单(好)的解决方案。以这种方式制作并不支持动态先决条件。
上面关于OBJ
的条件添加的解决方案是我认为你在这里的最接近的解决方案(并且只要在DEBUG_OBJS=$(SRCS:.cpp=.o) src/test.o
DEBUG_EXE := bin/yasa
debug: $(DEBUG_EXE)
$(DEBUG_EXE): $(DEBUG_OBJS)
$(CXX) $^ -o $@
分配之前发生这种情况就应该正常工作。)
实际上,稍微好一点的解决方案可能是做这样的事情:
User