makefile的发展过程
makefile工程实践回顾:
----手工编写makefile
----重构我们的makefile
----减少开发者负担,使其精力关注在软件逻辑及业务实现上,而不是底层的编译,链接细节。
----减少项目维护者负担
自动创建makefile:
----使用工具自动创建makefile
----GNU Autotools,Cmake,Scons,Ant等
----大型项目
什么是GNU Autotools?
----全称GNU‘s Not Unix(GNU不是unix的缩写)
----GNU工程:对Unix兼容的自由软件系统(free software system)
----GPL:General Public License,GNU通用公共许可证
Autotools
----系列工具包:Autoconf,Automake,Libtool
工具安装
----检测系统是否已经安装:which autoconf
----自动安装:apt install autoconf automake libtool
----需要依赖的包:m4\perl\autotools-dev\autoconf-archive\gnu-standards\autobook...
autotools自动创建makefile流程
生成makefile的通用规则文件makefile.in
1.手动编写makefile.am文件
2.#automake:将makefile.am ->makefile.in
生成配置脚本configure
1.#autoscan:生成configure.scan->configure.ac
2.修改,配置configure.ac
3.#aclocal:生成aclocal.m4,存放autoconf运行需要的宏
4.#autoconf:将configure.ac->configure
通过configure生成makefile
1.#./configure: makefile.in->makefile
2.#make;make install
Autotools发展史
手工makefile时代
----针对unix平台,手工编写makefile
----配置脚本configure的出现,用来检查系统特性,用户的一些包选项:
---随着unix发展,各分支差异越来越大
---linux的崛起,各发行版本新特性不断更新,跟unix越走越远
---平台差异相关的选项,软件包本身的一些选项
----不断发行的unix/linux版本,差异越来越大,越来越多,编写一个可移植的configure脚本更加困难。
autoconf时代
autoconf工具问世:
----1991年,Daivd Mackenzie开发了Autoconf
----用户只需要定义几个宏,配置选项即可:configure.ac
----自动检测系统平台,编译器,库的版本等
----软件版本,最终安装路径等
----剩下的工作交给autoconf,根据configure.ac->configure
autoconf工具包:
----使用perl语言编写,但生成的configure脚本是shell脚本
----autoscan
----autoheader
----autoconf
----autoreconf
automake时代
automake工具:
---用户创建makefile.am:生成目标,所需要的源文件
---使用#automake自动添加规则,生成makefile.in
---再使用#./configure,配置makefile.in->makefile
aclocal工具:
---automake再autoconf提供宏的基础上进行了扩展
---这些宏在运行#autoconf时提示未定义,出错,怎么办?
---在configure.ac同目录下面创建一个aclocal.m4文件,存放用户自动义宏,automake扩展宏
---后来aclocal工具接管了这个手工活,自动autoconf,automake,以及用户自定义宏都保存在aclocal.m4
---再运行#autoconf命令时,就直接到这里看宏定义就可以了
libtool时代
不同unix平台,共享库的编译,命名,管理方式不同:
----库的命名:so .a (windows下后缀是dll)
----有的平台支持动态加载,有的平台提供其它机制
----libtool对库进行抽象,生成.la形式,支持不同平台
libtool包:
----包含libtool和libtoolize两个工具
----使用libtool之前,先使用libtoolize,生成本地化的libtool
使用Autotools宏,变量配置flat目录的makefile
软件目录结构
flat:所有的文件都存放在同一个目录下
shallow:主程序源文件放在顶层目录中,各个模块文件放在各个子目录中
deep:所有源文件都存放在各个子目录中
makefile.am语法
主要有宏,变量组成:
---各个变量定义生成需要被编译,链接的目标,依赖源文件,要安装的目录等
---工具automake根据这些目标和源文件添加规则,生成makefile.in
少量的makefile语法,注释等:
---在makefile.am定义的makefile代码将被添加到makefile.in的合适的位置
---注释使用##表示,不会被输出到makefile.in
AM_INIT_AUTOMAKE 运行automake必需的宏
automake --add-missing
shallow目录架构的makefile
(1.静态库的生成及使用 2.各个目录makefile.am的编写 3.使用SUBDIRS进行目录递归编写)
shallow目录架构:
因为automake会生成大量的中间文件,导致污染原目录结构。因此新建一个src目录,将所有目录拷贝至到这个文件夹。
随后进行如下两步操作
修改configure.ac文件
输入如下几个命令生成configure
编写根目录makefile.am文件
编写src目录下的makefile.am,其中SUBDIRS是递归到子目录进行编译
编写模块目录下的makefile.am
进入如下操作
make install 安装程序 make uninstall 卸载程序
头文件管理及路径指定
新建inc目录,将所有的头文件移动到该目录下面
修改makefile.am,添加宏INCLUDES 链接所需头文件
删除player.c源文件的头文件的相对路
输入下面三个指令:
automake -a
./configure
make
将mp3_CFLAGS变量加入到makefile.am中
使用make dist将软件打包
使用tar xvf [文件]将文件解压
从上图可以看出,头文件并没有打包
这个时候如果./configure生成makefile,然后再使用make安装编译会生成如下错误
在inc目录下新建一个makefile.am文件
在confiugre.ac添加一个生成的文件
在src下面的makefile.am添加inc目录进行编译
使用下面这个宏就可安装头文件了
将头文件添加到依赖中,在所有的模块.c文件添加对应的头文件
指定头文件的路径
或者使用绝对路径
构建目标文件
修改lcd目录下的makefile.am,注释该两行
退出根目录,输入指令./configure生成makefile
重新make生成以下,使用tree查看生成了.o文件
修改src目录下的makefile.am文件,直接使用.o文件,不链接库文件
输入指令automake -a
因为重新生成了makefile.in 所以需要重新注释一下
输入./configure重新生成makefile
直接输入make
第二种方法就是修改lcd目录下的makefile.am。让他直接生成一个程序
主目录下输入指令automake -a
修改lcd目录下的makefile.in
./configure生成makefile,然后再make一下
使用libtool构建动态链接库
libtool简介:
---不同unix平台,共享库的编译,命名,管理方式不相同
1.库的命名:so/.a/.sa/.o
2.有的平台支持动态加载,有的平台提供其它机制,有的不提供
3.litool对库进行抽象,生成.la形式,支持不同平台
libtool包:
---包含libtool和libtoolize两个工具
---使用libtool之前,先使用libtoolize,生成本地化的libtool
使用libtool生成动态链接库
使用gcc -fPIC -o jpg.o -c jpg.c生成jpg.o
gcc -shared -o libjpg.so jpg.o生成动态库
使用libtool --help查看帮助
使用指令libtool --tag=CC --mode=compile gcc -o jpg.lo -c jpg.c生成目标文件jpg.lo
使用指令libtool --tag=CC --mode=link gcc -o libjpg.la jpg.lo链接生成库文件
libjpg.la是可以打开的,使用ls -a可以看到有一个隐藏文件夹.libs
新建一个hello文件,在该文件中调用jpg_init函数
链接生成可执行程序hello
使用指令libtool --mode=install install -c hello /usr/local/bin/安装hello程序
使用指令libtool --mode=uninstall rm /usr/local/bin/hello
libtool可以和makefile搭配起来使用
新建文件makefile.am,使用_LTLIBRARIES宏生成libtool库文件
autoscan,并重命名为configure.ac,并做如下的修改:
输入指令aclocal
输入指令autoconf
输入指令libtoolize --automake
输入指令autoheader
输入指令automake -a生成makefile.in
输入./configure生成makefile
输入make执行makefile
输入make install进行安装
查看是否安装成功
修改configure.ac,添加宏AC_PROG_LIBTOOL生成动态库文件
修改src/lcd/目录下的makefile.am文件
在src目录下修改makefile.am文件,添加宏_LDFLAGS (该宏的作用:链接选项:-l/-L/-shared/-fPIC)
退回根目录,输入以下指令
切换至路径/ect/ld.so.conf.d/目录下,打开x86_64-linux-gnu.conf
---使用ldconfig刷新官方路径
---修改inc目录下的makefile.am文件安装头文件lcd.h
使用第三方静态库和动态库
-----第三方静态库的使用:
新建video文件夹,并且在video目录下新建video.c文件
使用指令ar rcs libvideo.a video.o生成静态库
新建头文件video.h
在src目录下新建一个lib目录
将第三方静态库拷贝到lib目录下,头文件拷贝到inc目录下
在player.c里面包含该头文件,并且调用该函数
修改src目录下的makefile.am文件
修改inc目录下的makefile.am文件
重新生成 automake -a ./configure make make install
-----第三方动态库的使用:
将动态库libjpg.so安装到系统官方路径当中
修改src目录下的makefile.am
修改player.c文件,调用jpg_init函数
依次输入以下指令:
automake -a
./configure
make
make install
ldconfig
deep目录结构makefile,库的多目录构建
新建一个app目录用来存放主程序源文件player.c,并将makefile.am和player.c文件移动到该目录下,并且在src目录新建一个makefile.am
修改app目录下的makefile.am
修改根目录下的configure.ac
依次输入以下指令:
acloacl
autoconf
automake -a
./configure
make install
在src/media/目录下新建一个文件夹h264,同时在该文件夹下新建h264.c和h264.h
在h264文件夹中新建一个makefile.am文件
修改media目录下的makefile.am文件
修改根目录下的configure.ac文件
修改player.c文件
修改media.h文件
依次输入以下指令
软件打包与发布
使用make dist进行打包
打包:
--包含在自动规则下的所有文件:
所有源文件
makefile.am/Makefile.in文件
缺省的一些README.NEWS,config.h.in等文件
--不包含在自动规则下的文件:
使用EXTRA_DIST指定手动添加
指定目录,添加该目录下所有子目录,文件
指定文件,添加文件到包中
修改src目录下的makefile文件---(如果不修改lib目录下的文件是不会被打包的)
因为修改了makefile.am需要重新使用指令automake -a 和./configure 生成makefile
有时候软件的发布需要添加一些说明,readme.text文件
在根目录下新建一个doc文件夹
修改当前src目录下的makefile.am
指定某个文件是否打包
----安装目录_文件编译类型=编译目标
-在之前添加dist表示打包
-在之前添加nodist表示不打包
----示例
bin_PROGRAMS = mp3
nodist_mp3_SOURCES = player.c
修改src/inc/makefile.am文件,使lcd.h不打包
一般这些头文件都是需要打包的,所以还是需要改回来的。