gpt4 book ai didi

c - Makefile 对多个文件的依赖

转载 作者:太空宇宙 更新时间:2023-11-04 04:39:46 26 4
gpt4 key购买 nike

我已经为单元测试创​​建了一个 Makefile,它使用带有参数的 GCC 在编译期间创建分析文件 (gcno)。这是其中进行编译和链接的简化部分:

UTEXE        = $(UTOBJSDIR)\$(UTUNIT).exe
UTOBJS = $(UTUUTSRC:.c=.o) $(UTUTSRC:.c=.o) $(UTCSRC:.c=.o)
UTOBJSFULL = $(addprefix $(UTOBJSDIR)\,$(UTOBJS))
UTOBJSGCNO = $(addprefix $(UTOBJSDIR)\,$(UTOBJS:.o=.gcno))

$(UTOBJS): %.o: %.c $(UTMAKEDEP)
$(call report,Compiling $(*F).c)
$(MKDEP) $(MKDFLAGS) -o.o -f$(UTOBJSDIR)\$(*F).dep $(subst /,\,$<)
$(CC) -c $(CFLAGS) $(subst /,\,$<) -o $(UTOBJSDIR)/$@

$(UTOBJSGCNO): $(UTOBJS) $(UTMAKEDEP)

utbuild: $(UTEXE) $(UTOBJSGCNO) $(UTOBJS) $(UTMAKEDEP)

$(UTEXE): $(UTOBJSGCNO) $(UTOBJS) $(UTMAKEDEP)
$(call report,Linking to $(UTUNIT).exe)
$(LINK) $(UTOBJSFULL) $(LNKFLAGS) -o $(UTEXE)

它编译所有目标文件和配置文件并将二进制文件链接在一起。但是,当我删除一些配置文件 (gcno) 并再次调用“utbuild”时,它不会重新编译以恢复 .gcno 文件。它尝试再次进行链接,因为 gcno 是它的先决条件,但它不会进行编译。

我不知道如何命名这个案例,所以无法从互联网上找到解决方案。基本上一个配方创建两个文件,我不知道如何编写重新运行配方的规则,即使只需要重新创建一个文件。

我将不胜感激一些链接或提示。

最佳答案

感谢所有评论。我试过不操作“;”和“:=”具有相同的结果。

我想我需要退后一步,解释一下我问这个问题的原因。这不仅仅是关于手动删除或不删除 gcno 文件,它是关于如何编写这样一个 Makefile 来恢复任何丢失或过时文件的一般理解。我的 Makefile 在几个地方有类似的情况并且它使用并行构建所以当某些文件丢失时它会产生很多奇怪的错误。通常它是通过“干净”和“全部”来解决的,但我希望 Makefile 是完美的并且可以很好地处理丢失的文件问题。

由于没有 Makefile 的所有其余部分,上面的示例不是很清楚,因此我进行了一个新的简单测试。

你好.c

#include <stdio.h>

int main()
{
printf("Hello world\n");
}

生成文件

CCDIR    = C:\tools\MinGW
CCBINDIR = $(CCDIR)\bin
CCINCDIR = $(CCDIR)\include;$(CCDIR)\lib\gcc\mingw32\4.8.1\include
CCLIBDIR = $(CCDIR)\lib;$(CCDIR)\lib\gcc\mingw32\4.8.1

# Overcome "missing dll file" messages on Windows
CC = set PATH=%PATH%;$(CCBINDIR)& $(CCBINDIR)\gcc.exe
LINK = set PATH=%PATH%;$(CCBINDIR)& $(CCBINDIR)\gcc.exe

# Compile and link for code coverage
CFLAGS = -fprofile-arcs -ftest-coverage -g3 -O0 $(addprefix -I,$(CCINCDIR))
LNKFLAGS = -fprofile-arcs -ftest-coverage -static -static-libgcc $(addprefix -L,$(CCLIBDIR))

OBJECTS = hello.o
EXE = hello.exe

$(OBJECTS): %.o: %.c
$(CC) -c $(CFLAGS) $(subst /,\,$<) -o $@

$(EXE): $(OBJECTS)
$(LINK) $(OBJECTS) $(LNKFLAGS) -o $(EXE)

build: $(EXE)

“make build”创建以下文件:

  • 你好.o
  • 你好.gcno
  • 你好.exe

现在,如果我删除“hello.gcno”并再次运行构建,它会告诉我:

mingw32-make: Nothing to be done for 'build'.

目标是更新 Makefile,以便 make 重新创建“hello.gcno”。它可能会在该过程中重新创建“hello.o”和“hello.exe”,但这不是问题。

编辑:明确一点:在真正的 Makefile 中,我真的非常需要 .gcno 文件。它不仅仅是附加信息或要避免或有选择地做的事情。 Makefile 构建单元测试可执行文件,运行它们并执行 gcov 以生成代码覆盖率信息,gcovr 创建所有 .gcov 文件的报告。如果缺少 .gcno 文件,它将无法工作。此外 - 因为它是并行构建,所以依赖关系应该是绝对正确的,以避免某些进程更早开始,这很棘手,因为覆盖率报告具有来自两个“分支”的依赖关系 - 来自编译阶段的 .gcno 文件和来自执行阶段的 .gcda 文件。所以这就是为什么我需要它是正确的。

关于c - Makefile 对多个文件的依赖,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27528664/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com