【问题标题】:autoreconf -i not running recursively with AX_SUBDIRS_CONFIGUREautoreconf -i 不使用 AX_SUBDIRS_CONFIGURE 递归运行
【发布时间】:2021-07-10 02:15:10
【问题描述】:

我正在使用autotools生成一个configure文件来编译一个名为hello的C项目,其编译依赖于一个库子目录的成功编译。该子目录名为the_subdir,并生成一个名为lib_mytest.a 的库。

子目录项目 (the_subdir) 可能会收到一个名为 --enable-other 的标志。如果它没有收到这个标志,它通过编译一个名为myfile.c 的C 文件创建库(lib_mytest.a),如果它收到这个标志,则使用C 文件myfile_other.c 生成库。在这两种情况下都会生成lib_mytest.a,但它们的行为不同。

Project hello 需要使用使用特殊标志 (--enable-other) 的 lib_mytest.a 版本,因此 hello 的 Makefile 必须通过传递特殊标志来递归生成 lib --enable-other 标志。我正在尝试通过自动工具来实现这一目标。阅读文档后,我了解到我需要使用 AX_SUBDIRS_CONFIGURE 命令,它模拟 AC_CONFIG_SUBDIRS,但允许我们通过将特定标志传递给特定子目录来递归运行 automake。

为此,我按以下方式设置项目。目录hello 具有如下所述的树结构和文件。

