c++ - Makefile子目录递归

标签 c++ c recursion makefile subdirectory

我对带有子目录的项目的 makefile 有疑问。 项目目录树如下:

project
├── Makefile
├── main.cpp
|
├── lib1
│   ├── lib1.cpp
│   ├── lib1.h
│   └── Makefile
|
├── lib2
│   ├── Makefile
│   ├── lib2_1.cpp
│   ├── lib2_1.h
|   ├── lib2_2.cpp
│   └── lib2_2.h
| 
├── lib3
│   ├── Makefile
│   ├── lib3.cpp
│   └── lib3.h

每个子目录(lib1, lib2...)的makefile是这样的:

SRC_DIR = ./
BUILD_DIR = ./obj/

DEPS = lib1.o

all: $(BUILD_DIR)$(DEPS)

$(BUILD_DIR)%.o: $(SRC_DIR)%.cpp $(SRC_DIR)%.h
     mkdir -p $(BUILD_DIR)
     g++ --std=c++11 $< -c -o $@

clean:
     rm -fr $(BUILD_DIR)

我的问题是:如何创建位于项目目录中的 make 文件或 makefile“root”? 我无法创建一个递归执行子目录中的 makefile 的 makefile,它链接每个子目录的 obj 文件夹中的所有目标文件。

你能帮帮我吗?请

最佳答案

我会这样做:

SUBDIRS = lib1 lib2 lib3

main: main.cpp $(SUBDIRS)
        $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(wildcard $(addsuffix /obj/*.o,$(SUBDIRS))) $(LDLIBS)

.PHONY: $(SUBDIRS)
$(SUBDIRS):
        $(MAKE) -C $@

这样做的好处:它将与 make -jN 一起正常工作以进行并行构建,如果您只想构建一个子目录,则可以运行 make lib1 等.

坏处:它会在每次运行 make 时重新链接 main 程序,即使没有任何改变也是如此。

如果您想避免坏事,您可能需要考虑使用非递归 makefile,这将需要稍微重写您的 makefile。

如果您愿意为每个子目录创建一个静态库,以目录命名(例如,liblib1.a 等)而不是链接所有目标文件本身,您可以制作它与递归生成文件一起工作。诀窍在于根 makefile 必须能够自行推断或计算库的名称。它不能使用 wildcard 等来找到它们。

关于c++ - Makefile子目录递归,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40562239/

相关文章:

haskell - 如何使用 foldr 编写此函数?

c++ - 数据库的最佳 OOP 设计

C - 在系统函数调用后将 SHELL 输出保存在文件中

recursion - 在Golang中为递归函数实现生成器( yield )的惯用方式

go - 动态编程-带内存的树递归

使用线程和信号量的代码

c++ - 在结构外调用指向函数的指针

c++ - 向类中添加另一个参数会使代码无法编译

C++ 字符串和分隔符

c - 从循环中的指针中提取值