2013-02-28 37 views
1

我正在開發一個autotools項目,並且是autotools世界的新手。由於各種原因,在底部詳細介紹了完整性,我有一個shell腳本,我想從中獲取輸出以供makefile使用。如何在編譯時將shell腳本輸出到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的,這意味着abs_top_builddir可以訪問的唯一地方的錯誤是在配置時間AC_CONFIG_FILES生成的配置文件。有關於爲什麼我想在鏈接問題中執行此操作的詳細信息。

+0

make變量'$(abs_top_builddir)'有什麼問題? – 2013-02-28 13:33:48

+0

@WilliamPursell,我會編輯這個問題來解釋這一點。 – crobar 2013-02-28 13:45:05

+0

@WilliamPursell,我現在編輯過,如果你有一個想法,我會接受完全不同的解決方案。我是新來的。 – crobar 2013-02-28 13:52:50

回答

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(需要distcheck,在這裏我們要測試的一切)和--with-mkfoo=external(一個善良包裝維護者,誰不喜歡捆綁子項目)。
  2. AM_SUBST_NOTMAKE([MKFOO])停止automakeMakefile.in生成MKFOO = @[email protected]表格的一行。我們需要有條件地完成這項任務。
  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要使用的內部複製,因爲它是更好地行使在源碼包中的一切。

現在,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 2013-03-05 09:50:22

+0

有一件事我忘了提及,在實際情況下,子項目只需要開發者,它被用來生成一些源代碼。它不是必需的發行版,它只會發佈創建的代碼,所以'make dist'不需要包含'foo'。 – crobar 2013-03-05 10:03:44

+0

然後,我會將構建工具分解到其自己的項目中。要求開發者安裝它,並將主要項目中的所有黑魔法帶走。 – 2013-03-05 11:11:05

0

在你的Makefile.am文件中,下列行不起作用?

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

'FOOPLACE'是由條件生成的,請參閱我的鏈接問題中的詳細信息,以瞭解爲什麼我無法執行此操作。 – crobar 2013-03-04 20:11:43

0

FOOPLACE似乎是由它在configure.ac存在的條件來創建,即使條件不成立(詳見鏈接的問題)。因此,它是現在,但在製作時是空的。它也似乎變量不能在Makefile.am中重新定義,但是,它們可以被附加到。由於FOOPLACE爲空,因此可以使用以下內容將腳本的輸出添加到腳本中。

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

如果有人提出更好的答案,我會很樂意接受它! – crobar 2013-03-04 20:31:37

+0

Jack Kelly在上面添加了真實的答案。 – crobar 2013-03-05 10:10:55