问题:当我在根目录运行autoreconf -i生成./configure文件时,子目录配置文件(the_subdir/configure没有生成,然后当我运行@ 987654342@,我收到一条警告说the_subdir/configure 不存在。这与AC_CONFIG_SUBDIRS 的行为不同,AC_CONFIG_SUBDIRS 在运行autoreconf -i确实创建配置子目录。这与 AX_SUBDIRS_CONFIGURE 应该模仿 AC_CONFIG_SUBDIRS 的行为这一事实不符。如果我在根目录和the_subdir 中都运行autoreconf -i,那么./configure 会正常运行,同时运行对根目录和子目录的检查。然而,这感觉像是一种 hack,因为我发现我不太可能需要在一个更大的项目中自动创建所有子目录。什么是正确的语法来实现(1)将--enable-other标志传递给我的子目录和(2)在根目录中调用autoreconf -i(或任何其他命令)为我的子目录生成所有configure文件?

这是这个示例项目的树形结构(m4和C文件与我认为的问题无关?)

├── configure.ac
├── m4
│   ├── ax_configure_args.m4
│   └── ax_subdirs_configure.m4
├── main.c
├── Makefile.am
└── the_subdir
    ├── configure.ac
    ├── Makefile.am
    ├── mytest.c
    ├── mytest.h
    ├── mytest_other.c
    └── mytest_other.h

configure.ac有以下内容:

AC_INIT([Tutorial Program], 1.0)                                                                                                                                                                                                                                                    
AM_INIT_AUTOMAKE([foreign])
AC_PROG_CC
AC_CONFIG_MACRO_DIR([m4])

dnl here we compare AC_CONFIG_SUBDIRS with
dnl AC_CONFIG_SUBDIRS([the_subdir])
AX_SUBDIRS_CONFIGURE([the_subdir], [--enable-other])

AC_CONFIG_FILES(Makefile)
AC_OUTPUT

Makefile.am:

SUBDIRS := the_subdir                                                                                                                                                                                                                                                               

bin_PROGRAMS = prog
prog_SOURCES = main.c

LDADD = the_subdir/lib_mytest.a

the_subdir/configure.ac:

AC_INIT([Subdir Program], 1.0)                                                                                                                                                                                                                                                      
AM_INIT_AUTOMAKE([foreign])
AC_PROG_CC

AC_CONFIG_SRCDIR([mytest.h])

AM_PROG_AR
AC_PROG_RANLIB

dnl the line breaks in this message are intended
other_fail_msg="

Failed to locate OtherLib on your system.
"

AC_ARG_ENABLE([other],
  [AS_HELP_STRING([--enable-other], [Enable OtherLib @<:@no@:>@])],
  [enable_other=yes], [enable_other=no])
dnl AS_IF([test "x$enable_other" = "xyes"],
dnl   [AC_CHECK_LIB([other], [other_version], [], [AC_MSG_FAILURE([$other_fail_msg])])])
AM_CONDITIONAL([ENABLE_OTHER], [test "x$enable_other" = "xyes"])

AC_CONFIG_FILES(Makefile)
AC_OUTPUT

the_subdir/Makefile.am:

lib_LIBRARIES = lib_mytest.a                                                                                                                                                                                                                                                        

lib_mytest_a_SOURCES = mytest.c

if ENABLE_OTHER
lib_mytest_a_SOURCES += mytest_other.c
endif

include_HEADERS = mytest.h

if ENABLE_OTHER
lib_mytest_a_SOURCES += mytest_other.h
endif

这是我在运行autoreconf -v -i 时得到的(注意它不会递归到子目录中):

autoreconf: Entering directory `.'
autoreconf: configure.ac: not using Gettext
autoreconf: running: aclocal 
autoreconf: configure.ac: tracing
autoreconf: configure.ac: not using Libtool
autoreconf: running: /usr/bin/autoconf
autoreconf: configure.ac: not using Autoheader
autoreconf: running: automake --add-missing --copy --no-force
configure.ac:3: installing './compile'
configure.ac:2: installing './install-sh'
configure.ac:2: installing './missing'
Makefile.am: installing './depcomp'
autoreconf: Leaving directory `.'

这是./configure的输出,它抱怨the_subdir中没有./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... /usr/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 whether make supports the include directive... yes (GNU style)
checking dependency style of gcc... gcc3
checking that generated files are newer than configure... done
=== configuring in the_subdir (/home/sena/hello/the_subdir)
configure: WARNING: no configuration information is in the_subdir
configure: creating ./config.status
config.status: creating Makefile
config.status: executing depfiles commands

但如果我也在子目录中运行autoreconf -i,然后在根目录中运行./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... /usr/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 whether make supports the include directive... yes (GNU style)
checking dependency style of gcc... gcc3
checking that generated files are newer than configure... done
=== configuring in the_subdir (/home/sena/hello/the_subdir)
configure: running /bin/bash ./configure '--prefix=/home/sena/hello' --disable-option-checking  '--enable-other' '--srcdir=.' --cache-file=
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for a thread-safe mkdir -p... /usr/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 whether make supports the include directive... yes (GNU style)
checking dependency style of gcc... gcc3
checking for ar... ar
checking the archiver (ar) interface... ar
checking for ranlib... ranlib
checking that generated files are newer than configure... done
configure: creating ./config.status
config.status: creating Makefile
config.status: executing depfiles commands
configure: creating ./config.status
config.status: creating Makefile
config.status: executing depfiles commands

任何有关正确方法的帮助将不胜感激!

【问题讨论】:

  • 你有没有机会自己解决这个问题?我也遇到了同样的问题,这让我发疯了。

标签: autotools


【解决方案1】:

AX_SUBDIRS_CONFIGURE 不是 Autoconf 的一部分(AX_ 前缀告诉你)。它可以从 GNU 托管的 Autoconf 存档中获得,但宏本身并不由 GNU 或 Autoconf 开发人员拥有或维护。因此,Autoconf 的autoreconf 工具并没有赋予该宏任何特殊意义或给予它给予AC_CONFIG_SUBDIRS 的那种特殊处理。就前者的文档所暗示的情况而言,该文档存在缺陷。

另一种方法是改用AC_CONFIG_SUBDIRS,并依靠将--enable-other 传递给顶级configure 脚本,然后它将转发到(每个)子配置。您可以为顶级 configure 提供一个自动执行此操作的包装脚本,以减少由于未能指定该标志而导致配置错误的可能性。

另一种选择是(再次)使用AC_CONFIG_SUBDIRS,并依赖于其行为的这个细节:

如果给定目录包含configure.gnu,则运行它而不是configure

(Autoconf manual)

虽然...

这适用于可能使用非 Autoconf 脚本 Configure 的软件包, 不能通过包装器调用configure,因为它会是 不区分大小写的文件系统上的相同文件。

...您也可以通过输入configure.gnu 来将其用于您的目的,如下所示:

#!/bin/sh
exec "${0%.gnu}" --enable-other "$@"

主要的另一种选择是满足autoreconf 不递归到子目录。根据具体情况,这可能被视为功能而不是错误。

在这种情况下,问题的描述表明 Autotools 构建的构建系统组件在子目录中尚不可用,但为什么会这样呢?基于 Autotools 的项目的源代码分发应该包括已经构建的自动工具,这样只想构建项目的人根本不需要自己拥有 Autotools。如果您在自己的源代码分发中分发第三方项目,这同样适用。

在某些情况下,将子项目合并到主项目中可能也是一个可行的选择,这样它就不再需要担心单独的配置脚本了。

【讨论】:

  • 所以您是说AX_SUBDIRS_CONFIGURE 根本不起作用,是吗? —关于您的最后一个选择,不幸的是,这并不适用于所有情况,例如在构建包含第三方依赖项作为 Git 子模块的项目时。一个肮脏的解决方法是拥有一个执行正确调用的顶级构建脚本,但是如果顶级项目可以使用自动工具而不需要此类自定义脚本包装器,那当然会更好。
  • 不,@KonradRudolph,我是说它不适用于问题所询问的特定用途,以 autoreconf 实用程序为中心。这种情况也不是AC_CONFIG_SUBDIRS 的重点。这些宏都主要是关于生成的configure 脚本的行为,而不是关于autoconfautomakeautoreconfetc 工具。
  • 啊,谢谢。在我看来,这两种用途非常紧密地交织在一起。毕竟没有autoconf,没有configure 脚本。
  • @KonradRudolph,我同意“依赖”,但“交织”暗示了与 Autotools 所设计的不同的使用模型。运行autoreconf 是项目开发人员/维护人员的一项活动,一旦建立了构建系统,就很少执行。其他所有人都应该获得已经构建的自动工具,尤其是 configure 脚本,并且不需要运行自动工具。例如,make dist 生成的 tarball 将提供该内容。
  • 我认识到近年来在某些地方已经有了一个想法,configureMakefile.in 和类似的文件应该被视为构建文件,因此不应分发——尤其是在修订控制系统的地方被压入作为分发机制的服务——但这种方法充满了更多的问题,而不仅仅是需要额外的工具来构建软件。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-03-23
  • 2018-06-21
  • 2014-07-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多