8

我有一个 C++ 项目,其中包含所有其他 C++ 文件所依赖的生成文件。我试图在任何其他编译开始之前强制生成和编译该文件。通常它就像将该文件放在all:目标中一样简单,但复杂的是我的 Makefile 也是由构建系统生成的,我只能将片段附加到 Makefile,而不是一般编辑它。

那么,有没有办法通过依赖或其他方式强制生成的文件目标首先运行?我想过使用这样的东西:

cpp_files := $(wildcard src/*.cpp)
$(cpp_files): generated_file.cpp
generated_file.cpp:
    # generate the file here

但这似乎不起作用。作为参考,我的源目录结构是这样的,所以我需要递归收集cpp文件:

src/
|---file1.cpp
|---file2.cpp
|---subdir1/
    |---file3.cpp

gen/
|---generated_file.cpp
4

2 回答 2

21

如果您确定这确实是您想要的,这里有一种方法:为一个虚拟文件制定一个规则,makefile 将include.

.PHONY: dummy
dummy:
    # generate the file here

-include dummy

无论您指定什么目标,Make 都会首先运行dummy规则,然后自行重启。

于 2012-05-23T20:47:35.747 回答
4

实际上,其他cpp文件不依赖于生成的文件(就 Make 规则而言)。依赖关系图仍然如下所示:

program
 |
 ^- file1.o
 |   ^- file1.c
 |
 ^- file2.o
 |   ^- file2.c
 |
 ^- generated_file.o
     ^- generated_file.c
         ^- <generator prerequisites>

您的源文件只能依赖于某种生成的头文件(如果它是#include由这些源生成的)。

如果您只需要生成一个cpp文件,那么以下 makefile 就足够了:

srcs := $(wildcard src/*.cpp src/*/*.cpp)

gen_file := gen/generated_file.cpp
srcs += $(gen_file)

objs := $(srcs:.cpp=.o)

.PHONY : all
all : program

program : $(objs)
    @$(LD) ...

%.o : %.c
    @$(CC) ...

$(gen_file) :
    # generate the file here

UPD。

基于Beta 的回答进行了一点改进。

-include generator-task
.PHONY : generator-task

generator-task : $(gen_files)

$(gen_files) : $(gen_prerequisites)
    # generate the file here

而不是在每次调用 Make 时运行生成器,这只会在其先决条件之一发生变化时重新生成文件。

于 2012-05-23T19:41:11.417 回答