makefile - 单个项目的多个 Makefile
问题描述
我正在尝试构建一个包含多个模块的项目。文件树如下所示:
lib_one、lib_two 和 Main.cpp 的各个 Makefile 工作正常,为项目生成 2 个 DLL 和 EXE,但需要在每个目录中输入并为每个模块执行命令“make”。
我现在想要一个顶层目录('/project')中的 Makefile,它会触发一次所有其他模块(DLL 和 EXE)的构建。根据一些搜索结果,我得到了类似的东西:
lib_one := ./src/lib_one
lib_two := ./src/lib_two
libraries := $(lib_one) $(lib_two)
player := ./src
.PHONY: all $(player) $(libraries)
all: $(player)
$(player) $(libraries):
$(MAKE) --directory=$@
$(player): $(libraries)
当我执行命令'make'时,我得到了这个错误:
Makefile:10: ***. Stop.
(第 10 行是这个:)$(MAKE) --directory=$@
。除了解决此错误的方法外,我还在寻找一种方法来完成这三件事:
1) 来自所有模块(DLL 和 EXE)的目标文件(*.o
)应存储在与目录build
相同位置的目录src
中。
2) 最终文件 (*.dll
和*.exe
) 应该放在reelease
目录src
和build
.
3)如果第 2 项是可能的,如果将每种类型的文件放在内部的特定目录中release
(bin
for *.exe
,lib
for*.dll
和shared
for 其他类型),那就太好了。此外,即使 exe 和 dll 在不同的目录中,也可以从该目录运行可执行文件(使其../lib
在其他常用位置旁边搜索必要的库?)。
解决方案
@Maxim 很可能是错误的原因——空格与制表符。至于您的其他问题,如果不使用非递归 make,您可以执行以下操作:
生成文件:
export base_dir := ${CURDIR}
export obj_dir := ${base_dir}/build
export release_dir := ${base_dir}/release
lib_one := ${base_dir}/src/lib_one
lib_two := ${base_dir}/src/lib_two
libraries := $(lib_one) $(lib_two)
player := ${base_dir}/src
.PHONY: all $(player) $(libraries)
all: $(player)
$(player) $(libraries): | ${obj_dir} ${release_dir}
$(MAKE) --directory=$@
$(player): $(libraries)
${obj_dir} ${release_dir} :
@mkdir -f $@
子 makefile 可以访问从父级导出的任何变量(请参见此处),因此在这些文件中您可以执行以下操作:
${obj_dir}/%.o : %.c
@echo compiling "$^ ==> $@"
$(CC) -c -o $@ $^ $(CFLAGS)
这会将对象编译到正确的目录。
但请注意——如果您有两个组件生成同名的目标文件,因为它们是在同一个目录中生成的,那么您最终可能会遇到难以调试的竞争条件。通常,每个组件都会在其自己的唯一目录中生成目标文件,以避免这种情况。
推荐阅读
- javascript - 角度 6 如果未选择任何选项,如何更新属性
- ios - 如何移动 UIView 并使用 Swift 以编程方式放置新的 UIView?
- chilkat - 我可以向 Chilkat 任务链添加多少个任务?
- python-3.x - 如何在 pandas.read_csv() 之前预处理数据
- javascript - Vue prop 默认值无法正常工作
- javascript - 如何使用事件侦听器将类切换到单个列表项
- ruby-on-rails - 我正在尝试通过在 Rails 中使用 webpacker 来安装 toastr
- python - 如何使用 Python 在 Cplex 中制定线性规划问题
- ios - 在 ReactiveSwift 中对 Signal 的 Skip(while:) 调用被忽略
- mysql - 如何备份 Heroku ClearDB MySQL 数据库?