autoconf:如何替换库前缀?

autoconf: how do I substitute the library prefix?

CLISP's interface to PARI is configured with the configure.in containing AC_LIB_LINKFLAGS([pari]) from lib-link.m4.

构建过程还需要 Makefile 知道 PARIdatadir 所在的位置。为此,Makefile.in

prefix = @LIBPARI_PREFIX@
DATADIR = @datadir@

并希望找到 $(DATADIR)/pari/pari.desc(通常 /usr/share/pari/pari.desc/usr/local/share/pari/pari.desc).

这似乎适用于 Mac OS X,其中 PARIhomebrew 安装在 /usr/local(和 LIBPARI_PREFIX=/usr/local)中,但不在 Ubuntu 上,其中 PARI/usr 中,而 LIBPARI_PREFIXempty.

如何将 PARIdatadir 的位置插入 Makefile

PS。我也在 autoconf mailing list.

上问过这个

PPS。为了回应@BrunoHaible 的建议,这里是在 Linux 上进行调试的微不足道的尝试(其中 LIBPARI_PREFIXempty)。

$ bash -x configure 2>&1 | grep found_dir
+ found_dir=
+ eval ac_val=$found_dir
+ eval ac_val=$found_dir

您正试图以非预期的方式使用 $(prefix)。在基于 Autotools 的构建系统中,$(prefix) 表示您正在构建的软件的 target 安装位置的前缀。通过在 Makefile.in 中设置它,您将覆盖 configure 将尝试分配的前缀。但是,由于您似乎没有任何安装目标,至少在那个级别上,这可能更多的是形式不佳的问题,而不是故障原因。

How do I insert the location of the PARI's datadir into the Makefile?

我建议在您的配置脚本中计算或发现所需的目录,并通过其自己的输出变量将其导出到生成的 Makefile。让我们先看第二部分,因为它很简单。在 configure.in 中,以某种方式找到所需的数据目录并将其分配给变量

DATADIR=...

,您可以通过 AC_SUBST 宏创建一个输出变量:

AC_SUBST([DATADIR])

由于您只使用 Autoconf,而不是 Automake,因此您可以通过更改 Makefile.in:[=40= 中的分配来手动将其接收到 Makefile 中]

DATDIR = @DATADIR@

现在,至于首先定位数据目录,您必须先知道您要实现的是什么,然后才能实现它。从你的问题和后续评论来看,在我看来你想要这个:

  1. 如果有的话,使用用户明确指定的数据目录。否则,

  2. 查找与共享库位置相关的数据目录。如果在那里找不到,那么

  3. (可选)在指定给configureprefix下查找,或者具体在指定的datadir中查找(两者都可能来自顶层configure).最后,如果还是没找到那么

  4. 查看一些标准位置。

要创建一个 configure 选项,用户可以通过该选项指定自定义数据目录,您可能会使用 AC_ARG_WITH 宏,可能像这样:

AC_ARG_WITH([pari-datadir], [AS_HELP_STRING([--with-pari-datadir],
    [explicitly specifies the PARI data directory])],
  [], [with_pari_datadir=''])

感谢@BrunoHaible,我们看到虽然 Gnulib 手册没有记录它,但宏的内部文档指定如果 AC_LIB_LINKFLAGS 定位到 libpari 那么它将 LIBPARI_PREFIX 设置为库目录前缀.当使用 --with-libpari 选项为其提供替代搜索位置时,您会发现它确实有效,因此我建议使用它。您当然可以尝试调试 AC_LIB_LINKFLAGS 以使其在找到 lib 的所有情况下都设置为 LIBPARI_PREFIX,但是如果您不想这样做,那么您可以解决它(请参阅下面)。

虽然在 configure 中可以访问默认或指定的安装前缀作为 $prefix,但我建议改为转到指定的 $datadir。然而,这有点棘手,因为默认情况下它间接引用前缀。因此,您可以这样做:

eval "datadir_expanded=${datadir}"

最后,您可以硬编码一组前缀,例如 /usr/usr/local


根据上述所有内容,您的 configure.in 可能会执行以下操作:

DATADIR=
for d in \
    ${with_pari_datadir} \
    ${LIBPARI_PREFIX:+${LIBPARI_PREFIX}/share/pari} \
    ${datadir_expanded}/pari \
    /usr/local/share/pari \
    /usr/share/pari
do
  AS_IF([test -r "$[]d/pari.desc"], [DATADIR="$[]d"; break])
done

AS_IF([test x = "x$DATADIR"], [AC_MSG_ERROR(["Could not identify PARI data directory"])])
AC_SUBST([DATADIR])

与其猜测 datadir 的位置,不如问问 PARI/GP 它的 datadir 在哪里?即,

$ echo "default(datadir)" | gp -qf
"/usr/share/pari"

成功了。