后端砖头

利用autotool生成Makefile

2022-04-09  本文已影响0人  明翼

平时自己写的程序多是直接写Makefile,大型的开源C代码,多是通过autotool工具来生成,需要学习下。为了具备通用性,用工作中实际程序来测试。

一 用autoscan生成configure.scan

步骤很简单,解压程序后,在源码目录运行autoscan就会生成configure.scan 如下:

#autoscan
# ll configure.scan 
-rw-r--r-- 1 root root 1108 3月  25 20:58 configure.scan

说明:

1、 AC_PREREQQ宏声明本文件要求的autoconf版本,这里是2.69
2、 AC_INIT定义软件的名称和信息。(DULL-PACKAGE-NAME为软件名,VERSION为软件的版本号,BUG-REPORT-ADDRESS为bug的报告地址,一般为软件作者的邮箱)
3、 AC_CONFIG_SRCDIR用来侦测指定的源码文件是否存在,确定源码目录的有效性。此
4、 AC_CONFIG_HEADER用于生成config.h文件,以便autoheader使用
5、 AC_PROG_CC用来指定编译器,以便不指定的时候默认为gcc
6、 AC_OUTPUT用来设定config要产生的文件。如果是Makefile,config会把它检查出来的结果带入Makefile.in文件产生合适的Makefile.

下面需要修改configure.scan 为configure.ac 且修改内容如下:

[root@localhost trunk]# cat configure.ac
#                                               -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.

AC_PREREQ([2.69])
AC_INIT(flow, 2.6, null)
AM_INIT_AUTOMAKE(flow,2.6)
AC_CONFIG_SRCDIR([aes.c])
AC_CONFIG_HEADERS([config.h])

# Checks for programs.
AC_PROG_CC

# Checks for libraries.
# Checks for libraries.
AC_CHECK_LIB(pthread, pthread_create)  

# Checks for header files.
AC_CHECK_HEADERS([arpa/inet.h fcntl.h limits.h locale.h malloc.h netinet/in.h stddef.h stdint.h stdlib.h string.h sys/socket.h sys/time.h unistd.h])

# Checks for typedefs, structures, and compiler characteristics.
AC_CHECK_HEADER_STDBOOL
AC_C_INLINE
AC_TYPE_INT32_T
AC_TYPE_INT64_T
AC_TYPE_PID_T
AC_TYPE_SIZE_T
AC_TYPE_SSIZE_T
AC_TYPE_UINT32_T
AC_TYPE_UINT64_T
AC_TYPE_UINT8_T
AC_CHECK_TYPES([ptrdiff_t])

# Checks for library functions.
AC_FUNC_FORK
AC_FUNC_LSTAT_FOLLOWS_SLASHED_SYMLINK
AC_FUNC_MALLOC
AC_FUNC_MKTIME
AC_FUNC_REALLOC
AC_FUNC_STRTOD
AC_CHECK_FUNCS([bzero dup2 gethostname gettimeofday localeconv localtime_r memchr memmove memset mkdir pow regcomp socket strchr strdup strerror strncasecmp strrchr strstr strtol strtoul tzset])
AC_OUTPUT(Makefile etc/Makefile)

1)主要是修改AC_INIT 三个中括号里面内容依次是软件名,版本名,bug报告地址;
2)添加AM_INIT_AUTOMAKE(软件名,版本)
这个宏是必须的,它描述了我们将要生成的软件包的名字及其版本号:PACKAGE是软件包的名字,VERSION是版本号。当你使用make dist命令时,它会给你生成一个类似helloworld-1.0.tar.gz的软件发行包,其中就有对应的软件包的名字和版本号。

  1. 输出文件名也修改:AC_OUTPUT(Makefile)

二 configure的生成

运行以下命令生成m4宏定义,比如我们使用的AM_INIT_AUTOMAKE,就是用aclocal生成的m4文件里面的:

[root@localhost trunk]# aclocal

如下:

[root@localhost trunk]# ll *.m4
-rw-r--r-- 1 root root 41888 3月  25 21:13 aclocal.m4

运行命令autoconf来生成configure文件:

#autoconf

运行configure文件,报错,缺少Makefile.in无法生成Makefile

三 编写Makefile.am

编写为生成Makefile需要的Makefile.am 文件如下:

AUTOMAKE_OPTIONS=foreign
SUBDIRS=etc
bindir=${prefix}
bin_PROGRAMS=flow
flow_SOURCES=aes.c args.c bloomfilter.c bstrlib.c cJSON.c conf.c deal_flow_file.c file.c flow_deal_main.c ini.c iptool.c list.c log.c mac2.c mac_tool.c  
flow_LDFLAGS=  -fvisibility=hidden -L/usr/lib64/mysql
AM_CFLAGS= -Wall -O0  -m64 -pg  -g    -D_REENTRANT -D_THREAD_SAFE  -std=gnu99
noinst_HEADERS=aes.h app_context.h args.h  Version.h workerid.h
AM_CPPFLAGS=-I/usr/include/mysql
flow_LDADD=-lmysqlclient -lm -lpthread

