RFR: JDK-8219971 Introduce SetupExecute in build system
Magnus Ihse Bursie
magnus.ihse.bursie at oracle.com
Fri Mar 1 13:24:34 UTC 2019
The most important operations performed by the build system is
generalized into various Setup<Foo> functionality, which forms the API
on top of which the rest of the build system is erected.
However, we have a long tail with various small operations, calling a
specific build tool, etc, that are done on a more ad-hoc basis. Over the
years, a more and more refined set of "best practice" rules has emerged
for such operations, but they tend to be implemented only for new
operations, and not retrospectively updated on old code.
To make sure we always keep all such operations up to date with modern
robustness solutions, I propose to create a new, more general, function,
SetupExecute. Basically, this takes a command line to execute, and make
sure this is done The Right Way.
In this patch, I'm introducing the SetupExecute function, and I've
installed it for all locations that are currently using ExecuteWithLog.
(Those were easy to find.) As the next step, operations that do not even
use ExecuteWithLog (which is part of the "best practice" since some time
ago, but was not from the start) should be located and converted, too.
I have verified using COMPARE_BUILD that the resulting output does not
change. (The solaris_sparcv9 confirmation build is still running.)
The SetupExecute API works like this: You need to specify a COMMAND, the
actual command line to execute. You are strongly recommended to provide
a INFO with the text to display for LOG=info on what operation is
performed. You can use DEPS to provide additional dependencies for your
command to run. You can optionally include a PRE_COMMAND and a
POST_COMMAND, intended for simple pre- and post-processing. The latter
might be e.g. a mv from a temporary file to the final destination, the
former e.g. a simple sed replacement on the input file. If the
operations are unrelated to the main COMMAND, this is not a suitable
If your command outputs a variety of files, or if it's really a single
file but you don't really care about the output from the perspective,
you can just supply a OUTPUT_DIR. You are supposed to make sure the
command creates files in this directory (which will be created for you
if it does not exist), but this can't be enforced by SetupExecute.
Additional support files (like logs and markers) are created in this
directory. If you want support files in a separate directory (e.g. if
you're targeting an OUTPUT_DIR in the image directly), you can specify a
SUPPORT_DIR. If your command outputs only a single file, you can get rid
of the marker files (but not the log files) by specifying OUTPUT_FILE.
Note that if you specify an OUTPUT_FILE, support log files will be
placed in the same directory as the OUTPUT_FILE. If you do not want
that, use SUPPORT_DIR as well.
After the call to SetupExecute, $1 will contain references to all
generated files (that make knows about), and $1_TARGET will contain a
reference to the final target (that is OUTPUT_FILE if it exists, or the
$1_exec.marker file otherwise).
All the above keep functioning as expected even if PRE_COMMAND and
POST_COMMAND are given. One special case worth noting is that if
OUTPUT_FILE and POST_COMMAND is both given, the actual OUTPUT_FILE is
considered to be a result of running the POST_COMMAND. (This will
probably interact badly with a chmod as POST_COMMAND. I believe we still
have a few such places, so this behavior might need to get revisited
when I get around to converting those.)
While this might sound a bit convoluted, I find that it matches our
actual usage very well. The guiding idea here, as in the other
Setup<Foo> functions, is to make the usage of the function as natural
and simple as possible, even if at the expense of a slightly more
More information about the build-dev