Discussion: How to handle partial requirements in configure
Magnus Ihse Bursie
magnus.ihse.bursie at oracle.com
Mon Feb 17 13:55:27 UTC 2014
One issue with configure currently is that it is a bit of a "all or
nothing" solution. Either you pass, and then you can build anything in
the product, or you do not pass (since some requirement is missing) and
then you can build nothing -- not even parts of the build that does not
really require that component. For instance, hotspot do not require
cups, yet you can not build just hotspot without having cups installed,
since configure won't let you pass.
For some of these issues, we have just ignored them, and forced the user
to install unneccessary requirements. For others, we have made more or
less hacky workarounds. For others still, we might skip a requirement if
it is not present, but are not clear about what will be missing.
Going forward, we will need to handle this in a more structured way.
Here is a proposal, on a very high level, on how we could address these
We start by introducing two new concepts "environment requirements"
(could *really* need a better name!) and "components" (could perhaps
need a better name).
A "component" is something we will guarantee that it will run, e.g.
"build-jdk", "build-hotspot", "compare-script". If the configure script
says that "build-jdk" is enabled, then we have everything in place to be
able to build the jdk. If it says "compare-script" is enabled, then we
can run the compare script. We might also extend these to include
testing, so if "test-hotspot" is enabled then everything is present to
be able to run hotspot tests. (This is subject of a different debate;
let's keep this possibility in mind but not extend the discussion
further on this for now.)
An "environment requirement" is the vague concept of "something that
configure checks". Typically, it is the presence of some kind of tool,
e.g. "bootjdk", "native-toolchain", "basic-tools", "objcopy", etc. But
it could just as well be some kind of other environmental check, like
checking if the build directory is on a network drive.
A component will have an associated list of environment requirements.
For instance, build-jdk would require basic-tools, bootjdk and
native-toolchain, etc. If a requirement is not found, configure can
handle this in different ways. If the component was essential, we will
fail. If it was non-essential, we will flag that component as disabled.
More specifically, components can be set to either "enabled" (or
"forced", "essential", "required"), "disabled" or "auto" (or "default",
"if possible", or..?). (We need to think about the names a bit...)
* An enabled component must have all its environment requirements
fullfilled. If one or more of these are missing, configure will abort
and will not allow a build.
* A disabled component will not have its requirements checked (unless if
that checking is done since it is needed by another, non-disabled
component), and will be flagged as disabled in the configure output, so
you cannot for instance try to build it using make.
* An "auto" component will have its requirements checked, and will be
enabled if they are present, and disabled otherwise. Either case is fine
and will result in no warnings, but just some kind of information wether
it succeeded or not. This would typically be the default behaviour.
We will need some suitable set of options to configure to specify which
components should be enabled, disabled or auto. By default, our current
behavior should not change (so build-jdk will need to be enabled, and
our closed extensions would be "auto"). What constitutes a suitable
command-line UI to this functionality is left to be examined.
We would like the configure script to continue to fail-fast as much as
possible, so as soon as we find that we cannot fulfil an environment
requirement of an enabled (essential) component, we will fail.
Some kind of dependency between components is likely to be needed. For
instance "build-jdk" depends on "build-hotspot", and we have closed-only
extensions that depend on e.g. build-jdk. These dependencies can be
satisfied either by building with make, or with prebuilt packages. We
already have --with-import-hotspot, which should probably be remodeled
to fit better into this scheme. Continuing this path to far leads us to
re-implement Maven :-), so we need to take care to only actually solve
the problems we actually need to.
It can also be noted that the line between "component" and "environment
requirement" can be a bit fuzzy. If both are to be considered
dependencies of components, what's the real difference between requiring
"build-hotspot" (which can be satisfied with a prebuilt JDK with
--import-hotspot) and "bootjdk" (which can be satisfied with a prebuilt
JDK)? Similarly, the interim-langtools.jar behaves somewhere in the
borderline between these two concepts. Nevertheless, for most cases
there is a large difference, and it seems to make intuitive sense to
treat them differently.
The proposed implementation would be to group the current requirement
tests using m4/autoconf macro logic. For instance, something like this
#... test for the bootjdk
if test "x$BOOTJDK" = x; then
We believe the code is already structured enough that most of the
reasonable ways we would like to group such requirements are already
located together, though some code shuffling might be needed.
This will be complemented with a dependency declaration, that indicates
that for instance "build-jdk" requires "bootjdk". We'll need to research
suitable ways to express this in m4/autoconf. We will need to make that
dependency information available before we start testing for
requirements, so the implementation of TEST_REQUIREMENT can abort
directly if a requirement failed for an enabled/essential component.
Also, we will need to be able to augment the open part of the dependency
with closed-only components. Finally, requirements might be platform
specific. For instance, the fixpath helper needs to be compiled on
Windows, which introduces a requirement on native compilers (even for
building parts of the product that by themselves contain no native code).
More information about the build-dev