(6)autotools工具的使用
autotools是专门用来生成Makefile的一系列工具,包括autoscan、aclocal、autoheader、autoconf、automake等。
(1)autotools解决了什么问题
在大型项目中,使用手写Makefile时,可能会很复杂并难以维护;
在不同的编译环境,由于参数不同,需要手写不同的Makefile,增加了工作量;
由于Makefile有一些复杂的参数,手写Makefil可能会不符合规范;
autotools工具能够帮助开发人员简单而快捷地生成Makefile,完成各种复杂工程地编译和链接。
(2)autotools生成Makefile的流程

. 源码根目录调用autoscan脚本,生成configure.scan文件,然后将此文件重命名为configure.ac(或configure.in,早期使用.in后缀);
. 修改【configure.ac】,利用autoconf提供的各种M4宏,配置项目需要的各种自动化探测项目;
. 编写【自定义宏】,建议每个宏一个单独的*.m4文件;
. 调用aclocal收集configure.ac中用到的各种非Autoconf的宏,包括自定义宏;
. 调用autoheader,扫描configure.ac(configure.in)、acconfig.h(如果存在),生成config.h.in宏定义文件,里面主要是根据configure.ac中
某些特定宏(如AC_DEFINE)生成的#define和#undefine宏,configure在将根据实际的探测结果决定这些宏是否定义(具体见后面例子)。
. 按照automake规定的规则和项目的目录结构,编写一个或多个【Makefile.am】(Makefile.am数目和存放位置和源码目录结构相关),Makefile.am主要写的
就是编译的目标及其源码组成。
. 调用automake,将每个Makefile.am转化成Makefile.in,同时生成满足GNU编码规范的一系列文件(带-a选项自动添加缺少的文件,但有几个仍需要自己添加,
在执行automake前需执行touch NEWS README AUTHORS ChangeLog)。如果configure.ac配置了使用libtool(定义了AC_PROG_LIBTOOL宏(老版本)或
LT_INIT宏),需要在此步骤前先在项目根目录执行libtoolize --automake --copy --force,以生成ltmain.sh,供automake和config.status调用。
. 调用autoconf,利用M4解析configure.ac,生成shell脚本configure。以上几步完成后,开发者的工作就算完成了,后面的定制就由开源软件的用户根
据需要给configure输入不同的参数来完成。
. 用户调用configure,生成Makefile,然后make && make install。
autotools系列工具简单操作示例如下:
现有test文件夹存在如下文件:
//test
calc_test.h
calc_test.cpp
make_test.h
make_test.cpp
main.cpp
步骤一:在test目录同级目录下执行autoscan test 或者 在test目录下执行autoscan

