0

First of all, sorry if I end up making a too long post, but I think it would be missing information otherwise.

I'd like to include my repository version in each build. There is a main makefile that masters some other ones in their respective subdirectories. The subprojects are "automaked".

I am trying to pass a variable containing the svnversion to inner Makefiles like this:

# 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 $@ finished."

subdirs: $(SUBDIRS)

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

Each subdirectory has a Makefile.am and configure.ac like this:

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], [<suport@domain>])
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

I expected this to work, but autotools are embedding REPO_VERSION in the makefile when run, and changes in the main Makefile's REPO_VERSION are ignored in further builds.

A piece of an output looks like this:

== 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'

The program outputs:

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

This clearly is not what I wanted.

Can anybody here please give a way to fix this?

Thanks.

j4x
  • 3,595
  • 3
  • 33
  • 64

2 Answers2

4

In your top level make file add

export REPO_VERSION

and modify each Makefile.am to have

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

The export directive makes it so that the value of REPO_VERSION is exported to recursive make invocations. The Makefile.am snippet sets a default value for REPO_VERSION if it is not given (e.g. make is run from the shell in the subdirectory) and AM_CPPFLAGS specifies the default value of CPPFLAGS for all targets in that Makefile. If you have a target specific _CPPFLAGS variable, you should either add $(AM_CPPFLAGS) to that or include the -DREPO_VERSION="$(REPO_VERSION)" in it. With a bit more effort you can add some stuff into the configure.ac files so that the default for REPO_VERSION can be set at configure time.

Geoff Reedy
  • 34,891
  • 3
  • 56
  • 79
  • +1: this is a good solution except that export is not portable, and many make do not support it. – William Pursell Feb 13 '12 at 16:51
  • Allright! That was what I was looking for. The only change is that I had to write `AM_CPPFLAGS = -DREPO_VERSION=\"$(REPO_VERSION)\"` (escaped `"`). Really thanks. – j4x Feb 13 '12 at 17:09
1

You are trying to pass CPPFLAGS via the environment, but I don't see where the invocation of configure is getting CPPFLAGS set in its environment. Try passing it at the command line:

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

Also, you are only running configure once. After the Makefile exists, you do not rerun configure, so you never reset the value of CPPFLAGS in the subdirectory.

Setting the version at configure time is very inconvenient. Take a look here for some techinques that allow the version to be set at make time.

Community
  • 1
  • 1
William Pursell
  • 204,365
  • 48
  • 270
  • 300
  • I agree with your correction, but it does not respond to my question. I would still be tied to regenerating `configure` to see my version updated. I will think about the link you gave latter, but @Geoff Reedy reply just fitted my needs. Thank you. – j4x Feb 13 '12 at 17:12