在Xcode中,我们写完程序直接Run编译运行,我们的IDE集成开发环境会帮我们自动编译。不用自己写编译文件,而在Linux下,我们的g++编译器,在写完程序后需要一个Makefile文件,把程序编译出来。也就是把我们的代码编译成二进制文件,程序才能运行。手写一个Makefile文件,可以从一个最基本的层面了解程序是如何跑起来的,Makefile的写法很多,我们用一种比较精简的方式,基本上所有的程序都可以这样去做。

文件结构

先看一下我们已经写好的程序源文件和借由Makefile生成的编译文件的整体目录结构。这是一个模拟深度神经网络中,输入原始图像数据和卷积核,生成图像特征的过程。即我们用图像的原始数据和卷积核的乘积计算了一次图像的特征值。程序的细节无需了解,我们重点看程序是如何通过我们制作的Makefile文件运行并跑起来的。

文件目录结构
基础篇 | 18 Linux下Makefile编译文件制作

最外层的cnn文件夹和main.cpp util.cpp util.h是我们的源程序。
Makefile是我们即将要制作的手写编译文件。
最上面的build文件夹是我们通过Makefile编译出来的文件,内部的obj文件夹内是与源程序的实现文件相对应的目标文件,而build下面的cnn你可以认为它类似于Windows下的.exe可执行文件。

软件环境:

VirtualBox虚拟机
Linux版本:LinuxMint18.2(安装于Mac下)
Vim编辑器:未安装第三方IDE,直接用Linux下比较简单的vim,也就是说,我们是直接打开命令行终端写代码的。

Makefile编译文件制作

打开控制台,cd到程序所在的文件目录LearnCNN,创建Makefile文件:vim Makefile

注意
已经创建好,想删除重新创建,在当前目录下,可以执行 rm -rf Makefile 命令,按回车键。
已经创建好,想进入文件,使用 vi Makefile ,回车即可。

如何编辑Makefile文件
同时按住 shift + i 进入编辑模式,此时,可以写编译文件了。
写完之后,按esc键,退出编辑模式。
退出Makefile: 同时按住 shift + :,输入wq,回车即可。
显示行标:同时按住 shift + :,输入set nu,回车即可。

手写编译文件内容

基础篇 | 18 Linux下Makefile编译文件制作

Makefile 语法注解
Line 1-2:include 和src 习惯上这样去做
Line 3: 构建出来的文件放到build目录里
Line 4: 中间文件放在build目录下的obj文件中
Line 11:all是标准写法,生成出来的程序叫cnn(即刚刚大家看到的可执行文件build/cnn)
Line 12-13 : clean是Linux下的命令,我们要把生成的东西删掉,即清理工作
Line 16:cnn为可执行文件,它依赖于以.o结尾的目标文件,分别是:cnn.o util.o blob.o conv.o

目标文件是xxx.o的格式,我们有四个.cpp的实现文件,所以产生四个目标文件,产生目标文件的前提是它有实现文件,而layer.h文件是纯接口文件,没有实现,所以不能产生.o文件。

后面三个.o文件是和我的.cpp文件命名一致,而cnn.o文件是哪来的?
它其实是main.cpp ,C++很自由,想干什么就干什么,但前提是你知道你在干什么。我换了个名字而已,无所谓的。

我在一步一步的写关系链,我们的程序是cnn,它依赖于cnn.o等四个目标文件,而我们的目标文件又依赖于谁呢?我们继续来写。

Line 19:cnn.o它其实是文件main.cpp,而main.cpp里我们依赖三个导入文件:/util.h /cnn/blob.h /cnn/conv.h 。Line 22、25、28 与此类似,我们分别添加入目标文件util.o blob.o conv.o 的路径和依赖,不再解释。
Line 17, 20, 26, 29: 这些是Makefile的语法,没有为什么,就这样写即可。

利用Makefile编译源程序

好了,写好Makefile,退出回到源程序目录,我们开始使用Makefile编译源程序。

整个编译过程如下:
基础篇 | 18 Linux下Makefile编译文件制作

编译使用命令注解
make clean 清除上一次的编译文件
mkdir build 创建build文件夹目录
cd build/ 进入build文件目录
mkdir obj 创建obj文件夹目录
cd .. 退回到根文件目录
make 开始执行编译

编译成功后,会看到我们的根目录下多了一个build文件夹,内部为我们的编译后的文件。

Run - 执行编译后的文件

基础篇 | 18 Linux下Makefile编译文件制作
这是一个通过输入图像原始数据和卷积核并计算它们的乘积,而后输出图像特征的过程。

至此,我们通过手写Makefile编译文件,并执行编辑、运行程序的完整过程结束。


相关文章: