目录
AutoTools
1.简介
- Autotools是一个代码打包和发布工具,它包含很多工具,比如说:
- autoconf:一个工具,从configure.ac文件生成configure脚本
- automake:一个工具,从Makefile.am文件生成Makefile.in文件
- aclocal
- autoheader:扫描configure.ac文件,生成config.h.in文件
- autoscan:一个工具,用于扫描源码生成configure.scan文件,这是configure.ac的雏形文件
- 因此在项目中使用autotools,则需要编写
configure.ac
、Makefile.am
两个文件。
2.configure.ac文件编写规则
vscode编写Makefile.am、configure.ac,代码高亮插件:autoconf
- 常见宏:
- AC_PREREQ:声明要求autoconf工具的版本号
- AC_INIT:定义软件包名称、版本号、联系方式
AC_INIT([软件包名称], [版本号], [联系方式])
- AC_CONFIG_HEADERS:通常在AC_INIT之后调用,用来生成config.h头文件
AC_CONFIG_HEADERS([config.h])
- AM_INIT_AUTOMAKE:指定在Makefile.am中可用的Automake选项
- AC_MSG_ERROR:通知用户错误,例如:
AC_MSG_ERROR(libpthread not found !)
- AC_PROG_CC:可用于检查系统下是否存在C编译器
- AC_PROG_CXX:可用于检查系统下是否存在C++编译器
- AM_PROG_AS:可用于检查系统下是否存在汇编器
- AC_PROG_MAKE_SET:可用于检查make工具是否定义了变量
$MAKE
- AC_PROG_INSTALL:设置输出变量install的值
- AC_SUBST:设置变量的值,语法为
AC_SUBST (variable, [value])
,在configure.ac文件中定义好变量以后,可以在Makefile.am中使用,使用语法为@变量名@
# 定义变量表示美元符号 AC_SUBST([DOLLAR_SIGN],[$]) # 定义变量表示百分比符号 AC_SUBST([PERCENT_SIGN],[%])
- AC_MSG_WARN:提示可能出现的问题,不影响configure的继续运行
- AC_PATH_PROG:检查某个应用程序是否在path环境变量下
- AC_HEADER_STDBOOL:检查stdbool.h是否存在,是否符合 C99 或更高版本的标准。然后将检查的结果保存到ac_cv_header_stdbool_h变量
- AC_HAVE_LIBRARY:检查指定库是否存在
# 语法为 AC_HAVE_LIBRARY (library, [action-if-found], [Macro] [action-if-not-found], [other-libraries]) # 示例:pthread存在则定义LIBS变量 AC_HAVE_LIBRARY(pthread, LIBS="${LIBS} -lpthread", AC_MSG_ERROR(libpthread not found !)) AC_SUBST(LIBS)
- AC_CONFIG_FILES:使用示例
AC_CONFIG_FILES([Makefile src/Makefile man/Makefile X/Imakefile])
- AC_OUTPUT:每一个configure.ac文件应当以AC_OUTPUT结尾
- 预定义变量:在configure.ac文件中使用变量的语法是${预定义变量名}
- CXXFLAGS:指定C++编译器的调试和优化选项。示例如下
// -Werror表示显示错误信息 // -O2开启优化等级2 CXXFLAGS="-Werror -O2 -Wno-deprecated -pipe -Wall -Wno-strict-aliasing ${CXXFLAGS} -DNRUNTIME -D_GNU_SOURCE -D_REENTRANT -DBUILDTIME=`date +%s` -std=c++17 -rdynamic"
- CFLAGS:指定C编译器的调试和优化选项
- LDFLAGS:链接器的选项
- LIBS:-l options to pass to the linker.
3.Makefile.am文件编写规则
1.常用的变量
- SUBDIRS:SUBDIRS is a special variable listing all directories that make should recurse into before processing the current directory。这个变量一般在项目顶层的Makefile.am文件中定义。
- 以
_PROGRAMS
结尾的变量:指定编译生成的程序名称- 例如bin_PROGRAMS:表示需要将编译生成的程序安装进bindir
- noinst_PROGRAMS:只编译生成目标程序但不进行安装
- lib_LIBRARIES:其值为构建链接库的名称,构建好的库会安装到lib目录
- lib_LTLIBRARIES:使用libtool工具构建库,其值为库的名称,构建好的库会安装到lib目录
- noinst_LTLIBRARIES:使用libtool工具构建库,其值为库的名称,构建好的库不会安装到lib目录
- 以dist_为前缀的变量:将列出的文件添加到发行版本中
- 以nodist_为前缀的变量:从发行版本中忽略文件
- xxx_SOURCES:构建目标xxx需要的源文件,目标可能是库也可能是应用程序。这些源文件都会添加到发行版本中
- nodist_xxx_sources:参与构建目标xxx的源文件,不添加到发行版本中
- xxx_LDADD:添加其他编译生成的目标文件(例如后缀名为.o的文件)或者库到应用程序中
- xxx_LIBADD:添加其他编译后的目标文件(如后缀名为.o的文件)到库中
- xxx_CPPFLAGS:指定传递给预处理器的选项
- xxx_CFLAGS:指定C编译器的调试和优化选项
- xxx_CXXFLAGS:指定C++编译器的调试和优化选项
- xxx_LDFLAGS:链接时,给链接器传递的选项
- include_HEADERS:构建目标的头文件,这些头文件会安装到include目录
- AM_CPPFLAGS:指定传递给预处理器的选项,比如说-I和-D
- AM_CXXFLAGS:指定传递给c++编译器的选项
- top_srcdir:源码的顶层目录
4.案例
1.示例1
- 现有一个小demo autools_test,项目目录如下:
root@hecs-205584:~/autools_test# tree
.
├── AUTHORS
├── ChangeLog
├── func.cpp
├── func.h
├── main.cpp
├── NEWS
└── README
- 使用autotools进行项目的构建流程如下(了解):
- 执行autoscan对源码文件进行扫描,生成configure.scan和autoscan.log文件。configure.scan文件如下
# -*- Autoconf -*- # Process this file with autoconf to produce a configure script. # autoconf的版本要求 AC_PREREQ([2.71]) AC_INIT([FULL-PACKAGE-NAME], [VERSION], [BUG-REPORT-ADDRESS]) AC_CONFIG_SRCDIR([func.cpp]) AC_CONFIG_HEADERS([config.h]) # Checks for programs. AC_PROG_CXX AC_PROG_CC # Checks for libraries. # Checks for header files. # Checks for typedefs, structures, and compiler characteristics. # Checks for library functions. AC_OUTPUT
- 将configure.scan文件进行重命名
mv configure.scan configure.ac
- 编辑configure.ac文件
# Process this file with autoconf to produce a configure script. AC_PREREQ([2.71]) AC_INIT([AutoToolsTest], [0.1.0], [[email protected]]) AC_CONFIG_SRCDIR([func.cpp]) AC_CONFIG_HEADERS([config.h]) AM_INIT_AUTOMAKE() # Checks for programs. AC_PROG_CXX AC_PROG_CC # Checks for libraries. # Checks for header files. # Checks for typedefs, structures, and compiler characteristics. # Checks for library functions. AC_CONFIG_FILES([Makefile]) AC_OUTPUT
- 执行aclocal,将生成aclocal.m4文件、autom4te.cache目录。这个命令依赖configure.ac文件
- 执行aotoheader,生成config.h.in文件。这个命令依赖configure.ac文件和aclocal.m4文件
- 在项目目录下创建Makefile.am文件,编辑Makefile.am文件
# 指定可执行程序名称 bin_PROGRAMS = autotools_test autotools_test_SOURCES = main.cpp func.cpp
- 执行autoconf,生成configure脚本。这个命令依赖configure.ac文件和aclocal.m4文件
- 执行
automake -a
生成Makefile.in文件,这个命令依赖Makefile.am文件 - 执行
./configure
生成Makefile,这个脚本依赖Makefile.in和config.h.in文件 - 执行
make
,编译生成可执行程序autotools_test。这个命令依赖Makefile文件 - 运行可执行程序:
./autotools_test
- 实际项目中,在项目根目录下创建一个脚本,比如说
autogen.sh
。项目根目录下执行sh autogen.sh
就可以生成可执行程序。
# /bin/sh
# --force表示replace existing files
# --automake表示libtool和automake一起使用,有了这个选项,会将libtoolize产生的一些结果放到其他文件中
libtoolize --force --automake
# 删除不必要的输出文件...
rm -f config.log
aclocal
autoheader
autoconf
automake -a
./configure
make -j 4
Libtool
1.简介
- 为构建动态库、静态库提供了统一的方式。
- 使用Libtool工具构建的库名称一般以
la
结尾
2.常用参数
- -avoid-version:编译生成库的时候不存储版本信息
- -module:创建一个库,这个库可以调用
dlopen
来打开 - AM_PROG_LIBTOOL:用于打开共享库