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. MySQL之binlog日志

    一.什么是binlog binlog 是一个二进制格式的文件,用于记录用户对数据库 更新的SQL语句 信息,例如更改数据库表和更改内容的SQL语句都会记录到binlog里,但是对库表等内容的查询不会记 ...

  2. python 17 内置模块

    目录 1. 序列化模块 1.1 json 模块 1.2 pickle 模块 2. os 模块 3. sys 模块 4. hashlib 加密.摘要 4.1 加密 4.2 加盐 4.3 文件一致性校验 ...

  3. 从技术小白到收获BAT研发offer,分享我的学习经验和感悟(赠送相关学习资料)

    去年秋季参加了校园招聘,有幸拿到了BAT.头条.网易.滴滴.亚马逊.华为等offer,经过研究生两年的学习积累,终于达成了自己的目标,期间也经历了很多,谨以此文,聊表感叹,也会分享很多我的Java学习 ...

  4. Python数据类型详解——列表

    Python数据类型详解--列表 在"Python之基本数据类型概览"一节中,大概介绍了列表的基本用法,本节我们详细学一下列表. 如何定义列表:在[]内以英文里输入法的逗号,,按照 ...

  5. html基础——下拉式菜单

    一个网站能否让用户容易使用该网站往往是由菜单栏体现出来,因为它为网页的大多数页面提供功能入口.一个轻轻的点击以后,即可显示出菜单项,将网站的大部分页面和功能显示出来让用户清楚了解从而用户节约一定的时间 ...

  6. Drop Table对MySQL的性能影响分析

    [问题描述] 最近碰到有台MySQL实例出现了MySQL服务短暂hang死,表现为瞬间的并发线程上升,连接数暴增. 排查Error Log文件中有page_cleaner超时的信息,引起我们的关注: ...

  7. python控制窗口缩放

    import win32gui import win32con import time # 使用之前先打开一个记事本 notepad = win32gui.FindWindow("Notep ...

  8. [python]通过微信公众号“Python程序员”,编写python代码

    今天发现微信公众号中,居然可以编写python代码,很是惊喜,觉得蛮有趣的. 步骤如下: 1.关注微信公众号“Python程序员” 2.关注成功后,点击右下角的“潘多拉”->"Pyth ...

  9. 2019DX#8

    Solved Pro.ID Title Ratio(Accepted / Submitted)   1001 Acesrc and Cube Hypernet 7.32%(3/41)   1002 A ...

  10. Java的8种基本数据类型的内存占用字节数和取值范围

    这是8中基本类型的内存中占用字节数(取值范围是2的(字节数X8-1)次方) 1.整型 类型 存储需求 bit数 取值范围 byte 1字节 1*8 -128-127 short 2字节 2*8 -32 ...