这里不再说Makefile的基本知识,如果需要学习,那么请参考: 下载:makefile 中文手册

或者

点击打开链接

或者

跟我一起写Makefile( 陈皓 )

这里说的是一般的实际的一个工程应该怎么去写。

环境:ubuntu 10.04

先看看我的文件的分布情况:

顶层:

然后src中:是所有的源程序以及头文件( 我这里是使用自己的IR树的代码作为实验 )

而build文件夹是为了编译使用的!下面有:

obj文件夹里面放的是编译过程中的.o和.d文件,还有一个subdir.mk的子文件,

用于指示怎么生成.o

obj中:

下面我们从顶层开始慢慢分析:

*******温馨提示:下面的注释是为了方便处理,写在每一条语句后面,其实这样的风格是不好的,所以,如果

你使用了这个makefile,请将注释换行...或者去掉,否则可能编译异常!谢谢记住!

*******

最外层的makefile:

  1. SHELL = /bin/sh             # 这个地方是指示使用的shell是sh
  2. EXEC = ir_tree              # 最终生成的binary的名称
  3. BUILD_DIR = build           # 这个子文件夹,此处也就是我们build文件夹
  4. all:                        # all在此处是终极目标,这个你应该知道的。一般我们make的时候,第一个目标作为终极目标
  5. @( cd ${BUILD_DIR}; make )  # 这句是进去build文件夹去执行那个makefile
  6. clean:                      # clean就不说了
  7. @echo 'start clean...'
  8. @($(RM) $(EXEC))
  9. @(cd ${BUILD_DIR}; make clean)
  10. @echo 'Finished!'
  11. @echo ''

现在进入build文件夹,看这个文件夹下面的makefile

  1. SHELL = /bin/sh            # 同上
  2. INCLUDE_DIR :=             # include文件夹,一般我们在引用库的时候,需要将其头文件放在一个include中,然后自己的程序                           # 编译的时候需要包含这个include,例如-I$(<span style="font-family: SimHei;">INCLUDE_DIR</span><span style="font-family: SimHei;">)</span>
  3. LIB_DIR := -lm             # 引入的库
  4. EXEC = ../ir_tree          # 这是一个最终binary名称,这里是将这个可执行放在了上层文件夹中
  5. -include obj/subdir.mk     # 这个地方是include了一个子文件
  6. # 这里子文件作用是,为了生成所有的.o文件(当然附带生成.d文件!),生成.o之后,才能回到这一                           # 层的makefile进行链接成最终的可执行的操作!具体操作我们稍后再看
  7. all:${EXEC}                # 好!这里是这个makefile的第一个目标。即终极目标,所有需要找<span style="font-family: SimHei;">${EXEC}的生成规则!</span>
  8. ${EXEC}: ${OBJS}           # <span style="font-family: SimHei;">${EXEC}的生成规则,注意这里我们没有看到$(OBJS),那是因为在</span><span style="font-family: SimHei;">obj/subdir.mk中!</span><span style="font-family: SimHei;">
  9. </span> @echo ' Building target: $@ '
  10. gcc -o $@ $(OBJS) $(LIB_DIR)   # 这一句就是为了将所有的.o文件 + 引用的库 链接起来,生成最后的$@,也就是$(EX                                       # EC),也就是最后的binary!
  11. @echo 'Finished building target: $@'
  12. @echo ''
  13. clean:
  14. @echo 'start rm objs and deps ...'
  15. $(RM) $(OBJS) \
  16. $(C_DEPS)
  17. @echo 'Finish rm objs and deps ...'
  18. .PHONY: all clean                      # 伪目标
  19. .SECONDARY:

下面需要看看obj中的subdir.mk的内容了!这个是为了生成所有的.o文件。

同时!请注意:当我们的一个.c或者.h被修改之后,需要重新编译!这一点非常重要!

