Hi,
It's almost been 6 months since bug 1250294 landed, initiating the long
and slow move off autoconf.
Where are we, 6 months later? While there hasn't been constant progress
in the migration (we've all been busy with other things too), the
current status is that, pending in-flight bugs, the size of shell and m4
scripts is down below 70% of their original size.
https://plot.ly/~glandium/14/lines-vs-time/
The python configure script also does more checks than the autoconf
counterparts we moved. Most notably, we're now verifying that the
toolchain will actually build for the given --target.
Now, with 30% of the shell and m4 mess moved, and corresponding python
code written, it's time to sit back and look at what works and what
doesn't.
Here's my own list of things that I find suboptimal, with suggestions
when I have some.
- @depends('--disable-foo') and related are confusing. I still think
that at the sandbox level, it's a good thing that the options are
treated in consistent manner, ignoring their defaults. But referring
options by their name incurs some ambiguities along the negatives.
Maybe we should declare all options with their positive name
(--enable-foo, --with-foo), and set an explicit default of True when
the option is enabled by default. And make python configure reject
declarations with the negative name (--disable-foo, --without-foo).
- Relatedly, many of the help messages contain "Enable or disable",
and end up completely wrong when the default is opposite to what the
help says.
Maybe we can make all help messages start with e.g. "Enable"/
"Disable" or "Build with"/"Build without" automatically depending on
the default. The help argument would then *not* contain those.
Or we could have the --help handle replace "Enable" with "Disable" and
vice-versa, automatically...
- We have a lot of things like @depends_if(foo)(lambda x: True). Or
things largely equivalent to that, but in the full written form like
@depends(foo)
def bar(foo):
if foo:
return True
We probably need more helpers.
- It can be cumbersome to have to create @depends functions for
simple conditionals.
We have a bunch of templates that take a "when" argument. There also
is imply_option, set_config, set_define and
add_old_configure_assignment that all take @depends functions. In many
places, we do ad-hoc things like
depends(target)(lambda target: target.os == 'OSX')
or
delayed_getattr(milestone, 'is_nightly')
I know Nick didn't like the magic, but after having written to many of
those, I'm really considering magic would be nicer. What I was
thinking was to make calling a depends function possible, and it would
return a special class that create new pseudo depends function for
common operations.
Such that instead of
depends(target)(lambda target: target.os == 'OSX')
you could write:
target().os == 'OSX'
Instead of
delayed_getattr(milestone, 'is_nightly')
you could write:
milestone().is_nightly
Instead of
@depends(a, b)
def foo(a, b):
return a or b
you could write:
foo = a() or b()
etc.
- We need option defaults depending on the target. While I was looking
at some of the remaining options to move to python, I saw a lot of
them depend on the target. Option defaults need a dependency on
--help, which means the functions would run even when displaying
--help. Which makes a lot of sense, since --help is supposed to
display the defaults.
So far, we've avoided adding such a dependency for --target, because
it would mean running config.guess and config.sub during --help, and
it's not very desirable. I'm thinking about having --help imply a
--target derived in some minimalistic python code, avoiding both
config.guess and config.sub.
- I'm trying to enforce separation of concerns between generic things,
app-specific things and toolkit-specific things. This is something
that was essentially completely ignored in autoconf-base configure,
and leads to new problems. The main one is that the order in which
the python configure files are treated is, for most purposes, app first,
then toolkit, then generic. The problem is that e.g. toolchain tests are
in the latter, and sometimes we'd need for app or toolkit checks to do
toolchain-based checks (concrete example: --enable-valgrind needs to
check that valgrind.h can be found)
One thing I just thought about while writing the above is that we
could have a wrapper around the include() function that, when called
for foo.configure, would include all foo.configure files existing in
build/moz.configure/, toolkit/, and $build_project/. I haven't thought
too much about this one, it may or may not be a workable solution.
- There is no clear standard for app-overridable defaults. Sometimes we
have an imply_option in the app moz.configure, which means the option
can then never be overridden by a developer locally (however, that can
be the expected thing in some cases). Sometimes we have a default
function checking build_project. Sometimes we do a check with a
function that depends on the option (but I think those are usually
related to --target, rather than the app). I'm not sure there is
something nicer we could do here.
These are the items off the top of my head. Please add your own in a reply,
if you have others, and/or comments wrt the suggestions.
Cheers,
Mike