Skip to content

Commit 5d5bf16

Browse files
committed
8282567: Improve source-date handling in build system
Reviewed-by: erikj, sgehwolf
1 parent 3996782 commit 5d5bf16

File tree

8 files changed

+162
-82
lines changed

8 files changed

+162
-82
lines changed

doc/building.html

Lines changed: 20 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -890,30 +890,28 @@ <h3 id="getting-help">Getting Help</h3>
890890
<p>If you need general help or advice about developing for the JDK, you can also contact the Adoption Group. See the section on <a href="#contributing-to-openjdk">Contributing to OpenJDK</a> for more information.</p>
891891
<h2 id="reproducible-builds">Reproducible Builds</h2>
892892
<p>Build reproducibility is the property of getting exactly the same bits out when building, every time, independent on who builds the product, or where. This is for many reasons a harder goal than it initially appears, but it is an important goal, for security reasons and others. Please see <a href="https://reproducible-builds.org">Reproducible Builds</a> for more information about the background and reasons for reproducible builds.</p>
893-
<p>Currently, it is not possible to build OpenJDK fully reproducibly, but getting there is an ongoing effort. There are some things you can do to minimize non-determinism and make a larger part of the build reproducible:</p>
893+
<p>Currently, it is not possible to build OpenJDK fully reproducibly, but getting there is an ongoing effort.</p>
894+
<p>An absolute prerequisite for building reproducible is to speficy a fixed build time, since time stamps are embedded in many file formats. This is done by setting the <code>SOURCE_DATE_EPOCH</code> environment variable, which is an <a href="https://reproducible-builds.org/docs/source-date-epoch/">industry standard</a>, that many tools, such as gcc, recognize, and use in place of the current time when generating output.</p>
895+
<p>To generate reproducible builds, you must set <code>SOURCE_DATE_EPOCH</code> before running <code>configure</code>. The value in <code>SOURCE_DATE_EPOCH</code> will be stored in the configuration, and used by <code>make</code>. Setting <code>SOURCE_DATE_EPOCH</code> before running <code>make</code> will have no effect on the build.</p>
896+
<p>You must also make sure your build does not rely on <code>configure</code>'s default adhoc version strings. Default adhoc version strings <code>OPT</code> segment include user name and source directory. You can either override just the <code>OPT</code> segment using <code>--with-version-opt=&lt;any fixed string&gt;</code>, or you can specify the entire version string using <code>--with-version-string=&lt;your version&gt;</code>.</p>
897+
<p>This is a typical example of how to build the JDK in a reproducible way:</p>
898+
<pre><code>export SOURCE_DATE_EPOCH=946684800
899+
bash configure --with-version-opt=adhoc
900+
make</code></pre>
901+
<p>Note that regardless if you specify a source date for <code>configure</code> or not, the JDK build system will set <code>SOURCE_DATE_EPOCH</code> for all build tools when building. If <code>--with-source-date</code> has the value <code>updated</code> (which is the default unless <code>SOURCE_DATE_EPOCH</code> is found by in the environment by <code>configure</code>), the source date value will be determined at build time.</p>
902+
<p>There are several aspects of reproducible builds that can be individually adjusted by <code>configure</code> arguments. If any of these are given, they will override the value derived from <code>SOURCE_DATE_EPOCH</code>. These arguments are:</p>
894903
<ul>
895-
<li>Turn on build system support for reproducible builds</li>
904+
<li><p><code>--with-source-date</code></p>
905+
<p>This option controls how the JDK build sets <code>SOURCE_DATE_EPOCH</code> when building. It can be set to a value describing a date, either an epoch based timestamp as an integer, or a valid ISO-8601 date.</p>
906+
<p>It can also be set to one of the special values <code>current</code>, <code>updated</code> or <code>version</code>. <code>current</code> means that the time of running <code>configure</code> will be used. <code>version</code> will use the nominal release date for the current JDK version. <code>updated</code>, which means that <code>SOURCE_DATE_EPOCH</code> will be set to the current time each time you are running <code>make</code>. All choices, except for <code>updated</code>, will set a fixed value for the source date timestamp.</p>
907+
<p>When <code>SOURCE_DATE_EPOCH</code> is set, the default value for <code>--with-source-date</code> will be the value given by <code>SOURCE_DATE_EPOCH</code>. Otherwise, the default value is <code>updated</code>.</p></li>
908+
<li><p><code>--with-hotspot-build-time</code></p>
909+
<p>This option controls the build time string that will be included in the hotspot library (<code>libjvm.so</code> or <code>jvm.dll</code>). When the source date is fixed (e.g. by setting <code>SOURCE_DATE_EPOCH</code>), the default value for <code>--with-hotspot-build-time</code> will be an ISO 8601 representation of that time stamp. Otherwise the default value will be the current time when building hotspot.</p></li>
910+
<li><p><code>--with-copyright-year</code></p>
911+
<p>This option controls the copyright year in some generated text files. When the source date is fixed (e.g. by setting <code>SOURCE_DATE_EPOCH</code>), the default value for <code>--with-copyright-year</code> will be the year of that time stamp. Otherwise the default is the current year at the time of running configure. This can be overridden by <code>--with-copyright-year=&lt;year&gt;</code>.</p></li>
912+
<li><p><code>--enable-reproducible-build</code></p>
913+
<p>This option controls some additional behavior needed to make the build reproducible. When the source date is fixed (e.g. by setting <code>SOURCE_DATE_EPOCH</code>), this flag will be turned on by default. Otherwise, the value is determined by heuristics. If it is explicitly turned off, the build might not be reproducible.</p></li>
896914
</ul>
897-
<p>Add the flag <code>--enable-reproducible-build</code> to your <code>configure</code> command line. This will turn on support for reproducible builds where it could otherwise be lacking.</p>
898-
<ul>
899-
<li>Do not rely on <code>configure</code>'s default adhoc version strings</li>
900-
</ul>
901-
<p>Default adhoc version strings OPT segment include user name, source directory and timestamp. You can either override just the OPT segment using <code>--with-version-opt=&lt;any fixed string&gt;</code>, or you can specify the entire version string using <code>--with-version-string=&lt;your version&gt;</code>.</p>
902-
<ul>
903-
<li>Specify how the build sets <code>SOURCE_DATE_EPOCH</code></li>
904-
</ul>
905-
<p>The JDK build system will set the <code>SOURCE_DATE_EPOCH</code> environment variable during building, depending on the value of the <code>--with-source-date</code> option for <code>configure</code>. The default value is <code>updated</code>, which means that <code>SOURCE_DATE_EPOCH</code> will be set to the current time each time you are running <code>make</code>.</p>
906-
<p>The <a href="https://reproducible-builds.org/docs/source-date-epoch/"><code>SOURCE_DATE_EPOCH</code> environment variable</a> is an industry standard, that many tools, such as gcc, recognize, and use in place of the current time when generating output.</p>
907-
<p>For reproducible builds, you need to set this to a fixed value. You can use the special value <code>version</code> which will use the nominal release date for the current JDK version, or a value describing a date, either an epoch based timestamp as an integer, or a valid ISO-8601 date.</p>
908-
<p><strong>Hint:</strong> If your build environment already sets <code>SOURCE_DATE_EPOCH</code>, you can propagate this using <code>--with-source-date=$SOURCE_DATE_EPOCH</code>.</p>
909-
<ul>
910-
<li>Specify a hotspot build time</li>
911-
</ul>
912-
<p>Set a fixed hotspot build time. This will be included in the hotspot library (<code>libjvm.so</code> or <code>jvm.dll</code>) and defaults to the current time when building hotspot. Use <code>--with-hotspot-build-time=&lt;any fixed string&gt;</code> for reproducible builds. It's a string so you don't need to format it specifically, so e.g. <code>n/a</code> will do. Another solution is to use the <code>SOURCE_DATE_EPOCH</code> variable, e.g. <code>--with-hotspot-build-time=$(date --date=@$SOURCE_DATE_EPOCH)</code>.</p>
913-
<ul>
914-
<li>Copyright year</li>
915-
</ul>
916-
<p>The copyright year in some generated text files are normally set to the current year. This can be overridden by <code>--with-copyright-year=&lt;year&gt;</code>. For fully reproducible builds, this needs to be set to a fixed value.</p>
917915
<h2 id="hints-and-suggestions-for-advanced-users">Hints and Suggestions for Advanced Users</h2>
918916
<h3 id="bash-completion">Bash Completion</h3>
919917
<p>The <code>configure</code> and <code>make</code> commands tries to play nice with bash command-line completion (using <code>&lt;tab&gt;</code> or <code>&lt;tab&gt;&lt;tab&gt;</code>). To use this functionality, make sure you enable completion in your <code>~/.bashrc</code> (see instructions for bash in your operating system).</p>

doc/building.md

Lines changed: 66 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1527,57 +1527,85 @@ https://reproducible-builds.org) for more information about the background and
15271527
reasons for reproducible builds.
15281528
15291529
Currently, it is not possible to build OpenJDK fully reproducibly, but getting
1530-
there is an ongoing effort. There are some things you can do to minimize
1531-
non-determinism and make a larger part of the build reproducible:
1530+
there is an ongoing effort.
1531+
1532+
An absolute prerequisite for building reproducible is to speficy a fixed build
1533+
time, since time stamps are embedded in many file formats. This is done by
1534+
setting the `SOURCE_DATE_EPOCH` environment variable, which is an [industry
1535+
standard]( https://reproducible-builds.org/docs/source-date-epoch/), that many
1536+
tools, such as gcc, recognize, and use in place of the current time when
1537+
generating output.
1538+
1539+
To generate reproducible builds, you must set `SOURCE_DATE_EPOCH` before running
1540+
`configure`. The value in `SOURCE_DATE_EPOCH` will be stored in the
1541+
configuration, and used by `make`. Setting `SOURCE_DATE_EPOCH` before running
1542+
`make` will have no effect on the build.
1543+
1544+
You must also make sure your build does not rely on `configure`'s default adhoc
1545+
version strings. Default adhoc version strings `OPT` segment include user name
1546+
and source directory. You can either override just the `OPT` segment using
1547+
`--with-version-opt=<any fixed string>`, or you can specify the entire version
1548+
string using `--with-version-string=<your version>`.
15321549
1533-
* Turn on build system support for reproducible builds
1550+
This is a typical example of how to build the JDK in a reproducible way:
1551+
1552+
```
1553+
export SOURCE_DATE_EPOCH=946684800
1554+
bash configure --with-version-opt=adhoc
1555+
make
1556+
```
15341557
1535-
Add the flag `--enable-reproducible-build` to your `configure` command line.
1536-
This will turn on support for reproducible builds where it could otherwise be
1537-
lacking.
1558+
Note that regardless if you specify a source date for `configure` or not, the
1559+
JDK build system will set `SOURCE_DATE_EPOCH` for all build tools when building.
1560+
If `--with-source-date` has the value `updated` (which is the default unless
1561+
`SOURCE_DATE_EPOCH` is found by in the environment by `configure`), the source
1562+
date value will be determined at build time.
15381563
1539-
* Do not rely on `configure`'s default adhoc version strings
1564+
There are several aspects of reproducible builds that can be individually
1565+
adjusted by `configure` arguments. If any of these are given, they will override
1566+
the value derived from `SOURCE_DATE_EPOCH`. These arguments are:
15401567
1541-
Default adhoc version strings OPT segment include user name, source directory
1542-
and timestamp. You can either override just the OPT segment using
1543-
`--with-version-opt=<any fixed string>`, or you can specify the entire version
1544-
string using `--with-version-string=<your version>`.
1568+
* `--with-source-date`
15451569
1546-
* Specify how the build sets `SOURCE_DATE_EPOCH`
1570+
This option controls how the JDK build sets `SOURCE_DATE_EPOCH` when
1571+
building. It can be set to a value describing a date, either an epoch based
1572+
timestamp as an integer, or a valid ISO-8601 date.
15471573
1548-
The JDK build system will set the `SOURCE_DATE_EPOCH` environment variable
1549-
during building, depending on the value of the `--with-source-date` option for
1550-
`configure`. The default value is `updated`, which means that
1551-
`SOURCE_DATE_EPOCH` will be set to the current time each time you are running
1552-
`make`.
1574+
It can also be set to one of the special values `current`, `updated` or
1575+
`version`. `current` means that the time of running `configure` will be
1576+
used. `version` will use the nominal release date for the current JDK
1577+
version. `updated`, which means that `SOURCE_DATE_EPOCH` will be set to the
1578+
current time each time you are running `make`. All choices, except for
1579+
`updated`, will set a fixed value for the source date timestamp.
15531580
1554-
The [`SOURCE_DATE_EPOCH` environment variable](
1555-
https://reproducible-builds.org/docs/source-date-epoch/) is an industry
1556-
standard, that many tools, such as gcc, recognize, and use in place of the
1557-
current time when generating output.
1581+
When `SOURCE_DATE_EPOCH` is set, the default value for `--with-source-date`
1582+
will be the value given by `SOURCE_DATE_EPOCH`. Otherwise, the default value
1583+
is `updated`.
15581584
1559-
For reproducible builds, you need to set this to a fixed value. You can use the
1560-
special value `version` which will use the nominal release date for the current
1561-
JDK version, or a value describing a date, either an epoch based timestamp as an
1562-
integer, or a valid ISO-8601 date.
1585+
* `--with-hotspot-build-time`
15631586
1564-
**Hint:** If your build environment already sets `SOURCE_DATE_EPOCH`, you can
1565-
propagate this using `--with-source-date=$SOURCE_DATE_EPOCH`.
1587+
This option controls the build time string that will be included in the
1588+
hotspot library (`libjvm.so` or `jvm.dll`). When the source date is fixed
1589+
(e.g. by setting `SOURCE_DATE_EPOCH`), the default value for
1590+
`--with-hotspot-build-time` will be an ISO 8601 representation of that time
1591+
stamp. Otherwise the default value will be the current time when building
1592+
hotspot.
15661593
1567-
* Specify a hotspot build time
1594+
* `--with-copyright-year`
15681595
1569-
Set a fixed hotspot build time. This will be included in the hotspot library
1570-
(`libjvm.so` or `jvm.dll`) and defaults to the current time when building
1571-
hotspot. Use `--with-hotspot-build-time=<any fixed string>` for reproducible
1572-
builds. It's a string so you don't need to format it specifically, so e.g. `n/a`
1573-
will do. Another solution is to use the `SOURCE_DATE_EPOCH` variable, e.g.
1574-
`--with-hotspot-build-time=$(date --date=@$SOURCE_DATE_EPOCH)`.
1596+
This option controls the copyright year in some generated text files. When
1597+
the source date is fixed (e.g. by setting `SOURCE_DATE_EPOCH`), the default
1598+
value for `--with-copyright-year` will be the year of that time stamp.
1599+
Otherwise the default is the current year at the time of running configure.
1600+
This can be overridden by `--with-copyright-year=<year>`.
15751601
1576-
* Copyright year
1602+
* `--enable-reproducible-build`
15771603
1578-
The copyright year in some generated text files are normally set to the current
1579-
year. This can be overridden by `--with-copyright-year=<year>`. For fully
1580-
reproducible builds, this needs to be set to a fixed value.
1604+
This option controls some additional behavior needed to make the build
1605+
reproducible. When the source date is fixed (e.g. by setting
1606+
`SOURCE_DATE_EPOCH`), this flag will be turned on by default. Otherwise, the
1607+
value is determined by heuristics. If it is explicitly turned off, the build
1608+
might not be reproducible.
15811609
15821610
## Hints and Suggestions for Advanced Users
15831611

make/InitSupport.gmk

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#
2-
# Copyright (c) 2011, 2021, Oracle and/or its affiliates. All rights reserved.
2+
# Copyright (c) 2011, 2022, Oracle and/or its affiliates. All rights reserved.
33
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
#
55
# This code is free software; you can redistribute it and/or modify it
@@ -310,17 +310,16 @@ else # $(HAS_SPEC)=true
310310
# level of reproducible builds
311311
define SetupReproducibleBuild
312312
ifeq ($$(SOURCE_DATE), updated)
313-
SOURCE_DATE := $$(shell $$(DATE) +"%s")
314-
endif
315-
export SOURCE_DATE_EPOCH := $$(SOURCE_DATE)
316-
ifeq ($$(IS_GNU_DATE), yes)
317-
export SOURCE_DATE_ISO_8601 := $$(shell $$(DATE) --utc \
318-
--date="@$$(SOURCE_DATE_EPOCH)" \
319-
+"%Y-%m-%dT%H:%M:%SZ" 2> /dev/null)
320-
else
321-
export SOURCE_DATE_ISO_8601 := $$(shell $$(DATE) -u \
322-
-j -f "%s" "$$(SOURCE_DATE_EPOCH)" \
323-
+"%Y-%m-%dT%H:%M:%SZ" 2> /dev/null)
313+
# For static values of SOURCE_DATE (not "updated"), these are set in spec.gmk
314+
export SOURCE_DATE_EPOCH := $$(shell $$(DATE) +"%s")
315+
ifeq ($$(IS_GNU_DATE), yes)
316+
export SOURCE_DATE_ISO_8601 := $$(shell $$(DATE) --utc \
317+
--date="@$$(SOURCE_DATE_EPOCH)" +"$$(ISO_8601_FORMAT_STRING)" \
318+
2> /dev/null)
319+
else
320+
export SOURCE_DATE_ISO_8601 := $$(shell $$(DATE) -u -j -f "%s" \
321+
"$$(SOURCE_DATE_EPOCH)" +"$$(ISO_8601_FORMAT_STRING)" 2> /dev/null)
322+
endif
324323
endif
325324
endef
326325

make/autoconf/configure.ac

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,7 @@ BOOTJDK_SETUP_DOCS_REFERENCE_JDK
152152
#
153153
###############################################################################
154154

155+
JDKOPT_SETUP_REPRODUCIBLE_BUILD
155156
JDKOPT_SETUP_JDK_OPTIONS
156157

157158
###############################################################################
@@ -207,7 +208,6 @@ PLATFORM_SETUP_OPENJDK_TARGET_BITS
207208
PLATFORM_SETUP_OPENJDK_TARGET_ENDIANNESS
208209

209210
# Configure flags for the tools. Need to know if we should build reproducible.
210-
JDKOPT_SETUP_REPRODUCIBLE_BUILD
211211
FLAGS_SETUP_FLAGS
212212

213213
# Setup debug symbols (need objcopy from the toolchain for that)

make/autoconf/help.m4

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,13 @@ AC_DEFUN_ONCE([HELP_PRINT_SUMMARY_AND_WARNINGS],
296296
printf "* OpenJDK target: OS: $OPENJDK_TARGET_OS, CPU architecture: $OPENJDK_TARGET_CPU_ARCH, address length: $OPENJDK_TARGET_CPU_BITS\n"
297297
printf "* Version string: $VERSION_STRING ($VERSION_SHORT)\n"
298298
299+
if test "x$SOURCE_DATE" != xupdated; then
300+
source_date_info="$SOURCE_DATE ($SOURCE_DATE_ISO_8601)"
301+
else
302+
source_date_info="Determined at build time"
303+
fi
304+
printf "* Source date: $source_date_info\n"
305+
299306
printf "\n"
300307
printf "Tools summary:\n"
301308
if test "x$OPENJDK_BUILD_OS" = "xwindows"; then

make/autoconf/hotspot.m4

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#
2-
# Copyright (c) 2011, 2020, Oracle and/or its affiliates. All rights reserved.
2+
# Copyright (c) 2011, 2022, Oracle and/or its affiliates. All rights reserved.
33
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
#
55
# This code is free software; you can redistribute it and/or modify it
@@ -114,12 +114,26 @@ AC_DEFUN_ONCE([HOTSPOT_SETUP_MISC],
114114
HOTSPOT_TARGET_CPU_ARCH=zero
115115
fi
116116
117+
117118
AC_ARG_WITH([hotspot-build-time], [AS_HELP_STRING([--with-hotspot-build-time],
118-
[timestamp to use in hotspot version string, empty for on-the-fly @<:@empty@:>@])])
119+
[timestamp to use in hotspot version string, empty means determined at build time @<:@source-date/empty@:>@])])
120+
121+
AC_MSG_CHECKING([what hotspot build time to use])
119122
120123
if test "x$with_hotspot_build_time" != x; then
121124
HOTSPOT_BUILD_TIME="$with_hotspot_build_time"
125+
AC_MSG_RESULT([$HOTSPOT_BUILD_TIME (from --with-hotspot-build-time)])
126+
else
127+
if test "x$SOURCE_DATE" = xupdated; then
128+
HOTSPOT_BUILD_TIME=""
129+
AC_MSG_RESULT([determined at build time (default)])
130+
else
131+
# If we have a fixed value for SOURCE_DATE, use it as default
132+
HOTSPOT_BUILD_TIME="$SOURCE_DATE_ISO_8601"
133+
AC_MSG_RESULT([$HOTSPOT_BUILD_TIME (from --with-source-date)])
134+
fi
122135
fi
136+
123137
AC_SUBST(HOTSPOT_BUILD_TIME)
124138
125139

0 commit comments

Comments
 (0)