多个子目录中来源的单个Makefile

时间:2019-02-20 15:39:01

标签: 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 目录中创建,而可执行文件 MyBinary src 与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时的错误是:致命错误:无法创建obj / src / Application.o:找不到文件或目录。

有人可以帮忙吗?

1 个答案:

答案 0 :(得分:1)

OBJ=$(patsubst %,$(OBJ_DIR)/%,$(_OBJ))obj/的单词前面加上_OBJ。您想用src代替obj

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 ++的类似选项),这里您在更改标头时会重新编译所有内容。 / p>