多个子目录中源的单个Makefile 在我的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 在我的C++项目中,源是在SRC目录内组织的。src目录中有子目录,所有子目录都包含头文件和源文件,例如 project ├── Makefile │ ├── MyBinary │ ├── src │ │ │ ├── main.cpp │ │ │ ├── Application │ │ │ │ │ ├── Application.h │ │ └── Application.cpp │ │ │ │ │ └── Tasks │ ├── BackgroundWorker.h │ └── BackgroundWorker.cpp │ └── obj ├── Application.o └── BackgroungWorker.o,c++,makefile,subdirectory,C++,Makefile,Subdirectory,我正在尝试创建一个Makefile,以便所有对象文件都在obj目录中创建,可执行文件MyBinary在src目录上与Makefile相同的级别上创建 它不必太复杂或自动化。我不介意在Makefile中手动指定每个.cpp和.h文件 但我是Makefiles新手,不幸的是,我正在努力尝试: CXX=c++ CXXFLAGS=-Wall -Os -g0 # Name of the output binary APPNAME=MyBinary # Source root directory SRC

我正在尝试创建一个Makefile,以便所有对象文件都在obj目录中创建,可执行文件MyBinary在src目录上与Makefile相同的级别上创建

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

但我是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)
CXX=c++
CXXFLAGS=-Wall-Os-g0
#输出二进制文件的名称
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%,$(OBJ\U DIR)/%,$(\U OBJ))
#此规则表示.o文件取决于.c版本的
#文件和DEPS宏中包含的.h文件。
$(OBJ_DIR)/%.o:%.cpp$(DEPS)
$(CXX)-c-o$@$<$(CXXFLAGS)
#构建应用程序。
#注意:$@表示冒号的左侧,此处为$(APPNAME)
#$^表示冒号的右侧,此处为$(OBJ)
$(APPNAME):$(OBJ)
$(CXX)-o$@$^$(CXXFLAGS)
清洁:
rm-f$(对象目录)/*.o$(应用名称)
调用make时的错误是:致命错误:无法创建obj/src/Application.o:找不到文件或目录。

有人能帮忙吗?

OBJ=$(patsubst%,$(OBJ\u DIR)/%,$(\u OBJ))
\u OBJ
前面加上
OBJ/
。您想用
obj
替换
src

OBJ=$(patsubst $(SRC_ROOT)/%,$(OBJ_DIR)/%,$(_OBJ))
请注意,您获得的目录结构期望子目录
Application
Tasks
obj
您必须在调用
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 $@
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)
回声从$<
触摸$@
$(APPNAME):$(OBJ)
回声从$^
触碰$@

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

在调用编译器之前,您还需要向编译配方中添加
mkdir-p$(@D)
。编译器不会为您创建目录,在您要求编译器在其中创建文件之前,您必须确保它们存在。@程序员谢谢-不幸的是,它仍然会出错。make:**“MyBinary”所需的目标“obj/Application/Application.o”没有规则。Stop
$(obj_DIR)/%.o:%.cpp$(DEPS)
可能应该是
$(obj_DIR)/%.o:$(SRC_ROOT)/%.cpp$(DEPS)
@AProgrammer-仍然是相同的错误消息。也许这一行必须考虑到某些文件(main.cpp)直接位于src/中,而其他(Application.cpp,…)位于src/?的子目录中,谢谢,@AProgrammer为您提供了扩展示例。它非常具有描述性,在用编译器调用替换touch'es时有效。有效解决方案: