2013-02-28 4 views
1

Я работаю над проектом autotools, и я новичок в мире autotools. По разным причинам, подробно описанным внизу для полноты, у меня есть сценарий оболочки, из которого я хочу получить вывод для использования в моем make-файле.Как получить вывод скрипта оболочки в Makefile.am во время выполнения?

У меня есть ситуация, аналогичная следующей. Autoconf генерирует скрипт из команды AC_CONFIG_FILES. например

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

thescript.in

#!/bin/sh 
# -*- sh -*- 
# @[email protected] 
echo @[email protected]/bar/foo 

То, что я действительно хочу сделать, это использовать то, что возвращается @[email protected]/bar/foo для использования в моем Makefile. Я хочу, чтобы это значение доступно в переменной на время выполнения и иметь доступ к нему в моем Makefile.am, например, $(FOOPLACE). Как я могу это достичь?

Причина Я требую Это/Экстренная Информация

Этот вопрос связан с предыдущим вопросом о руднике здесь:

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

Проект требует подпроект, который имеет свой собственный Makefile и configure.ac. Подпроект - это программа, которая используется для генерации исходных файлов для основного проекта. Существует возможность отключить создание этого проекта и попытаться использовать установленную версию. В этом случае местоположение установленной версии предоставляется в переменной FOOPLACE (uisng AC_PATH_PROG). Когда я использую локально построенную версию, я хочу поместить ее ее в FOOPLACE. Затем переменная используется в Makefile.am как $(FOOPLACE).

Похоже, что в autoconf есть ошибка, что означает, что доступ к абс_top_builddir можно найти только в файлах конфигурации, сгенерированных AC_CONFIG_FILES во время настройки. Есть детали того, почему я хочу сделать это в связанном вопросе.

+0

Что не так с переменной make '$ (abs_top_builddir)'? –

+0

@WilliamPursell, я отредактирую вопрос, чтобы объяснить это. – crobar

+0

@WilliamPursell, теперь я отредактирован, я открыт для совершенно разных решений, если у вас есть идея. Я новичок в этом. – crobar

ответ

4

вопрос, как написано

В вашем Makefile.am, вы могли бы сделать что-то вроде этого:

foo.c: foo.in 
     FOOPLACE=`./thescript`; $(FOOPLACE) -c -o [email protected] $< 

Это имеет преимущество не требует GNU-изма в том, что имеется в виду быть портативным кодом Makefile.

Право и трудный путь

Я подготовил фиктивный пакет, который использует инструмент под названием mkfoo. Он может использовать внутреннюю копию или копию в системе хоста.

Давайте сначала посмотрим на configure.ac:

AC_PREREQ([2.67]) 
AC_INIT([parent], [0], [[email protected]]) 
AM_INIT_AUTOMAKE([foreign]) 

AC_ARG_WITH([mkfoo], 
    [AS_HELP_STRING([--with-mkfoo], 
    [Path to mkfoo, "external", "internal", or "check" @<:@[email protected]:>@])], 
    [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 (необходимо для проверки, где мы хотим протестировать все) и --with-mkfoo=external (доброжелательность к сторонним разработчикам пакетов, которым не нравятся связанные подпроекты).
  2. AM_SUBST_NOTMAKE([MKFOO]) остановок automake от создания строки MKFOO = @[email protected] в Makefile.in. Нам нужно сделать это назначение условно.
  3. Мы создали Automake условное, потому что мы должны делать разные вещи для внутреннего/внешнего mkfoo внутри 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даже не настроен, он может не иметь Makefile. Это означает, что мы сломали make dist (и, в дополнение, make distcheck). Таким образом, мы также должны установить DIST_SUBDIRS, а если у нас нет mkfoo, то конфигурация, обеспечивающая его распространение, станет нашей ответственностью.
  3. Когда мы make distcheck, мы хотим использовать внутреннюю копию, потому что лучше всего использовать все в исходном tarball.

Теперь src/Makefile.am:

if USE_INTERNAL_MKFOO 
MKFOO = $(abs_top_builddir)/mkfoo/mkfoo 
else 
MKFOO = @[email protected] 
endif 

bin_SCRIPTS = foo 
CLEANFILES = foo 
EXTRA_DIST = foo.in 

foo: foo.in 
     $(MKFOO) < $< > [email protected] 

Там нет ничего шокирующего здесь, кроме условного присвоения MKFOO.

src/foo.in:

I am foo.in! 

Теперь для подпакета. mkfoo/configure.ac:

AC_PREREQ([2.67]) 
AC_INIT([mkfoo], [0], [[email protected]]) 
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; 
} 

Просто фиктивная тестовая программа.

+0

Удивительный, спасибо за все ваше время. – crobar

+0

Одна вещь, о которой я забыл упомянуть, в реальном случае подпроект требуется только для разработчиков, он используется для генерации некоторого исходного кода. Это не требуется для дистрибутивов, которые просто отправят созданный код, поэтому 'make dist' не нужно включать' foo'. – crobar

+0

Затем я сломал инструмент построения самостоятельно. Требовать от разработчиков, чтобы он был установлен и вытащил всю черную магию из вашего основного проекта. –

0

Что не работает со следующей строкой в ​​вашем Makefile.am?

FOOPLACE=$(shell @[email protected]/thescript) 
+0

'FOOPLACE' генерируется условием, см. Подробности в моем связанном вопросе, почему я не могу этого сделать. – crobar

0

FOOPLACE, кажется, создан благодаря своему присутствию в configure.ac в условном, даже если условие не верно (см связанный вопрос для деталей). Поэтому он присутствует, но пуст во время выполнения. Также кажется, что переменные не могут быть переопределены в Makefile.am, однако они могут быть добавлены. Поскольку FOOPLACE пуст, вывод скрипта может быть добавлен к нему со следующим.

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

Если кто-то предложит лучший ответ, я буду рад принять его! – crobar

+0

Джек Келли добавил настоящий ответ выше. – crobar

Смежные вопросы