步骤二:更改生成的configure.scan 为configure.ac,编辑并修改为以下内容(标粗的是新添加或者修改的内容)
# -*- Autoconf -*-
# Process this file with autoconf to produce a configure script. AC_PREREQ([2.69])
AC_INIT([autotest], [1.0], [BUG-REPORT-ADDRESS])
AM_INIT_AUTOMAKE([foreign -Wall -Werror])
AC_CONFIG_SRCDIR([calc_test.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_CONFIG_FILES([Makefile])
AC_OUTPUT
步骤三:依此执行aclocal命令、autoheader、autoconf命令,生成configure文件
步骤四:新建Makefile.am命令
bin_PROGRAMS = autotest
autotest_SOURCES = calc_test.h \
calc_test.cpp \
make_test.cpp \
main.cpp
autotest_LDADD =
autotest_LDFLAGS =
autotest_CFLAGS = -g
步骤五:执行automake --add-missing

步骤六:执行./configure命令生成Makefile


(3)autotool参数详解
1)configure.scan的参数
| 标签名 | 说明 |
| AC_PREREQ | 声明autoconf要求的版本号 |
| AC_INIT | 定义软件名称、版本号、联系方式 |
| AM_INIT_AUTOMAKE | 必须要的,指定编译参数 |
| AC_CONFIG_SRCDIR | 用来侦测所指定的源码文件是否存在, 来确定源码目录的有效性 |
| AC_CONFIG_HEADER | 指定产生的配置文件名称(一般是config.h),用于生成config.h文件,以便 autoheader 命令使用 |
| AC_PROG_CC | 用以探测当前系统的C编译器 |
| AC_PROG_RANLIB | 用于生成静态库 |
| AC_PROG_LIBTOOL | 用于生成动态库 |
| AM_PROG_AR | 生成静态库时使用,用于指定打包工具,一般指ar |
| AC_CONFIG_FILES | 告知autoconf本工程生成哪些相应的Makefile文件,不同文件夹下的Makefile通过空格分隔 |
| AC_OUTPUT | 最后一个必须的宏,用以输出需要产生的文件 |
| AC_PROG_CXX | 用于探测系统的c++编译器 |
| AC_CHECK_LIB | 探测工程中出现的库文件及库文件中的方法 |
2)Makefile.am的参数
| include_HEADERS | 标明哪些头文件将在执行make install命令之后被安装到系统include目录下 |
| bin_PROGRAMS | 生成的目标库文件名,如果有多个,用空格隔开,与configure.ac中AC_INIT对应库名对应 |
| XXX_SOURLDADDCES | 编译XXX库需要哪些源文件,使用相对路径 |
| XXX_LDADD | 指定要链接的静态库名称 |
| LIBS | 指定要链接的动态库名称 |
| INCLUDE | 一般指定要使用的头文件所在路径 |
| AUTOMAKE_OPTIONS |
设置automake的选项,automake提供了三种软件等级:foreign、gnu和gnits,当当前库文件编译所需源文件不在当前目录时要设置参数subdir-objects |
| XXX_CPPFLAGS | 预处理器选项,编译选项,一般用来指定所需要头文件目录 |
| noinst_LIBRARIES | 指定生成的静态库名称,当前目录下源码及头文件最终生成的目标文件名 |
| AM_V_AR | 指定把目标打包成静态库,使用ar命令 |
| RANLIB | 指定为静态库创建索引,使用ranlib |
(4)autotools使用范例
1)单个Makefile.am生成多个库文件
现test文件夹下有如下文件
//用于生成 make_test 动态库
calc_test.h
calc_test.cpp
make_test.h
make_test.cpp
main.cpp
//用于生成 tiny_test 动态库
tinyxml2_main.cpp
tinyxml2.h //在/usr/include/tinyxml2路径下
tinyxml2.cpp //在/usr/include/tinyxml2路径下
使用autoscan生成configure.in,并改名为configure.ac,修改添加参数后如下:
# -*- Autoconf -*-
# Process this file with autoconf to produce a configure script. AC_PREREQ([2.69])
AC_INIT([make_test tiny_test], [1.0 1.0], [1577429698@qq.com])
AC_CONFIG_SRCDIR([calc_test.cpp])
AC_CONFIG_SRCDIR([../../../usr/include/tinyxml2/tinyxml2.cpp])
AM_INIT_AUTOMAKE([foreign -Wall -Werror])
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_CONFIG_FILES([Makefile])
AC_OUTPUT
Makefile.am书写如下:
#include_HEADERS = /usr/include/tinyxml2/tinyxml2.h
bin_PROGRAMS = make_test tiny_test
AUTOMAKE_OPTIONS = subdir-objects
#INCLUDE = -l/usr/include/tinyxml2/
make_test_SOURCES = calc_test.h \
calc_test.cpp \
make_test.cpp \
main.cpp
tiny_test_SOURCES = tinyxml2_main.cpp \
tinyxml2.h \
../../../usr/include/tinyxml2/tinyxml2.cpp
make_test_LDADD =
make_test_LDFLAGS =
make_test_CFLAGS = -g #-I/usr/include/tinyxml2/
2)多级源码路径多个Makefile.am生成多个库文件(包含动态库及静态库使用)
参考https://blog.csdn.net/zhengqijun_/article/details/70105077
在test目录下,make_test子目录将单独生成一个动态库make_test,tinyxml子目录单独生成一个静态库tinyxml2,test本身目录引用tinyxml目录生成的静态库和自身文件再生成一个动态库tiny_test;
make_test及tinyxml子目录下各自有的configure.ac文件和Makefile.am文件配合在一起单独使用,生成相应库;make_test及tinyxml目录下Makefile.am文件和test根目录下Makefile.am及总configure.ac文件配合在一起也可组合生成三个库。
1.文件树状图:

