从头開始写项目Makefile:统一目标输出文件夹

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了从头開始写项目Makefile:统一目标输出文件夹相关的知识,希望对你有一定的参考价值。

【版权声明:转载请保留出处: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):
>[email protected] "    Create directory [email protected] ..."
>---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) :
>[email protected] "   MKDIR $(notdir [email protected])..."
>[email protected] -p [email protected]
……
此时我们编译一下后查看build文件夹:
build/
└── unix_dbg
    ├── bin
    ├── lib
    └── obj
        ├── ipc
        ├── main
        └── tools

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


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

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



以上是关于从头開始写项目Makefile:统一目标输出文件夹的主要内容,如果未能解决你的问题,请参考以下文章

从头開始写项目Makefile:变量的使用

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

[Golang] 从零開始写Socket Server:将执行參数放入配置文件(XML/YAML)

[Golang] 从零開始写Socket Server: 自己定义通讯协议

表单验证(登录/注冊)

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