特别是.h被修改的时候,不能忘记重新编译( 当然,有些时候.h修改,我们不需要编译,这个先暂时不说,后面在讨论!其实,你使用一个make --touch就可以~ )

  1. C_SRCS += \            # 所有的.c文件,当然你喜欢使用wildcard也是可的!
  2. ../src/card.c \        # $(<span style="font-family: SimHei;">wildcard ../src/*.c</span><span style="font-family: SimHei;">)</span>
  3. ../src/index.c \
  4. ../src/node.c \
  5. ../src/rect.c \
  6. ../src/split_l.c \
  7. ../src/test.c
  8. OBJS += \             <span style="font-family: SimHei;"># 所有的.c文件,当然你喜欢使用wildcard也是可的!</span>
  9. ./obj/card.o \        # OBJS = $(patsubst %.c,%.o,$(wildcard ../src/*.c))
  10. ./obj/index.o \       # 但是你要将src文件目录改成obj的 <span style="font-family: SimHei;">OBJS := $(addprefix "./obj/",$(notdir $(OBJS)))</span>
  11. ./obj/node.o \
  12. ./obj/rect.o \
  13. ./obj/split_l.o \
  14. ./obj/test.o
  15. C_DEPS += \          # deps
  16. ./obj/card.d \
  17. ./obj/index.d \
  18. ./obj/node.d \
  19. ./obj/rect.d \
  20. ./obj/split_l.d \
  21. ./obj/test.d
  22. all: $(OBJS)        # 注意在这个subdir中,这个是终极目标,也就是所有的objs
  23. obj/%.o: ../src/%.c ./obj/%.d    #这里是o文件的依赖规则:注意是.c和.d同时成为依赖,.d文件中是一个目标的所有的依赖文                                 # 件,包括.c和.h文件,所有一旦.h被修改,这个地方也是可以识别的!
  24. @echo 'start building $< ...'
  25. gcc -O3 -Wall -c -fmessage-length=0 -MMD -MP -MF"$(@:%.o=%.d)" \
  26. -MT"$(@:%.o=%.d)" -o "$@" "$<"
  27. @echo 'Finished building: $< '
  28. @echo ''
  29. -include $(C_DEPS) # 注意:这里将所有的.d文件引入!注意,第一次引入时候,没有.d文件,会寻找.d的生成规则,也就是下面                   # 的,这个.d又是依赖.c文件的,所有,一旦一个.c文件中多了一个头文件之类,又可以跟新.d,从而,执行                   # 上面的.o生成时候,就能够实时跟新
  30. ./obj/%.d: ../src/%.c   # 注意:这里为了生成.d
  31. @echo 'start building $(notdir $@)...'
  32. $(CC) $< $(INCLUDE) -MM -MD -o $@

好了,上面所有的都分析完了,然后可以make一下,.、ir_tree 看看效果吧~

如果你要下载这个工程,我已经上传了,你可以免费下载:ir_tree

from:http://blog.csdn.net/shanshanpt/article/details/17198413

