Makefile 实际用例分析(一) —- 比较通用的一种架构
Thursday, December 1, 2016
4:10 PM
Makefile 实际用例分析(一) ———- 比较通用的一种架构
.
2013-12-08 12:20 3641人阅读 评论(3) 收藏 举报
.
Makefile 实际用例分析(一) --- 比较通用的一种架构 - 图1
分类:
C/Cpp(68)
Makefile 实际用例分析(一) --- 比较通用的一种架构 - 图2
其他技术类(55)
Makefile 实际用例分析(一) --- 比较通用的一种架构 - 图3
好玩的东东~程序(13)
Makefile 实际用例分析(一) --- 比较通用的一种架构 - 图4
.
版权声明:本文为博主原创文章,未经博主允许不得转载。
这里不再说Makefile的基本知识,如果需要学习,那么请参考: 下载:makefile 中文手册
或者

点击打开链接
或者
跟我一起写Makefile( 陈皓 )
这里说的是一般的实际的一个工程应该怎么去写。
环境:ubuntu 10.04
先看看我的文件的分布情况:
顶层:
build src makefile
然后src中:是所有的源程序以及头文件( 我这里是使用自己的IR树的代码作为实验 )
card.c node.c test.c card.h rect.c index.c split_l.c index.h split_l.h
而build文件夹是为了编译使用的!下面有:
obj makefile
obj文件夹里面放的是编译过程中的.o和.d文件,还有一个subdir.mk的子文件,
用于指示怎么生成.o
obj中:
subdir.mk
下面我们从顶层开始慢慢分析:
*温馨提示:下面的注释是为了方便处理,写在每一条语句后面,其实这样的风格是不好的,所以,如果
你使用了这个makefile,请将注释换行…或者去掉,否则可能编译异常!谢谢记住!


