autotools及Yocto下通过autotools编译

2022-05-10 15:17:45 浏览数 (1)

一样新的东西的由来,往往因为之前的东西用的很不爽,然后更具弊端创造出更加容易使用的东西,比如在大型的项目中,如Linux,他是通过Makefile的方式进行编译。但是,Makefile复杂的语法结构,难于让人领会。在一个很大的项目中,维护Makefile是一个非常头疼的烦恼事。于是一个新的产物Autotools就出来了,他用来生成复杂的Makefile,很大程度降低了我们的开发难度。

Autotools并不是单独一个工具,而是一系列工具:

  • autoscan
  • aclocal
  • autoconf
  • autoheader
  • automake

autotools提供的这一系列工具,最终的目的就是生成Makefile,这个Makefile是自动生成的。

首先我们创建一个测试代码main.c,通过简单的例子来说明autotools的使用流程,源文件内容如下:

代码语言:javascript复制
#include <stdio.h>

int main(int argc, char *argv[])
{
        printf("Rice Autotools!!!n");

        return 0;
}
  • autoscan工具: 执行autoscan命令,该命令主要用于扫描工作目录,并生成configure.scan文件。然后将configure.scan文件重新命名成configure.ac,然后对这个文件进行配置。这样我们才能执行以下的命令。
代码语言:javascript复制
rice@rice:~/rice-autotools$ autoscan
Unescaped left brace in regex is deprecated, passed through in regex; marked by <-- HERE in m/${ <-- HERE [^}]*}/ at /usr/bin/autoscan line 361.
rice@rice:~/rice-autotools$ ls
autoscan.log  configure.scan  main.c
rice@rice:~/rice-autotools$ mv configure.scan configure.ac
rice@rice:~/rice-autotools$ ls
autoscan.log  configure.scan  main.c
rice@rice:~/rice-autotools$ 

configure.ac的文件内容:

代码语言:javascript复制
#                                               -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.

AC_PREREQ([2.69])
AC_INIT([FULL-PACKAGE-NAME], [VERSION], [BUG-REPORT-ADDRESS])
AC_CONFIG_SRCDIR([main.c])
AC_CONFIG_HEADERS([config.h])

# Checks for programs.
AC_PROG_CC

# Checks for libraries.

# Checks for header files.

# Checks for typedefs, structures, and compiler characteristics.

# Checks for library functions.

AC_OUTPUT

我们将其修改为下面的内容:

代码语言:javascript复制
#                                               -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.

AC_PREREQ([2.69])
AC_INIT(rice, 1.0, 980307037@qq.com)
AM_INIT_AUTOMAKE(rice, 1.0)
AC_CONFIG_SRCDIR([main.c])
AC_CONFIG_HEADERS([config.h])

# Checks for programs.
AC_PROG_CC

# Checks for libraries.

# Checks for header files.
AC_CHECK_HEADERS([stdlib.h])

# Checks for typedefs, structures, and compiler characteristics.

# Checks for library functions.
AC_CONFIG_FILES([Makefile])
AC_OUTPUT

其中configure.ac的标签说明

标签

说明

AC_PREREQ

声明autoconf要求的版本号

AC_INIT

定义软件名称、版本号、联系方式

AM_INIT_AUTOMAKE

必须要的,参数为软件名称和版本号

AC_CONFIG_SCRDIR

宏用来侦测所指定的源码文件是否存在, 来确定源码目录的有效性.。此处为当前目录下main.c。

AC_CONFIG_HEADER

宏用于生成config.h文件,以便 autoheader 命令使用。

AC_PROG_CC

指定编译器,默认GCC

AC_CONFIG_FILES

生成相应的Makefile文件,不同文件夹下的Makefile通过空格分隔。例如:AC_CONFIG_FILES([Makefile, src/Makefile])

AC_OUTPUT

用来设定 configure 所要产生的文件,如果是makefile,configure 会把它检查出来的结果带入makefile.in文件产生合适的makefile。

  • aclocal工具: 执行aclocal命令。扫描 configure.ac 文件生成 aclocal.m4文件, 该文件主要处理本地的宏定义,它根据已经安装的宏、用户定义宏和 acinclude.m4文件中的宏将configure.ac文件需要的宏集中定义到文件 aclocal.m4 中。
代码语言:javascript复制
rice@rice:~/rice-autotools$ aclocal
rice@rice:~/rice-autotools$ ls
aclocal.m4  autom4te.cache  autoscan.log  configure.ac  main.c
rice@rice:~/rice-autotools$ 
  • autoconf工具: 执行autoconf命令。此命令将configure.ac文件中的宏展开,生成configure脚本。这个过程可能会用到aclocal.m4中定义的宏。
