c++ - 多个子目录中源的单个 Makefile

标签 c++ makefile subdirectory

在我的 C++ 项目中,源代码被组织在 src 目录中。在 src 目录中是子目录,它们都包含头文件和源文件,例如

project
├── Makefile
│
├── MyBinary
│
├── src
│    │
│    ├── main.cpp
│    │
│    ├── Application
│    │      │
│    │      ├── Application.h
│    │      └── Application.cpp
│    │      
│    │
│    └── Tasks
│           ├── BackgroundWorker.h
│           └── BackgroundWorker.cpp
│
└── obj
     ├── Application.o
     └── BackgroungWorker.o

我正在尝试创建一个 Makefile,以便在 obj 目录中创建所有目标文件,并在 src 之上创建可执行文件 MyBinary> 与 Makefile 处于同一级别的目录。

它不必太复杂或太自动化。我不介意在 Makefile 中手动指定每个 .cpp 和 .h 文件。

但我是 Makefile 的新手,不幸的是我正在努力尝试:

CXX=c++
CXXFLAGS=-Wall -Os -g0

# Name of the output binary
APPNAME=MyBinary

# Source root directory
SRC_ROOT=src

# Object file directory
OBJ_DIR=obj

DEPS=$(SRC_ROOT)/Application/Application.h \
     $(SRC_ROOT)/Tasks/BackgroundWorker.h

_OBJ=$(SRC_ROOT)/Application/Application.o \
    $(SRC_ROOT)/Tasks/BackgroundWorker.o\
    $(SRC_ROOT)/main.o

OBJ=$(patsubst %,$(OBJ_DIR)/%,$(_OBJ))

# This rule says that the .o file depends upon the .c version of the 
# file and the .h files included in the DEPS macro.
$(OBJ_DIR)/%.o: %.cpp $(DEPS)
  $(CXX) -c -o $@ $< $(CXXFLAGS)

# Build the application.
# NOTE: The $@ represents the left side of the colon, here $(APPNAME)
#       The $^ represents the right side of the colon, here $(OBJ)
$(APPNAME): $(OBJ)
  $(CXX) -o $@ $^ $(CXXFLAGS)

clean:
  rm -f $(OBJ_DIR)/*.o $(APPNAME)

调用make时的错误是:Fatal error: can't create obj/src/Application.o: File or directory not found.

有人能帮忙吗?

最佳答案

OBJ=$(patsubst %,$(OBJ_DIR)/%,$(_OBJ))obj/ 添加到 _OBJ 的单词之前>。你想用 obj 替换 src ,你可以用它来做

OBJ=$(patsubst $(SRC_ROOT)/%,$(OBJ_DIR)/%,$(_OBJ))

请注意,您获得的目录结构需要子目录 ApplicationTasksobj 您必须在调用 之前手动创建它们make 或更新 Makefile 以创建它们。

在预先创建目录结构时,这里的行为符合我的预期。

APPNAME=MyBinary
SRC_ROOT=src
OBJ_DIR=obj

DEPS=$(SRC_ROOT)/Application/Application.h \
     $(SRC_ROOT)/Tasks/BackgroundWorker.h

_OBJ=$(SRC_ROOT)/Application/Application.o \
    $(SRC_ROOT)/Tasks/BackgroundWorker.o\
    $(SRC_ROOT)/main.o

OBJ=$(patsubst $(SRC_ROOT)/%,$(OBJ_DIR)/%,$(_OBJ))

$(OBJ_DIR)/%.o: $(SRC_ROOT)/%.cpp $(DEPS)
    echo Making $@ from $<
    touch $@ 

$(APPNAME): $(OBJ)
    echo Making $@ from $^
    touch $@

请注意,在实践中,您必须更好地处理依赖项,并且可能让它们由编译器生成(请参阅 -MM 和 g++ 的类似选项),在这里,您在更改时重新编译所有内容一个标题。

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

相关文章:

c++ - 如果参数是地址,则通用引用推导

c++ - 虽然循环条件不起作用

c++ - 即使明确指定,也使用 Makefile : picks file. c 而不是 file.cpp 进行构建

python - 从python中的子目录链接导入

Linux 脚本应位于父目录

c++ - 带有使用模板的方法的嵌套结构

c++ - 安装了 Cuda 8,它似乎缺少 npp.lib

c - C 和 CUDA-C 代码中的 NVCC 链接错误

visual-studio - GCC 与 Visual Studio 一起使用吗?

Python统计目录及其所有子目录中的文件