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) [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死磕笔记

时间: 2024-10-23 19:32:18

makefile死磕笔记的相关文章

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

原文:<死磕 Elasticsearch 方法论>:普通程序员高效精进的 10 大狠招!(完整版) 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/wojiushiwo987/article/details/79293493 人工智能.大数据快速发展的今天,对于 TB 甚至 PB 级大数据的快速检索已然成为刚需.Elasticsearch 作为开源领域的后起之秀,从2010年至今得到飞跃

2015考研数学考前必须死磕的知识点

2015考研数学考前必须死磕的知识点 来源:跨考教育    划词:关闭划词   收藏 编辑点评:下文为2015年考研数学必须掌握的知识点的大汇总,供考生们参考.沪江考研为你及时整合各路干货复习资料,敬请关注. 第一章 函数.极限与连续 1.函数的有界性 2.极限的定义(数列.函数) 3.极限的性质(有界性.保号性) 4.极限的计算(重点)(四则运算.等价无穷小替换.洛必达法则.泰勒公式.重要极限.单侧极限.夹逼定理及定积分定义.单调有界必有极限定理) 5.函数的连续性 6.间断点的类型 7.渐近

【死磕Java并发】-----J.U.C之重入锁:ReentrantLock

此篇博客所有源码均来自JDK 1.8 ReentrantLock,可重入锁,是一种递归无阻塞的同步机制.它可以等同于synchronized的使用,但是ReentrantLock提供了比synchronized更强大.灵活的锁机制,可以减少死锁发生的概率. API介绍如下: 一个可重入的互斥锁定 Lock,它具有与使用 synchronized 方法和语句所访问的隐式监视器锁定相同的一些基本行为和语义,但功能更强大.ReentrantLock 将由最近成功获得锁定,并且还没有释放该锁定的线程所拥

【死磕Java并发】-----Java内存模型之分析volatile

前篇博客[死磕Java并发]-–深入分析volatile的实现原理 中已经阐述了volatile的特性了: volatile可见性:对一个volatile的读,总可以看到对这个变量最终的写: volatile原子性:volatile对单个读/写具有原子性(32位Long.Double),但是复合操作除外,例如i++; JVM底层采用"内存屏障"来实现volatile语义 下面LZ就通过happens-before原则和volatile的内存语义两个方向介绍volatile. volat

死磕,死磕死磕

坚持就能看到希望,遇到问题,有时候就是要死磕,才能慢慢看到希望.甚至是,一天之内经历希望,又绝望,如此反复. 早上,赖在床上一个小时,还是没有起来去锻炼,如果只是想的话,这一个小时我已经把一天的事情全部做完.说说上午做的事情.主要就是理解了Intel以前的tick-tock,处理器更新节奏,也就是滴答,一个tick,主要更新一下制程,比如从32nm到22nm,一个tock就是主要更新架构,不过到了后摩尔时代,就变成了三步走的战略,tick.tock.优化,比如最近刚出的七代core kabyla

死磕Spring AOP系列4:剖析AOP schema方式原理

这个是<死磕Spring AOP系列>第4个.已经讲过的内容 死磕Spring AOP系列3:剖析Bean处理器之DefaultAdvisorAutoProxyCreator 死磕Spring AOP系列2:剖析Bean处理器之BeanNameAutoProxyCreator 死磕Spring AOP系列1:编程式实现AOP 通过前3篇,大家应该可以清楚的知道:AOP代理原理有3元素 BeanPostProcessor,作为代理对象初始入口 Advisor&Pointcut&M

【死磕Java并发】-----J.U.C之AQS:CLH同步队列

此篇博客所有源码均来自JDK 1.8 在上篇博客[死磕Java并发]-–J.U.C之AQS:AQS简介中提到了AQS内部维护着一个FIFO队列,该队列就是CLH同步队列. CLH同步队列是一个FIFO双向队列,AQS依赖它来完成同步状态的管理,当前线程如果获取同步状态失败时,AQS则会将当前线程已经等待状态等信息构造成一个节点(Node)并将其加入到CLH同步队列,同时会阻塞当前线程,当同步状态释放时,会把首节点唤醒(公平锁),使其再次尝试获取同步状态. 在CLH同步队列中,一个节点表示一个线程

死磕Spring AOP系列1:编程式实现AOP

作为[死磕Spring AOP]系列的第一篇, 这个系列是AOP源码分析级别的文章.由于现在AOP已经不是什么高深的技术,网上的例子也比比皆是,不论是xml schema,还是annotation声明式.相信用过Spring的朋友,都可以信手拈来. 本系列文章的原则 如何配置AOP不是重点 AOP相关概念讲解不是重点 AOP 底层代码设计才是重点 本篇的主要内容 认识ProxyFactory,并通过该工厂类,将"日志"和"安全校验"代码切入到业务逻辑中 分析代理对象

【死磕Java并发】-----J.U.C之读写锁:ReentrantReadWriteLock

此篇博客所有源码均来自JDK 1.8 重入锁ReentrantLock是排他锁,排他锁在同一时刻仅有一个线程可以进行访问,但是在大多数场景下,大部分时间都是提供读服务,而写服务占有的时间较少.然而读服务不存在数据竞争问题,如果一个线程在读时禁止其他线程读势必会导致性能降低.所以就提供了读写锁. 读写锁维护着一对锁,一个读锁和一个写锁.通过分离读锁和写锁,使得并发性比一般的排他锁有了较大的提升:在同一时间可以允许多个读线程同时访问,但是在写线程访问时,所有读线程和写线程都会被阻塞. 读写锁的主要特