代码语言:javascript复制
rice@rice:~/rice-autotools$ autoconf
rice@rice:~/rice-autotools$ ls
aclocal.m4  autom4te.cache  autoscan.log  configure  configure.ac  main.c
rice@rice:~/rice-autotools$ 
  • autoheader工具: 执行autoheader命令。该命令生成 config.h.in 文件。该命令通常会从 "acconfig.h” 文件中复制用户附加的符号定义。该例子中没有附加的符号定义, 所以不需要创建 "acconfig.h” 文件。
代码语言:javascript复制
rice@rice:~/rice-autotools$ autoheader
rice@rice:~/rice-autotools$ ls
aclocal.m4  autom4te.cache  autoscan.log  config.h.in  configure  configure.ac  main.c
rice@rice:~/rice-autotools$ 
  • 创建Makefile.am: 创建Makefile.am文件。Automake工具会根据configure.in中的参量把Makefile.am转换成Makefile.in文件。最终通过Makefile.in生成Makefile文件,所以Makefile.am这个文件非常重要,定义了一些生成Makefile的规则 。

Makefile.am文件内容:

代码语言:javascript复制
AUTOMARK_OPTIONS = foreign

bin_PROGRAMS = rice

rice_SOURCES = main.c
  1. AUTOMAKE_OPTIONS:由于GNU对自己发布的软件有严格的规范, 比如必须附带许可证声明文件COPYING等,否则automake执行时会报错. automake提供了3中软件等级:foreign, gnu和gnits, 供用户选择。默认级别是gnu. 在本例中, 使用了foreign等级, 它只检测必须的文件。
  2. bin_PROGRAMS = rice:生成的可执行文件名称,生成多个可执行文件,可以用空格隔开。
  3. rice_SOURCES:生成可执行文件rice需要依赖的源文件。其中rice_为可执行文件的名称。
  • automake工具: 执行automake命令。该命令生成Makefile.in文件。使用选项"--add-missing" 可以让Automake自动添加一些必需的脚本文件。如果发现一些文件不存在(NEWS,README,AUTHORS,ChangLog),可以通过手工 touch命令创建。
代码语言:javascript复制
rice@rice:~/rice-autotools$ automake --add-missing
configure.ac:6: warning: AM_INIT_AUTOMAKE: two- and three-arguments forms are deprecated.  For more info, see:
configure.ac:6: http://www.gnu.org/software/automake/manual/automake.html#Modernize-AM_005fINIT_005fAUTOMAKE-invocation
configure.ac:11: installing './compile'
configure.ac:6: installing './install-sh'
configure.ac:6: installing './missing'
Makefile.am: installing './INSTALL'
Makefile.am: error: required file './NEWS' not found
Makefile.am: error: required file './README' not found
Makefile.am: error: required file './AUTHORS' not found
Makefile.am: error: required file './ChangeLog' not found
Makefile.am: installing './COPYING' using GNU General Public License v3 file
Makefile.am:     Consider adding the COPYING file to the version control system
Makefile.am:     for your code, to avoid questions about which license your project uses
Makefile.am: installing './depcomp'
rice@rice:~/rice-autotools$ touch NEWS
rice@rice:~/rice-autotools$ touch README
rice@rice:~/rice-autotools$ touch AUTHORS
rice@rice:~/rice-autotools$ touch ChangeLog
rice@rice:~/rice-autotools$ ls
aclocal.m4  autom4te.cache  ChangeLog  config.h.in  configure.ac  depcomp  install-sh  Makefile.am  NEWS
AUTHORS     autoscan.log    compile    configure    COPYING       INSTALL  main.c      missing      README
rice@rice:~/rice-autotools$ automake --add-missing
configure.ac:6: warning: AM_INIT_AUTOMAKE: two- and three-arguments forms are deprecated.  For more info, see:
configure.ac:6: http://www.gnu.org/software/automake/manual/automake.html#Modernize-AM_005fINIT_005fAUTOMAKE-invocation
rice@rice:~/rice-autotools$  
  • configure命令: 执行./configure脚本。把Makefile.in变成最终的Makefile文件。configure会把一些配置参数配置到Makefile文件里面。
