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 
concerns.

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 
pseudocode:
TEST_REQUIREMENT([bootjdk], [
   #... test for the bootjdk
   if test "x$BOOTJDK" = x; then
     TEST_REQUIREMENT_FAILED
   fi
])

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).

/Magnus



More information about the build-dev mailing list