大部分程序员对makefile都不陌生,在Linux环境下开发简单项目时,一般手工编写makefile文件。但是对于大型项目,如包含整个Linux kernel的嵌入式平台及应用,大部分makefile通常通过GNU的自动化工具生成。这里面有automake, autoconf等,还要用到/生成一个很重要的配置文件configure。这么做的好处是为了方便程序在不同平台下的移植和不同配置下的编译,只需要对几个关键文件做少量的修改,而不是要修改每个具体的makefile文件。
在GNU Build系统里,configure.ac起到了关键的作用,且一般由开发者写好后不会修改。但是后面的开发者可以在configure.ac的基础上通过不同的配置选项(命令行)生成不同的configure文件。
上图是GNU autotool的工作流程图,在实际工作中,upstream可能是(芯片)原厂提供的SDK,下一个环节是产品开发商进行的二次开发。
在autoconf读取configure.ac的过程中,通常还要用到.m4结尾的文件,里面有一些生成configure所需的宏的定义,这些文件通常存储在M4目录下。autotool调用程序autom4te来完成这个过程。这个过程会生成autom4te.cache目录来存储另外的一些信息。这些信息被autoheader和automake直接使用,不需要再次处理configure.ac。这样可以节省整个生成Makefile文件的时间大约30%(configure.ac越大,节省比例越高)。 实际过程比我这里说的要复杂,但是大部分开发者只需要知道,autom4te.cache是autotool在处理m4文件时的副产物,存储有生成configure,Makefile文件所需的一些信息。
autom4te.cache虽然能够提高编译过程的效率,但是它也可能因为携带本地环境相关信息,在项目移植到新的平台时,因为环境的不匹配,导致报错。如以下:
aclocal-1.16: command not found
WARNING: 'aclocal-1.16' is missing on your system.
You should only need it if you modified 'acinclude.m4' or
'configure.ac' or m4 files included by 'configure.ac'.
The 'aclocal' program is part of the GNU Automake package:
<https://www.gnu.org/software/automake>
It also requires GNU Autoconf, GNU m4 and Perl in order to run:
<https://www.gnu.org/software/autoconf>
<https://www.gnu.org/software/m4/>
<https://www.perl.org/>
make[1]: *** [aclocal.m4] Error 127
make[1]: Leaving directory `/home/lijun/cucc/apps/private/dlna_src/thirdp_src/libupnp-1.6.6'
报错的原因是aclocal-1.16命令没有找到,本地版本是1.15.
解决方案可以是安装 aclocal-1.16,使用$sudo apt upgrade acloal,如果没有找到,则直接到GNU网站下载aclocal-1.16的源码,编译安装。
但是对于此类报错没有必要这样做,aclocal-1.15也可以完成自动化编译任务。我们可以运行如下命令:
$cd apps/private/dlna_src/thirdp_src/libupnp-1.6.6
$grep -r aclocal-1.16
进入到产生报错的目录,寻找aclolal-1.16的存在。返回如下:
upnp/doc/Makefile:ACLOCAL = ${SHELL} /home/lijun/cucc/apps/private/dlna_src/thirdp_src/libupnp-1.6.6/build-aux/missing aclocal-1.16
upnp/sample/Makefile:ACLOCAL = ${SHELL} /home/lijun/cucc/apps/private/dlna_src/thirdp_src/libupnp-1.6.6/build-aux/missing aclocal-1.16
upnp/Makefile:ACLOCAL = ${SHELL} /home/lijun/cucc/apps/private/dlna_src/thirdp_src/libupnp-1.6.6/build-aux/missing aclocal-1.16
config.status:S["ACLOCAL"]="${SHELL} /home/lijun/cucc/apps/private/dlna_src/thirdp_src/libupnp-1.6.6/build-aux/missing aclocal-1.16"
autom4te.cache/traces.1:m4trace:/usr/share/aclocal-1.16/amversion.m4:14: -1- AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version='1.16'
autom4te.cache/traces.1:m4trace:/usr/share/aclocal-1.16/amversion.m4:33: -1- AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], [AM_AUTOMAKE_VERSION([1.16.1])dnl
autom4te.cache/traces.1:m4trace:/usr/share/aclocal-1.16/auxdir.m4:47: -1- AC_DEFUN([AM_AUX_DIR_EXPAND], [AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl
autom4te.cache/traces.1:m4trace:/usr/share/aclocal-1.16/cond.m4:12: -1- AC_DEFUN([AM_CONDITIONAL], [AC_PREREQ([2.52])dnl
autom4te.cache/traces.1:m4trace:/usr/share/aclocal-1.16/depend.m4:26: -1- AC_DEFUN([_AM_DEPENDENCIES], [AC_REQUIRE([AM_SET_DEPDIR])dnl
autom4te.cache/traces.1:m4trace:/usr/share/aclocal-1.16/depend.m4:163: -1- AC_DEFUN([AM_SET_DEPDIR], [AC_REQUIRE([AM_SET_LEADING_DOT])dnl
autom4te.cache/traces.1:m4trace:/usr/share/aclocal-1.16/depend.m4:171: -1- AC_DEFUN([AM_DEP_TRACK], [AC_ARG_ENABLE([dependency-tracking], [dnl
autom4te.cache/traces.1:m4trace:/usr/share/aclocal-1.16/depout.m4:11: -1- AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], [{
autom4te.cache/traces.1:m4trace:/usr/share/aclocal-1.16/depout.m4:62: -1- AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], [AC_CONFIG_COMMANDS([depfiles],
autom4te.cache/traces.1:m4trace:/usr/share/aclocal-1.16/init.m4:29: -1- AC_DEFUN([AM_INIT_AUTOMAKE], [AC_PREREQ([2.65])dnl
autom4te.cache/traces.1:m4trace:/usr/share/aclocal-1.16/init.m4:186: -1- AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], [# Compute $1's index in $config_headers.
autom4te.cache/traces.1:m4trace:/usr/share/aclocal-1.16/install-sh.m4:11: -1- AC_DEFUN([AM_PROG_INSTALL_SH], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
autom4te.cache/traces.1:m4trace:/usr/share/aclocal-1.16/lead-dot.m4:10: -1- AC_DEFUN([AM_SET_LEADING_DOT], [rm -rf .tst 2>/dev/null
autom4te.cache/traces.1:m4trace:/usr/share/aclocal-1.16/make.m4:13: -1- AC_DEFUN([AM_MAKE_INCLUDE], [AC_MSG_CHECKING([whether ${MAKE-make} supports the include directive])
autom4te.cache/requests: '/usr/share/aclocal-1.16/internal/ac-config-macro-dirs.m4',
autom4te.cache/requests: '/usr/share/aclocal-1.16/amversion.m4',
autom4te.cache/requests: '/usr/share/aclocal-1.16/auxdir.m4',
autom4te.cache/requests: '/usr/share/aclocal-1.16/cond.m4',
autom4te.cache/requests: '/usr/share/aclocal-1.16/depend.m4',
autom4te.cache/requests: '/usr/share/aclocal-1.16/depout.m4',
autom4te.cache/requests: '/usr/share/aclocal-1.16/init.m4',
autom4te.cache/requests: '/usr/share/aclocal-1.16/install-sh.m4',
autom4te.cache/requests: '/usr/share/aclocal-1.16/lead-dot.m4',
autom4te.cache/requests: '/usr/share/aclocal-1.16/make.m4',
autom4te.cache/requests: '/usr/share/aclocal-1.16/missing.m4',
autom4te.cache/requests: '/usr/share/aclocal-1.16/options.m4',
autom4te.cache/requests: '/usr/share/aclocal-1.16/prog-cc-c-o.m4',
autom4te.cache/requests: '/usr/share/aclocal-1.16/runlog.m4',
autom4te.cache/requests: '/usr/share/aclocal-1.16/sanity.m4',
autom4te.cache/requests: '/usr/share/aclocal-1.16/silent.m4',
autom4te.cache/requests: '/usr/share/aclocal-1.16/strip.m4',
autom4te.cache/requests: '/usr/share/aclocal-1.16/substnot.m4',
autom4te.cache/requests: '/usr/share/aclocal-1.16/tar.m4',
从上面可以看出, Makefile和config.status中都含有build-aux/missing aclocal-1.16记录,这是结果。原因我们可以看到autom4te.cache目录下的traces.1和requests文件里都包含/usr/share/aclocal-1.16,因为上一个编译平台是Ubuntu-20.04,它使用的aclocal是/usr/share/aclocal-1.16。
解决该问题很简单,首先把autom4te.cache目录及里面的文件都删除。
$rm -rf autom4te.cache
然后再重新生成configure和Makefile文件
$autoreconf -ivf
运行这个命令不报错,则表示成功。
采用如上方法可以解决所有因autom4te.cache存有旧平台信息导致的环境变量不匹配。