makepp/make for prebuild target
考虑一个场景,某些cpp文件是通过脚本生成的,并且生成的文件数目还很多,所以想用$(wildcard )来模糊匹配出生成的所有cpp文件,想用make/makepp来构建工程。
Linux 实验环境如下:
make版本: /home/utils/make-3.81/bin/make
makepp版本: /home/utils/makepp-2.0/bin/makepp
main.cpp
#include <iostream>
using namespace std;
int main() {
cout << "hello world" << endl;
}
### gen.sh
#!/bin/bash
mkdir gen
cd gen
echo "" > a.cpp
echo "" > b.cpp
不可行的方案
gen:
gen.sh
CPPFILES = main.cpp
CPPFILES += $(wildcard /*.cpp)
main : $(CPPFILES)
@echo CPPFILES = $(CPPFILES)
@echo folder = $(folder)
/home/utils/gcc-5.2.0/bin/g++ $(CPPFILES) -o main
$(phony clean):
rm -rf gen main
$ makepp main
makepp: Loading makefile /home/<…>/File/cpp/makepp/Makeppfile
makepp: Entering directory /home/<…>/File/cpp/makepp
CPPFILES = main.cpp
folder =
/home/utils/gcc-5.2.0/bin/g++ main.cpp -o main
makepp: 1 file updated and 0 phony targets built
可以看到a.cpp和b.cpp 并没有被编译。这主要是因为求CPPFILES这个变量的值的时候,gen这个target还没有被执行(在本例中其压根不会被执行),所以$(wildcard )执行结束之后结果为空。
可行方案
make 方案
### Makefile
$(shell gen.sh)
CPPFILES = main.cpp
CPPFILES += $(wildcard gen/*.cpp)
main : $(CPPFILES)
@echo CPPFILES = $(CPPFILES)
/home/utils/gcc-5.2.0/bin/g++ $(CPPFILES) -o main
$(phony clean):
rm -rf gen main
$ make main
make: Warning: File `gen/a.cpp’ has modification time 0.0044 s in the future
CPPFILES = main.cpp gen/a.cpp gen/b.cpp
/home/utils/gcc-5.2.0/bin/g++ main.cpp gen/a.cpp gen/b.cpp -o main
make: warning: Clock skew detected. Your build may be incomplete.
注意此时有warning,不确定是否有影响。
makepp 方案
### Makeppfile
gen:
gen.sh
#prebuild gen
folder := $(shell echo $(prebuild gen))
CPPFILES = main.cpp
CPPFILES += $(wildcard gen/*.cpp)
main : $(CPPFILES)
@echo CPPFILES = $(CPPFILES)
@echo folder = $(folder)
/home/utils/gcc-5.2.0/bin/g++ $(CPPFILES) -o main
$(phony clean):
rm -rf gen main
pdx-xterm-24:/home/<…>/File/cpp/makepp> makepp main
makepp: Loading makefile /home/<…>/File/cpp/makepp/Makeppfile
makepp: Entering directory /home/<…>/File/cpp/makepp
gen.sh
makepp: Scanning /home/<…>/File/cpp/makepp/gen/a.cpp
makepp: Scanning /home/<…>/File/cpp/makepp/gen/b.cpp
CPPFILES = main.cpp gen/a.cpp gen/b.cpp
folder = gen
/home/utils/gcc-5.2.0/bin/g++ main.cpp gen/a.cpp gen/b.cpp -o main
makepp: 2 files updated and 0 phony targets built
- 可以直接把folder := $(shell echo $(prebuild gen)) 换为 prebuild gen, 这也是更加推荐的方式。此处的prebuild关键字的介绍参考这里。
- 也可以在wildcard那里修改:CPPFILES += $(wildcard $(prebuild gen)/*.cpp),这是第二推荐的方式, $(prebuild )函数的用法参考这里。
- folder := $(shell echo $(prebuild gen)), 注意此处的 :=, 这是很重要的,对于makepp,也可以使用 ;=, 参考这里对;的介绍,其 和 := 的作用相同,唯一不同的是右边的表达式只会被执行一次并记录下来,对于那些开销大的命令比较有用。后续如果还有相同的表达式,会直接使用记录值来减小开销。
如果此处改为 =, 会产生奇怪的现象,我目前还无法解释:
### Makeppfile2
gen:
gen.sh
#prebuild gen
folder = $(shell echo $(prebuild gen))
CPPFILES = main.cpp
CPPFILES += $(wildcard gen/*.cpp)
main : $(CPPFILES)
@echo CPPFILES = $(CPPFILES)
@echo folder = $(folder)
/home/utils/gcc-5.2.0/bin/g++ $(CPPFILES) -o main
$(phony clean):
rm -rf gen main
$ makepp main
makepp: Loading makefile /home/<…>/File/cpp/makepp/Makeppfile
makepp: Entering directory /home/<…>/File/cpp/makepp
gen.sh
makepp: Scanning /home/<…>/File/cpp/makepp/gen/a.cpp’
makepp: Scanning `/home/<…>/File/cpp/makepp/gen/b.cpp’
CPPFILES = main.cpp
folder = gen
/home/utils/gcc-5.2.0/bin/g++ main.cpp gen/a.cpp gen/b.cpp -o main
makepp: 2 files updated and 0 phony targets built
makepp 关键字介绍参考这里。
makepp介绍参考这里。
similar interesting issue:https://stackoverflow.com/questions/53603406/makefile-with-generated-c-source-files
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!