我有一些C ++类,每个都有自己的文件夹和makefile,test.cpp用于测试目的等等。
Main folder
|-> Class1 folder
|-> Class2 folder
|-> Class2.1 folder
|-> Class2 folder
我有一个主项目,必须包含这些类。我试图将所有子makefile包含在主makefile中。
我尝试过“INCLUDE POO / makefile”,但这个解决方案有两个问题:
我希望所有的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
答案 0 :(得分:5)
我希望所有的makefile都独立,所以我可以复制/通过类文件夹到一个新的项目中它仍然有效,或者我可以单独执行makefile而不进行任何更改。
我很确定这是不可能的。您的makefile要么是独立的,在这种情况下,您可以使顶级文件以递归方式在较低级别目录中调用make
(所以不要include
它们)或您可以通过包含其他makefile形成一个非递归的makefile。我认为两者都不可能。
如何将(正确)makefile包含到其他makefile中?
唯一有效的答案是“使用include
指令”(除了通常的“依赖”)。任何其他建议都取决于makefile的结构。将包含的Makefile 设计显然更容易包含。只是包含一些随机的makefile并希望它可以工作...将无法正常工作。查看Implementing non-recursive make和Boilermake,了解如何使非递归makefile工作。
请注意,不需要将它们包含在文件的顶部,这样做可能是个坏主意,因为默认目标成为包含文件中的第一个目标。
答案 1 :(得分:1)
感谢@ Jonathan-wakely提供此解决方案的初始概念。
可能有很多事情可以改进,但它确实有效。
要求摘要:
一个简单的解决方案是调用递归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结构,因为它可能对任何人都有用。
要工作,所有班级必须位于自己的文件夹中:
生成文件
#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))))