如何将makefile包含到其他makefile中?

时间:2013-10-10 22:23:24

标签: c++ makefile g++

我有一些C ++类,每个都有自己的文件夹和makefile,test.cpp用于测试目的等等。

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

我有一个主项目,必须包含这些类。我试图将所有子makefile包含在主makefile中。

我尝试过“INCLUDE POO / makefile”,但这个解决方案有两个问题:

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

我希望所有的makefile都独立,所以我可以复制/通过类文件夹到一个新的项目中它仍然有效,或者我可以单独执行makefile而不进行任何更改。

所以问题是:如何将(正确)makefile包含到其他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)

子makefile示例(简化)

#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)

类似于Color / makefile而不是Vector3D

2 个答案:

答案 0 :(得分:5)

  

我希望所有的makefile都独立,所以我可以复制/通过类文件夹到一个新的项目中它仍然有效,或者我可以单独执行makefile而不进行任何更改。

我很确定这是不可能的。您的makefile要么是独立的,在这种情况下,您可以使顶级文件以递归方式在较低级别目录中调用make(所以不要include它们)您可以通过包含其他makefile形成一个非递归的makefile。我认为两者都不可能。

  

如何将(正确)makefile包含到其他makefile中?

唯一有效的答案是“使用include指令”(除了通常的“依赖”)。任何其他建议都取决于makefile的结构。将包含的Makefile 设计显然更容易包含。只是包含一些随机的makefile并希望它可以工作...将无法正常工作。查看Implementing non-recursive makeBoilermake,了解如何使非递归makefile工作。

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

答案 1 :(得分:1)

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

可能有很多事情可以改进,但它确实有效。

要求摘要:

  • Makefile应独立运作
  • 主要的makefile将包含子makefile
  • 不应出现冲突或路径问题。

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

  • 为leaf makefiles创建“普通”脚本
  • 使用空目标允许执行总是调用例如“sub-make:”而没有任何要求“:”
  • 使用“ -C ”参数设置make调用的根目录。
  • 使用子makefile创建的二进制文件创建最终链接。

主要makefile的示例:

#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二进制文件,但这是另一个问题。

创建清洁目标。对于叶子makefile,没有特别的考虑因素,但对于主makefile,它必须调用子清理规则。

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

<强>编辑:

这是我已经完成的makefile结构,因为它可能对任何人都有用。

要工作,所有班级必须位于自己的文件夹中:

  • .hpp header
  • .cpp code
  • main.cpp进行测试
  • 必需的类(LIBS)目录使用与此makefile相关的“$(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))))