如何在制作时将Shell脚本输出到Makefile.am中? [英] How to get shell script output into Makefile.am at make time?

查看:100
本文介绍了如何在制作时将Shell脚本输出到Makefile.am中?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在从事一个自动工具项目,并且是自动工具领域的新手.由于种种原因,为了完整起见,在底部进行了详细说明,我有一个Shell脚本,我希望从中获取输出以供在我的Makefile中使用.

I am working on an autotools project, and am a newbie to the autotools world. For various reasons, detailed at the bottom for completeness, I have a shell script from which I want to get the output for use in my makefile.

我的情况类似于以下情况. Autoconf通过AC_CONFIG_FILES命令生成脚本.例如

I have a situation similar to the following. Autoconf generates a script from an AC_CONFIG_FILES command. e.g.

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

thescript.in

thescript.in

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

我真正想做的是使用@abs_top_builddir@/bar/foo返回的任何东西在我的Makefile中使用.我想在make时使该值在变量中可用,并能够以例如$(FOOPLACE)的形式在我的Makefile.am中访问它.我该如何实现?

What I really want to do is use whatever is returned by @abs_top_builddir@/bar/foo for use in my Makefile. I want to have this value available in a variable at make time and be able to access it in my Makefile.am as, say $(FOOPLACE). How can I achieve this?

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

这个问题与我先前的问题有关:

This question is related to a previous question of mine located here:

如何获取

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

The project requires a subproject which has its own makefile and configure.ac. The subproject is a program which is used to generate source files for the main project. There is an option to disable the building of this project and attempt to use an installed version instead. In this case, the location of the installed version is provided in the variable FOOPLACE (uisng AC_PATH_PROG). When I am using the locally built verision I want to put the location of it in FOOPLACE instead. The variable is then used in Makefile.am as $(FOOPLACE).

似乎autoconf中存在一个错误,这意味着可以访问abs_top_builddir的唯一位置是在配置时由AC_CONFIG_FILES生成的配置文件中.在链接的问题中有我为什么要这样做的详细信息.

It seems there is a bug in autoconf which means the only place that abs_top_builddir can be accessed is in configure files generated by AC_CONFIG_FILES at configure time. There are details of why I want to do this in the linked question.

推荐答案

书面问题

在您的Makefile.am中,您可以执行以下操作:

The question as written

In your Makefile.am, you could do something like this:

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

这样做的好处是,在可移植的Makefile代码中不需要GNU-ism.

That has the benefit of not requiring a GNU-ism in what is meant to be portable Makefile code.

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

I have prepared a dummy package that uses a tool called mkfoo. It can use the internal copy or the copy on the host's system.

我们先来看一下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(对软件包维护者的好意,他们不愿意这样做). t像捆绑的子项目一样.)
  2. AM_SUBST_NOTMAKE([MKFOO])阻止automakeMakefile.in中生成格式为MKFOO = @MKFOO@的行.我们需要有条件地进行分配.
  3. 我们设置了有条件的自动制作功能,因为我们需要对Makefile.am内的内部/外部mkfoo做不同的事情
  4. 我们有条件地配置mkfoo目录.
  1. The default behaviour is "check for mkfoo, if it's not there, build and use the bundled copy". Note also that it supports --with-mkfoo=PATH (user may have a copy installed in an odd place), --with-mkfoo=internal (needed for distcheck, where we want to test everything) and --with-mkfoo=external (a kindness to package maintainers, who don't like bundled subprojects).
  2. AM_SUBST_NOTMAKE([MKFOO]) stops automake from generating a line of the form MKFOO = @MKFOO@ in Makefile.in. We need to do that assignment conditionally.
  3. We set up an automake conditional because we need to do different stuff for internal/external mkfoo inside Makefile.am
  4. We configure the mkfoo directory conditionally.

现在,顶级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,并在需要$MKFOOsrc之前执行.
  2. 由于有时mkfoo甚至没有配置 ,因此它可能没有Makefile.这意味着我们已经破坏了make dist(扩展名为make distcheck).因此,我们还必须有条件地设置DIST_SUBDIRS,如果没有配置mkfoo,则确保其分发成为我们的责任.
  3. 当我们make distcheck时,我们希望使用内部副本,因为最好在源代码压缩包中执行所有操作.
  1. Conditionally recurse into mkfoo, and do it before src, which needs $MKFOO.
  2. Because there are times mkfoo is not even configured, it might not have a Makefile. That means we've broken make dist (and by extension, make distcheck). So we have to set DIST_SUBDIRS conditionally as well, and if we don't have mkfoo configured ensuring that it's distributed becomes our responsibility.
  3. When we make distcheck we want to use the internal copy because it's better to exercise everything in the source tarball.

现在,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的条件赋值之外,这里没有其他令人震惊的地方.

There is nothing shocking here except the conditional assignment of 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呢?

As you can see, nothing special. What about mkfoo/Makefile.am?

bin_PROGRAMS = mkfoo

mkfoo/mkfoo.c:

#include <stdio.h>
int main(int argc, char *argv[]) {
  puts("Internal mkfoo.");
  return 0;
}

只是一个虚拟测试程序.

Just a dummy test program.

这篇关于如何在制作时将Shell脚本输出到Makefile.am中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