Makefile 实际用例分析(一) ------- 比较通用的一种架构的更多相关文章

  1. Makefile 实际用例分析(二) ------- 比较通用的一种架构

    之前已经讲了这一篇文章:Makefile实际用例分析(一)-----比较通用的一种架构 现在这篇其实和那个差的不是很多,只是在布局上有些差别(这个makefile也是论坛上一起讨论过的,囧,忘了哪个论 ...

  2. Makefile 实际用例分析(三) ------- 是用GUN automake 处理自己的工程

    前面两篇已经说过了自己怎么去为一个工程写makefile: 第一篇 第二篇 现在这一篇说的是怎么使用GNU的工具去写一个符合开源标准的Makefile呢! 首先我觉你应该参考: Automake Au ...

  3. Psp个人软件开发软件需求分析和用例分析

    Psp个人软件开发软件需求分析和用例分析 一.需求分析 1.业务需求 1.1 应用背景 开发项目进度计划总是那么不明确,延期经常出现,甚至无法给出一个相对比较明确的延迟时间.这样给市场的推广会带来很大 ...

  4. K米APP----案例分析

    K米APP----案例分析 第一部分 调研,评测 第一次上手体验 软件的美工做得不错,功能排版很清楚,用户很容易上手,不至于用户不知道怎么用这个APP点歌 软件最主要的功能是KTV的点歌功能,这个功能 ...

  5. Psp个人软件开发软件需求分析及用例分析

    一.需求分析 1.  业务需求 1.1 应用背景 开发项目进度计划总是那么不明确,延期经常出现,甚至无法给出一个相对比较明确的延迟时间.这样给市场的推广会带来很大的影响,不确定因素使得应对十分困难. ...

  6. [转][LoadRunner]LR性能测试结果样例分析

    LR性能测试结果样例分析 测试结果分析 LoadRunner性能测试结果分析是个复杂的过程,通常可以从结果摘要.并发数.平均事务响应时间.每秒点击数.业务成功率.系统资源.网页细分图.Web服务器资源 ...

  7. 需求用例分析之五:业务用例之Rational系

    版权声明:作者:张克强.未经作者允许不得转载. https://blog.csdn.net/zhangmike/article/details/28134897 作者:张克强    作者微博:张克强- ...

  8. [LoadRunner]LR性能测试结果样例分析

    R性能测试结果样例分析 测试结果分析 LoadRunner性能测试结果分析是个复杂的过程,通常可以从结果摘要.并发数.平均事务响应时间.每秒点击数.业务成功率.系统资源.网页细分图.Web服务器资源. ...

  9. LoadRunner性能测试样例分析

    LR性能测试结果样例分析 测试结果分析 LoadRunner性能测试结果分析是个复杂的过程,通常可以从结果摘要.并发数.平均事务响应时间.每秒点击数.业务成功率.系统资源.网页细分图.Web服务器资源 ...

随机推荐

  1. Socket中BufferedReader.readLine()的阻塞特性导致的数据无法多次发送的问题

    https://blog.csdn.net/shenpibaipao/article/details/70236657

  2. C++ Primer(第4版)-学习笔记-第5部分:高级主题

    第17章  用于大型程序的工具 异常处理 不存在数组或函数类型的异常.相反,如果抛出一个数组,被抛出的对象转换为指向数组首元素的指针,类似地,如果抛出一个函数,函数被转换为指向该函数的指针. 不要抛出 ...

  3. python_ 学习笔记(基本数据类型)

    python3有6中标准数据类型:Number(数字).String(字符串).List(列表).Tuple(元组).Dictionary(字典).Set(集合)不可变数据:Number.String ...

  4. 使用Mybatis的逆向工程自动生成代码

    1.逆向工程的作用 Mybatis 官方提供了逆向工程,可以针对数据库表自动生成Mybatis执行所需要的代码(包括mapper.xml.Mapper.java.pojo). 2.逆向工程的使用方法 ...

  5. nginx4win10 文件下载服务器

    默认root是Nginx下目录html. 我们在其目录下新建download目录,然后在该目录下copy几个供下载的文件. 在浏览器输入http://localhost:9001/download/y ...

  6. 【01】CSS3 Gradient 分为 linear-gradient(线性渐变)和 radial-gradient(径 向渐变)(转)

    CSS3 Gradient 分为 linear-gradient(线性渐变)和 radial-gradient(径 向渐变).而我们今天主要是针对线性渐变来剖析其具体的用法.为了更好的应用 CSS3 ...

  7. 闸门机制(Gate Mechanism)

    本系列文章由 @yhl_leo 出品,转载请注明出处. 文章链接: http://blog.csdn.net/yhl_leo/article/details/51728107 神经网络中常说的闸门机制 ...

  8. [bzoj1613][Usaco2008 Jan]Running贝茜的晨练计划_动态规划

    Running贝茜的晨练计划 bzoj-1613 Usaco-2008 Jan 题目大意:题目链接(U组题题意真的是没法概括qwq....). 注释:略. 想法:一眼dp题. 状态:dp[i][j]表 ...

  9. 洛谷——P1396 营救

    P1396 营救 题目描述 “咚咚咚……”“查水表!”原来是查水表来了,现在哪里找这么热心上门的查表员啊!小明感动的热泪盈眶,开起了门…… 妈妈下班回家,街坊邻居说小明被一群陌生人强行押上了警车!妈妈 ...

  10. Python: 解决simple-db-migrate的"No module named 'MySQLdb'错误

    sudo apt-get install libmysqlclient-dev sudo -H pip3 install mysqlclient