开始我会插播一段我如何学习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死磕笔记的更多相关文章

  1. 【死磕 Spring】----- IOC 之深入理解 Spring IoC

    在一开始学习 Spring 的时候,我们就接触 IoC 了,作为 Spring 第一个最核心的概念,我们在解读它源码之前一定需要对其有深入的认识,本篇为[死磕 Spring]系列博客的第一篇博文,主要 ...

  2. 《死磕 Elasticsearch 方法论》:普通程序员高效精进的 10 大狠招!(完整版)

    原文:<死磕 Elasticsearch 方法论>:普通程序员高效精进的 10 大狠招!(完整版) 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链 ...

  3. mysql每秒最多能插入多少条数据 ? 死磕性能压测

    前段时间搞优化,最后瓶颈发现都在数据库单点上. 问DBA,给我的写入答案是在1W(机械硬盘)左右. 联想起前几天infoQ上一篇文章说他们最好的硬件写入速度在2W后也无法提高(SSD硬盘) 但这东西感 ...

  4. Makefile的学习笔记

    Makefile的学习笔记 标签: makefilewildcard扩展includeshellfile 2012-01-03 00:07 9586人阅读 评论(2) 收藏 举报  分类: Linux ...

  5. 【死磕Java并发】-----Java内存模型之happend-before

    在上篇博客([死磕Java并发]-–深入分析volatile的实现原理)LZ提到过由于存在线程本地内存和主内存的原因,再加上重排序,会导致多线程环境下存在可见性的问题.那么我们正确使用同步.锁的情况下 ...

  6. 死磕 java集合之DelayQueue源码分析

    问题 (1)DelayQueue是阻塞队列吗? (2)DelayQueue的实现方式? (3)DelayQueue主要用于什么场景? 简介 DelayQueue是java并发包下的延时阻塞队列,常用于 ...

  7. 死磕 java集合之PriorityBlockingQueue源码分析

    问题 (1)PriorityBlockingQueue的实现方式? (2)PriorityBlockingQueue是否需要扩容? (3)PriorityBlockingQueue是怎么控制并发安全的 ...

  8. 死磕 java集合之PriorityQueue源码分析

    问题 (1)什么是优先级队列? (2)怎么实现一个优先级队列? (3)PriorityQueue是线程安全的吗? (4)PriorityQueue就有序的吗? 简介 优先级队列,是0个或多个元素的集合 ...

  9. 【死磕 Spring】----- IOC 之解析 bean 标签:开启解析进程

    原文出自:http://cmsblogs.com import 标签解析完毕了,再看 Spring 中最复杂也是最重要的标签 bean 标签的解析过程. 在方法 parseDefaultElement ...

随机推荐

  1. Path Sum,Path Sum II

    Path Sum Total Accepted: 81706 Total Submissions: 269391 Difficulty: Easy Given a binary tree and a ...

  2. A - Next_permutation

    首先介绍一下next_permutation函数的用途! 按照STL文档的描述,next_permutation函数将按字母表顺序生成给定序列的下一个较大的排列,直到整个序列为降序为止. prev_p ...

  3. 简单的JQuery top返回顶部

    一个最简单的JQuery Top返回的代码,Mark一下: HTML如下: <div id="backtop"> <a href="javascript ...

  4. Android studio checkstyle 使用

    首先要安装CheckStyle-IDEA插件,官网:https://plugins.jetbrains.com/plugin/1065 打开Android studio进入设置->Plugins ...

  5. Python之路第六天,基础(8)-反射

    反射 利用字符串的形式去对象(模块)中操作(寻找/检查/删除/设置)成员(函数). Python中反射用到的4个内置函数:getattr(),setattr(),hasattr(),delattr() ...

  6. Ajax XMLHttpRequest对象的三个属性以及open和send方法

    (1)onreadystatechange 属性onreadystatechange 属性存有处理服务器响应的函数.下面的代码定义一个空的函数,可同时对 onreadystatechange 属性进行 ...

  7. python核心编程-第四章-习题

    1.身份.类型.值.其中,身份是每个对象的标识,与内存地址密切相关,可用id()返回:类型决定了对象可以保存什么类型的值,用type()函数.isinstance()函数可以得到对象的类型:值就是对象 ...

  8. 【原创】QT5-卸载精灵v1.0-卸载windows软件-简易版

    由于项目需求,需要实现卸载windows上的普通软件的小功能,实现起来还是比较简单的. 先发个图: 思路: 1.根据注册表的信息去打开应用程序,卸载也一样: 2.读桌面的快捷方式,根据快捷方式的指向路 ...

  9. PHP设计模式之委托模式

    委托模式: 通过分配或委托至其他对象,委托设计模式能够去除核心对象中的判决和复杂的功能性. class Bank{ protected $info; /* 设置基本信息 @param string $ ...

  10. 谈谈我对Java中CallBack的理解

    谈谈我对Java中CallBack的理解 http://www.cnblogs.com/codingmyworld/archive/2011/07/22/2113514.html CallBack是回 ...