【问题标题】:force makefile to build sources twice强制 makefile 构建源两次
【发布时间】:2012-04-18 15:50:51
【问题描述】:

我有以下生成文件:

all: a.out b.out
.PHONY: gen_hdr1
gen_hdr1:
    #call script 1 that generates x.h
    rm a.o #try to force rebuild of a.cpp

.PHONY: gen_hdr2
gen_hdr2:
    #call script 2 that generates x.h
    rm a.o #try to force rebuild of a.cpp

b.out: gen_hdr2 a.o
    g++ -o b.out a.o

a.out: gen_hdr1 a.o
    g++ -o a.out a.o
*.o : *.cpp
    g++ -c $< -o $@

a.cpp includex x.h

我想做什么:

  1. 如果存在则删除 a.o
  2. 为应用 A 生成 x.h
  3. 编译a.cpp
  4. 构建应用 A
  5. 如果存在则删除 a.o
  6. 为应用 B 生成 x.h
  7. 再次编译a.cpp
  8. 构建应用 B

运行makefile的输出是:

#call script 1 that generates x.h
rm -f a.o #try to force rebuild of a.cpp
g++    -c -o a.o a.cpp
g++ -o a.out a.o
#call script 2 that generates x.h
rm -f a.o #try to force rebuild of a.cpp
g++ -o b.out a.o
g++: a.o: No such file or directory
g++: no input files
make: *** [b.out] Error 1

基本上,在构建 App B 时找不到 a.o。 如何强制 make 系统重建它?

【问题讨论】:

  • 您是否尝试过伪造a.o 目标? IE。 .PHONY: a.o
  • 是的,我将 *.o : *.cpp 的一般规则替换为 .PHONY: a.o a.o : a.cpp ;这就是你的意思?

标签: c++ makefile


【解决方案1】:

解决这类问题的好方法是使用单独的构建对象文件夹,每个目标多一个子文件夹。

所以你会得到类似的东西:

build/first/a.o: src/a.cpp gen/a.h
    # Do you stuff in here
gen/a.h:
    # Generate you .h file if needed

build/second/a.o: src/a.cpp gen/a.h
    # Same thing

使用此解决方案,您将在 build 文件夹中拥有所有构建对象,因此 clean 命令稍微简单一些:

clean:
    rm -rf build/*
    rm -rf gen/*
    rm -rf bin/*

您应该确保的唯一一件事是该目录在构建之前存在,但这不是一项艰巨的工作:)

如果您必须生成两个版本的 a.h,您可以使用相同的设计(gen/first 和 gen/second 文件夹)。

希望对您有所帮助,如果我遗漏了什么,请告诉我

【讨论】: