单个项目的多个 Makefile
multiple Makefile for a single project
我正在尝试构建一个包含多个模块的项目。文件树如下所示:
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
)应与目录 src
和 build
.
一起放在目录 reelease
中
3) 如果第 2 项是可能的,如果每种类型的文件都放在 release
内的特定目录中(bin
for *.exe
,lib
对于 *.dll
和 shared
对于其他类型)。此外,即使 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 $@
子生成文件可以访问父生成文件中的任何导出变量(参见 here),因此您可以在其中执行以下操作:
${obj_dir}/%.o : %.c
@echo compiling "$^ ==> $@"
$(CC) -c -o $@ $^ $(CFLAGS)
这会将对象编译到正确的目录。
但请注意——如果您有两个组件生成同名的目标文件,因为它们是在同一目录中生成的,您最终可能会遇到难以调试的竞争条件。通常,每个组件都会在自己唯一的目录中生成目标文件,以避免发生这种情况。
我正在尝试构建一个包含多个模块的项目。文件树如下所示:
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
)应与目录 src
和 build
.
reelease
中
3) 如果第 2 项是可能的,如果每种类型的文件都放在 release
内的特定目录中(bin
for *.exe
,lib
对于 *.dll
和 shared
对于其他类型)。此外,即使 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 $@
子生成文件可以访问父生成文件中的任何导出变量(参见 here),因此您可以在其中执行以下操作:
${obj_dir}/%.o : %.c
@echo compiling "$^ ==> $@"
$(CC) -c -o $@ $^ $(CFLAGS)
这会将对象编译到正确的目录。
但请注意——如果您有两个组件生成同名的目标文件,因为它们是在同一目录中生成的,您最终可能会遇到难以调试的竞争条件。通常,每个组件都会在自己唯一的目录中生成目标文件,以避免发生这种情况。