最外层的makefile:
[plain] view plain copy
print?
在CODE上查看代码片
<>

  1. SHELL = /bin/sh # 这个地方是指示使用的shell是sh
  2. EXEC = ir_tree # 最终生成的binary的名称
  3. BUILD_DIR = build # 这个子文件夹,此处也就是我们build文件夹
    4. ```
  4. all: # all在此处是终极目标,这个你应该知道的。一般我们make的时候,第一个目标作为终极目标

  5. @( cd ${BUILD_DIR}; make ) # 这句是进去build文件夹去执行那个makefile 7.

  6. clean: # clean就不说了
  7. @echo ‘start clean…’
  8. @($(RM) $(EXEC))
  9. @(cd ${BUILD_DIR}; make clean)
  10. @echo ‘Finished!’
  11. @echo ‘’
  1. 现在进入build文件夹,看这个文件夹下面的makefile<br />**[plain]** [view plain](http://blog.csdn.net/shanshanpt/article/details/17198413#) [copy](http://blog.csdn.net/shanshanpt/article/details/17198413#)<br />[print](http://blog.csdn.net/shanshanpt/article/details/17198413#)[?](http://blog.csdn.net/shanshanpt/article/details/17198413#)<br />[![在CODE上查看代码片](https://cdn.nlark.com/yuque/0/2021/png/3018302/1639544408816-5855f70a-8dca-4a16-9a46-0b66dc533daa.png)](https://code.csdn.net/snippets/102483)<br /><<ico_fork.svg>><br />
  2. 1. SHELL = /bin/sh # 同上<br />
  3. 2.
  1. INCLUDE_DIR := # include文件夹,一般我们在引用库的时候,需要将其头文件放在一个include中,然后自己的程序 # 编译的时候需要包含这个include,例如-I$(INCLUDE_DIR)

  2. LIB_DIR := -lm # 引入的库

  3. EXEC = ../ir_tree # 这是一个最终binary名称,这里是将这个可执行放在了上层文件夹中 6.
  4. -include obj/subdir.mk # 这个地方是include了一个子文件

  5. 这里子文件作用是,为了生成所有的.o文件(当然附带生成.d文件!),生成.o之后,才能回到这一 # 层的makefile进行链接成最终的可执行的操作!具体操作我们稍后再看

9.

  1. all:${EXEC} # 好!这里是这个makefile的第一个目标。即终极目标,所有需要找${EXEC}的生成规则!

11.

  1. ${EXEC}: ${OBJS} # ${EXEC}的生成规则,注意这里我们没有看到$(OBJS),那是因为在obj/subdir.mk中!

  2. @echo ‘ Building target: $@ ‘

  3. gcc -o $@ $(OBJS) $(LIB_DIR) # 这一句就是为了将所有的.o文件 + 引用的库 链接起来,生成最后的$@,也就是$(EX # EC),也就是最后的binary!

  4. @echo ‘Finished building target: $@’

  5. @echo ‘’ 17.
  6. clean:
  7. @echo ‘start rm objs and deps …’
  8. $(RM) $(OBJS) \
  9. $(C_DEPS)
  10. @echo ‘Finish rm objs and deps …’ 23.
  11. .PHONY: all clean # 伪目标
  12. .SECONDARY:
  1. 下面需要看看obj中的subdir.mk的内容了!这个是为了生成所有的.o文件。<br />
  2. 同时!请注意:当我们的一个.c或者.h被修改之后,需要重新编译!这一点非常重要!<br />特别是.h被修改的时候,不能忘记重新编译( 当然,有些时候.h修改,我们不需要编译,这个先暂时不说,后面在讨论!其实,你使用一个make --touch就可以~ )<br />**[plain]** [view plain](http://blog.csdn.net/shanshanpt/article/details/17198413#) [copy](http://blog.csdn.net/shanshanpt/article/details/17198413#)<br />[print](http://blog.csdn.net/shanshanpt/article/details/17198413#)[?](http://blog.csdn.net/shanshanpt/article/details/17198413#)<br />[![在CODE上查看代码片](https://cdn.nlark.com/yuque/0/2021/png/3018302/1639544408816-5855f70a-8dca-4a16-9a46-0b66dc533daa.png)](https://code.csdn.net/snippets/102483)<br /><<ico_fork.svg>><br />
  3. 1. C_SRCS += \ # 所有的.c文件,当然你喜欢使用wildcard也是可的!
  1. ../src/card.c \ # $(wildcard ../src/*.c)

  2. ../src/index.c \

  3. ../src/node.c \
  4. ../src/rect.c \
  5. ../src/split_l.c \
  6. ../src/test.c 8.

  7. OBJS += \ # 所有的.c文件,当然你喜欢使用wildcard也是可的!

  8. ./obj/card.o \ # OBJS = $(patsubst %.c,%.o,$(wildcard ../src/*.c))

  9. ./obj/index.o \ # 但是你要将src文件目录改成obj的 OBJS := $(addprefix “./obj/“,$(notdir $(OBJS)))

  10. ./obj/node.o \

  11. ./obj/rect.o \
  12. ./obj/split_l.o \
  13. ./obj/test.o 16.
  14. C_DEPS += \ # deps
  15. ./obj/card.d \
  16. ./obj/index.d \
  17. ./obj/node.d \
  18. ./obj/rect.d \
  19. ./obj/split_l.d \
  20. ./obj/test.d 24.
  21. all: $(OBJS) # 注意在这个subdir中,这个是终极目标,也就是所有的objs 26.

  22. obj/%.o: ../src/%.c ./obj/%.d #这里是o文件的依赖规则:注意是.c和.d同时成为依赖,.d文件中是一个目标的所有的依赖文 # 件,包括.c和.h文件,所有一旦.h被修改,这个地方也是可以识别的!

  23. @echo ‘start building $< …’

  24. gcc -O3 -Wall -c -fmessage-length=0 -MMD -MP -MF”$(@:%.o=%.d)” \

  25. -MT”$(@:%.o=%.d)” -o “$@” “$<”

  26. @echo ‘Finished building: $< ‘
  27. @echo ‘’ 33.

  28. -include $(C_DEPS) # 注意:这里将所有的.d文件引入!注意,第一次引入时候,没有.d文件,会寻找.d的生成规则,也就是下面 # 的,这个.d又是依赖.c文件的,所有,一旦一个.c文件中多了一个头文件之类,又可以跟新.d,从而,执行 # 上面的.o生成时候,就能够实时跟新

35.

  1. ./obj/%.d: ../src/%.c # 注意:这里为了生成.d
  2. @echo ‘start building $(notdir $@)…’
  3. $(CC) $< $(INCLUDE) -MM -MD -o $@
  1. 好了,上面所有的都分析完了,然后可以make一下,.、ir_tree 看看效果吧~<br />如果你要下载这个工程,我已经上传了,你可以免费下载:[ir_tree](http://download.csdn.net/detail/shanshanpt/6678235)<br />.<br />
  2. 顶<br />
  3. 7<br />
  4. 踩<br />
  5. 0<br />
  6. .<br />
  7. [ ](http:///)<br />
  8. [ ](http:///)<br />
  9. 上一篇[矩阵的求逆](http://blog.csdn.net/shanshanpt/article/details/16820325)<br />下一篇[Makefile 实际用例分析(二) ------- 比较通用的一种架构](http://blog.csdn.net/shanshanpt/article/details/17199695)<br />.<br />
  10. _我的同类文章_<br />
  11. **C/Cpp68)** 其他技术类(55 好玩的东东~程序(13

``` 更多文章
已使用 Microsoft OneNote 2016 创建。


ico_fork.svg
ico_fork.svg