automake
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Creating plain Makefiles with automake


From: Gavin Smith
Subject: Creating plain Makefiles with automake
Date: Wed, 24 Apr 2013 00:10:44 +0100

I've been working recently on making automake create plain Makefiles
when it is run, rather than Makefile.in's, and thought I would share
my progress and thoughts on this.

The Makefile would trigger configure to be run when it is run for the
first time, eliminating the need for both "./configure" and "make" to
be run manually. Why? Basically, for simplicity. I don't feel that
there's a strong philosophical distinction between the configure and
make stages: some of what is done at the make stage could be viewed as
portability checks as well; for example, a compiler deciding what type
of object code to output. It would remove a layer of indirection from
the build system and possibly make it is easier to reason about. In
the long run I'd like to see creating and running a build system to be
as simple as doing something like

$ echo >Makefile.am <<END
bin_PROGRAMS = hello
hello_SOURCES = hello.c beetroot.h rhubarb.h second.c
END
$ automake
$ make

(This would also require generating a configure script, which is an
orthogonal design decision.)

The challenge has been to remove autoconf substitutions from generated
Makefile.in's. Most them are simple assignments like "CC = @CC@", and
I have placed these in a separate file which is included in the
generated Makefile. There are various other uses:

* To toggle particular lines in the makefile at configure time using
automake conditionals. This is possible in a restricted way: we can
toggle commands in makefile rules, but nothing else. I'll give an
example. Currently, automake outputs a rule template like the
following:

.c.o:
@am__fastdepCC_TRUE@    $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF
$(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCC_TRUE@    $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@       $(AM_V_CC)source='$<'
object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@       DEPDIR=$(DEPDIR) $(CCDEPMODE)
$(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@   $(address@hidden@)$(COMPILE) -c $<

Strings like @am__fastdepCC_TRUE@ and @am__fastdepCC_FALSE@ are
replaced with "#" or "" to optionally comment out lines. My modified
version optionally outputs the following instead:

.c.o:
        $(AM_V_CC)
        $(am__fastdepCC_enabled)$(AM_V_at)$(COMPILE) -MT $@ -MD -MP
-MF $(DEPDIR)/$*.Tpo -c -o $@ $<
        $(am__fastdepCC_enabled)$(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo
$(DEPDIR)/$*.Po
        $(am__fastdepCC_disabled)$(am__AMDEP_enabled)$(AM_V_at)source='$<'
object='$@' libtool=no \
        DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
        $(COMPILE) -c  $<
        $(am__AMDEP_disabled)$(AM_V_at)$(COMPILE) -c  $<

Variables like $(am_fastdepCC_enabled) evaluate to either "" or "@: ",
a shell no-op which has the effect of disabling the line. $(AM_V_CC)
has been placed on its own line as ":" doesn't have any effect past a
semi-colon (i.e. ": echo foo; echo bar" will echo bar).

All automake conditionals would need to be TRUE or FALSE at automake
time, which would dramatically reduce their availability. Apart from
the conditionals to pick the dependency tracking method, automake uses
a couple of other configure-time automake conditionals (declared with
AM_CONDITIONAL): am__EXEEXT, and a check whether "maintainer mode" is
enabled. I've only glanced at how these are used, but they don't
appear to be essential.

* @AM_BACKSLASH@ and @AMDEPBACKSLASH@ in conjunction with @am__nodep@
to optionally join lines, as seen above. (Actually, @AM_BACKSLASH@
doesn't appear to be used at all.) These would not be available, but
you can work round it by doubling up the lines you want to create.

* Variables to avoid nested make variable expansion - @AM_V@ used in
the likes of "AM_V_at = $(address@hidden@)" where we would otherwise
$(V). This would be incompatible with some versions of make.

* @am__include@ and @am__quote@ for variance in the syntax of include
directives.

* Miscellaneous substitutions like @SET_MAKE@ (whose functionality can
be replicated using a hack), @ac_configure_input@ (replaced with
"created by automake"), and @PACKAGE@ (we can use $(PACKAGE) instead).

The good news for this approach is it is possible to get rid of all of
the autoconf substitutions. The bad news is that you can't do this
portably; but the lack of portability is limited to make syntax
(syntax of include directives and nested variables), not any other
behaviour or property that autoconf scans for.

One possible problem which was pointed out to me on the autoconf
mailing list with having an included file with all the autoconf
substitutions in it is that the user may want to override these
variables in their Makefile.am. (Nick Bowler on April 1st 2013.) I'm
not sure how much of a problem this is: firstly, I don't know if
overriding these variables is ever necessary; and secondly, in GNU
make at least, multiple variable definitions can be read in a makefile
and the later ones do override the earlier ones.

I'm still working on the details of exactly what goes in a
distribution and how the build system is bootstrapped when "make" is
run for the first time. I think I've worked out how it should be done
but may discover difficulties when I try to implement it. I've thought
that some of these details would be easier to sort out if automake
generated configure.ac, which admittedly would be another big
architectural change.

My question is, is there any interest in this kind of approach? I feel
that it would be a step towards making the GNU build system easier to
use and understand.

I haven't included the patches I've made so far as the changes are
incomplete and there are a few problems which I need to sort out which
would be distracting, but I can certainly share more information if
desired. When I get it in a more polished state, I'll post the patches
for playing around with.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]