简体   繁体   English

多个子目录中源的单个 Makefile

[英]Single Makefile for sources in multiple sub directories

In my C++ project the sources are organized inside a src directory.在我的 C++ 项目中,源代码组织在 src 目录中。 Inside the src directory are sub directories which all contain headers and source files, eg src 目录内是子目录,它们都包含头文件和源文件,例如

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

I'm trying to create a Makefile so that all object files are created inside obj directory and the executable MyBinary is created above the src directory at the same level as the Makefile is.我正在尝试创建一个 Makefile,以便在obj目录中创建所有对象文件,并且在与 Makefile 相同级别的src目录上方创建可执行文件MyBinary

It hasn't to be too complicated or automated.它不必太复杂或自动化。 I don't mind manually specifying each .cpp and .h file in the Makefile.我不介意在 Makefile 中手动指定每个 .cpp 和 .h 文件。

But I'm new to Makefiles and unfortunately I'm struggling with this attempt:但我是 Makefiles 的新手,不幸的是我正在努力尝试:

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)

The error when calling make is: Fatal error: can't create obj/src/Application.o: File or directory not found.调用make时的错误是:致命错误:无法创建obj/src/Application.o:找不到文件或目录。

Can anyone help?任何人都可以帮忙吗?

OBJ=$(patsubst %,$(OBJ_DIR)/%,$(_OBJ)) prepends obj/ to the words of _OBJ . OBJ=$(patsubst %,$(OBJ_DIR)/%,$(_OBJ))_OBJ的单词前加上obj/ You want to replace the src by obj something which you can do with你想用obj替换src一些你可以做的事情

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

Note that the directory structure you get expect subdirectories Application and Tasks to obj you either have to create them manually before calling make or updating the Makefile to create them.请注意,您获得的目录结构需要子目录ApplicationTasksobj您必须在调用make或更新 Makefile 以创建它们之前手动创建它们。

Here is something which behaves as I expect when the directory structure is pre-created.当预先创建目录结构时,这里的行为与我期望的一样。

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 $@

Note that in practice you have to be finer with the dependencies and probably have them to be generated by the compiler (see -MM and similar options for g++), here you recompile everything when you change an header.请注意,在实践中,您必须更好地处理依赖项,并且可能让它们由编译器生成(请参阅-MM和 g++ 的类似选项),在这里您在更改头文件时重新编译所有内容。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM