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工具的使用的更多相关文章

  1. automake - 使用 autotools 工具集

    一般而言,对于小项目或玩具程序,手动编写 Makefile 即可.但对于大型项目,手动编写维护 Makefile 成为一件费时费力的无聊工作. 本文介绍 autotools 工具集自动生成符合 Lin ...

  2. 使用autotools工具用configure、make、make install编译安装linux工程的详细步骤

    使用autotools工具用configure.make.make install编译安装linux工程的详细步骤 转载tmxkwzy 最后发布于2016-11-24 10:20:15 阅读数 324 ...

  3. autotools工具使用记录

    参考 http://blog.chinaunix.net/uid-25100840-id-271131.html http://blog.sina.com.cn/s/blog_4c2bf01a0101 ...

  4. autotools工具使用 good

    学习GNU/LINUX开发的编程人员,上手之后不久就会在编译开源软件的时候碰到configure脚本,过段时间还会知道configure脚本是 autoconf生成的:但是真正想用起来autoconf ...

  5. 利用autotools工具制作从源代码安装的软件 分类: linux 2014-06-02 23:27 340人阅读 评论(0) 收藏

    编写程序(helloworld.c)并将其放到一个单独目录. helloworld.c: #include<stdio.h> int main() { printf("hello ...

  6. 在 Linux 中使用 Eclipse 和 Gnu Autotools 管理 C/C++ 项目

    在我该系列的之前的所有随笔中,都是采用 Linux 发行版自带的包管理工具(如 apt-get.yum 等)进行软件的安装和卸载,从来没有向大家展示使用源代码自行编译安装软件的方法.但是长期混迹于 U ...

  7. linux下使用automake工具自动生成makefile文件

    linux环境下,当项目工程很大的时候,编译的过程很复杂,所以需要使用make工具,自动进行编译安装,但是手写makefile文件比较复杂,所幸在GNU的计划中,设计出了一种叫做Autoconf/Au ...

  8. GNU Autotools的研究(转)

    最近对Linux下软件项目的构建过程研究了一番.Linux下的软件项目通常用Autotools工具集和make工具来构建,我们通常使用./configure.make.make install这样的命 ...

  9. 如何使用autotools生成Makefile

    安装autotools工具sudo apt-get install autoconf 一,四个代码文件init.s lcd.c addr.h uart.c 二,命令:autoscan 三,命令:vi ...

随机推荐

  1. java杨辉三角

    public static void main(String[] args) { Scanner scanner=new Scanner(System.in); System.out.println( ...

  2. Python数据类型详解——元组

    Python数据类型详解--元组 有时候我们的列表数据不想被别人修改时该怎么办? 此时,就可以使用元组来存放,元祖又称为只读列表,不能修改 定义方式:与列表类似,将列表的[]换成()即可. 特性: 1 ...

  3. Mongodb操作2-windows系统安装数据库

    1.下载mongodb 本人提供的是64位的下载地址 百度云盘连接 :链接:https://pan.baidu.com/s/1fp6aB5rvLa9dD4q4YysIXQ 提取码:ekr2    并送 ...

  4. Codeforces Round #506 (Div. 3) 1029 F. Multicolored Markers

    CF-1029F 题意: a,b个小正方形构造一个矩形,大小为(a+b),并且要求其中要么a个小正方形是矩形,要么b个小正方形是矩形. 思路: 之前在想要分a,b是否为奇数讨论,后来发现根本不需要.只 ...

  5. 关于斐波那契数列的一些恒等式 模板 牛客OI测试赛 A 斐波拉契

    牛客A 斐波拉契 链接:https://www.nowcoder.com/acm/contest/181/A来源:牛客网 设f[i]表示斐波那契数论的第i项 f[1]=1,f[2] =1,f[i] = ...

  6. Codeforces 734D. Anton and Chess(模拟)

    Anton likes to play chess. Also, he likes to do programming. That is why he decided to write the pro ...

  7. CF1072A Palindromic Twist 思维

    Palindromic Twist time limit per test 2 seconds memory limit per test 256 megabytes input standard i ...

  8. CodeForces Round#480 div3 第2场

    这次div3比上次多一道, 也加了半小时, 说区分不出1600以上的水平.(我也不清楚). A. Remove Duplicates 题意:给你一个数组,删除这个数组中相同的元素, 并且保留右边的元素 ...

  9. codeforces 743D. Chloe and pleasant prizes(树形dp)

    题目链接:http://codeforces.com/contest/743/problem/D 大致思路挺简单的就是找到一个父节点然后再找到其两个字节点总值的最大值. 可以设一个dp[x]表示x节点 ...

  10. 2017 ACM/ICPC Asia Regional Qingdao Online 1003 The Dominator of Strings hdu 6208

    The Dominator of Strings Time Limit: 3000/3000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java ...