代码语言:javascript复制
rice@rice:~/rice-autotools$ ./configure 
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for a thread-safe mkdir -p... /bin/mkdir -p
checking for gawk... gawk
checking whether make sets $(MAKE)... yes
checking whether make supports nested variables... yes
checking for gcc... gcc
checking whether the C compiler works... yes
checking for C compiler default output file name... a.out
checking for suffix of executables... 
checking whether we are cross compiling... no
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether gcc accepts -g... yes
checking for gcc option to accept ISO C89... none needed
checking whether gcc understands -c and -o together... yes
checking for style of include used by make... GNU
checking dependency style of gcc... gcc3
checking how to run the C preprocessor... gcc -E
checking for grep that handles long lines and -e... /bin/grep
checking for egrep... /bin/grep -E
checking for ANSI C header files... yes
checking for sys/types.h... yes
checking for sys/stat.h... yes
checking for stdlib.h... yes
checking for string.h... yes
checking for memory.h... yes
checking for strings.h... yes
checking for inttypes.h... yes
checking for stdint.h... yes
checking for unistd.h... yes
checking for stdlib.h... (cached) yes
checking that generated files are newer than configure... done
configure: creating ./config.status
config.status: creating Makefile
config.status: creating config.h
config.status: executing depfiles commands
rice@rice:~/rice-autotools$ ls
aclocal.m4      autoscan.log  config.h     config.status  COPYING  install-sh  Makefile.am  NEWS
AUTHORS         ChangeLog     config.h.in  configure      depcomp  main.c      Makefile.in  README
autom4te.cache  compile       config.log   configure.ac   INSTALL  Makefile    missing      stamp-h1
rice@rice:~/rice-autotools$ 
  • make命令: 执行make命令。生成可执行文件rice。并执行可执行文件,查看结果。
代码语言:javascript复制
rice@rice:~/rice-autotools$ make
make  all-am
make[1]: Entering directory '/home/tym/rice-autotools/temp'
gcc -DHAVE_CONFIG_H -I.     -g -O2 -MT main.o -MD -MP -MF .deps/main.Tpo -c -o main.o main.c
mv -f .deps/main.Tpo .deps/main.Po
gcc  -g -O2   -o rice main.o  
make[1]: Leaving directory '/home/tym/rice-autotools/temp'
rice@rice:~/rice-autotools$ ./rice 
Rice Autotools!!!
rice@rice:~/rice-autotools$ 

上述的内容是在ubuntu上进行操作的,接下来我们说说如何在arm架构的板子进行运行。由于我目前的系统构建环境是基于Yocto上的。所以我这里直接以Yocto进行说明。

在Yocto工程创建自己的recipe。这里我随便找了一个地方放我的recipe进行演示。创建files目录rice-autotools_git.bb文件。然后将上面我们利用autotools工具得到的内容拷贝到files目录下。如下:

代码语言:javascript复制
rice@rice:~/yocto/poky/meta-sdk/recipes-connectivity/rice-autotools$ tree 
.
├── files
│   ├── AUTHORS
│   ├── ChangeLog
│   ├── configure.ac
│   ├── main.c
│   ├── Makefile.am
│   ├── NEWS
│   └── README
└── rice-autotools_git.bb

1 directory, 9 files
ice@rice:~/yocto/poky/meta-sdk/recipes-connectivity/rice-autotools$

为了方便我们操作,我们将files文件的内容进行压缩。如下:

代码语言:javascript复制
rice@rice:~/yocto/poky/meta-sdk/recipes-connectivity/rice-autotools$ tar -cvzf rice-autotools.tgz .
./
./.deps/
./.deps/main.Po
./ChangeLog
./NEWS
./AUTHORS
./Makefile.am
./main.c
./README
./configure.ac
tar: .: file changed as we read it
rice@rice:~/yocto/poky/meta-sdk/recipes-connectivity/rice-autotools$ ls
AUTHORS  ChangeLog  configure.ac  main.c  Makefile.am  NEWS  README  rice-autotools.tgz
rice@rice:~/yocto/poky/meta-sdk/recipes-connectivity/rice-autotools$

rice-autotools_git.bb文件:内容如下:

代码语言:javascript复制
SMMARY = "Rice Autotools Test"
LICENSE = "CLOSED"

SRC_URI = "file://rice-autotools.tgz"

S = "${WORKDIR}"

do_install() {
        install -d ${D}/usr/bin
        install -m 0755 ${WORKDIR}/rice -D ${D}/usr/bin/
}

inherit autotools
  • SRC_URI:源包下载URI,其中我们这里指向files目录的rice-autotools.tgz。这也就是我们上面为什么要压缩的原因。不然你要一个文件一个文件的指向。
  • S:到Bitbake放置以解压文件所在目录的完整路径。
  • do_install():将我们编译完的源文件放进板子的根文件系统目录中。
  • inherit:继承。这里继承autotools。

然后我们在Yocto进行编译,然后将镜像烧录到板子上。运行结果:

代码语言:javascript复制
/ # rice 
Rice Autotools!!!
/ # 

0 人点赞