【版权声明:转载请保留出处:blog.csdn.net/gentleliu。

Mail:shallnew at 163 dot com】

    上一节我们把规则单独提取出来,方便了Makefile的维护,每一个模块仅仅须要给出关于自己的一些变量,然后再使用统一的规则Makefile。这一节我们继续改进我们的Makefile,到眼下为止我们的Makefile编译链接输出的目标都在源文件同文件夹下或模块Makefile同一文件夹下。当一个项目大了之后,这样会显得非常乱,寻找编译输出的文件也比較困难。

既然Makefile本身就是依照我们的的规则来编译链接程序,那么我们就能够指定其编译链接目标的文件夹。这样。我们能够清楚输出文件的地方,而且在清除已编译的目标时直接删除指定文件夹就可以。不须要一层一层的进入源码文件夹进行删除。这样又提高了效率。

    既然要统一目标输出文件夹,那么该文件夹就须要存在。所以我们能够添加一条规则来创建这些文件夹。包含创建可运行文件的文件夹、链接库文件的文件夹以及.o文件的文件夹。而且文件夹还能够通过条件推断依据是否产生调试信息来区分开对应的目标文件。

一般一个project的顶层文件夹下都会有一个build文件夹来存放编译的目标文件结果,眼下我的project文件夹下通过Makefile创建的文件夹build的文件夹树例如以下:

build/            //build根文件夹
├── unix //unix平台项目下不带调试信息输出文件夹
│ ├── bin //存放可运行文件文件夹
│ ├── lib //存放可文件文件夹
│ └── obj //存放.o文件文件夹,该文件夹下将每一个模块生成的.o文件各自的文件夹以下
│ ├── ipc
│ ├── main
│ └── tools
└── unix_dbg ////unix平台项目下带调试信息输出文件夹
├── bin
├── lib
└── obj
├── ipc
├── main
└── tools 14 directories, 0 files

以上文件夹中bin和lib文件夹在顶层Makefile中创建,obj及其以下模块子文件夹在各模块的Makefile里面创建。

顶层Makefile创建文件夹例如以下:

ifeq ($(DEBUG_SYMBOLS), TRUE)
>---BUILDDIR = ./build/$(PLATFORM)_dbg
else
>---BUILDDIR = ./build/$(PLATFORM)
endif all : $(BUILDDIR) $(MODULES) $(BUILDDIR):
>---@echo " Create directory $@ ..."
>---mkdir -p $(BUILDDIR)/bin $(BUILDDIR)/lib

我们在all目标里面添加了其依赖目标BUILDDIR。该目标相应的规则为创建bin文件夹和lib文件夹。这样每次编译之前都会创建文件夹。



各模块内部Makefile创建生成.O文件的文件夹。如上文件夹树所看到的。

类似于顶层Makefile,各模块内部Makefile须要依据平台、编译调试信息、以及模块名称来生成须要的文件夹名称,然后再添加创建该文件夹的规则。

由于每一个模块都会做这些处理。所以我们将这部分写在规则Makefile(Makefile.rule)里面。例如以下:

……
# define a root build directory base on the platform
# if without a SRC_BASE defined, just use local src directory
ifeq ($(SRC_BASE),)
>---BUILDDIR = $(MOD_SRC_DIR)
>---OBJDIR = $(MOD_SRC_DIR)
>---LIBDIR = $(MOD_SRC_DIR)
>---BINDIR = $(MOD_SRC_DIR)
else
>---ifeq ($(DEBUG_SYMBOLS), TRUE)
>--->---BUILDDIR = $(SRC_BASE)/build/$(PLATFORM)_dbg
>---else
>--->---BUILDDIR = $(SRC_BASE)/build/$(PLATFORM)
>---endif
>---OBJDIR = $(BUILDDIR)/obj/$(MODULE)
>---LIBDIR = $(BUILDDIR)/lib
>---BINDIR = $(BUILDDIR)/bin
endif
……
ifeq ($(MAKELEVEL), 0)
all : msg
else
all : lib bin
endif lib : $(OBJDIR) $(SRC_LIB) bin : $(OBJDIR) $(SRC_BIN) $(OBJDIR) :
>---@echo " MKDIR $(notdir $@)..."
>---@mkdir -p $@
……

此时我们编译一下后查看build文件夹:

build/
└── unix_dbg
├── bin
├── lib
└── obj
├── ipc
├── main
└── tools 7 directories, 0 files

因为我们是开启了调试信息,所以创建了unix_dbg文件夹,而且该文件夹下创建了bin、lib、obj文件夹及其模块文件夹,但我们没有发现有文件存放在里面。

到眼下为止,这一节只讲述怎样创建统一的目标文件存放文件夹。可是要想将编译生成的目标文件自己主动生成到这些文件夹还没有完毕。

事实上我们只须要给目标加上路径就可以,但还是有一些具体的地方须要处理,具体的我们会在下一节中讲到,这一节暂不给出最后的Makefile。

