【问题标题】:Adding debug file to makefile build?将调试文件添加到makefile构建?
【发布时间】:2015-05-12 03:25:32
【问题描述】:

我有一个项目的生成文件,我想将其用于调试和发布版本。对于调试版本,我必须包含一个包含所有单元测试的额外 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

【问题讨论】:

  • 你如何测试这个?该分配仅对该目标和作为该目标的先决条件的任何目标有效。 (更具体地说,当您在那里尝试时,它对目标本身的先决条件有效。所以使用中间假debug 目标而不是让debug 拥有构建配方(或实时事实上,对该测试文件的更改不会触发 debug 二进制文件的 make 重建)。
  • 如果测试是指调用,那么我在进行发布构建时使用常规“make”,在进行调试构建时使用“make debug”,当我使用“make clean”或“make rebuild”时从一个切换到另一个。如果这不是您的意思,请澄清。
  • 我的意思是你如何测试作业没有做任何事情。它绝对改变了SRCS 的值,但这种改变的范围是有限的。见gist.github.com/deryni/897ff4584abc34fa8851
  • 哦,我现在明白了。我正在使用$(info $$SRCS is [${SRCS}]) 打印出值。赋值后输出不会改变,即使在干净的构建中,test.cpp 也不会被编译。
  • 对,顶级$(info) 调用不会看到它。分配的范围是这样的,因此无法运行。 debug 目标的主体是什么?它必须自己进行编译(因为您有 .c 文件而不是列为先决条件的目标文件)。我假设它可能在配方中使用$^?在此处使用$(SRCS) 将“解决”问题,但最终更简单的解决方案是根据正在构建的目标而不是特定于目标来使分配全局化。我会写一个答案。

标签: makefile gnu-make


【解决方案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 部分阅读有关 make 如何读取 makefile 以及何时在 makefile 的不同部分扩展变量的所有信息。

如前所述,这意味着在debug 目标的配方中使用$(SRCS) 可以在这里工作(因为它具有正确的值),但使用自动变量却不行,但这并不是一个好的(或不一定是可能的)解决方案.

另一种方法是使分配全局化,但仅当debug 是正在构建的目标时才这样做。像这样的:

ifneq (,$(filter debug,$(MAKECMDGOALS)))
    SRCS += src/test.cpp
endif

这不会让您运行 make all debug 来构建两者(例如),但可以正常工作。

makefile 中的一些通用 cmets。你会比那些 flexbison 目标做得更好,教 make 如何在这些输入和输出对上运行这些命令,然后让它去做。

类似这样的:

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 $@ $^

并从alldebug 先决条件中删除flexbison。无需添加任何其他内容,make 已经知道它需要那些 .cpp 文件,现在它知道如何从源代码生成它们,因此如果需要它就会这样做。

另外alldebug 不想依赖$(SRCS),他们也不需要。 (他们已经通过$(EXE)$(OBJS) 传递。

但这些都不能解决问题。不幸的是,这个问题没有简单(好的)解决方案。 make 不支持这种方式的动态先决条件。

上面关于有条件添加SRCS 的解决方案是我认为您在这里最接近的解决方案(只要在OBJ 分配之前发生,就应该可以正常工作)。

实际上,一个稍微好一点的解决方案可能是这样做:

DEBUG_OBJS=$(SRCS:.cpp=.o) src/test.o

DEBUG_EXE := bin/yasa

debug: $(DEBUG_EXE)

$(DEBUG_EXE): $(DEBUG_OBJS)
    $(CXX) $^ -o $@

【讨论】:

  • 我花了大约 30 分钟尝试根据您的示例修复它,但它似乎不起作用。我的all debug 目标看起来像我帖子中的最后一个debug,下面有你的回显命令。如果我删除 $(EXE) 它会打印正确的文件,但如果我不删除它会到达 $(EXE) 并说 test.o 不存在。这让我觉得即使内容正在改变,它们并没有因为编译所有内容的调用而改变,我仍然不知道为什么。我将在我的 makefile 的一个缩短版本中进行编辑,以便您查看。
  • 感谢您的所有帮助。我可能最终会做一个不允许alldebug 目标的解决方案,因为我现在只构建一个文件。另外,感谢您提到 flex/bison 的事情。我早就知道这是不对的,但我对 makefile 不是特别擅长。事实上,这个 makefile 结构是我从 2012 年开始使用的;我只是复制它并放入正确的文件。
  • 如果输入和输出文件名在 flex/bison 上匹配,您可以将它们组合成一个模式规则(一个用于 flex,一个用于 bison),并且不需要复制命令并写出以这种方式命名文件。
猜你喜欢
  • 1970-01-01
  • 2019-02-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多