说明:

  1. AUTOMAKE_OPTIONS: 设置成foreign会改用一般软件套件标准来检查,默认是gnu模式,automake会检查目录是否存在标准的GNU套件所具备的文档。
  2. bin_PROGRAMS: 可指定程序名,这里面的bin表示要被安装到系统中,不想安装到系统中,使用noinst_PROGRAMS指定不按照程序到系统中,这里面我们指定程序名。
  3. flow_SOURCES:生成可执行程序所需要的所有原文件,flow是前面指定的程序名字。
  4. flow_CPPFLAGS: c预处理器参数,不是CFLAGS(c编译器参数),CXXFLAGS 表示C++编译器参数。
  5. flow_LDFLAGS: c链接选项
  6. noinst_HEADERS:不安装到系统中的头文件
  7. flow_LDADD:链接需要的库
  8. AM_CFLAGS:C编译选项

四 automake生成Makefile.in

[root@localhost trunk]# automake --add-missing
configure.ac:6: warning: AM_INIT_AUTOMAKE: two- and three-arguments forms are deprecated.  For more info, see:
configure.ac:6: https://www.gnu.org/software/automake/manual/automake.html#Modernize-AM_005fINIT_005fAUTOMAKE-invocation
Makefile.am:6: warning: 'INCLUDES' is the old name for 'AM_CPPFLAGS' (or '*_CPPFLAGS')

在Makefile.am 文件中 INCLUDES根据提示用AM_CPPFLAGS替换下。
正常生成Makefile.in之后,用configure 来结合Makefile.in 生成Makefile文件

#通过configure命令后
./configure
[root@localhost trunk]# ll Makefile
-rw-r--r-- 1 root root 37366 3月  26 00:29 Makefile

生成了Makefile文件。

五 编译和安装

make && make install 

六 定制安装

刚才默认的安装是安装到/usr/local/下面的,我现在有两个需求:
一是指定安装路径,且不在bin下面,直接在那个目录下面;
二是需要把配置文件拷贝过去,安装后的目录如下;

[root@localhost install-flow]# tree ../install-flow/
../install-flow/
├── etc
│   ├── finger.csv
│   ├── flowDeal.conf
│   ├── mac2org.db
│   ├── MAC_out.log
│   └── mac.sig
└── flow

6.1 更改configure.ac 设置输出

AC_OUTPUT(Makefile etc/Makefile)

原来我们只有一个Makefile,由于配置我们也需要安装,所以增加了配置目录的etc/Makefile的输出。

6.2 制作Makefile.am

更改根目录的Makefile.am 设置下安装目录bindir,且要设置递归调用Makefile子目录SUBDIRS,整体如下:

bindir=${prefix}
SUBDIRS=etc

在配置文件目录etc下新建Makefile.am内容如下:

configdir=${prefix}/etc
config_DATA=finger.csv  flowDeal.conf  mac2org.db  MAC_out.log  mac.sig

6.3 重新编译安装

重新生成和编译安装:

#automake --add-missing
#./configure --prefix=/root/flowdeal/install-flow
#make && make install

结果顺利完成编译和安装。

七 梳理 整体步骤

1. autoscan
2. configure.scan ==> configure.in/configure.ac
3. aclocal
4. autoheader(可选,生成config.h.in)
5. Makefile.am(根据源码目录可能需要多个)
6. libtoolize –automake –copy –force(如果configure.ac中使用了libtool)
7. automake –add-missing
8. autoconf 
9. ./configure && make && make install

以前画的图:


image.png

八 参考

[automake 和 autoconf 使用简明教程](https://thebigdoc.readthedocs.io/en/latest/auto-make-conf.html)
[大型项目使用Automake/Autoconf完成编译配置(2)——步步为营_华仔爱技术的博客-CSDN博客](https://blog.csdn.net/yunhua_lee/article/details/6172617)
[linux 下 automake 使用教程_踏莎行的博客-程序员宅基地 - 程序员宅基地 (cxyzjd.com)](https://www.cxyzjd.com/article/u012234115/45060673)
[https://www.jianshu.com/p/2f5e586c3402](https://www.jianshu.com/p/2f5e586c3402)
[https://www.cnblogs.com/zhangrxiang/p/8366596.html](https://www.cnblogs.com/zhangrxiang/p/8366596.html)

上一篇 下一篇

猜你喜欢

热点阅读