开始我会插播一段我如何学习makefile的废话,如果不想听的话,请直接跳到我的makefile教程。
首先得先说明学习makefile真是一个痛苦的过程,尤其是用干巴巴的看书来学习的过程,简直可以用如坐针毡来形容了……不过作为一个想成为真正程序员的人这又算得了什么呢?为了不被人诟病编程只会用IDE,你得硬着头皮来学习这个让人痛苦的东西,好在有一句话,痛苦是进步的标识,这至少说明了你在进步,也挺好的。
通过这几天的痛苦学习,我觉得学习makefile得分这么几个步骤:
1、熟悉大概的makefile语句,写几个简单的makefile–只需要很简单的,能编译出几个文件的demo程序即可,可以严重提高自信心;—done
2、读这本书《GNU Make项目管理》的1、2、3、6、8章;–done
3、然后着手写一个较大型系统的makefile;–done
4、goto 2;–todo
5、在平时的项目中提醒自己用makefile来管理,不断的查找遇到的新知识点,记录,回顾;–todo
我得说,走完第2步给我的感觉不是我学会了makefile,实则是我依然写不了太大的makefile,只能说我再看到大型的makefile不再害怕了,我自信我能看得懂这个makefile所要表现的编译系统。这也算是对makefile的入门吧。
—-—————————–—-———————————-
当我在着手完成上面的第3步的时候,真的还是什么都不会,最痛苦的是不知道怎么下手,苦于没有找到错综复杂的困境中的“绳头”,我当时能想到的一件事就是google,我用了这样的关键字:the best way of wrighting makefile,然后我得到了这个地址。这里面一个很重要的信息就是避免使用传统上的嵌套makefile,具体用什么方式来构建一个大的工程呢?我有找到了这篇论文《Recursive make considered harmful》,其中讲述的很清楚,我查了下被引用的次数还是不少的,关于这篇文章,请参考这里,不再赘述。
当我读完这篇论文之后,我开始重新思考我该怎样完成上面的步骤3,然后慢慢的尝试完成其中一个静态库的编译,最后写成这个摸样:
# include some common definitions of make include common.mk MODULES := asyn_frame rsa platform torrent_parser utility CFLAGS += $(patsubst %,-I%,$(MODULES)) CFLAGS += -I. -I./include CFLAGS += -DLINUX -DNDEBUG CFLAGS += -O2 SRC := $(wildcard *.c) # It‘s used for debug makefile. MODULES_MK := $(patsubst %,src/%/module.mk,$(MODULES)) include $(MODULES_MK) OBJ := $(patsubst %.c,%.o,$(SRC)) LIB := libcommon.a $(LIB) : $(OBJ) @echo ‘enter produce the lib files*************‘ $(AR) $(LIB) $(OBJ) $(RM) $(OBJ) @echo ‘leave produce the lib files*************‘ all : $(LIB) %d : %c @set -e; $(RM) [email protected]; $(CC) -M $(CFLAGS) $< > [email protected]$$$$; sed ‘s,\($*\)\.o[ :]*,\1.o [email protected] : ,g‘ < [email protected]$$$$ > [email protected]; $(RM) [email protected]$$$$ -include $(SRC:.c=.d) .PHONY : clean all test : @echo ‘make test enter‘ @echo ‘the src of asyn_frame:‘ @echo $(SRC) @echo ‘the obj of asyn_frame:‘ @echo $(OBJ) @echo ‘the mk file of common‘ @echo $(MODULES) @echo $(MODULES_MK) @echo $(CFLAGS) @echo ‘make test leaving‘ clean : $(RM) $(LIB) $(OBJ) find . -name "*.d" | xargs rm -f
看起来不算复杂,但是从无到有的过程还是比较曲折的,可以看到这里面有一个伪目标test,这是我用来测试make中的基本变量的,不断地尝试终于出来这个还算能用的东西。所以总算是完成了步骤3,当然是在预计的时间内,心中很是舒服,至少可以说我的知识库中又多了一项武器。
走完第3步之后我没有再继续走第4步,因为我觉得目前看来我还没有到需要非常熟悉makefile的地步,学习它的初衷也是为了能在日常的工作实践中帮助自己做实际的项目,如果过于沉浸在理论上就与我的初衷相违背了,非我所欲也,更何况目前的项目大都是跨平台的,所以CMake才是我的菜。此刻我选择“浅尝辄止”,但是我还是回顾了一遍makefile的基础知识,我的参考资料是网上看的比较多的陈皓的《跟我一起写makefile》,总共14章,我觉得这个系列也不是特别好,很多东西都是GNU manual的摘录,当然也还有作者自己的理解,不过作为参考帮助回顾一些常见的知识点还是很有帮助的。这也就是我为啥没有找那本大而全的教科书,而是看了这种网上的精简tutorial。
前面基本上是我学习makefile的简单历程,耗费的时间大约在3周左右,毕竟工作了、有小孩了,真没有太多自己的时间了,不过有了这件事让我得到一个很好的习惯就是每天早上能在5点半左右起来,看两个小时的书再去上班,这真是无心插柳的结果,因为晚上实在没有时间做这些事。。。前面虽然有很多的废话,但是我觉得学习知识不是最关键的,了解怎样获取知识才是重要的而且通常是最难的,我试图用比较简单的语言来描述这个获取知识的思考过程,但细细读来还是觉得啰嗦满地。。嘿嘿,就这样吧,反正就是这么一回事,我也不想做什么事后诸葛亮。
下面我会转入正文,写一个我自己的makefile教程:
目录:
1、构建多级目录结构的makefile最佳实践 — The Best Way
2、一个真实项目的makefile及其解释
3、makefile最常用的知识点整理
4、参考资料
具体的内容请移步这里《我的makefile教程》。
makefile死磕笔记