Makefile 实际用例分析(二) ------- 比较通用的一种架构
之前已经讲了这一篇文章:Makefile实际用例分析(一)-----比较通用的一种架构
现在这篇其实和那个差的不是很多,只是在布局上有些差别(这个makefile也是论坛上一起讨论过的,囧,忘了哪个论坛)
还是先看看基本的文件布局:
介绍:
debug是调试版本的binary文件夹
release是发行版本binary文件夹
src是所有的源文件文件夹、
lib是引用库
include一般是引用库头文件之类,或者其他头文件
obj所有.o文件和.d文件
src中:依然使用之前的那个ir_tree的例子
在lib中有一个外来的引用库,命名为libnew.a,
在include中是这个库的头文件new.h:
我们对于最基本的文件分别已经清楚了,这种架构下只使用了一个makefile,下面我们具体看看:
---------------->>>>>> 我无语了,对csdn格式彻底无语了!这是第三次修改代码格式了,
算了,直接贴成文字吧。。。。。。。。。。。。。。。。。。。。。。。。。。。
********温馨提示:由于csdn格式问题,下面的命令前面的TAB都没有了,所以自己写的时候就得加上!
#################################
# 常见的配置,不多说
#
SHELL=/bin/sh
CC=gcc
MAKE=make
#################################
# 下面定义的是一些目录路径
#
MAKE_DIR=. # 当前文件夹
SRC_DIR=$(MAKE_DIR)/src/ # 源文件夹
OBJ_DIR=$(MAKE_DIR)/obj/ # obj文件夹
LIB_DIR=$(MAKE_DIR)/lib/ # 引用库文件夹
INCLUDE_DIR=$(MAKE_DIR)/include/ # include文件夹
DEBUG_DIR=$(MAKE_DIR)/debug/ # debug文件夹
RELEASE_DIR=$(MAKE_DIR)/release/# release文件夹
EXEC_DIR= # 最终的binary文件夹
#################################
# 下面是include路径和库的路径
#
INCLUDE=-I$(INCLUDE_DIR) -I$(SRC_DIR)
LIB=$(LIB_DIR)/libnew.a -L$(OBJ_DIR) -lm # 引入库,包括自己的库文件( 如果你将libnew.a放到/usr/lib中了, )
# 那么直接-lnew就可以了
#################################
# 下面是可执行名称
#
EXEC=ir_tree
#################################
#
# 注意:当我们下面出现%.c的时候,先在当前文件夹寻找,如果找不到,那么
# 到下面指定的文件夹中寻找!!!
#
# 说白就是:如果依赖文件在本文件夹找不到,那么到下面文件夹寻找!仅仅是依赖文件!
#
vpath %.h $(INCLUDE_DIR)
vpath %.c $(SRC_DIR)
vpath %.o $(OBJ_DIR)
vpath %.d $(OBJ_DIR)
#################################
# 下面是指定SRC OBJ DEP
# 注意:都是不带目录的basename
#
SRC_TMP:=$(wildcard $(SRC_DIR)*.c)
C_SRCS:=$(notdir $(SRC_TMP)) # 源文件
C_OBJS:=$(patsubst %.c,%.o,$(C_SRCS)) # o文件
C_DEPS:=$(patsubst %.c,%.d,$(C_SRCS)) # deps
#################################
# 编译选项!
#
FLAG_DEBUG=-g
CFLAGS=-O2 -Wall -c
# 下面判断是debug还是release
#
DEBUG:=1
ifeq ($(DEBUG),1)
EXEC_DIR:=$(DEBUG_DIR)
CFLAGS:=$(CFLAGS) $(FLAG_DEBUG)
else
EXEC_DIR:=$(RELEASE_DIR)
endif
# 最终binary的名称( 路径+名称 )
#
EXEC:=$(EXEC_DIR)$(EXEC)
################################
# 下面是终极目标all
#
#################################################################
# 关于下面的执行:
#
# 首先-include $(addprefix $(OBJ_DIR),$(C_DEPS))
# 目的是为了将所有的.d文件包含进来,那么.d文件里面是所有的.o的
# 完整的依赖,那么即使.h被修改了,那么也是可以识别编译的!在第一次
# 处理时,没有.d文件,那么需要找.d的生成规则。因为我们include的是
# $(addprefix $(OBJ_DIR),$(C_DEPS)),那么需要找的依赖是$(OBJ_DIR)%.d
# ,那么OK,这个地方必须注意!如果你include的.d是例如card.d,那么
# 规则必须是:%.d: %.c,而不是$(OBJ_DIR)%.d: %.c。好!现在生成.d文件了
# 然后执行all:$(EXEC),那么需要找依赖$(C_OBJS),本文件夹没有,那么到
# vpath %.o $(OBJ_DIR)中寻找!那么可以因为开始.o是不存在(或者过期的),
# 那么需要寻找生成规则:%.o: %.c %.d,OK生成!
# 等所有的.o处理OK,链接成可执行!
#
#################################################################
#
# 重要理解:
# 1: 你有什么样的依赖,那么就是什么样的一个子规则的目标!
# 例如:$(C_OBJS)是不带目录路径的.o的集合,例如a.o b.o c.o
# 那么,我们需要寻找生成他们的规则,那么肯定有一个子伪目标
# 名称是:(%.o:依赖),而不是($(OBJ_DIR)%.o:依赖),所以
# 要理解哦!
#
# 2: 注意vpath用途,当“依赖”在本文件夹下找不到的时候,去指定
# 文件夹寻找!
#
# 3:注意Include是将.d文件中的内容加载到当前文件夹中!那么,如果.d
# 里的是例如:card.o: card.c card.h,那么$(C_OBJS)也应该是不带目录
# 路径的*.o形式!!!
#
all:$(EXEC)
$(EXEC): $(C_OBJS)
@echo 'start building $(notdir $@) ...'
@$(CC) $(addprefix $(OBJ_DIR),$(notdir $^)) $(LIB) -o $@
#
# 注意关系:每次makefile的时候,需要加载.d文件,那么所有的依赖被加进来
# 但是也必须有$(OBJ_DIR)%.d: %.c,这个是为了当我们的.c改变的时候,例如
# 可能心增加一个include,那么可以改变.d文件!那么后面的处理又是连带关系!
#
# 与上一篇说的一样
%.o: %.c %.d
@echo 'start building $(notdir $@)...'
@$(CC) $(CFLAGS) $< $(INCLUDE) -o $(OBJ_DIR)$@
$(OBJ_DIR)%.d: %.c
@echo 'start building $(notdir $@)...'
@$(CC) $< $(INCLUDE) -MM -MD -o $@
# 将所有的d文件引入,作用,为了更新~
-include $(addprefix $(OBJ_DIR),$(C_DEPS))
clean:
@$(RM) $(OBJ_DIR)*
@$(RM) $(EXEC)
@clear
run:
@$(EXEC)
debug:
@echo $(C_OBJS)
@echo $(C_DEPS)
.PHONY:all clean debug run
OK,现在你可以make,然后make run看结果、、、
如果你需要这个工程,同样可以免费下载:ir_tree
from:http://blog.csdn.net/shanshanpt/article/details/17199695
Makefile 实际用例分析(二) ------- 比较通用的一种架构的更多相关文章
- Makefile 实际用例分析(一) ------- 比较通用的一种架构
这里不再说Makefile的基本知识,如果需要学习,那么请参考: 下载:makefile 中文手册 或者 点击打开链接 或者 跟我一起写Makefile( 陈皓 ) 这里说的是一般的实际的一个工程应该 ...
- Makefile 实际用例分析(三) ------- 是用GUN automake 处理自己的工程
前面两篇已经说过了自己怎么去为一个工程写makefile: 第一篇 第二篇 现在这一篇说的是怎么使用GNU的工具去写一个符合开源标准的Makefile呢! 首先我觉你应该参考: Automake Au ...
- 十、Spring之BeanFactory源码分析(二)
Spring之BeanFactory源码分析(二) 前言 在前面我们简单的分析了BeanFactory的结构,ListableBeanFactory,HierarchicalBeanFactory,A ...
- Psp个人软件开发软件需求分析和用例分析
Psp个人软件开发软件需求分析和用例分析 一.需求分析 1.业务需求 1.1 应用背景 开发项目进度计划总是那么不明确,延期经常出现,甚至无法给出一个相对比较明确的延迟时间.这样给市场的推广会带来很大 ...
- K米APP----案例分析
K米APP----案例分析 第一部分 调研,评测 第一次上手体验 软件的美工做得不错,功能排版很清楚,用户很容易上手,不至于用户不知道怎么用这个APP点歌 软件最主要的功能是KTV的点歌功能,这个功能 ...
- SNMP报文抓取与分析(二)
SNMP报文抓取与分析(二) SNMP报文抓取与分析(二) 1.SNMP报文表示简介 基本编码规则BER 标识域Tag表示 长度域length表示 2.SNMP报文详细分析(以一个get-respon ...
- Psp个人软件开发软件需求分析及用例分析
一.需求分析 1. 业务需求 1.1 应用背景 开发项目进度计划总是那么不明确,延期经常出现,甚至无法给出一个相对比较明确的延迟时间.这样给市场的推广会带来很大的影响,不确定因素使得应对十分困难. ...
- SQLite入门与分析(二)---设计与概念(续)
SQLite入门与分析(二)---设计与概念(续) 写在前面:本节讨论事务,事务是DBMS最核心的技术之一.在计算机科学史上,有三位科学家因在数据库领域的成就而获ACM图灵奖,而其中之一Jim G ...
- Linux内核启动代码分析二之开发板相关驱动程序加载分析
Linux内核启动代码分析二之开发板相关驱动程序加载分析 1 从linux开始启动的函数start_kernel开始分析,该函数位于linux-2.6.22/init/main.c start_ke ...
随机推荐
- 事件的节流(throttle)与防抖(debounce)
事件的节流(throttle)与防抖(debounce) 有些浏览器事件可以在短时间内快速触发多次,比如调整窗口大小或向下滚动页面.例如,监听页面窗口滚动事件,并且用户持续快速地向下滚动页面,那么滚动 ...
- python队列的实现
队列是一种抽象数据结构,具有以下特点: (1)具有先进先出的特性(FIFO) (2)拥有两种基本操作,即加入和删除,而且使用front和rear两个指针来分别指向队列的前端和末尾. 队列的基本操作 c ...
- illuminate/routing 源码分析之注册路由
我们知道,在 Laravel 世界里,外界传进来一个 Request 时,会被 Kernel 处理并返回给外界一个 Response.Kernel 在处理 Request 时,会调用 illumina ...
- Q-criterion- definition and post-processing
Q-criterion Table of Contents 1. Q-Criterion 1.1. Q-criterion– Hunt, Wray & Moin 1988 1.2. Q cri ...
- PAT 1125 Chain the Ropes
Given some segments of rope, you are supposed to chain them into one rope. Each time you may only fo ...
- 解决ASP.NET Core部署到IIS,更新项目"另一个程序正在使用此文件,进程无法访问"
问题:部署到IIS上的ASP.NET Core项目,在更新的时候会进程占用的错误 初步解决方案: 1,关闭应用程序池 2,关闭网站 3,更新项目 缺点:网站没法访问,部署项目停的时间过长 查询官方文档 ...
- 【Codeforces 339C】Xenia and Weights
[链接] 我是链接,点我呀:) [题意] 在天平上放砝码 你要在左边放一下然后到右边放一下 一直重复这样放m次 每次你放在其中一边都要让另外一边的重量比你少 你可以用1~10中的某些砝码 问你要怎样放 ...
- HDU 1561 树形DP背包问题
这是自己第一道背包上树形结构问题,不是很理解这个概念的可以先看看背包九讲 自己第一次做,看了一下别人的思路,结合着对简单背包问题的求解方式自己一次AC了还是有点小激动的 题目大意是: 攻克m个城市,每 ...
- P1516 青蛙的约会 洛谷
https://www.luogu.org/problem/show?pid=1516 题目描述 两只青蛙在网上相识了,它们聊得很开心,于是觉得很有必要见一面.它们很高兴地发现它们住在同一条纬度线上, ...
- Hackerrank manasa-and-combinatorics(数学推导)
题意:有n个字符A,2n个字符B,问你能用这3n个字母组成多少种字符串,使得组成的字符串所有前缀与后缀的B的数目都大于等于A的数目,对答案mod 99991 分析:类似卡特兰数 ans=总方案数-存在 ...