生成文件:动态源文件名和对象目录

Makefile: dynamic source file names and object directory

本文关键字:对象 文件名 源文件 文件 动态      更新时间:2023-10-16

我目前正在尝试改进用于使用 sfml 框架构建我的 c++ 项目的 makefile im。我的项目的文件夹结构目前如下所示:

  • 文件的源/头
  • .cpp文件的源/源
  • 垃圾桶/用于.exe
  • Lib/用于 sfml 库

我当前的生成文件:

CC  = g++ -g    
SRC = Src/Source/  
BIN = Bin/    
INC = -I Lib/SFML/include/ -I Src/Header/    
LIB = -L Lib/SFML/lib/ -lsfml-graphics-d -lsfml-window-d -lsfml-system-d
EXE = Test     
SOURCEFILES = $(SRC)Main.cpp $(SRC)Menu.cpp $(SRC)Button.cpp
OBJ = $(SOURCEFILES:.cpp=.o)
all: $(SOURCEFILES) $(EXE)
$(EXE) : $(OBJ)
$(CC) -o $(BIN)$(EXE).exe $(OBJ) $(LIB)
.cpp.o:
$(CC) -c $< $(INC) -o $@

这个制作文件工作正常,但是有一些事情我想改进但无法开始工作。

  1. 目前需要手动将所有 cpp 文件添加到源文件列表中。由于该项目很可能在文件数量方面快速增长,并且我有点想将源文件拆分为不同的子目录,因此很快就会一团糟。我试图将所有 cpp 文件都放在带有 $(通配符 Src/Source/*.cpp( 的目录中,而不是单独列出它们,但它甚至无法执行 makefile。我在那里错过了什么?

  2. 使用我当前的makefile,所有.o文件都放置在与.cpp文件相同的位置,这也是我并不真正想要的。有没有办法将所有 .o 文件输出到一个额外的 \obj\ 目录中并从那里链接到.exe?

此外,由于这是我第一次编写makefile,如果我的方法有一些一般改进,也非常感谢任何建议。

  1. wildcard应该可以工作:

    SOURCEFILES = $(wildcard $(SRC)/*.cpp)
    
  2. 但是,如果您打算将源文件放在Src/Source/的各个子目录中,它将无法很好地工作。请改用find实用程序,这要归功于shellmake 函数。是的,您可以将所有目标文件存储在单独的目录中:

    CC  = g++ -g
    SRC = Src/Source/
    OBJ = Obj/
    BIN = Bin/
    INC = -I Lib/SFML/include/ -I Src/Header/
    LIB = -L Lib/SFML/lib/ -lsfml-graphics-d -lsfml-window-d -lsfml-system-d
    EXE = $(BIN)Test.exe
    SOURCEFILES = $(shell find $(SRC) -type f -name *.cpp)
    OBJECTFILES = $(patsubst $(SRC)%.cpp,$(OBJ)%.o,$(SOURCEFILES))
    all: $(SOURCEFILES) $(EXE)
    $(EXE): $(OBJECTFILE)
    $(CC) -o $@ $^ $(LIB)
    $(OBJ)%.o: $(SRC)%.cpp
    mkdir -p $(dir $@)
    $(CC) -c $< $(INC) -o $@
    

请注意,我还修改了您的EXE定义,以便相应的规则是真正的文件到文件制作规则,并使用$@$^自动变量。

我有点惊讶通配符对您不起作用,您可以分享任何错误代码吗?
通常我像这样编写我的 SRCS 和 OBJS 变量:

SRCS = $(wildcard src/*.cpp) 
$(wildcard test/*.cpp)
OBJS = $(patsubst %.cpp,$(BINDIR)/%.o,$(SRCS))

要将目标文件构建到另一个目录中,您可以编写如下内容:

$(BINDIR)/%.o: %.cpp
$(CXX) $(CXXFLAGS) $(INCLUDES) -c $< -o $@