Discussion:
Feature suggestion: Option to generate a Makefile include file containing assignments for all of the output variables
Gavin Smith
2013-03-30 14:56:54 UTC
Permalink
autoconf-generated configure scripts substitute strings like @var@ in files
like for the value of output variables set in the configure script. Most of
the time, these will only be used in lines like

var = @var@

in Makefile.in. The Makefile.in may have many of these lines. In fact,
automake scans configure.ac for use of the AC_SUBST macro and automatically
adds such lines to the generated Makefile.in.

It can be confusing to try to understand what it means for variables to
copied from one level of the build system to another. If a user writes
Makefile.in by hand, they will have to write out all these lines manually.
Also, it's hard to read Makefile.in's because of such lines.

My suggestion would provide a simpler way which would work for most use
cases. It would be to generate a file (called, say, "config.mk") which
contained all these assignments automatically. I.e., config.mk would
contain lines like

CC = cc
CXX = g++

and so on. Then in the Makefile, have a line "include config.mk". The
output variables would be referred to in the Makefile as ordinary
environment variable (e.g. $(CC)).

This could be done with a macro like AC_CONFIG_INCLUDE(config.mk) in
configure.ac.

As well as being simpler (only having a Makefile instead of a Makefile and
Makefile.in, and only having one type of variable instead of two (@var@ and
$(var)), this would let the user browse through config.mk to see exactly
what configure decided. At the moment, you would have to read config.status
to do this, which is not easy.

It may be advisable to also produce a config.mk.in file showing what
variables are set. Then a user on a system where configure doesn't work
would know what they had to set manually. (This is the same rationale for
having a config.h.in.)

There is a possible problem with the user running make before they run
configure. In a lot of cases, the user doesn't care about the difference
between make and configure, and wants to use the default configure options.
Then a default config.mk could be included with a a rule to rebuilding
itself by running configure. (GNU make would then read the produced
config.mk in again.) Alternatively, the program developer could decide for
make to spit out a message saying "Please run configure first." if they
want to make running configure manually compulsory.
Nick Bowler
2013-04-01 14:23:16 UTC
Permalink
Post by Gavin Smith
like for the value of output variables set in the configure script. Most of
the time, these will only be used in lines like
in Makefile.in. The Makefile.in may have many of these lines. In fact,
automake scans configure.ac for use of the AC_SUBST macro and automatically
adds such lines to the generated Makefile.in.
It can be confusing to try to understand what it means for variables to
copied from one level of the build system to another. If a user writes
Makefile.in by hand, they will have to write out all these lines manually.
Also, it's hard to read Makefile.in's because of such lines.
My suggestion would provide a simpler way which would work for most use
cases. It would be to generate a file (called, say, "config.mk") which
contained all these assignments automatically. I.e., config.mk would
contain lines like
CC = cc
CXX = g++
and so on. Then in the Makefile, have a line "include config.mk". The
output variables would be referred to in the Makefile as ordinary
environment variable (e.g. $(CC)).
[...]

To be honest, most Autoconf-using packages use Automake, and it's
unclear that Automake would be able to make use of this feature. In
particular, Automake needs to suppress these definitions for assignments
that are explicitly written into Makefile.am. More importantly, a
package can have more than one Makefile.am file, some of which have
explicit assignments and others do not. So I'm not sure if this
feature would be useful to very many packages.

But the good news is that Autoconf can already be used for something
very close to what you are asking. Totally untested, but you could add
something like the following (perhaps with more error checking) to your
bootstrap script:

% autoconf --trace 'AC_SUBST:$1' | sed 's/.*/& = @&@/' > config.mk.in

then add AC_CONFIG_FILES([config.mk]) to configure.ac.

Note also that just because something is AC_SUBSTed does not mean that
it is syntactically valid to stick in a Makefile like this. Automake
also provides AM_SUBST_NOTMAKE to suppress the automatic Makefile.in
assignment, and you may want something similar.

Cheers,
--
Nick Bowler, Elliptic Technologies (http://www.elliptictech.com/)
Gavin Smith
2013-04-03 11:45:49 UTC
Permalink
Thanks, your suggestion works.

I'm not sure if what you say about automake would be true of any kind
of Makefile generator which did what automake did, but I'm still
experimenting with alternatives.
Post by Nick Bowler
Post by Gavin Smith
like for the value of output variables set in the configure script. Most of
the time, these will only be used in lines like
in Makefile.in. The Makefile.in may have many of these lines. In fact,
automake scans configure.ac for use of the AC_SUBST macro and automatically
adds such lines to the generated Makefile.in.
It can be confusing to try to understand what it means for variables to
copied from one level of the build system to another. If a user writes
Makefile.in by hand, they will have to write out all these lines manually.
Also, it's hard to read Makefile.in's because of such lines.
My suggestion would provide a simpler way which would work for most use
cases. It would be to generate a file (called, say, "config.mk") which
contained all these assignments automatically. I.e., config.mk would
contain lines like
CC = cc
CXX = g++
and so on. Then in the Makefile, have a line "include config.mk". The
output variables would be referred to in the Makefile as ordinary
environment variable (e.g. $(CC)).
[...]
To be honest, most Autoconf-using packages use Automake, and it's
unclear that Automake would be able to make use of this feature. In
particular, Automake needs to suppress these definitions for assignments
that are explicitly written into Makefile.am. More importantly, a
package can have more than one Makefile.am file, some of which have
explicit assignments and others do not. So I'm not sure if this
feature would be useful to very many packages.
But the good news is that Autoconf can already be used for something
very close to what you are asking. Totally untested, but you could add
something like the following (perhaps with more error checking) to your
then add AC_CONFIG_FILES([config.mk]) to configure.ac.
Note also that just because something is AC_SUBSTed does not mean that
it is syntactically valid to stick in a Makefile like this. Automake
also provides AM_SUBST_NOTMAKE to suppress the automatic Makefile.in
assignment, and you may want something similar.
Cheers,
--
Nick Bowler, Elliptic Technologies (http://www.elliptictech.com/)
Gavin Smith
2013-04-21 22:20:39 UTC
Permalink
Post by Nick Bowler
Post by Gavin Smith
My suggestion would provide a simpler way which would work for most use
cases. It would be to generate a file (called, say, "config.mk") which
contained all these assignments automatically.
I thought I'd report back what I've been using. I have a m4 file which
I use with aclocal. (It actually creates two files in each
subdirectory (config.mk.in and dir.mk.in), but this would be easy to
change as appropriate.)
Post by Nick Bowler
Note also that just because something is AC_SUBSTed does not mean that
it is syntactically valid to stick in a Makefile like this. Automake
also provides AM_SUBST_NOTMAKE to suppress the automatic Makefile.in
assignment, and you may want something similar.
I'm doing this using a patched automake which sets
am_subst_notmake_$var if var is declared with AM_SUBST_NOTMAKE.

ax_config_include.m4:
--
# Create config.mk.in and dir.mk.in in source tree.
AC_DEFUN([_AX_CONFIG_INCLUDE],
[for ac_file in $@; do
t=$srcdir/$ac_file.in
d=$srcdir/$(dirname $ac_file)/dir.mk.in
rm -f $t $d

for ac_var in $ac_subst_vars; do
eval am_var=am_subst_notmake_\$ac_var
eval am_var_val=\$$am_var
if test -n "$am_var_val"; then :; else
echo $ac_var = \@$ac_var\@ >> $t
fi
done
# These variables are substituted within config.status
# on a Makefile-by-Makefile basis.
for var in \
top_builddir top_build_prefix \
srcdir abs_srcdir top_srcdir abs_top_srcdir \
builddir abs_builddir abs_top_builddir; do
echo "$var = @$var@" >> $d
done
echo am__aux_dir = $am_aux_dir >> $d
done
])

AC_DEFUN([AX_CONFIG_INCLUDE],
[AC_CONFIG_COMMANDS_PRE([_AX_CONFIG_INCLUDE($@)])
# This will cause automake to generate rebuild rules
AC_CONFIG_FILES($@)
for ac_file in $@; do
dir_mk_name=$(dirname $ac_file)/dir.mk
AC_CONFIG_FILES([$dir_mk_name])
done
])
--

This generates a config.mk.in file as well. This is slightly against
current autoconf philosophy; otherwise config.h.in would be generated
by configure instead of the user having to remember to run autoheader.
Post by Nick Bowler
To be honest, most Autoconf-using packages use Automake, and it's
unclear that Automake would be able to make use of this feature. In
particular, Automake needs to suppress these definitions for assignments
that are explicitly written into Makefile.am. More importantly, a
package can have more than one Makefile.am file, some of which have
explicit assignments and others do not. So I'm not sure if this
feature would be useful to very many packages.
Out of interest, is there any reason why anybody would want/need to be
overriding the assignments that emanate from autoconf? (I understand
that it is done, and stopping it being done would be
backwards-incompatible.) Also on tests I did, if a variable was
defined multiple times in a makefile, make took the definition that
occurred latest in the file, so overriding definitions is possible, at
least in GNU make.

Regards,
Gavin Smith
(Apologies for the double reply.)
Post by Nick Bowler
Post by Gavin Smith
like for the value of output variables set in the configure script. Most of
the time, these will only be used in lines like
in Makefile.in. The Makefile.in may have many of these lines. In fact,
automake scans configure.ac for use of the AC_SUBST macro and automatically
adds such lines to the generated Makefile.in.
It can be confusing to try to understand what it means for variables to
copied from one level of the build system to another. If a user writes
Makefile.in by hand, they will have to write out all these lines manually.
Also, it's hard to read Makefile.in's because of such lines.
My suggestion would provide a simpler way which would work for most use
cases. It would be to generate a file (called, say, "config.mk") which
contained all these assignments automatically. I.e., config.mk would
contain lines like
CC = cc
CXX = g++
and so on. Then in the Makefile, have a line "include config.mk". The
output variables would be referred to in the Makefile as ordinary
environment variable (e.g. $(CC)).
[...]
To be honest, most Autoconf-using packages use Automake, and it's
unclear that Automake would be able to make use of this feature. In
particular, Automake needs to suppress these definitions for assignments
that are explicitly written into Makefile.am. More importantly, a
package can have more than one Makefile.am file, some of which have
explicit assignments and others do not. So I'm not sure if this
feature would be useful to very many packages.
But the good news is that Autoconf can already be used for something
very close to what you are asking. Totally untested, but you could add
something like the following (perhaps with more error checking) to your
then add AC_CONFIG_FILES([config.mk]) to configure.ac.
Note also that just because something is AC_SUBSTed does not mean that
it is syntactically valid to stick in a Makefile like this. Automake
also provides AM_SUBST_NOTMAKE to suppress the automatic Makefile.in
assignment, and you may want something similar.
Cheers,
--
Nick Bowler, Elliptic Technologies (http://www.elliptictech.com/)
Loading...