从头開始写项目Makefile(七):统一目标输出文件夹的更多相关文章

  1. 从头開始写项目Makefile(十):make内嵌函数及make命令显示

    [版权声明:转载请保留出处:blog.csdn.net/gentleliu.Mail:shallnew at 163 dot com]     这一节我们讲一下make的函数,在之前的章节已经讲到了几 ...

  2. 从头開始写项目Makefile(五):嵌套运行

    [版权声明:转载请保留出处:blog.csdn.net/gentleliu.Mail:shallnew at 163 dot com] 在大一些的项目里面,全部源码不会仅仅放在同一个文件夹,一般各个功 ...

  3. 从零開始写游戏引擎(一) - project创建以及文件夹设置还有版本号控制

    一句话提要 好的開始等于成功了一半. 创建文件夹结构 project文件夹下最好分为以下几个文件夹 Docs - 开发文档,设计文档 Assets - 角色,动作,模型和音效等 Source - 代码 ...

  4. 从0開始写MyScrollView

    从0開始写MyScrollView 上篇文章对ScrollView的详细实现进行了分析.本文依据上篇分析的结果.自己动手写一个ScrollView. step1 尾随手指滑动,非常easy.重写2个函 ...

  5. [php learn] php 从头開始学习1

    前言:大概在2006年的时候,学习过一段时间的php.而且当时做了一个下载的站点,后来因为读研究生阶段用的是java.j2ee相关,所以php就搁浅掉了,php这些年也发生了非常大的变化,最大一个变化 ...

  6. 项目工程的包package与文件夹的关系

    项目工程的包package与文件夹的关系: 1. 包名与文件夹是分层关系,包名只是一个字符串而已,包名.对应的是层级的文件夹. 如,com.Immoc.Access包,只是一个字符串.但他对应的win ...

  7. SQL从头開始

    SQL 分为两个部分:数据操作语言 (DML) 和 数据定义语言 (DDL) 查询和更新指令构成了 SQL 的 DML 部分: SELECT - 从数据库表中获取数据 UPDATE - 更新数据库表中 ...

  8. [Golang] 从零開始写Socket Server(3): 对长、短连接的处理策略(模拟心跳)

    通过前两章,我们成功是写出了一套凑合能用的Server和Client,并在二者之间实现了通过协议交流.这么一来,一个简易的socket通讯框架已经初具雏形了,那么我们接下来做的.就是想办法让这个框架更 ...

  9. 从头開始学 RecyclerView(六) LayoutManager

    前言 在前面的文章中.每一个演示样例,都使用了LayoutManager,毕竟它是RecyclerView必不可少的一部分. LayoutManager,顾名思义,就是『布局管理器』. 使用例如以下代 ...

随机推荐

  1. php部分学习笔记

    [web 开发分为]1. 静态web 开发(html 页面) 如果我们的一个页面,始终是一成不变的,则就是属于静态web 开发,一般讲用html 技术就ok2. 动态web 开发 比如: 我们需要发帖 ...

  2. C#学习日志 day 6 ------ 常用正则表达式例举

    c#支持正则表达式匹配文本,这里讨论一下正则表达式的使用方法以及例举一些常用的正则表达式的匹配. 1.在vs中使用正则表达式 在vs中使用正则表达式,需要using System.Text.Regul ...

  3. QT连接mysql中文显示问题

    亲测OK! #vim /etc/mysql/my.cnf [mysqld]下面加入: default-character-set=utf8 重启mysql /etc/init.d/mysql rest ...

  4. [方法] ubuntu12.04开启root账户

    ubuntu 12.04使用LightDM显示管理器,默认禁止root账户登录. 通过修改/etc/lightdm/lightdm.con文件可以打开root登录权限. 方法很简单,只要在lightd ...

  5. InputStream、OutputStream、String的相互转换(转)

    //1.字符串转inputStream String string; //...... InputStream is = new ByteArrayInputStream(string.getByte ...

  6. opencv 图像修复函数

    void cv::inpaint( const Mat& src, const Mat& mask, Mat& dst, double inpaintRange, int fl ...

  7. Lua学习2 Lua小框架的搭建

    看了上一篇Lua环境搭建具体http://blog.csdn.net/liuwumiyuhuiping/article/details/9196435 为了方便学习. 具体新开始搭建一下学习的小框架. ...

  8. ubuntu13.04安装SenchaArchitect-2.2无法启动的问题

    系统是ubuntukylin-13.04-desktop版本,不知道别的版本有没有这个问题,未测试.SenchaArchitect采用最新版本2.2.2,我安装的是32位的. 具体无法启动的问题如下: ...

  9. golang 之 defer(统计函数执行时间)

    package main import ( "fmt" "time" ) func sum(a ...int) int { defer trace(" ...

  10. Ninject简介(转)

    1.为什么要用Ninject? Ninject是一个IOC容器用来解决程序中组件的耦合问题,它的目的在于做到最少配置.其他的的IOC工具过于依赖配置文件,需要使用assembly-qualified名 ...