makefile死磕笔记
开始我会插播一段我如何学习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) $@; $(CC) -M $(CFLAGS) $< > $@.$$$$; \
sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; $(RM) $@.$$$$
-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死磕笔记的更多相关文章
- 【死磕 Spring】----- IOC 之深入理解 Spring IoC
在一开始学习 Spring 的时候,我们就接触 IoC 了,作为 Spring 第一个最核心的概念,我们在解读它源码之前一定需要对其有深入的认识,本篇为[死磕 Spring]系列博客的第一篇博文,主要 ...
- 《死磕 Elasticsearch 方法论》:普通程序员高效精进的 10 大狠招!(完整版)
原文:<死磕 Elasticsearch 方法论>:普通程序员高效精进的 10 大狠招!(完整版) 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链 ...
- mysql每秒最多能插入多少条数据 ? 死磕性能压测
前段时间搞优化,最后瓶颈发现都在数据库单点上. 问DBA,给我的写入答案是在1W(机械硬盘)左右. 联想起前几天infoQ上一篇文章说他们最好的硬件写入速度在2W后也无法提高(SSD硬盘) 但这东西感 ...
- Makefile的学习笔记
Makefile的学习笔记 标签: makefilewildcard扩展includeshellfile 2012-01-03 00:07 9586人阅读 评论(2) 收藏 举报 分类: Linux ...
- 【死磕Java并发】-----Java内存模型之happend-before
在上篇博客([死磕Java并发]-–深入分析volatile的实现原理)LZ提到过由于存在线程本地内存和主内存的原因,再加上重排序,会导致多线程环境下存在可见性的问题.那么我们正确使用同步.锁的情况下 ...
- 死磕 java集合之DelayQueue源码分析
问题 (1)DelayQueue是阻塞队列吗? (2)DelayQueue的实现方式? (3)DelayQueue主要用于什么场景? 简介 DelayQueue是java并发包下的延时阻塞队列,常用于 ...
- 死磕 java集合之PriorityBlockingQueue源码分析
问题 (1)PriorityBlockingQueue的实现方式? (2)PriorityBlockingQueue是否需要扩容? (3)PriorityBlockingQueue是怎么控制并发安全的 ...
- 死磕 java集合之PriorityQueue源码分析
问题 (1)什么是优先级队列? (2)怎么实现一个优先级队列? (3)PriorityQueue是线程安全的吗? (4)PriorityQueue就有序的吗? 简介 优先级队列,是0个或多个元素的集合 ...
- 【死磕 Spring】----- IOC 之解析 bean 标签:开启解析进程
原文出自:http://cmsblogs.com import 标签解析完毕了,再看 Spring 中最复杂也是最重要的标签 bean 标签的解析过程. 在方法 parseDefaultElement ...
随机推荐
- WINFORM窗体里使用网页控件的一些办法
最近弄一个项目,是个CS的.当然也是有表单之类的,如果将HTML表单搬到窗体上就省事多了. .首先要使用一个控件 WebBrowser 载入页面没使用URL属性,使用了下面这个属性 this.webB ...
- js如何控制css伪元素内容(before,after)
曾经遇到的问题,在对抗UC浏览器屏蔽需要把内容输出到css 伪元素中输出.有个疑问如何用js控制它.于是在segmentfault提问,如下是对问题的整理: 如何用js控制css伪类after 简单粗 ...
- 常用的PHP正则表达式汇总
PHP中的常用正则表达式集锦: 匹配中文字符的正则表达式: [\u4e00-\u9fa5] 评注:匹配中文还真是个头疼的事,有了这个表达式就好办了 匹配双字节字符(包括汉字在内):[^\x00-\xf ...
- 解决ERROR C2011: 'FD_SET' : 'STRUCT' TYPE REDEFINITION问题
在socket编程的过程中头文件中 #include <windows.h> #include "stdafx.h" #include "WinSock2.h ...
- twisted 使用
工欲善其事,必先利其器,我们先来进行 twisted 框架的安装,由于平时使用的都是 Windows 系统,那么下面我们就讲解下 Windows 下 twisted 框架的安装(1)下载 twiste ...
- python socket 编程之三:长连接、短连接以及心跳
长连接:开启一个socket连接,收发完数据后,不立刻关闭连接,可以多次收发数据包. 短连接:开启一个socket连接,收发完数据后,立刻关闭连接. 心跳:长连接在没有数据通信时,定时发送数据包(心跳 ...
- Binary Numbers(HDU1390)
Binary Numbers 点我 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others ...
- 【转载】来自苹果的编程语言——Swift简介
本文转自Lucida的博客 (新浪微博.豆瓣) 这篇文章简要介绍了苹果于WWDC 2014发布的编程语言——Swift. 前言 在这里我认为有必要提一下Brec Victor的Invent ...
- JVM的体系结构——JVM之三
JVM的内部体系结构分为四部分, (1)类装载器(ClassLoader)子系统 作用: 用来装载.class文件 (2)执行引擎 作用:执行字节码,或者执行本地方法 (3)垃圾回收子系统 作用:垃圾 ...
- linux之SQL语句简明教程---主键,外来键
主键 (Primary Key) 中的每一笔资料都是表格中的唯一值.换言之,它是用来独一无二地确认一个表格中的每一行资料.主键可以是原本资料内的一个栏位,或是一个人造栏位 (与原本资料没有关系的栏位) ...