3

私はautotoolsプロジェクトに取り組んでおり、autotoolsの世界の初心者です。さまざまな理由により、完全を期すために下部に詳述されていますが、makefile で使用する出力を取得するシェル スクリプトがあります。

次のような状況があります。Autoconf は、AC_CONFIG_FILESコマンドからスクリプトを生成します。例えば

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 で使用するために返されたものをすべて使用することです。この値をメイク時に変数で使用できるようにし、Makefile.am でアクセスできるようにしたいと考えています$(FOOPLACE)。どうすればこれを達成できますか?

これが必要な理由 / 追加情報

この質問は、ここにある私の以前の質問に関連しています。

autoconf configure.acでトップビルドディレクトリへの絶対パスを取得するには?

このプロジェクトには、独自の makefile と configure.ac を持つサブプロジェクトが必要です。サブプロジェクトは、メイン プロジェクトのソース ファイルを生成するために使用されるプログラムです。このプロジェクトのビルドを無効にして、代わりにインストール済みのバージョンを使用するオプションがあります。この場合、インストールされたバージョンの場所は変数FOOPLACE( uisng AC_PATH_PROG) で提供されます。FOOPLACEローカルにビルドされたバージョンを使用している場合、代わりにその場所を入れたいと思います。この変数は Makefile.am で として使用され$(FOOPLACE)ます。

autoconf にバグがあるようです。つまり、abs_top_builddir にアクセスできる唯一の場所は、AC_CONFIG_FILES構成時に生成された構成ファイル内にあるということです。リンクされた質問に、なぜこれをやりたいのかの詳細があります。

4

3 に答える 3

5

書かれた質問

Makefile.amでは、次のようなことができます。

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

これには、移植可能なMakefileコードであることが意図されているものにGNU-ismを必要としないという利点があります。

正しくて難しい方法

というツールを使ったダミーパッケージを用意しました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])automakeでフォームの行を生成するのを停止MKFOO = @MKFOO@Makefile.inます。その割り当てを条件付きで行う必要があります。
  3. mkfoo内部/外部の内部で異なることを行う必要があるため、automake条件付きを設定しましたMakefile.am
  4. mkfoo条件付きでディレクトリを設定します。

さて、トップレベル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に実行します。これには。が必要$MKFOOです。
  2. 設定されていない場合もあるため、mkfooがない場合があります。それは私たちが壊れたことを意味します(そしてひいては)。したがって、条件付きで設定する必要があります。設定していない場合は、確実に配布されるようにすることが私たちの責任になります。Makefilemake distmake distcheckDIST_SUBDIRSmkfoo
  3. make distcheckソース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

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

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

単なるダミーのテストプログラム。

于 2013-03-05T06:06:13.430 に答える
0

Makefile.am の次の行で何が機能しないのですか?

FOOPLACE=$(shell @abs_top_builddir@/thescript)
于 2013-03-04T17:51:13.887 に答える
0

FOOPLACE条件が true でない場合でも、条件付きで configure.ac に存在することによって作成されたようです (詳細については、リンクされた質問を参照してください)。したがって、存在しますが、作成時には空です。また、変数は Makefile.am で再定義できないようですが、追加することはできます。は空であるためFOOPLACE、スクリプトからの出力を次のように追加できます。

FOOPLACE+=$(shell $(abs_top_builddir)/thescript)
于 2013-03-04T20:22:51.750 に答える