单个项目的多个Makefile

单个项目的多个Makefile,makefile,mingw,gnu-make,Makefile,Mingw,Gnu Make,我正在尝试构建一个包含几个模块的项目。文件树如下所示: 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 librari

我正在尝试构建一个包含几个模块的项目。文件树如下所示:

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)--目录=$@
)。除了修复此错误的方法外,我正在寻找一种方法来完成这三件事:

(一) 来自所有模块(DLL和EXE)的目标文件(
*.o
)应存储在
build
目录下
src
的同一位置

(二) 最后的文件(
*.dll
*.exe
)应该放在
reelese
目录下,与
src
build
目录一起


3) 如果第2项是可能的,那么最好将每种类型的文件放在
发行版
中的特定目录中(对于
*.exe
对于
*.dll
共享
对于其他类型)。此外,即使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 $@
子makefiles可以访问从父级导出的任何变量(请参见),因此在这些子makefiles中,您可以执行以下操作:

${obj_dir}/%.o : %.c
       @echo  compiling "$^ ==> $@"
       $(CC) -c -o $@ $^ $(CFLAGS)
将对象编译到正确的目录


但是要小心——如果有两个组件生成同名的对象文件,因为它们是在同一个目录中生成的,那么最终将出现一个潜在的难以调试的争用条件。通常,每个组件都会在其自己的唯一目录中生成对象文件,以避免出现这种情况。

确保使用制表符而不是空格缩进配方行。您发布的代码中包含空格。这个非递归的makefile可能会帮助您:好的,我认为这会起作用,但现在它不会创建目录
build
release
(如果不存在的话)。是否可以自动执行此操作?
$(播放器)$(库):|${obj_dir}${release_dir}
(请注意,这些必须是先决条件)。然后执行
${obj_dir}${release_dir}:;mkdir-f$@