2012-02-13 88 views
0

首先,抱歉,如果我最终做了一个太长的帖子,但我认为它会丢失信息,否则。Makefile递归不通过CPPFLAGS

我想在每个版本中包含我的存储库版本。 有一个主makefile在其各自的子目录中掌握了一些其他的。 子项目是“automaked”。

我试图通过包含可变的svnversion到内Makefiles这样的:

# Main Makefile 

SUBDIRS = sd1 sd2 
REPO_VERSION = `svnversion` 
export ECHO = @echo 
export CPPFLAGS 

all: versioned 
    $(ECHO) "Build of all projects in $(PWD) finished." 

clean : 
    $(ECHO) "Cleaning up entire project tree..." 
    -for d in $(SUBDIRS); do ($(ECHO) "Cleaning up \"$$d\""; $(MAKE) -C $$d clean); done 

.PHONY: versioned unversioned $(SUBDIRS) 

versioned: CPPFLAGS = -DREPO_VERSION=\"v$(REPO_VERSION)\" 

versioned: subdirs 

unversioned: subdirs 

versioned unversioned: 
    $(ECHO) "Build [email protected] finished." 

subdirs: $(SUBDIRS) 

$(SUBDIRS): 
    $(ECHO) "== Building [email protected]      ==" 
    $(ECHO) " [ CPPFLAGS = \"$(CPPFLAGS)\" ]" 
    (cd [email protected] && \ 
     ([ -f Makefile ] || \ 
      (aclocal  && \ 
      autoheader && \ 
      automake --foreign --add-missing && \ 
      autoconf && \ 
      configure)) && \ 
     $(MAKE) \ 
     ) 

每个子目录具有Makefile.amconfigure.ac这样的:

Makefile.am

# Makefile.am in "sd1" and "sd2" 

bin_PROGRAMS = app 
app_SOURCES = source.c 

configure.ac

AC_PREREQ(2.59) 

AC_INIT([app], [1.00], [<[email protected]>]) 
AM_INIT_AUTOMAKE 

AC_CONFIG_HEADER([config.h]) 

# Checks for programs. 
AC_PROG_CC 
AC_PROG_CPP 
AC_PROG_INSTALL 
AC_PROG_LN_S 
AC_PROG_MAKE_SET 

# Checks for header files. 
AC_HEADER_STDC 

# Checks for typedefs, structures, and compiler characteristics. 
AC_C_CONST 
AC_TYPE_SIZE_T 

# Output configuration files. 
AC_CONFIG_FILES([Makefile]) 
AC_OUTPUT 

我预计今年的工作,但在运行时自动工具在生成文件中嵌入REPO_VERSION,并在主Makefile中的REPO_VERSION变化被忽略在进一步构建。

一块的输出是这样的:

== Building sd1      == 
    [ CPPFLAGS = "-DREPO_VERSION="1050"" ] 
(cd sd1 && \ 
     ([ -f Makefile ] || \ 
       (aclocal    && \ 
       autoheader  && \ 
       automake --foreign --add-missing && \ 
       autoconf  && \ 
       configure)) && \ 
     make \ 
     ) 
make[1]: Entrando no diretório `./recursive/sd1' 
make all-am 
make[2]: Entrando no diretório `./recursive/sd1' 
gcc -DHAVE_CONFIG_H -I. -DREPO_VERSION=\"1049M\" -g -O2 -MT source.o -MD -MP -MF .deps/source.Tpo -c -o source.o source.c 
mv -f .deps/source.Tpo .deps/source.Po 
gcc -g -O2 -o app source.o 
make[2]: Saindo do diretório `./recursive/sd1' 
make[1]: Saindo do diretório `./recursive/sd1' 

程序输出:

> ./sd1/appVersão = [1049M]. 

这显然不是我想要的。

有人可以在这里请给出一种方法来解决这个问题吗?

谢谢。

回答

4

在您的顶级make文件添加

export REPO_VERSION 

和修改每个Makefile.am有

REPO_VERSION ?= unknown 
AM_CPPFLAGS = -DREPO_VERSION="$(REPO_VERSION)" 

出口指令,使得它使REPO_VERSION的价值出口递归调用作。 Makefile.am片段为REPO_VERSION设置了默认值(例如,make是从子目录中的shell运行的),并且AM_CPPFLAGS为该Makefile中的所有目标指定了CPPFLAGS的默认值。如果您有一个特定于目标的_CPPFLAGS变量,则应该为其添加$(AM_CPPFLAGS)或在其中包含-DREPO_VERSION =“$(REPO_VERSION)”。再花些功夫,你可以在configure.ac文件中添加一些东西,这样就可以在配置时设置REPO_VERSION的默认值。

+0

+1:这是一个很好的解决方案,除了导出不可移植,许多make不支持它。 – 2012-02-13 16:51:38

+0

好吧!那正是我正在寻找的。唯一的变化就是我不得不写'AM_CPPFLAGS = -DREPO_VERSION = \“$(REPO_VERSION)\”'(转义''') – j4x 2012-02-13 17:09:48

1

您试图通过环境传递CPPFLAGS,但我看不到配置的调用在其环境中设置CPPFLAGS的位置。尝试通过它在命令行:

 
$(SUBDIRS): 
    $(ECHO) "== Building [email protected]      ==" 
    $(ECHO) " [ CPPFLAGS = \"$(CPPFLAGS)\" ]" 
    cd [email protected] && autoreconf -i && ./configure CPPFLAGS=$(CPPFLAGS) && $(MAKE) 

此外,您只运行配置一次。 Makefile存在后,您不会重新运行configure,因此您不会重置子目录中CPPFLAGS的值。

在配置时设置版本非常不方便。看一看 here对于一些技术,允许在设置时间的版本。

+0

我同意你的更正,但它没有回应我的问题。我仍然想要重新生成'configure'来查看我的版本,我会考虑你给后者的链接,但是@Geoff Reedy的回复恰好符合我的需求。 – j4x 2012-02-13 17:12:17