linux autotools使用总结(关键字、文件更新顺序,调试技巧与错误解决)

1、configure.ac文件

  1. configure.ac如果要使用 = 运算符,则其两边不要加空格
  2. 一些不可不关注的关键字段
    • AM_INIT_AUTOMAKE(subdir-objects) 如果项目需使用automake工具,则这个需要开发人员手动添加; 如果项目无子目录,则可以不写subdir-objects关键字
    • AC_CONFIG_SRCDIR([./]) 指定Makefile.am中 top_srcdir 变量的值; ./ 表示指定该值为项目的根目录
    • AC_CONFIG_FILES([Makefile test1/Makfile subdir/Makfile]) 如果项目存在子目录,且子目录中存在需要编译的文件,那么这里需要将该目录列举出来
  3. autoconf生成configure脚本后,感兴趣的读者可以打开该脚本搜索跟踪一下例如 includedir 等变量的值

2、Makefile.am文件

  1. 一般在Makefile.am中用以下关键字表示make最终要生成的目标
    • bin_PROGRAMS 该条目后列举的若成功编译,则会生成二进制可执行文件
    • noinst_LTLIBRARIES 该条目后列举的若成功编译,则最终会生成中间文件,如常见的libtool文件(.la文件)
    • lib_LTLIBRARIES 该条目后列举的若成功编译,则会生成库文件(.so .a文件)
  2. 其余一些关键字:
    • _CFLAGS 或 _CPPFLAGS 列举预处理阶段源码中包含的头文件的寻找路径
    • _SOURCES 列举要生成的目标文件所依赖的源码文件(.c .cpp等)
    • _LIBADD 和 _LDADD
      • 均表示链接阶段要链接的库名
      • 不同:
        • _LIBADD 用于Makefile生成中间文件(.la等)或库文件(.so .a)的情况
        • _LDADD 用于Makefile生成二进制可执行文件的情况
    1. 涉及到make install操作时要注意三个关键字(后2个需要成对出现)
      • DESTDIR : 该变量默认为空,安装时需要sudo权限,可安装到系统目录
      • _include_HEADERS : 列举要安装的头文件
      • _includedir : 指定头文件的安装路径
  3. 项目根目录下的Makefile.am需要注意:
    1. 若子目录间的源码间存在依赖关系,则SUBDIRS 关键字后需要将被其他目录依赖的目录写在前面,否则会编译失败,读者自己尝试。

3、调试技巧总结:

  1. 如果初学autotools系列工具,建议源码编写完成后,先在命令行手动进行编译,保证程序可以成功编译运行,再进行configure.ac、Makefile.am的调试
  2. make命令编译出错后肯定要看命令行报错信息,这是一句废话,却也很重要。
  3. autotools系列工具出错后优先考虑修改以下文件:Makefile.am 、configure.ac

4、我遇到过的错误:

  1. 提示Makefile文件多少行出错
    查看具体行数信息,有可能是Makefile.am内部 $(NULL) 变量赋值出错。

  2. 生成Makefile文件后,make编译报错,但是进入子目录挨个make,最后可以编译成功。
    这个是因为项目根目录下的Makfile.am中子目录的列举顺序存在问题,即列举子目录时需要考虑子目录间源码的依赖顺序,被依赖的要先列举

  3. No rule to make target ‘libxxx.la’

    • 出错文件:这个表示正在编译的目录下的Makefile.am文件出错
    • 原因分析:即当前子目录依赖于别的目录生成的libtool中间文件,但是在实际链接时在对应目录中找不到
    • 解决方法:修改对应目录Makfile.am文件中的 _LIBADD 或 _LDADD 条目,正确列出 libxxx.la文件的所在目录即可。注意正确使用$(top_srcdir)变量。
  4. configure.ac:16: required file ‘./ltmain.sh’ not found.

    • 原因分析:查看configure.ac 16行发现是AC_PROG_LIBTOOL,这意味着我们的项目中需要生成 .la 文件
    • 解决方法:运行libtoolize命令即可链接系统ltmain.sh文件到项目目录下
  5. 按照README文件中命令顺序,执行autoconf后,./configure 执行失败
    这个可能是因为使用autoconf命令生成的configure脚本没有可执行权限,chmod +x configure即可。

5、文件之间的关系

1)先上图
linux autotools使用总结(关键字、文件更新顺序,调试技巧与错误解决)_第1张图片
2)文件的更新关系:(用箭头表示更新的顺序)

  • Makefile.am–>Makefile.in–>Makefile
  • configure.ac–>configure–>Makefile.
  • 经过实例调试我发现,在一套完整的流程走下来之后(即已经生成Makefile后),假设我们修改了configure.ac和Make file.am的任一项,直接运行make命令,在此后编译的过程中,那些需要被更新的文件都会被重新生成。(关于这一点,读者请自己尝试)

3)关于我在Makefile.am中多次提到的继承关系:

继承这个词是我在查阅资料时网上一个前辈的记录里提到的,所以就一直沿用了。(以下3个描述是同一个意思)

  • automake可以从autoconf继承变量
  • Makefile.am可以从configure.ac继承变量
  • Makefile可以从configure继承变量

4)关于autoconf与automake的继承关系

  • 在实际的试错过程中发现:无论是使用PKG_CHECK_MODULES 宏还是自定义的方法,在configure.ac内部定义 _CFLAGS 和 _LIBS 变量后,如果不使用 AC_SUBST 宏对 _CFLAGS 和 _LIBS 进行提交,最终项目也可成功编译。
  • 注:上述的意思是:configure.ac内部可以不使用AC_SUBST,但是 _CFLAGS 和 _LIBS变量必须定义,若未定义,则make编译时会在gcc的预处理阶段报错:头文件No such file.

6、autotools系列工具大致执行顺序(需要已经编写好源码)

​ 1)运行autoscan生成configure.scan, 将其重命名为configure.ac,并修改configure.ac内容
​ 2)编写Makefile.am文件(可适当放后)
​ 2)运行autoheader生成config.h.in文件
​ 3)运行aclocal生成aclocal.m4文件
​ 4)运行ibtoolize链接系统的ltmain.sh文件到项目根目录下(可选)
​ 5)运行automake --copy --add-missing添加缺少文件,若报错则手动touch项目必须的文件(如README、Changelog等),生成或更新Makefile.in文件
​ 6)运行autoconf命令,根据configure.ac文件生成configure脚本文件
​ 7)运行./configure,根据Makefile.am和Makefile.in生成Makefile文件。

你可能感兴趣的:(linux)