如何将生成文件包含在其他生成文件中

How to include a makefile into an other makefile?

本文关键字:其他 文件 文件包      更新时间:2023-10-16

我有一些C++类,每个类都放到他自己的文件夹中,其中包含一个makefile,test.cpp用于测试目的等。

Main folder
 |-> Class1 folder
 |-> Class2 folder
      |-> Class2.1 folder
 |-> Class2 folder

我有一个主项目,必须包含这些类。我正在尝试将所有子生成文件包含在主生成文件中。

我尝试过"包括POO/makefile",但是此解决方案有2个问题:

  • 子 makefile 的路径不正确,因此找不到文件("没有规则来构建目标'Vector3D.cpp'"(。
  • "test.cpp"文件被覆盖,可能是因为路径问题。("警告:覆盖目标的配方..."(

我希望所有 makefile 都是独立的,所以我可以将类文件夹复制/粘贴到一个新项目中并且它仍然有效,或者我可以单独执行 makefile,而无需对其进行更改。

所以问题是:如何将一个生成文件(正确(包含到另一个生成文件中?

示例,仅用于测试目的。

主生成文件(简化(

include Vector3D/makefile
include Color/makefile
CPP      = g++
CXXFLAGS = $(CXXINCS) -Wall -O0
all: main
main: main.o Vector3D.o Color.o
    $(CPP) main.o Vector3D.o Color.o -o main
main.o: main.cpp
    $(CPP) -c main.cpp -o main.o $(CXXFLAGS)

子生成文件示例(简化(

#Vector3D
CPP      = g++
CXXFLAGS = $(CXXINCS) -Wall -O0

all: test
test: Vector3D.o test.o
    $(CPP) Vector3D.o test.o -o test
Vector3D/test.o: test.cpp
    $(CPP) -c test.cpp -o test.o $(CXXFLAGS)
Vector3D.o: Vector3D.cpp Vector3D.hpp
    $(CPP) -c Vector3D.cpp -o Vector3D.o $(CXXFLAGS)

颜色/制作文件类似于Vector3D。

我希望所有 makefile 都是独立的,所以我可以将类文件夹复制/粘贴到一个新项目中并且它仍然有效,或者我可以单独执行 makefile 而不对其进行更改。

我很确定这是不可能的。 您的生成文件要么需要是独立的,在这种情况下,您可以使顶级文件以递归方式调用较低级别目录中的make(因此不要include它们(,也可以通过包含其他生成文件来形成单个非递归生成文件。我认为不可能两者兼而有之。

如何将生成文件(正确(包含到其他生成文件中?

唯一有效的答案是"使用 include 指令"(除了通常的"视情况而定"(。任何其他建议都取决于生成文件的结构。设计为包含的生成文件显然更容易包含。只是包括一些随机的制作文件并希望它会起作用......行不通。查看实现非递归生成和 Boilermake 了解如何使非递归生成文件工作。

请注意,没有必要将它们包含在文件顶部,这样做可能是一个坏主意,因为默认目标将成为包含文件中的第一个目标。

感谢 @Jonathan-wakely 提供此解决方案的初始概念。

可能有很多地方可以改进,但它有效。

需求摘要:

  • 生成文件应独立工作
  • 主生成文件
  • 将包括子生成文件
  • 不应出现冲突或路径问题。

一个简单的解决方案是递归调用makefiles:

  • 为叶生成文件创建"普通"脚本
  • 使用空目标允许执行总是调用例如"sub-make:",在":"之后没有任何要求
  • 使用 ">-C" 参数设置 make 调用的根目录。
  • 使用子生成文件创建的二进制文件创建最终链接。

主生成文件的示例:

#all make recursive calls
sub-make:
    make -C Vector3D
    make -C Color
#final linking
CPP      = g++
FLAGS = $(CXXINCS) -Wall -O0
all: main
main: main.o Vector3D/Vector3D.o Color/Color.o
    $(CPP) main.o Vector3D/Vector3D.o Color/Color.o -o main
main.o: main.cpp
    $(CPP) -c main.cpp -o main.o $(FLAGS)

可能有更好的方法可以在不写入所有完整路径的情况下向链接器提供 *.o 二进制文件,但这是另一个问题。

创建干净目标。对于叶生成文件,没有特殊的注意事项,但对于主生成文件,它必须调用子清理规则。

clean:
    make -C Vector3D clean
    make -C Color clean
    rm -f *.o main

编辑:

这是我所做的makefile结构,如果它对任何人都有用。

要工作,所有类都必须位于其自己的文件夹中,并且:

  • .hpp 标头
  • .cpp代码
  • 主.cpp用于测试
  • 必需的类 (LIBS( 目录是用与此生成文件相关的"$(LIBSPATH(LibName"指定的。

生成文件

#Following configuration may be set with a parameter:
#   e.g: make FLAGS="-Wall -O0"
FLAGS = $(CXXINCS) -Wall -O0
#Configurable variables
EXEC     = main
CLASS    = World
LIBS     = Color Vector3D Triangle
LIBSPATH = ../
#Static content
CPP      = g++
OBJS     = $(foreach dir, $(LIBS), $(LIBSPATH)$(dir)/$(dir))
all: $(EXEC)
clean: 
    rm -f *.o $(EXEC)
    $(foreach dir,$(LIBS),make clean --no-print-directory -C $(LIBSPATH)$(dir);)
$(EXEC): $(CLASS).o $(EXEC).o $(OBJS:=.o)
    $(CPP) $(CLASS).o $(OBJS:=.o) $(EXEC).o -o $(EXEC)
$(EXEC).o: $(EXEC).cpp
    $(CPP) -c $(EXEC).cpp -o $(EXEC).o $(CXXFLAGS)
$(CLASS).o: $(CLASS).cpp $(CLASS).hpp
    $(CPP) -c $(CLASS).cpp -o $(CLASS).o $(CXXFLAGS)
$(OBJS:=.o): $(OBJS:=.cpp) $(OBJS:=.hpp)
    make --no-print-directory -C $(LIBSPATH)$(strip $(foreach dir,$(LIBS),$(if $(findstring $(dir),$@),$(dir))))