对于我的面向对象编程课程,我必须完成一个最终项目(学术目的)。我想以“正确的方式”制作一个项目(即:makefile、模块化、DRY、易于扩展等),以便更好地理解类、makefile 和 C++。
我的想法是有一个“tree-source-file-structure-directory”,所以在每个子文件夹中,我都会得到带有头文件、测试文件和单个 makefile 的源文件。因此,如果我想在界面上工作,我会转到子文件夹界面,编辑文件,运行测试,如果一切正常,只需将对象链接到我的根目录中即可。如果我想处理我的数据结构,同样的事情,等等。不错的功能是,在每个子文件夹中都驻留在源代码和目标文件中,因此我根目录中的链接器将搜索已在子文件夹上编译的目标文件并将它们链接在一起
我一直在互联网上搜索,我可以看到许多不同的解决方案: - 递归地做,例如:
SUBDIRS=eda
.PHONY: subdirs $(SUBDIRS)
$(SUBDIRS):
$(MAKE) -C $@
我发现的问题是我对“eda”文件夹的先决条件是“古怪的”
- 使用自动变量$(@D),但我不太明白它是如何工作的 - 也许使用通配符函数,但我对这个选项有点困惑。
无论如何,对我来说最诱人的解决方案是第一个(递归使用 make),但我发现很多评论说不建议使用递归make有趣的文章
所以我想问你们一些建议:我怎样才能实现我的目标并将每个重要的模块放在一个单独的文件夹中?递归是最好的解决方案吗?也许我应该潜入“automake”?或者最好将所有对象文件放到根目录上的新“对象”子文件夹中,然后将它们链接在一起?
顺便说一句,我通过嗅探Amarok源代码得到了这个树结构的灵感:它有一个名为“src”的子文件夹,当你进入那里时,你可以看到很多子文件夹:均衡器,播放列表,动态、statusbar、core、playlistgenerator、playlistmanager等。而且很多子文件夹都有自己的子目录……结果就是一个不可思议的音乐播放器。如果这种方法对 Amarok 团队有效……我可以做类似的事情!
欢迎任何意见,反馈,建议和其他,在此先感谢!
编辑#1
Beta,我有一些隐式规则(后缀)和链接器的目标,该链接器需要我的eda文件夹上的对象。此目标的所有其他先决条件都建立在当前文件夹上。我遇到的问题是,当我运行 make 来构建该目标时,它会将“eda”文件夹上的先决条件的名称作为使用隐式规则构建的目标。这是我的项目中makefile递归的棘手/不干净的部分:我想我必须为每个必须在子文件夹中搜索的目标文件创建一个特殊的隐式规则。
这就是为什么我想要一些反馈:¿有更好的选择吗?或者在我的项目中使用 make recursive 的优势压倒了其他替代方案?
无论如何,如果让您更好地理解,这是我的Makefile 草案(它是 spnish-english :P)
#Makefile hecho para las pruebas de los archivos dentro de esta carpeta
FLAGS=-g -DDEBUG
OUT_TI=TIndividuo
OUT_TP=TProfesor
OUT_TA=TAula
.SUFFIXES: .cpp .c .h .o
.c.o: ; cc $(FLAGS) -c $*.c
.cc.o: ; gcc $(FLAGS) -c $*.cc
.cpp.o: ; g++ $(FLAGS) -c $*.cpp
SUBDIRS=eda
.PHONY: subdirs $(SUBDIRS)
$(OUT_TI): eda/TAula.o CandidatoHorario.o TIndividuo.o TIndividuoTest.o TGen.o
g++ CandidatoHorario.o TIndividuo.o TIndividuoTest.o TGen.o eda/TAula.o -o $@
CandidatoHorario.o: CandidatoHorario.cpp CandidatoHorario.h
TIndividuoTest.o: TIndividuoTest.cpp TIndividuo.h
TIndividuo.o: TIndividuo.cpp TIndividuo.h
TGen.o: TGen.cpp
#eda/TAula.o: eda/TAula.cpp eda/TAula.h
# g++ -c eda/TAula.cpp -o $@
$(SUBDIRS):
$(MAKE) -C $@
clean:
rm -f *.o $(OUT_TI) $(OUT_TA) eda/TAula.o