如何在make make时将shell脚本输出到Makefile.am?

时间:2013-02-28 13:03:08

标签: autotools autoconf automake

我正在开发一个autotools项目,并且是autotools世界的新手。由于各种原因,在底部详细说明完整性,我有一个shell脚本,我想从中获取输出以供我的makefile使用。

我的情况类似于以下情况。 Autoconf从AC_CONFIG_FILES命令生成脚本。 e.g。

AC_CONFIG_FILES([thescript], [chmod +x thescript])

thescript.in

#!/bin/sh
# -*- sh -*-
# @configure_input@
echo @abs_top_builddir@/bar/foo

我真正想做的是使用@abs_top_builddir@/bar/foo返回的内容在我的Makefile中使用。我想在make时在变量中提供这个值,并且能够在我的Makefile.am中访问它,比如$(FOOPLACE)。我怎样才能做到这一点?

我需要此/额外信息的原因

这个问题与我之前的一个问题有关:

How to get absolute path to top build directory in autoconf configure.ac?

项目需要一个子项目,它有自己的makefile和configure.ac。子项目是一个程序,用于为主项目生成源文件。可以选择禁用此项目的构建,并尝试使用已安装的版本。在这种情况下,已安装版本的位置在变量FOOPLACE(uisng AC_PATH_PROG)中提供。当我使用本地构建的verision时,我想将它的位置放在FOOPLACE中。然后,该变量在Makefile.am中用作$(FOOPLACE)

似乎autoconf中存在一个错误,这意味着可以访问abs_top_builddir的唯一地方是AC_CONFIG_FILES在配置时生成的配置文件。在链接问题中有详细说明我想要这样做的原因。

3 个答案:

答案 0 :(得分:5)

写的问题

在你的Makefile.am中,你可以这样做:

foo.c: foo.in
        FOOPLACE=`./thescript`; $(FOOPLACE) -c -o $@ $<

这样做的好处是不需要GNU-ism就是可移植的Makefile代码。

正确而艰难的方式

我准备了一个使用名为mkfoo的工具的虚拟包。它可以使用主机系统上的内部副本或副本。

让我们先来看configure.ac

AC_PREREQ([2.67])
AC_INIT([parent], [0], [jack@jackkelly.name])
AM_INIT_AUTOMAKE([foreign])

AC_ARG_WITH([mkfoo],
  [AS_HELP_STRING([--with-mkfoo],
    [Path to mkfoo, "external", "internal", or "check" @<:@check@:>@])],
  [MKFOO=$withval],
  [with_mkfoo=check])
AS_IF([test "$with_mkfoo" = check -o "$with_mkfoo" = external],
  [AC_PATH_PROG([MKFOO], [mkfoo], [no])])
AS_IF([test "$with_mkfoo" = external -a "$MKFOO" = no],
  [AC_MSG_ERROR([External mkfoo demanded, but not found.])])

dnl We conditionally set MKFOO in Makefile.am
AM_SUBST_NOTMAKE([MKFOO])

AM_CONDITIONAL([USE_INTERNAL_MKFOO],
  [test "$with_mkfoo" = internal -o "$MKFOO" = no])
AM_COND_IF([USE_INTERNAL_MKFOO], [AC_CONFIG_SUBDIRS([mkfoo])])

AC_CONFIG_FILES([Makefile src/Makefile])
AC_OUTPUT

这里有一些事情发生:

  1. 默认行为是“检查mkfoo,如果不存在,则构建并使用捆绑的副本”。另请注意,它支持--with-mkfoo=PATH(用户可能在奇数位置安装了副本),--with-mkfoo=internal(distcheck需要,我们要测试所有内容)和--with-mkfoo=external(对...软件包维护者,不喜欢捆绑的子项目。)
  2. AM_SUBST_NOTMAKE([MKFOO])阻止automakeMKFOO = @MKFOO@中生成Makefile.in格式的一行。我们需要有条件地完成这项任务。
  3. 我们设置了一个自动条件,因为我们需要为mkfoo
  4. 内部/外部Makefile.am做不同的事情
  5. 我们有条件地配置mkfoo目录。
  6. 现在,toplevel Makefile.am

    if USE_INTERNAL_MKFOO
    SUBDIRS = mkfoo
    DIST_SUBDIRS = mkfoo
    else
    SUBDIRS =
    DIST_SUBDIRS =
    endif
    SUBDIRS += src
    DIST_SUBDIRS += src
    
    ## Need to make sure the internal tools work during distcheck.
    DISTCHECK_CONFIGURE_FLAGS = --with-mkfoo=internal
    dist-hook:
    if ! USE_INTERNAL_MKFOO
            cp -fpR $(srcdir)/mkfoo $(distdir)
    endif
    

    这里发生了什么:

    1. 有条件地进入mkfoo,并在需要src的{​​{1}}之前执行此操作。
    2. 由于有时$MKFOO 甚至没有配置,因此它可能没有mkfoo。这意味着我们已经损坏了Makefile(以及make dist)。因此,我们必须有条件地设置make distcheck,如果我们没有配置DIST_SUBDIRS,那么确保它的分发成为我们的责任。
    3. 当我们mkfoo我们想要使用内部副本时,因为最好在源代码压缩包中运用所有内容。
    4. 现在,make distcheck

      src/Makefile.am

      除了if USE_INTERNAL_MKFOO MKFOO = $(abs_top_builddir)/mkfoo/mkfoo else MKFOO = @MKFOO@ endif bin_SCRIPTS = foo CLEANFILES = foo EXTRA_DIST = foo.in foo: foo.in $(MKFOO) < $< > $@

      的条件分配之外,这里没有什么令人震惊的

      MKFOO

      src/foo.in

      现在为子包。 I am foo.in!

      mkfoo/configure.ac

      如你所见,没什么特别的。那么AC_PREREQ([2.67]) AC_INIT([mkfoo], [0], [jack@jackkelly.name]) AM_INIT_AUTOMAKE([foreign]) AC_PROG_CC AC_CONFIG_FILES([Makefile]) AC_OUTPUT 呢?

      mkfoo/Makefile.am

      bin_PROGRAMS = mkfoo

      mkfoo/mkfoo.c

      只是一个虚拟测试程序。

答案 1 :(得分:0)

什么不适用于Makefile.am中的以下行?

FOOPLACE=$(shell @abs_top_builddir@/thescript)

答案 2 :(得分:0)

FOOPLACE似乎是由条件中的configure.ac中的存在创建的,即使条件不正确(有关详细信息,请参阅链接的问题)。因此它存在但在制作时是空的。它似乎也无法在Makefile.am中重新定义变量,但是,它们可以附加到。由于FOOPLACE为空,因此可以使用以下内容将脚本的输出添加到其中。

FOOPLACE+=$(shell $(abs_top_builddir)/thescript)