2.文件内容:
2.1 tinyxml2_main.cpp
#include <iostream>
//必须写相对路径
#include "tinyxml/tinyxml2.h"
using namespace std;
using namespace tinyxml2; int main(int argv,char *argc[])
{
XMLDocument xmlDoc;
xmlDoc.LoadFile("test.xml");
int errorID = xmlDoc.ErrorID();
if(errorID)
{
cout<<"Load xml test.xml fail!"<<endl;
return -;
}
cout<<"Load xml test.xml success!"<<endl;
XMLElement *pRootElement = xmlDoc.RootElement();
const char * name = pRootElement->FirstChildElement("name")->GetText();
cout<<"name = "<<name<<endl;
return ;
}
2.2 configure.ac
# -*- Autoconf -*-
# Process this file with autoconf to produce a configure script. AC_PREREQ([2.69])
AC_INIT([tiny_test], [1.0], [1577429698@qq.com])
AC_CONFIG_SRCDIR([tinyxml2_main.cpp])
AC_CONFIG_SRCDIR([make_test/calc_test.cpp])
AC_CONFIG_SRCDIR([tinyxml/tinyxml2.cpp])
AM_INIT_AUTOMAKE([foreign -Wall -Werror]) AC_CONFIG_HEADERS([config.h]) # Checks for programs.
AC_PROG_CXX
AC_PROG_CC
AC_PROG_RANLIB
AM_PROG_AR([ar])
# Checks for libraries. # Checks for header files.
AC_CHECK_HEADERS([limits.h stddef.h stdint.h stdlib.h string.h]) # Checks for typedefs, structures, and compiler characteristics.
AC_CHECK_HEADER_STDBOOL
AC_C_INLINE
AC_TYPE_INT64_T
AC_TYPE_SIZE_T
AC_CHECK_TYPES([ptrdiff_t]) # Checks for library functions.
AC_CHECK_FUNCS([memset strchr]) AC_CONFIG_FILES([Makefile
make_test/Makefile
tinyxml/Makefile])
AC_CONFIG_SUBDIRS([make_test
tinyxml])
2.3 Makefile.am
AUTOMAKE_OPTIONS = foreign
SUBDIRS = tinyxml make_test
bin_PROGRAMS = tiny_test
tiny_test_SOURCES = tinyxml2_main.cpp
#INCLUDE = -I ./tinyxml
#静态库连接
#tiny_tes_CFLAGS = -I ./tinyxml
tiny_test_LDADD = tinyxml/libtinyxml2.a #动态库连接
2.4 make_test/Makefile.am
bin_PROGRAMS = make_test
make_test_SOURCES = calc_test.h \
calc_test.cpp \
make_test.h \
make_test.cpp \
main.cpp
make_test_LDADD =
make_test_LDFLAGS =
make_test_CFLAGS = -g
2.5 make_test/configure.ac
# -*- Autoconf -*-
# Process this file with autoconf to produce a configure script. AC_PREREQ([2.69])
AC_INIT([make_test], [1.0], [@qq.com])
AM_INIT_AUTOMAKE([foreign -Wall -Werror])
AC_CONFIG_SRCDIR([calc_test.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_CONFIG_FILES([Makefile])
AC_OUTPUT
2.6 make_test/calc_test.h
#ifndef _CALC_TEST_H_
#define _CALC_TEST_H_
namespace test
{ int add(int a,int b); }
#endif
2.7 make_test/clac_test.cpp
#include "calc_test.h"
namespace test
{
int add(int a,int b)
{
return a + b ;
}
}
2.8 make_test/make_test.h
#ifndef _MAKE_TEST_
#define _MAKE_TEST_
#include <iostream>
namespace test
{
class MakeTest
{
public:
void run();
};
}
2.9 make_test/make_test.cpp
#include "make_test.h"
#include "calc_test.h"
namespace test
{
void MakeTest::run()
{
int a = ;
int b = ;
std::cout<<test::add(a,b)<<std::endl;
}
}
2.10 make_test/main.cpp
#include <iostream>
#include "string.h"
#include "make_test.h" using namespace std; int main()
{
test::MakeTest makeTest;// = new MakeTest();
makeTest.run();
return ;
}
2.11 tinyxml/Makefile.am
noinst_LIBRARIES = libtinyxml2.a
libtinyxml2_a_SOURCES = tinyxml2.h tinyxml2.cpp
#AM_V_AR = ar
RANLIB = ranlib
2.12 tinyxml/configure.ac
# -*- Autoconf -*-
# Process this file with autoconf to produce a configure script. AC_PREREQ([2.69])
AC_INIT([tinyxml2], [1.0], [1577429698])
AM_INIT_AUTOMAKE([foreign -Wall -Werror])
AC_CONFIG_SRCDIR([tinyxml2.cpp])
AC_CONFIG_HEADERS([config.h]) # Checks for programs.
AC_PROG_CXX
AC_PROG_CC
AC_PROG_RANLIB
AM_PROG_AR([ar]) # Checks for libraries. # Checks for header files.
AC_CHECK_HEADERS([limits.h stddef.h stdint.h stdlib.h string.h]) # Checks for typedefs, structures, and compiler characteristics.
AC_CHECK_HEADER_STDBOOL
AC_C_INLINE
AC_TYPE_INT64_T
AC_TYPE_SIZE_T
AC_CHECK_TYPES([ptrdiff_t]) # Checks for library functions.
AC_CHECK_FUNCS([memset strchr]) AC_CONFIG_FILES([Makefile])
AC_OUTPUT
configure.ac文件均是由autoscan命令生成的configure.scan修改改名而来;在前面文件创建、均被完毕之后,执行以下命令:
aclocal
autoconf
autoheader
automake --add-missing
./configure
make
结果如下:

(6)autotools工具的使用的更多相关文章
- automake - 使用 autotools 工具集
一般而言,对于小项目或玩具程序,手动编写 Makefile 即可.但对于大型项目,手动编写维护 Makefile 成为一件费时费力的无聊工作. 本文介绍 autotools 工具集自动生成符合 Lin ...
- 使用autotools工具用configure、make、make install编译安装linux工程的详细步骤
使用autotools工具用configure.make.make install编译安装linux工程的详细步骤 转载tmxkwzy 最后发布于2016-11-24 10:20:15 阅读数 324 ...
- autotools工具使用记录
参考 http://blog.chinaunix.net/uid-25100840-id-271131.html http://blog.sina.com.cn/s/blog_4c2bf01a0101 ...
- autotools工具使用 good
学习GNU/LINUX开发的编程人员,上手之后不久就会在编译开源软件的时候碰到configure脚本,过段时间还会知道configure脚本是 autoconf生成的:但是真正想用起来autoconf ...
- 利用autotools工具制作从源代码安装的软件 分类: linux 2014-06-02 23:27 340人阅读 评论(0) 收藏
编写程序(helloworld.c)并将其放到一个单独目录. helloworld.c: #include<stdio.h> int main() { printf("hello ...
- 在 Linux 中使用 Eclipse 和 Gnu Autotools 管理 C/C++ 项目
在我该系列的之前的所有随笔中,都是采用 Linux 发行版自带的包管理工具(如 apt-get.yum 等)进行软件的安装和卸载,从来没有向大家展示使用源代码自行编译安装软件的方法.但是长期混迹于 U ...
- linux下使用automake工具自动生成makefile文件
linux环境下,当项目工程很大的时候,编译的过程很复杂,所以需要使用make工具,自动进行编译安装,但是手写makefile文件比较复杂,所幸在GNU的计划中,设计出了一种叫做Autoconf/Au ...
- GNU Autotools的研究(转)
最近对Linux下软件项目的构建过程研究了一番.Linux下的软件项目通常用Autotools工具集和make工具来构建,我们通常使用./configure.make.make install这样的命 ...
- 如何使用autotools生成Makefile
安装autotools工具sudo apt-get install autoconf 一,四个代码文件init.s lcd.c addr.h uart.c 二,命令:autoscan 三,命令:vi ...
随机推荐
- 简易数据分析 11 | Web Scraper 抓取表格数据
这是简易数据分析系列的第 11 篇文章. 今天我们讲讲如何抓取网页表格里的数据.首先我们分析一下,网页里的经典表格是怎么构成的. First Name 所在的行比较特殊,是一个表格的表头,表示信息分类 ...
- Leetcode之回溯法专题-216. 组合总和 III(Combination Sum III)
Leetcode之回溯法专题-216. 组合总和 III(Combination Sum III) 同类题目: Leetcode之回溯法专题-39. 组合总数(Combination Sum) Lee ...
- Java中集合的概述
一.集合和数组的区别 1.数组(可以存储基本数据类型)是用来存现对象的一种容器,但是数组的长度固定,不适合在对象数量未知的情况下使用. 2.集合(只能存储对象,对象类型可以不一样)的长度可变,可在多数 ...
- 重识 ArrayList
前言 ArrayList 作为 Java 集合框架中最常用的类,在一般情况下,用它存储集合数据最适合不过.知其然知其所以然,为了能更好地认识和使用 ArrayList,本文将从下面几方面深入理解 Ar ...
- KVC&KVO&运行时
运行时:要先了解程序运行的三个阶段 1.编译阶段:clang将OC代码转换成C++,查看运行机制调用的方法 2.链接阶段:与我们使用到得库文件进行链接 3.运行阶段:我们要谈的运行时主要针对这个阶段, ...
- CodeForces - 697D - Puzzles DFS
传送门:D - Puzzles 题意:在一个图中,从1开始dfs,求每一个点到达的期望: 思路:(下面是队长写的) 首先求的是到每一个点的步数的期望. 记fa( u ) = v, son( v )表示 ...
- git 生成密钥
1.本地安装好git: 2.桌面右键 Git Bash Here 打开git命令行: 3.ssh-keygen -t rsa -C "nideyouxiang@xxx.com" ...
- 题解 洛谷P1071【潜伏者】
题目链接:https://www.luogu.org/problem/P1071 题意概括:给你一段原来截获的英文密码和与之对应的明文,如果密码表非F♂A法,输出"Failed" ...
- 通过脚本实现将服务器的Log实时传送到Telegram群组
首先说下需求,IT老大提出的一个需求,实现将php-laravel的应用日志实时传送到telegram的监控群组中,不用登陆服务器就可以实时查看应用的日志. 具体思路是: 先要将日志切割,并实时更新这 ...
- javascript 中 typeof 和 instanceof 的区别
在 javascript 中经常会用到 typeof 和 instanceof 来判断一个对象的类型,可能 typeof 用得多些,那来看看这两个之间的区别吧. typeof : typeof 是一个 ...