| <!DOCTYPE html> | |
| <html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang=""> | |
| <head> | |
| <meta charset="utf-8" /> | |
| <meta name="generator" content="pandoc" /> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" /> | |
| <title>Building the JDK</title> | |
| <style> | |
| code{white-space: pre-wrap;} | |
| span.smallcaps{font-variant: small-caps;} | |
| div.columns{display: flex; gap: min(4vw, 1.5em);} | |
| div.column{flex: auto; overflow-x: auto;} | |
| div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;} | |
| ul.task-list{list-style: none;} | |
| ul.task-list li input[type="checkbox"] { | |
| width: 0.8em; | |
| margin: 0 0.8em 0.2em -1.6em; | |
| vertical-align: middle; | |
| } | |
| .display.math{display: block; text-align: center; margin: 0.5rem auto;} | |
| </style> | |
| <link rel="stylesheet" href="../make/data/docs-resources/resources/jdk-default.css" /> | |
| <style type="text/css">pre, code, tt { color: #1d6ae5; }</style> | |
| <!--[if lt IE 9]> | |
| <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script> | |
| <![endif]--> | |
| </head> | |
| <body> | |
| <header id="title-block-header"> | |
| <h1 class="title">Building the JDK</h1> | |
| </header> | |
| <nav id="TOC" role="doc-toc"> | |
| <ul> | |
| <li><a href="#tldr-instructions-for-the-impatient" | |
| id="toc-tldr-instructions-for-the-impatient">TL;DR (Instructions for the | |
| Impatient)</a></li> | |
| <li><a href="#introduction" id="toc-introduction">Introduction</a></li> | |
| <li><a href="#getting-the-source-code" | |
| id="toc-getting-the-source-code">Getting the Source Code</a> | |
| <ul> | |
| <li><a href="#special-considerations" | |
| id="toc-special-considerations">Special Considerations</a></li> | |
| </ul></li> | |
| <li><a href="#build-hardware-requirements" | |
| id="toc-build-hardware-requirements">Build Hardware Requirements</a> | |
| <ul> | |
| <li><a href="#building-on-x86" id="toc-building-on-x86">Building on | |
| x86</a></li> | |
| <li><a href="#building-on-aarch64" id="toc-building-on-aarch64">Building | |
| on aarch64</a></li> | |
| <li><a href="#building-on-32-bit-arm" | |
| id="toc-building-on-32-bit-arm">Building on 32-bit ARM</a></li> | |
| </ul></li> | |
| <li><a href="#operating-system-requirements" | |
| id="toc-operating-system-requirements">Operating System Requirements</a> | |
| <ul> | |
| <li><a href="#windows" id="toc-windows">Windows</a></li> | |
| <li><a href="#macos" id="toc-macos">macOS</a></li> | |
| <li><a href="#linux" id="toc-linux">Linux</a></li> | |
| <li><a href="#aix" id="toc-aix">AIX</a></li> | |
| </ul></li> | |
| <li><a href="#native-compiler-toolchain-requirements" | |
| id="toc-native-compiler-toolchain-requirements">Native Compiler | |
| (Toolchain) Requirements</a> | |
| <ul> | |
| <li><a href="#gcc" id="toc-gcc">gcc</a></li> | |
| <li><a href="#clang" id="toc-clang">clang</a></li> | |
| <li><a href="#apple-xcode" id="toc-apple-xcode">Apple Xcode</a></li> | |
| <li><a href="#microsoft-visual-studio" | |
| id="toc-microsoft-visual-studio">Microsoft Visual Studio</a></li> | |
| <li><a href="#ibm-open-xl-cc" id="toc-ibm-open-xl-cc">IBM Open XL | |
| C/C++</a></li> | |
| </ul></li> | |
| <li><a href="#boot-jdk-requirements" id="toc-boot-jdk-requirements">Boot | |
| JDK Requirements</a> | |
| <ul> | |
| <li><a href="#getting-jdk-binaries" | |
| id="toc-getting-jdk-binaries">Getting JDK Binaries</a></li> | |
| </ul></li> | |
| <li><a href="#external-library-requirements" | |
| id="toc-external-library-requirements">External Library Requirements</a> | |
| <ul> | |
| <li><a href="#freetype" id="toc-freetype">FreeType</a></li> | |
| <li><a href="#fontconfig" id="toc-fontconfig">Fontconfig</a></li> | |
| <li><a href="#cups" id="toc-cups">CUPS</a></li> | |
| <li><a href="#x11" id="toc-x11">X11</a></li> | |
| <li><a href="#alsa" id="toc-alsa">ALSA</a></li> | |
| <li><a href="#libffi" id="toc-libffi">libffi</a></li> | |
| </ul></li> | |
| <li><a href="#build-tools-requirements" | |
| id="toc-build-tools-requirements">Build Tools Requirements</a> | |
| <ul> | |
| <li><a href="#autoconf" id="toc-autoconf">Autoconf</a></li> | |
| <li><a href="#gnu-make" id="toc-gnu-make">GNU Make</a></li> | |
| <li><a href="#gnu-bash" id="toc-gnu-bash">GNU Bash</a></li> | |
| <li><a href="#graphviz-and-pandoc" id="toc-graphviz-and-pandoc">Graphviz | |
| and Pandoc</a></li> | |
| </ul></li> | |
| <li><a href="#running-configure" id="toc-running-configure">Running | |
| Configure</a> | |
| <ul> | |
| <li><a href="#common-configure-arguments" | |
| id="toc-common-configure-arguments">Common Configure Arguments</a></li> | |
| <li><a href="#configure-control-variables" | |
| id="toc-configure-control-variables">Configure Control | |
| Variables</a></li> | |
| </ul></li> | |
| <li><a href="#running-make" id="toc-running-make">Running Make</a> | |
| <ul> | |
| <li><a href="#common-make-targets" id="toc-common-make-targets">Common | |
| Make Targets</a></li> | |
| <li><a href="#make-control-variables" | |
| id="toc-make-control-variables">Make Control Variables</a></li> | |
| </ul></li> | |
| <li><a href="#running-tests" id="toc-running-tests">Running | |
| Tests</a></li> | |
| <li><a href="#signing" id="toc-signing">Signing</a> | |
| <ul> | |
| <li><a href="#macos-1" id="toc-macos-1">macOS</a></li> | |
| </ul></li> | |
| <li><a href="#cross-compiling" | |
| id="toc-cross-compiling">Cross-Compiling</a> | |
| <ul> | |
| <li><a href="#specifying-the-target-platform" | |
| id="toc-specifying-the-target-platform">Specifying the Target | |
| Platform</a></li> | |
| <li><a href="#boot-jdk-and-build-jdk" | |
| id="toc-boot-jdk-and-build-jdk">Boot JDK and Build JDK</a></li> | |
| <li><a href="#toolchain-considerations" | |
| id="toc-toolchain-considerations">Toolchain Considerations</a></li> | |
| <li><a href="#native-libraries" id="toc-native-libraries">Native | |
| Libraries</a></li> | |
| <li><a href="#verifying-the-build" | |
| id="toc-verifying-the-build">Verifying the Build</a></li> | |
| <li><a href="#cross-compiling-the-easy-way" | |
| id="toc-cross-compiling-the-easy-way">Cross-Compiling the Easy | |
| Way</a></li> | |
| <li><a href="#considerations-for-specific-targets" | |
| id="toc-considerations-for-specific-targets">Considerations for Specific | |
| Targets</a></li> | |
| </ul></li> | |
| <li><a href="#build-performance" id="toc-build-performance">Build | |
| Performance</a> | |
| <ul> | |
| <li><a href="#disk-speed" id="toc-disk-speed">Disk Speed</a></li> | |
| <li><a href="#virus-checking" id="toc-virus-checking">Virus | |
| Checking</a></li> | |
| <li><a href="#ccache" id="toc-ccache">Ccache</a></li> | |
| <li><a href="#precompiled-headers" | |
| id="toc-precompiled-headers">Precompiled Headers</a></li> | |
| <li><a href="#icecc-icecream" id="toc-icecc-icecream">Icecc / | |
| Icecream</a></li> | |
| <li><a href="#using-the-javac-server" | |
| id="toc-using-the-javac-server">Using the javac Server</a></li> | |
| <li><a href="#building-the-right-target" | |
| id="toc-building-the-right-target">Building the Right Target</a></li> | |
| </ul></li> | |
| <li><a href="#troubleshooting" | |
| id="toc-troubleshooting">Troubleshooting</a> | |
| <ul> | |
| <li><a href="#locating-the-source-of-the-error" | |
| id="toc-locating-the-source-of-the-error">Locating the Source of the | |
| Error</a></li> | |
| <li><a href="#fixing-unexpected-build-failures" | |
| id="toc-fixing-unexpected-build-failures">Fixing Unexpected Build | |
| Failures</a></li> | |
| <li><a href="#specific-build-issues" | |
| id="toc-specific-build-issues">Specific Build Issues</a></li> | |
| <li><a href="#getting-help" id="toc-getting-help">Getting Help</a></li> | |
| </ul></li> | |
| <li><a href="#reproducible-builds" | |
| id="toc-reproducible-builds">Reproducible Builds</a></li> | |
| <li><a href="#hints-and-suggestions-for-advanced-users" | |
| id="toc-hints-and-suggestions-for-advanced-users">Hints and Suggestions | |
| for Advanced Users</a> | |
| <ul> | |
| <li><a href="#bash-completion" id="toc-bash-completion">Bash | |
| Completion</a></li> | |
| <li><a href="#using-multiple-configurations" | |
| id="toc-using-multiple-configurations">Using Multiple | |
| Configurations</a></li> | |
| <li><a href="#handling-reconfigurations" | |
| id="toc-handling-reconfigurations">Handling Reconfigurations</a></li> | |
| <li><a href="#using-fine-grained-make-targets" | |
| id="toc-using-fine-grained-make-targets">Using Fine-Grained Make | |
| Targets</a></li> | |
| </ul></li> | |
| <li><a href="#understanding-the-build-system" | |
| id="toc-understanding-the-build-system">Understanding the Build | |
| System</a> | |
| <ul> | |
| <li><a href="#configurations" | |
| id="toc-configurations">Configurations</a></li> | |
| <li><a href="#build-output-structure" | |
| id="toc-build-output-structure">Build Output Structure</a></li> | |
| <li><a href="#fixpath" id="toc-fixpath">Fixpath</a></li> | |
| <li><a href="#native-debug-symbols" id="toc-native-debug-symbols">Native | |
| Debug Symbols</a></li> | |
| <li><a href="#autoconf-details" id="toc-autoconf-details">Autoconf | |
| Details</a></li> | |
| <li><a href="#developing-the-build-system-itself" | |
| id="toc-developing-the-build-system-itself">Developing the Build System | |
| Itself</a></li> | |
| </ul></li> | |
| <li><a href="#contributing-to-the-jdk" | |
| id="toc-contributing-to-the-jdk">Contributing to the JDK</a></li> | |
| <li><a href="#editing-this-document" | |
| id="toc-editing-this-document">Editing This Document</a></li> | |
| </ul> | |
| </nav> | |
| <h2 id="tldr-instructions-for-the-impatient">TL;DR (Instructions for the | |
| Impatient)</h2> | |
| <p>If you are eager to try out building the JDK, these simple steps work | |
| most of the time. They assume that you have installed Git (and Cygwin, | |
| MSYS2 or WSL if running on Windows), and want to clone the main-line JDK | |
| repository.</p> | |
| <ol type="1"> | |
| <li><p><a href="#getting-the-source-code">Get the complete source | |
| code</a>:<br /> | |
| <code>git clone https://git.openjdk.org/jdk</code></p></li> | |
| <li><p><a href="#running-configure">Run configure</a>:<br /> | |
| <code>bash configure</code></p> | |
| <p>If <code>configure</code> fails due to missing dependencies (to | |
| either the <a | |
| href="#native-compiler-toolchain-requirements">toolchain</a>, <a | |
| href="#build-tools-requirements">build tools</a>, <a | |
| href="#external-library-requirements">external libraries</a> or the <a | |
| href="#boot-jdk-requirements">boot JDK</a>), most of the time it prints | |
| a suggestion on how to resolve the situation on your platform. Follow | |
| the instructions, and try running <code>bash configure</code> | |
| again.</p></li> | |
| <li><p><a href="#running-make">Run make</a>:<br /> | |
| <code>make images</code></p></li> | |
| <li><p>Verify your newly built JDK:<br /> | |
| <code>./build/*/images/jdk/bin/java -version</code></p></li> | |
| <li><p><a href="#running-tests">Run basic tests</a>:<br /> | |
| <code>make test-tier1</code></p></li> | |
| </ol> | |
| <p>If any of these steps failed, or if you want to know more about build | |
| requirements or build functionality, please continue reading this | |
| document.</p> | |
| <h2 id="introduction">Introduction</h2> | |
| <p>The JDK is a complex software project. Building it requires a certain | |
| amount of technical expertise, a fair number of dependencies on external | |
| software, and reasonably powerful hardware.</p> | |
| <p>If you just want to use the JDK and not build it yourself, this | |
| document is not for you. See for instance <a | |
| href="https://openjdk.org/install">OpenJDK installation</a> for some | |
| methods of installing a prebuilt JDK.</p> | |
| <h2 id="getting-the-source-code">Getting the Source Code</h2> | |
| <p>Make sure you are getting the correct version. At the <a | |
| href="https://git.openjdk.org/">OpenJDK Git site</a> you can see a list | |
| of all available repositories. Commonly used repositories are:</p> | |
| <ul> | |
| <li><p>The <a href="https://openjdk.org/projects/jdk">JDK Project</a> | |
| (the main-line currently in development): | |
| https://git.openjdk.org/jdk</p></li> | |
| <li><p>The <a href="https://openjdk.org/projects/jdk-updates/">JDK | |
| Updates Project</a>, which has one repository per update release, e.g. | |
| https://git.openjdk.org/jdk17u for JDK 17.</p></li> | |
| </ul> | |
| <p>If you want to build an older version, e.g. JDK 17, it is strongly | |
| recommended that you use the JDK Updates repository, e.g. the | |
| <code>jdk17u</code>, which contains incremental updates, instead of the | |
| JDK Project repository <code>jdk17</code>, which was frozen at JDK 17 | |
| GA.</p> | |
| <p>If you are new to Git, a good place to start is the book <a | |
| href="https://git-scm.com/book/en/v2">Pro Git</a>. The rest of this | |
| document assumes a working knowledge of Git.</p> | |
| <h3 id="special-considerations">Special Considerations</h3> | |
| <p>For a smooth building experience, it is recommended that you follow | |
| these rules on where and how to check out the source code.</p> | |
| <ul> | |
| <li><p>Do not check out the source code in a path which contains spaces. | |
| Chances are the build will not work. This is most likely to be an issue | |
| on Windows systems.</p></li> | |
| <li><p>Do not check out the source code in a path which has a very long | |
| name or is nested many levels deep. Chances are you will hit an OS | |
| limitation during the build.</p></li> | |
| <li><p>Put the source code on a local disk, not a network share. If | |
| possible, use an SSD. The build process is very disk intensive, and | |
| having slow disk access will significantly increase build times. If you | |
| need to use a network share for the source code, see below for | |
| suggestions on how to keep the build artifacts on a local disk.</p></li> | |
| <li><p>UTF-8 support is needed to compile the JDK. On Unix systems, this | |
| typically means that the <code>C.UTF-8</code> or | |
| <code>en_US.UTF-8</code> locale needs to be available. For Windows | |
| users, please see the section on <a href="#locale-requirements">Locale | |
| Requirements</a> below.</p></li> | |
| <li><p>On Windows, extra care must be taken to have a smooth building | |
| experience:</p> | |
| <ul> | |
| <li><p>Make sure that all relevant paths have short names. Short names | |
| are used by the build system to create space-free alternative paths. | |
| Short name creation is enabled per volume. The default setting can be | |
| checked with the command: <code>fsutil 8dot3name query</code>. If short | |
| name creation was turned off when a directory was created, it will not | |
| have a short name. Whether a short name exists can be checked by running | |
| <code>dir /X</code> in the containing directory (in cmd.exe). If a short | |
| path is present you should see something like 'ASDF~1' being displayed | |
| in one of the columns of the ouput. If a directory is missing a short | |
| name, the safest way to get one is to enable short names for that | |
| particular volume with | |
| <code>fsutil 8dot3name set <drive letter>: 0</code> (note that | |
| you need to run as administrator for this), and then re-create the | |
| particular directory. A short name should be generated automatically | |
| then. Another option is to manually assign a short name to the directory | |
| using | |
| <code>fsutil file setShortName <path> <short name></code>.</p></li> | |
| <li><p>If using <a href="#cygwin">Cygwin</a>, you must make sure the | |
| file permissions and attributes between Windows and Cygwin are | |
| consistent. It is recommended that you follow this procedure:</p> | |
| <ul> | |
| <li><p>Create the directory that is going to contain the top directory | |
| of the JDK clone by using the <code>mkdir</code> command in the Cygwin | |
| bash shell. That is, do <em>not</em> create it using Windows Explorer. | |
| This will ensure that it will have proper Cygwin attributes, and that | |
| it's children will inherit those attributes.</p></li> | |
| <li><p>Do not put the JDK clone in a path under your Cygwin home | |
| directory. This is especially important if your user name contains | |
| spaces and/or mixed upper and lower case letters.</p></li> | |
| </ul> | |
| <p>Failure to follow these procedures might result in hard-to-debug | |
| build problems.</p></li> | |
| <li><p>You need to install a git client. You have two choices, Cygwin | |
| git or Git for Windows. Unfortunately there are pros and cons with each | |
| choice.</p> | |
| <ul> | |
| <li><p>The Cygwin <code>git</code> client has no line ending issues and | |
| understands Cygwin paths (which are used throughout the JDK build | |
| system). However, it does not currently work well with the Skara CLI | |
| tooling. Please see the <a | |
| href="https://wiki.openjdk.org/display/SKARA/Skara#Skara-Git">Skara wiki | |
| on Git clients</a> for up-to-date information about the Skara git client | |
| support.</p></li> | |
| <li><p>The <a href="https://gitforwindows.org">Git for Windows</a> | |
| client has issues with line endings, and do not understand Cygwin paths. | |
| It does work well with the Skara CLI tooling, however. To alleviate the | |
| line ending problems, make sure you set <code>core.autocrlf</code> to | |
| <code>false</code> (this is asked during installation).</p></li> | |
| </ul></li> | |
| </ul></li> | |
| </ul> | |
| <h2 id="build-hardware-requirements">Build Hardware Requirements</h2> | |
| <p>The JDK is a massive project, and require machines ranging from | |
| decent to powerful to be able to build in a reasonable amount of time, | |
| or to be able to complete a build at all.</p> | |
| <p>We <em>strongly</em> recommend usage of an SSD disk for the build, | |
| since disk speed is one of the limiting factors for build | |
| performance.</p> | |
| <h3 id="building-on-x86">Building on x86</h3> | |
| <p>At a minimum, a machine with 2-4 cores is advisable, as well as 2-4 | |
| GB of RAM. (The more cores to use, the more memory you need.) At least 6 | |
| GB of free disk space is required.</p> | |
| <p>Even for 32-bit builds, it is recommended to use a 64-bit build | |
| machine, and instead create a 32-bit target using | |
| <code>--with-target-bits=32</code>.</p> | |
| <p>Note: The 32-bit x86 port is deprecated and may be removed in a | |
| future release.</p> | |
| <h3 id="building-on-aarch64">Building on aarch64</h3> | |
| <p>At a minimum, a machine with 8 cores is advisable, as well as 8 GB of | |
| RAM. (The more cores to use, the more memory you need.) At least 6 GB of | |
| free disk space is required.</p> | |
| <p>If you do not have access to sufficiently powerful hardware, it is | |
| also possible to use <a href="#cross-compiling">cross-compiling</a>.</p> | |
| <h4 id="branch-protection">Branch Protection</h4> | |
| <p>In order to use Branch Protection features in the VM, | |
| <code>--enable-branch-protection</code> must be used. This option | |
| requires C++ compiler support (GCC 9.1.0+ or Clang 10+). The resulting | |
| build can be run on both machines with and without support for branch | |
| protection in hardware. Branch Protection is only supported for Linux | |
| targets.</p> | |
| <h3 id="building-on-32-bit-arm">Building on 32-bit ARM</h3> | |
| <p>This is not recommended. Instead, see the section on <a | |
| href="#cross-compiling">Cross-compiling</a>.</p> | |
| <h2 id="operating-system-requirements">Operating System | |
| Requirements</h2> | |
| <p>The mainline JDK project supports Linux, macOS, AIX and Windows. | |
| Support for other operating system, e.g. BSD, exists in separate "port" | |
| projects.</p> | |
| <p>In general, the JDK can be built on a wide range of versions of these | |
| operating systems, but the further you deviate from what is tested on a | |
| daily basis, the more likely you are to run into problems.</p> | |
| <p>This table lists the OS versions used by Oracle when building the | |
| JDK. Such information is always subject to change, but this table is up | |
| to date at the time of writing.</p> | |
| <table> | |
| <thead> | |
| <tr class="header"> | |
| <th>Operating system</th> | |
| <th>Vendor/version used</th> | |
| </tr> | |
| </thead> | |
| <tbody> | |
| <tr class="odd"> | |
| <td>Linux/x64</td> | |
| <td>Oracle Enterprise Linux 6.4 / 8.x</td> | |
| </tr> | |
| <tr class="even"> | |
| <td>Linux/aarch64</td> | |
| <td>Oracle Enterprise Linux 7.6 / 8.x</td> | |
| </tr> | |
| <tr class="odd"> | |
| <td>macOS</td> | |
| <td>macOS 14.x</td> | |
| </tr> | |
| <tr class="even"> | |
| <td>Windows</td> | |
| <td>Windows Server 2016</td> | |
| </tr> | |
| </tbody> | |
| </table> | |
| <p>The double version numbers for Linux are due to the hybrid model used | |
| at Oracle, where header files and external libraries from an older | |
| version are used when building on a more modern version of the OS.</p> | |
| <p>The Build Group has a wiki page with <a | |
| href="https://wiki.openjdk.org/display/Build/Supported+Build+Platforms">Supported | |
| Build Platforms</a>. From time to time, this is updated by contributors | |
| to list successes or failures of building on different platforms.</p> | |
| <h3 id="windows">Windows</h3> | |
| <p>Windows XP is not a supported platform, but all newer Windows should | |
| be able to build the JDK.</p> | |
| <p>On Windows, it is important that you pay attention to the | |
| instructions in the <a href="#special-considerations">Special | |
| Considerations</a>.</p> | |
| <p>Windows is the only non-POSIX OS supported by the JDK, and as such, | |
| requires some extra care. A POSIX support layer is required to build on | |
| Windows. Currently, the supported such layers are Cygwin, MSYS2 and | |
| Windows Subsystem for Linux (WSL). Of these, Cygwin is the one that has | |
| received the most real-world testing and is likely to cause least | |
| trouble.</p> | |
| <p>Internally in the build system, all paths are represented as | |
| Unix-style paths, e.g. <code>/cygdrive/c/git/jdk/Makefile</code> rather | |
| than <code>C:\git\jdk\Makefile</code>. This rule also applies to input | |
| to the build system, e.g. in arguments to <code>configure</code>. So, | |
| use <code>--with-msvcr-dll=/cygdrive/c/msvcr100.dll</code> rather than | |
| <code>--with-msvcr-dll=c:\msvcr100.dll</code>. For details on this | |
| conversion, see the section on <a href="#fixpath">Fixpath</a>.</p> | |
| <h4 id="locale-requirements">Locale Requirements</h4> | |
| <p>Building and testing the JDK requires a well-defined locale to be | |
| guaranteed to run correctly. On non-Windows operating systems, this is | |
| achieved using the <code>LC_*</code> variables, which propagate to all | |
| child processes of the build. Unfortunately, there is no way to set the | |
| locale for a specific process like this in Windows. Instead, changes to | |
| locale can only be made globally, which will affect all applications run | |
| by the user. Furthermore, Windows makes a difference between user locale | |
| and system locale, where the latter determines e.g. the file path | |
| encoding. Both this locale settings affect building and testing the | |
| JDK.</p> | |
| <p>The <strong>recommended</strong> and <strong>supported</strong> way | |
| of building the JDK on Windows is to set both the system locale and the | |
| user locale to <strong>US English</strong>. The system setting can be | |
| changed by going to the Control Panel, choosing "Regional Settings" | |
| -> "Administrative" and then pressing on the "Change System Locale" | |
| button.</p> | |
| <p>Since this is annoying for users who prefer another locale, we strive | |
| to get the building and testing to work on other locales as well. This | |
| is on a "best effort" level, so beware! You might get odd results in | |
| both building and testing. If you do, remember that locales other than | |
| US English are not supported nor recommended.</p> | |
| <p>It is also imperative to install the US English language pack in | |
| Visual Studio. For details, see <a | |
| href="#microsoft-visual-studio">Microsoft Visual Studio</a>.</p> | |
| <h4 id="cygwin">Cygwin</h4> | |
| <p>Install <a href="https://www.cygwin.com/">Cygwin</a> as instructed on | |
| the home page. It is strongly recommended to use the 64-bit version of | |
| Cygwin.</p> | |
| <p><strong>Note:</strong> Cygwin has a model of continuously updating | |
| all packages without any easy way to install or revert to a specific | |
| version of a package. This means that whenever you add or update a | |
| package in Cygwin, you might (inadvertently) update tools that are used | |
| by the JDK build process, and that can cause unexpected build | |
| problems.</p> | |
| <p>The JDK requires GNU Make 4.0 or greater in Cygwin. This is usually | |
| not a problem, since Cygwin currently only distributes GNU Make at a | |
| version above 4.0.</p> | |
| <p>Apart from the basic Cygwin installation, the following packages must | |
| also be installed:</p> | |
| <ul> | |
| <li><code>autoconf</code></li> | |
| <li><code>make</code></li> | |
| <li><code>zip</code></li> | |
| <li><code>unzip</code></li> | |
| </ul> | |
| <p>Often, you can install these packages using the following command | |
| line:</p> | |
| <pre><code><path to Cygwin setup>/setup-x86_64 -q -P autoconf -P make -P unzip -P zip</code></pre> | |
| <p>Unfortunately, Cygwin can be unreliable in certain circumstances. If | |
| you experience build tool crashes or strange issues when building on | |
| Windows, please check the Cygwin FAQ on the <a | |
| href="https://cygwin.com/faq/faq.html#faq.using.bloda">"BLODA" list</a> | |
| and the section on <a | |
| href="https://cygwin.com/faq/faq.html#faq.using.fixing-fork-failures">fork() | |
| failures</a>.</p> | |
| <h4 id="msys2">MSYS2</h4> | |
| <p>Install <a href="https://www.msys2.org/">MSYS2</a> as instructed on | |
| the home page.</p> | |
| <p>Apart from the basic MSYS2 installation, the following packages must | |
| also be installed:</p> | |
| <ul> | |
| <li><code>autoconf</code></li> | |
| <li><code>tar</code></li> | |
| <li><code>make</code></li> | |
| <li><code>zip</code></li> | |
| <li><code>unzip</code></li> | |
| </ul> | |
| <p>You can install these packages using the following command line:</p> | |
| <pre><code>pacman -S autoconf tar make zip unzip</code></pre> | |
| <h4 id="windows-subsystem-for-linux-wsl">Windows Subsystem for Linux | |
| (WSL)</h4> | |
| <p>WSL comes in two flavors, WSL1 and WSL2. These are drastically | |
| different under the hood. WSL1 runs the binaries natively by translating | |
| Linux kernel calls into Windows kernel calls, while WSL2 runs Linux in a | |
| virtual machine. Both solutions have their pros and cons, and you might | |
| need to test both before deciding which works best for you. Both WSL1 | |
| and WSL2 are supported, but to varying degrees.</p> | |
| <p>To use WSL for building the JDK, you will need Windows 10 version | |
| 1809 or later, and you will need to install an Ubuntu guest.</p> | |
| <p>It is possible to build both Windows and Linux binaries from WSL. To | |
| build Windows binaries, you must use a Windows boot JDK (located in a | |
| Windows-accessible directory). To build Linux binaries, you must use a | |
| Linux boot JDK. The default behavior is to build for Windows. To build | |
| for Linux, pass | |
| <code>--build=x86_64-unknown-linux-gnu --openjdk-target=x86_64-unknown-linux-gnu</code> | |
| to <code>configure</code>.</p> | |
| <p>If building Windows binaries, the source code must be located in a | |
| Windows- accessible directory. This is because Windows executables (such | |
| as Visual Studio and the boot JDK) must be able to access the source | |
| code. Also, the drive where the source is stored must be mounted as | |
| case-insensitive by changing either /etc/fstab or /etc/wsl.conf in WSL. | |
| Individual directories may be corrected using the fsutil tool in case | |
| the source was cloned before changing the mount options.</p> | |
| <p>Note that while it's possible to build on WSL, testing is still not | |
| fully supported.</p> | |
| <h3 id="macos">macOS</h3> | |
| <p>Apple is using a quite aggressive scheme of pushing OS updates, and | |
| coupling these updates with required updates of Xcode. Unfortunately, | |
| this makes it difficult for a project such as the JDK to keep pace with | |
| a continuously updated machine running macOS. See the section on <a | |
| href="#apple-xcode">Apple Xcode</a> on some strategies to deal with | |
| this.</p> | |
| <p>It is recommended that you use at least macOS 14 and Xcode 15.4, but | |
| earlier versions may also work.</p> | |
| <p>The standard macOS environment contains the basic tooling needed to | |
| build, but for external libraries a package manager is recommended. The | |
| JDK uses <a href="https://brew.sh/">homebrew</a> in the examples, but | |
| feel free to use whatever manager you want (or none).</p> | |
| <h3 id="linux">Linux</h3> | |
| <p>It is often not much problem to build the JDK on Linux. The only | |
| general advice is to try to use the compilers, external libraries and | |
| header files as provided by your distribution.</p> | |
| <p>The basic tooling is provided as part of the core operating system, | |
| but you will most likely need to install developer packages.</p> | |
| <p>For apt-based distributions (Debian, Ubuntu, etc), try this:</p> | |
| <pre><code>sudo apt-get install build-essential autoconf</code></pre> | |
| <p>For rpm-based distributions (Fedora, Red Hat, etc), try this:</p> | |
| <pre><code>sudo yum groupinstall "Development Tools"</code></pre> | |
| <p>For Alpine Linux, aside from basic tooling, install the GNU versions | |
| of some programs:</p> | |
| <pre><code>sudo apk add build-base bash grep zip</code></pre> | |
| <h3 id="aix">AIX</h3> | |
| <p>Please consult the AIX section of the <a | |
| href="https://wiki.openjdk.org/display/Build/Supported+Build+Platforms">Supported | |
| Build Platforms</a> OpenJDK Build Wiki page for details about which | |
| versions of AIX are supported.</p> | |
| <h2 id="native-compiler-toolchain-requirements">Native Compiler | |
| (Toolchain) Requirements</h2> | |
| <p>Large portions of the JDK consists of native code, that needs to be | |
| compiled to be able to run on the target platform. In theory, toolchain | |
| and operating system should be independent factors, but in practice | |
| there's more or less a one-to-one correlation between target operating | |
| system and toolchain.</p> | |
| <table> | |
| <thead> | |
| <tr class="header"> | |
| <th>Operating system</th> | |
| <th>Supported toolchain</th> | |
| </tr> | |
| </thead> | |
| <tbody> | |
| <tr class="odd"> | |
| <td>Linux</td> | |
| <td>gcc, clang</td> | |
| </tr> | |
| <tr class="even"> | |
| <td>macOS</td> | |
| <td>Apple Xcode (using clang)</td> | |
| </tr> | |
| <tr class="odd"> | |
| <td>AIX</td> | |
| <td>IBM Open XL C/C++</td> | |
| </tr> | |
| <tr class="even"> | |
| <td>Windows</td> | |
| <td>Microsoft Visual Studio</td> | |
| </tr> | |
| </tbody> | |
| </table> | |
| <p>Please see the individual sections on the toolchains for version | |
| recommendations. As a reference, these versions of the toolchains are | |
| used, at the time of writing, by Oracle for the daily builds of the JDK. | |
| It should be possible to compile the JDK with both older and newer | |
| versions, but the closer you stay to this list, the more likely you are | |
| to compile successfully without issues.</p> | |
| <table> | |
| <thead> | |
| <tr class="header"> | |
| <th>Operating system</th> | |
| <th>Toolchain version</th> | |
| </tr> | |
| </thead> | |
| <tbody> | |
| <tr class="odd"> | |
| <td>Linux</td> | |
| <td>gcc 14.2.0</td> | |
| </tr> | |
| <tr class="even"> | |
| <td>macOS</td> | |
| <td>Apple Xcode 15.4 (using clang 15.0.0)</td> | |
| </tr> | |
| <tr class="odd"> | |
| <td>Windows</td> | |
| <td>Microsoft Visual Studio 2022 version 17.13.2</td> | |
| </tr> | |
| </tbody> | |
| </table> | |
| <p>All compilers are expected to be able to handle the C11 language | |
| standard for C, and C++14 for C++.</p> | |
| <h3 id="gcc">gcc</h3> | |
| <p>The minimum accepted version of gcc is 10.0. Older versions will not | |
| be accepted by <code>configure</code>.</p> | |
| <p>The JDK is currently known to compile successfully with gcc version | |
| 14.2 or newer.</p> | |
| <p>In general, any version between these two should be usable.</p> | |
| <h3 id="clang">clang</h3> | |
| <p>The minimum accepted version of clang is 13. Older versions will not | |
| be accepted by <code>configure</code>.</p> | |
| <p>To use clang instead of gcc on Linux, use | |
| <code>--with-toolchain-type=clang</code>.</p> | |
| <h3 id="apple-xcode">Apple Xcode</h3> | |
| <p>The oldest supported version of Xcode is 13.0.</p> | |
| <p>You will need to download Xcode either from the App Store or specific | |
| versions can be easily located via the <a | |
| href="https://xcodereleases.com">Xcode Releases</a> website.</p> | |
| <p>When updating Xcode, it is advisable to keep an older version for | |
| building the JDK. To use a specific version of Xcode you have multiple | |
| options:</p> | |
| <ul> | |
| <li>Use <code>xcode-select -s</code> before running | |
| <code>configure</code>, e.g. | |
| <code>xcode-select -s /Applications/Xcode13.1.app</code>. The drawback | |
| is that the setting is system wide and you may have to revert it after a | |
| JDK build.</li> | |
| <li>Use configure option <code>--with-xcode-path</code>, e.g. | |
| <code>configure --with-xcode-path=/Applications/Xcode13.1.app</code> | |
| This allows using a specific Xcode version for a JDK build, | |
| independently of the active Xcode version by | |
| <code>xcode-select</code>.</li> | |
| </ul> | |
| <p>If you have recently (inadvertently) updated your OS and/or Xcode | |
| version, and the JDK can no longer be built, please see the section on | |
| <a href="#problems-with-the-build-environment">Problems with the Build | |
| Environment</a>, and <a href="#getting-help">Getting Help</a> to find | |
| out if there are any recent, non-merged patches available for this | |
| update.</p> | |
| <h3 id="microsoft-visual-studio">Microsoft Visual Studio</h3> | |
| <p>The minimum accepted version is Visual Studio 2019 version 16.8. | |
| (Note that this version is often presented as "MSVC 14.28", and reported | |
| by cl.exe as 19.28.) Older versions will not be accepted by | |
| <code>configure</code> and will not work. The maximum accepted version | |
| of Visual Studio is 2022.</p> | |
| <p>If you have multiple versions of Visual Studio installed, | |
| <code>configure</code> will by default pick the latest. You can request | |
| a specific version to be used by setting | |
| <code>--with-toolchain-version</code>, e.g. | |
| <code>--with-toolchain-version=2022</code>.</p> | |
| <p>If you have Visual Studio installed but <code>configure</code> fails | |
| to detect it, it may be because of <a href="#spaces-in-path">spaces in | |
| path</a>.</p> | |
| <p>You must install the US English locale, otherwise the build system | |
| might not be able to interact properly with the compiler. You can add | |
| additional language packs when installing Visual Studio.</p> | |
| <p>If you have already installed Visual Studio without the US English | |
| language pack, you can modify the installation to add this. You can | |
| either do this via a GUI like this:</p> | |
| <ul> | |
| <li>Click on "Visual Studio Installer" in Start menu.</li> | |
| <li>Click "Modify".</li> | |
| <li>Select the tab "Language packs".</li> | |
| <li>Choose "English".</li> | |
| <li>Click "Modify".</li> | |
| </ul> | |
| <p>or you can run it on the command line. For this to work, you need to | |
| start <code>cmd.exe</code> using "Run as Administrator". Then execute | |
| the following line: (note that the " characters are essential)</p> | |
| <pre><code>"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vs_installer.exe" modify --channelId VisualStudio.16.Release --productId Microsoft.VisualStudio.Product.BuildTools --addProductLang en-us -p</code></pre> | |
| <p><code>VisualStudio.16.Release</code> represent VS 2019, so adjust the | |
| version number accordingly. If you have not installed the | |
| <code>BuildTools</code>, but e.g. <code>Professional</code>, adjust the | |
| product ID accordingly.</p> | |
| <h3 id="ibm-open-xl-cc">IBM Open XL C/C++</h3> | |
| <p>The minimum accepted version of Open XL is 17.1.1.4. This is in | |
| essence clang 15, and will be treated as such by the OpenJDK build | |
| system.</p> | |
| <h2 id="boot-jdk-requirements">Boot JDK Requirements</h2> | |
| <p>Paradoxically, building the JDK requires a pre-existing JDK. This is | |
| called the "boot JDK". The boot JDK does not, however, have to be a JDK | |
| built directly from the source code available in the OpenJDK Community. | |
| If you are porting the JDK to a new platform, chances are that there | |
| already exists another JDK for that platform that is usable as boot | |
| JDK.</p> | |
| <p>The rule of thumb is that the boot JDK for building JDK major version | |
| <em>N</em> should be a JDK of major version <em>N-1</em>, so for | |
| building JDK 18 a JDK 17 would be suitable as boot JDK. However, the JDK | |
| should be able to "build itself", so an up-to-date build of the current | |
| JDK source is an acceptable alternative. If you are following the | |
| <em>N-1</em> rule, make sure you've got the latest update version, since | |
| e.g. JDK 8 GA might not be able to build JDK 9 on all platforms.</p> | |
| <p>Early in the release cycle, version <em>N-1</em> may not yet have | |
| been released. In that case, the preferred boot JDK will be version | |
| <em>N-2</em> until version <em>N-1</em> is available.</p> | |
| <p>The <code>configure</code> scripts tries to locate a suitable boot | |
| JDK automatically, but due to the lack of standard installation | |
| locations on most platforms, this heuristics has a high likelihood to | |
| fail. If the boot JDK is not automatically detected, or the wrong JDK is | |
| picked, use <code>--with-boot-jdk</code> to point to the JDK to use.</p> | |
| <h3 id="getting-jdk-binaries">Getting JDK Binaries</h3> | |
| <p>An overview of common ways to download and install prebuilt JDK | |
| binaries can be found on https://openjdk.org/install. An alternative is | |
| to download the <a | |
| href="https://www.oracle.com/java/technologies/downloads">Oracle | |
| JDK</a>. Another is <a href="https://adoptium.net/">Adoptium</a>, which | |
| publishes prebuilt binaries for various platforms.</p> | |
| <p>On Linux you can also get a JDK from the Linux distribution. On | |
| apt-based distros (like Debian and Ubuntu), | |
| <code>sudo apt-get install openjdk-<VERSION>-jdk</code> is | |
| typically enough to install a JDK <VERSION>. On rpm-based distros | |
| (like Fedora and Red Hat), try | |
| <code>sudo yum install java-<VERSION>-openjdk-devel</code>.</p> | |
| <h2 id="external-library-requirements">External Library | |
| Requirements</h2> | |
| <p>Different platforms require different external libraries. In general, | |
| libraries are not optional - that is, they are either required or not | |
| used.</p> | |
| <p>If a required library is not detected by <code>configure</code>, you | |
| need to provide the path to it. There are two forms of the | |
| <code>configure</code> arguments to point to an external library: | |
| <code>--with-<LIB>=<path></code> or | |
| <code>--with-<LIB>-include=<path to include> --with-<LIB>-lib=<path to lib></code>.</p> | |
| <p>The first variant is more concise, but require the include files and | |
| library files to reside in a default hierarchy under this directory. In | |
| most cases, it works fine. As a fallback, the second version allows you | |
| to point to the include directory and the lib directory separately.</p> | |
| <h3 id="freetype">FreeType</h3> | |
| <p>FreeType2 from <a href="https://www.freetype.org/">The FreeType | |
| Project</a> is not required on any platform. The exception is on | |
| Unix-based platforms when configuring such that the build artifacts will | |
| reference a system installed library, rather than bundling the JDK's own | |
| copy.</p> | |
| <ul> | |
| <li>To install on an apt-based Linux, try running | |
| <code>sudo apt-get install libfreetype6-dev</code>.</li> | |
| <li>To install on an rpm-based Linux, try running | |
| <code>sudo yum install freetype-devel</code>.</li> | |
| <li>To install on Alpine Linux, try running | |
| <code>sudo apk add freetype-dev</code>.</li> | |
| <li>To install on macOS, try running | |
| <code>brew install freetype</code>.</li> | |
| </ul> | |
| <p>Use <code>--with-freetype-include=<path></code> and | |
| <code>--with-freetype-lib=<path></code> if <code>configure</code> | |
| does not automatically locate the platform FreeType files.</p> | |
| <h3 id="fontconfig">Fontconfig</h3> | |
| <p>Fontconfig from <a href="https://fontconfig.org">freedesktop.org | |
| Fontconfig</a> is required on all platforms except Windows and | |
| macOS.</p> | |
| <ul> | |
| <li>To install on an apt-based Linux, try running | |
| <code>sudo apt-get install libfontconfig-dev</code>.</li> | |
| <li>To install on an rpm-based Linux, try running | |
| <code>sudo yum install fontconfig-devel</code>.</li> | |
| <li>To install on Alpine Linux, try running | |
| <code>sudo apk add fontconfig-dev</code>.</li> | |
| </ul> | |
| <p>Use <code>--with-fontconfig-include=<path></code> and | |
| <code>--with-fontconfig=<path></code> if <code>configure</code> | |
| does not automatically locate the platform Fontconfig files.</p> | |
| <h3 id="cups">CUPS</h3> | |
| <p>CUPS, <a href="https://www.cups.org">Common UNIX Printing System</a> | |
| header files are required on all platforms, except Windows. Often these | |
| files are provided by your operating system.</p> | |
| <ul> | |
| <li>To install on an apt-based Linux, try running | |
| <code>sudo apt-get install libcups2-dev</code>.</li> | |
| <li>To install on an rpm-based Linux, try running | |
| <code>sudo yum install cups-devel</code>.</li> | |
| <li>To install on Alpine Linux, try running | |
| <code>sudo apk add cups-dev</code>.</li> | |
| </ul> | |
| <p>Use <code>--with-cups=<path></code> if <code>configure</code> | |
| does not properly locate your CUPS files.</p> | |
| <h3 id="x11">X11</h3> | |
| <p>Certain <a href="https://www.x.org/">X11</a> libraries and include | |
| files are required on Linux.</p> | |
| <ul> | |
| <li>To install on an apt-based Linux, try running | |
| <code>sudo apt-get install libx11-dev libxext-dev libxrender-dev libxrandr-dev libxtst-dev libxt-dev</code>.</li> | |
| <li>To install on an rpm-based Linux, try running | |
| <code>sudo yum install libXtst-devel libXt-devel libXrender-devel libXrandr-devel libXi-devel</code>.</li> | |
| <li>To install on Alpine Linux, try running | |
| <code>sudo apk add libx11-dev libxext-dev libxrender-dev libxrandr-dev libxtst-dev libxt-dev</code>.</li> | |
| </ul> | |
| <p>Use <code>--with-x=<path></code> if <code>configure</code> does | |
| not properly locate your X11 files.</p> | |
| <h3 id="alsa">ALSA</h3> | |
| <p>ALSA, <a href="https://www.alsa-project.org/">Advanced Linux Sound | |
| Architecture</a> is required on Linux. At least version 0.9.1 of ALSA is | |
| required.</p> | |
| <ul> | |
| <li>To install on an apt-based Linux, try running | |
| <code>sudo apt-get install libasound2-dev</code>.</li> | |
| <li>To install on an rpm-based Linux, try running | |
| <code>sudo yum install alsa-lib-devel</code>.</li> | |
| <li>To install on Alpine Linux, try running | |
| <code>sudo apk add alsa-lib-dev</code>.</li> | |
| </ul> | |
| <p>Use <code>--with-alsa=<path></code> if <code>configure</code> | |
| does not properly locate your ALSA files.</p> | |
| <h3 id="libffi">libffi</h3> | |
| <p>libffi, the <a href="https://sourceware.org/libffi">Portable Foreign | |
| Function Interface Library</a> is required when building the Zero | |
| version of Hotspot.</p> | |
| <ul> | |
| <li>To install on an apt-based Linux, try running | |
| <code>sudo apt-get install libffi-dev</code>.</li> | |
| <li>To install on an rpm-based Linux, try running | |
| <code>sudo yum install libffi-devel</code>.</li> | |
| <li>To install on Alpine Linux, try running | |
| <code>sudo apk add libffi-dev</code>.</li> | |
| </ul> | |
| <p>Use <code>--with-libffi=<path></code> if <code>configure</code> | |
| does not properly locate your libffi files.</p> | |
| <h2 id="build-tools-requirements">Build Tools Requirements</h2> | |
| <h3 id="autoconf">Autoconf</h3> | |
| <p>The JDK build requires <a | |
| href="https://www.gnu.org/software/autoconf">Autoconf</a> on all | |
| platforms. At least version 2.69 is required.</p> | |
| <ul> | |
| <li>To install on an apt-based Linux, try running | |
| <code>sudo apt-get install autoconf</code>.</li> | |
| <li>To install on an rpm-based Linux, try running | |
| <code>sudo yum install autoconf</code>.</li> | |
| <li>To install on Alpine Linux, try running | |
| <code>sudo apk add autoconf</code>.</li> | |
| <li>To install on macOS, try running | |
| <code>brew install autoconf</code>.</li> | |
| <li>To install on Windows, try running | |
| <code><path to Cygwin setup>/setup-x86_64 -q -P autoconf</code>.</li> | |
| </ul> | |
| <p>If <code>configure</code> has problems locating your installation of | |
| autoconf, you can specify it using the <code>AUTOCONF</code> environment | |
| variable, like this:</p> | |
| <pre><code>AUTOCONF=<path to autoconf> configure ...</code></pre> | |
| <h3 id="gnu-make">GNU Make</h3> | |
| <p>The JDK build requires <a | |
| href="https://www.gnu.org/software/make">GNU Make</a>. No other flavors | |
| of make are supported.</p> | |
| <p>At least version 3.81 of GNU Make must be used. For distributions | |
| supporting GNU Make 4.0 or above, we strongly recommend it. GNU Make 4.0 | |
| contains useful functionality to handle parallel building (supported by | |
| <code>--with-output-sync</code>) and speed and stability | |
| improvements.</p> | |
| <p>Note that <code>configure</code> locates and verifies a properly | |
| functioning version of <code>make</code> and stores the path to this | |
| <code>make</code> binary in the configuration. If you start a build | |
| using <code>make</code> on the command line, you will be using the | |
| version of make found first in your <code>PATH</code>, and not | |
| necessarily the one stored in the configuration. This initial make will | |
| be used as "bootstrap make", and in a second stage, the make located by | |
| <code>configure</code> will be called. Normally, this will present no | |
| issues, but if you have a very old <code>make</code>, or a non-GNU Make | |
| <code>make</code> in your path, this might cause issues.</p> | |
| <p>If you want to override the default make found by | |
| <code>configure</code>, use the <code>MAKE</code> configure variable, | |
| e.g. <code>configure MAKE=/opt/gnu/make</code>.</p> | |
| <h3 id="gnu-bash">GNU Bash</h3> | |
| <p>The JDK build requires <a | |
| href="https://www.gnu.org/software/bash">GNU Bash</a>. No other shells | |
| are supported.</p> | |
| <p>At least version 3.2 of GNU Bash must be used.</p> | |
| <h3 id="graphviz-and-pandoc">Graphviz and Pandoc</h3> | |
| <p>In order to build man pages and the full docs (see the | |
| <code>--enable-full-docs</code> configure option) <a | |
| href="https://pandoc.org">Pandoc</a> is required. For full docs also <a | |
| href="https://www.graphviz.org">Graphviz</a> is required. Any recent | |
| versions should work. For reference, and subject to change, Oracle | |
| builds use Graphviz 9.0.0 and Pandoc 2.19.2.</p> | |
| <h2 id="running-configure">Running Configure</h2> | |
| <p>To build the JDK, you need a "configuration", which consists of a | |
| directory where to store the build output, coupled with information | |
| about the platform, the specific build machine, and choices that affect | |
| how the JDK is built.</p> | |
| <p>The configuration is created by the <code>configure</code> script. | |
| The basic invocation of the <code>configure</code> script looks like | |
| this:</p> | |
| <pre><code>bash configure [options]</code></pre> | |
| <p>This will create an output directory containing the configuration and | |
| setup an area for the build result. This directory typically looks like | |
| <code>build/linux-x64-server-release</code>, but the actual name depends | |
| on your specific configuration. (It can also be set directly, see <a | |
| href="#using-multiple-configurations">Using Multiple | |
| Configurations</a>). This directory is referred to as | |
| <code>$BUILD</code> in this documentation.</p> | |
| <p><code>configure</code> will try to figure out what system you are | |
| running on and where all necessary build components are. If you have all | |
| prerequisites for building installed, it should find everything. If it | |
| fails to detect any component automatically, it will exit and inform you | |
| about the problem.</p> | |
| <p>Some command line examples:</p> | |
| <ul> | |
| <li><p>Create a 32-bit build for Windows with FreeType2 in | |
| <code>C:\freetype-i586</code>:</p> | |
| <pre><code>bash configure --with-freetype=/cygdrive/c/freetype-i586 --with-target-bits=32</code></pre></li> | |
| <li><p>Create a debug build with the <code>server</code> JVM and DTrace | |
| enabled:</p> | |
| <pre><code>bash configure --enable-debug --with-jvm-variants=server --enable-dtrace</code></pre></li> | |
| </ul> | |
| <h3 id="common-configure-arguments">Common Configure Arguments</h3> | |
| <p>Here follows some of the most common and important | |
| <code>configure</code> argument.</p> | |
| <p>To get up-to-date information on <em>all</em> available | |
| <code>configure</code> argument, please run:</p> | |
| <pre><code>bash configure --help</code></pre> | |
| <p>(Note that this help text also include general autoconf options, like | |
| <code>--dvidir</code>, that is not relevant to the JDK. To list only | |
| JDK-specific features, use <code>bash configure --help=short</code> | |
| instead.)</p> | |
| <h4 id="configure-arguments-for-tailoring-the-build">Configure Arguments | |
| for Tailoring the Build</h4> | |
| <ul> | |
| <li><code>--enable-debug</code> - Set the debug level to | |
| <code>fastdebug</code> (this is a shorthand for | |
| <code>--with-debug-level=fastdebug</code>)</li> | |
| <li><code>--with-debug-level=<level></code> - Set the debug level, | |
| which can be <code>release</code>, <code>fastdebug</code>, | |
| <code>slowdebug</code> or <code>optimized</code>. Default is | |
| <code>release</code>. <code>optimized</code> is variant of | |
| <code>release</code> with additional Hotspot debug code.</li> | |
| <li><code>--with-native-debug-symbols=<method></code> - Specify if | |
| and how native debug symbols should be built. Available methods are | |
| <code>none</code>, <code>internal</code>, <code>external</code>, | |
| <code>zipped</code>. Default behavior depends on platform. See <a | |
| href="#native-debug-symbols">Native Debug Symbols</a> for more | |
| details.</li> | |
| <li><code>--with-version-string=<string></code> - Specify the | |
| version string this build will be identified with.</li> | |
| <li><code>--with-version-<part>=<value></code> - A group of | |
| options, where <code><part></code> can be any of <code>pre</code>, | |
| <code>opt</code>, <code>build</code>, <code>major</code>, | |
| <code>minor</code>, <code>security</code> or <code>patch</code>. Use | |
| these options to modify just the corresponding part of the version | |
| string from the default, or the value provided by | |
| <code>--with-version-string</code>.</li> | |
| <li><code>--with-jvm-variants=<variant>[,<variant>...]</code> | |
| - Build the specified variant (or variants) of Hotspot. Valid variants | |
| are: <code>server</code>, <code>client</code>, <code>minimal</code>, | |
| <code>core</code>, <code>zero</code>, <code>custom</code>. Note that not | |
| all variants are possible to combine in a single build.</li> | |
| <li><code>--enable-jvm-feature-<feature></code> or | |
| <code>--disable-jvm-feature-<feature></code> - Include (or | |
| exclude) <code><feature></code> as a JVM feature in Hotspot. You | |
| can also specify a list of features to be enabled, separated by space or | |
| comma, as | |
| <code>--with-jvm-features=<feature>[,<feature>...]</code>. | |
| If you prefix <code><feature></code> with a <code>-</code>, it | |
| will be disabled. These options will modify the default list of features | |
| for the JVM variant(s) you are building. For the <code>custom</code> JVM | |
| variant, the default list is empty. A complete list of valid JVM | |
| features can be found using <code>bash configure --help</code>.</li> | |
| <li><code>--with-target-bits=<bits></code> - Create a target | |
| binary suitable for running on a <code><bits></code> platform. Use | |
| this to create 32-bit output on a 64-bit build platform, instead of | |
| doing a full cross-compile. (This is known as a <em>reduced</em> | |
| build.)</li> | |
| </ul> | |
| <p>On Linux, BSD and AIX, it is possible to override where Java by | |
| default searches for runtime/JNI libraries. This can be useful in | |
| situations where there is a special shared directory for system JNI | |
| libraries. This setting can in turn be overridden at runtime by setting | |
| the <code>java.library.path</code> property.</p> | |
| <ul> | |
| <li><code>--with-jni-libpath=<path></code> - Use the specified | |
| path as a default when searching for runtime libraries.</li> | |
| </ul> | |
| <h4 id="configure-arguments-for-native-compilation">Configure Arguments | |
| for Native Compilation</h4> | |
| <ul> | |
| <li><code>--with-devkit=<path></code> - Use this devkit for | |
| compilers, tools and resources</li> | |
| <li><code>--with-sysroot=<path></code> - Use this directory as | |
| sysroot</li> | |
| <li><code>--with-extra-path=<path>[;<path>]</code> - Prepend | |
| these directories to the default path when searching for all kinds of | |
| binaries</li> | |
| <li><code>--with-toolchain-path=<path>[;<path>]</code> - | |
| Prepend these directories when searching for toolchain binaries | |
| (compilers etc)</li> | |
| <li><code>--with-extra-cflags=<flags></code> - Append these flags | |
| when compiling JDK C files</li> | |
| <li><code>--with-extra-cxxflags=<flags></code> - Append these | |
| flags when compiling JDK C++ files</li> | |
| <li><code>--with-extra-ldflags=<flags></code> - Append these flags | |
| when linking JDK libraries</li> | |
| </ul> | |
| <h4 id="configure-arguments-for-external-dependencies">Configure | |
| Arguments for External Dependencies</h4> | |
| <ul> | |
| <li><code>--with-boot-jdk=<path></code> - Set the path to the <a | |
| href="#boot-jdk-requirements">Boot JDK</a></li> | |
| <li><code>--with-freetype=<path></code> - Set the path to <a | |
| href="#freetype">FreeType</a></li> | |
| <li><code>--with-cups=<path></code> - Set the path to <a | |
| href="#cups">CUPS</a></li> | |
| <li><code>--with-x=<path></code> - Set the path to <a | |
| href="#x11">X11</a></li> | |
| <li><code>--with-alsa=<path></code> - Set the path to <a | |
| href="#alsa">ALSA</a></li> | |
| <li><code>--with-libffi=<path></code> - Set the path to <a | |
| href="#libffi">libffi</a></li> | |
| <li><code>--with-jtreg=<path></code> - Set the path to JTReg. See | |
| <a href="#running-tests">Running Tests</a></li> | |
| </ul> | |
| <p>Certain third-party libraries used by the JDK (libjpeg, giflib, | |
| libpng, lcms and zlib) are included in the JDK repository. The default | |
| behavior of the JDK build is to use the included ("bundled") versions of | |
| libjpeg, giflib, libpng and lcms. For zlib, the system lib (if present) | |
| is used except on Windows and AIX. However the bundled libraries may be | |
| replaced by an external version. To do so, specify <code>system</code> | |
| as the <code><source></code> option in these arguments. (The | |
| default is <code>bundled</code>).</p> | |
| <ul> | |
| <li><code>--with-libjpeg=<source></code> - Use the specified | |
| source for libjpeg</li> | |
| <li><code>--with-giflib=<source></code> - Use the specified source | |
| for giflib</li> | |
| <li><code>--with-libpng=<source></code> - Use the specified source | |
| for libpng</li> | |
| <li><code>--with-lcms=<source></code> - Use the specified source | |
| for lcms</li> | |
| <li><code>--with-zlib=<source></code> - Use the specified source | |
| for zlib</li> | |
| </ul> | |
| <p>On Linux, it is possible to select either static or dynamic linking | |
| of the C++ runtime. The default is static linking, with dynamic linking | |
| as fallback if the static library is not found.</p> | |
| <ul> | |
| <li><code>--with-stdc++lib=<method></code> - Use the specified | |
| method (<code>static</code>, <code>dynamic</code> or | |
| <code>default</code>) for linking the C++ runtime.</li> | |
| </ul> | |
| <h3 id="configure-control-variables">Configure Control Variables</h3> | |
| <p>It is possible to control certain aspects of <code>configure</code> | |
| by overriding the value of <code>configure</code> variables, either on | |
| the command line or in the environment.</p> | |
| <p>Normally, this is <strong>not recommended</strong>. If used | |
| improperly, it can lead to a broken configuration. Unless you're well | |
| versed in the build system, this is hard to use properly. Therefore, | |
| <code>configure</code> will print a warning if this is detected.</p> | |
| <p>However, there are a few <code>configure</code> variables, known as | |
| <em>control variables</em> that are supposed to be overridden on the | |
| command line. These are variables that describe the location of tools | |
| needed by the build, like <code>MAKE</code> or <code>GREP</code>. If any | |
| such variable is specified, <code>configure</code> will use that value | |
| instead of trying to autodetect the tool. For instance, | |
| <code>bash configure MAKE=/opt/gnumake4.0/bin/make</code>.</p> | |
| <p>If a configure argument exists, use that instead, e.g. use | |
| <code>--with-jtreg</code> instead of setting <code>JTREGEXE</code>.</p> | |
| <p>Also note that, despite what autoconf claims, setting | |
| <code>CFLAGS</code> will not accomplish anything. Instead use | |
| <code>--with-extra-cflags</code> (and similar for <code>cxxflags</code> | |
| and <code>ldflags</code>).</p> | |
| <h2 id="running-make">Running Make</h2> | |
| <p>When you have a proper configuration, all you need to do to build the | |
| JDK is to run <code>make</code>. (But see the warning at <a | |
| href="#gnu-make">GNU Make</a> about running the correct version of | |
| make.)</p> | |
| <p>When running <code>make</code> without any arguments, the default | |
| target is used, which is the same as running <code>make default</code> | |
| or <code>make jdk</code>. This will build a minimal (or roughly minimal) | |
| set of compiled output (known as an "exploded image") needed for a | |
| developer to actually execute the newly built JDK. The idea is that in | |
| an incremental development fashion, when doing a normal make, you should | |
| only spend time recompiling what's changed (making it purely | |
| incremental) and only do the work that's needed to actually run and test | |
| your code.</p> | |
| <p>The output of the exploded image resides in <code>$BUILD/jdk</code>. | |
| You can test the newly built JDK like this: | |
| <code>$BUILD/jdk/bin/java -version</code>.</p> | |
| <h3 id="common-make-targets">Common Make Targets</h3> | |
| <p>Apart from the default target, here are some common make targets:</p> | |
| <ul> | |
| <li><code>hotspot</code> - Build all of hotspot (but only hotspot)</li> | |
| <li><code>hotspot-<variant></code> - Build just the specified jvm | |
| variant</li> | |
| <li><code>images</code> or <code>product-images</code> - Build the JDK | |
| image</li> | |
| <li><code>docs</code> or <code>docs-image</code> - Build the | |
| documentation image</li> | |
| <li><code>test-image</code> - Build the test image</li> | |
| <li><code>all</code> or <code>all-images</code> - Build all images | |
| (product, docs and test)</li> | |
| <li><code>bootcycle-images</code> - Build images twice, second time with | |
| newly built JDK (good for testing)</li> | |
| <li><code>clean</code> - Remove all files generated by make, but not | |
| those generated by configure</li> | |
| <li><code>dist-clean</code> - Remove all files, including | |
| configuration</li> | |
| </ul> | |
| <p>Run <code>make help</code> to get an up-to-date list of important | |
| make targets and make control variables.</p> | |
| <p>It is possible to build just a single module, a single phase, or a | |
| single phase of a single module, by creating make targets according to | |
| these following patterns. A phase can be either of <code>gensrc</code>, | |
| <code>gendata</code>, <code>copy</code>, <code>java</code>, | |
| <code>launchers</code>, or <code>libs</code>. See <a | |
| href="#using-fine-grained-make-targets">Using Fine-Grained Make | |
| Targets</a> for more details about this functionality.</p> | |
| <ul> | |
| <li><code><phase></code> - Build the specified phase and | |
| everything it depends on</li> | |
| <li><code><module></code> - Build the specified module and | |
| everything it depends on</li> | |
| <li><code><module>-<phase></code> - Compile the specified | |
| phase for the specified module and everything it depends on</li> | |
| </ul> | |
| <p>Similarly, it is possible to clean just a part of the build by | |
| creating make targets according to these patterns:</p> | |
| <ul> | |
| <li><code>clean-<outputdir></code> - Remove the subdir in the | |
| output dir with the name</li> | |
| <li><code>clean-<phase></code> - Remove all build results related | |
| to a certain build phase</li> | |
| <li><code>clean-<module></code> - Remove all build results related | |
| to a certain module</li> | |
| <li><code>clean-<module>-<phase></code> - Remove all build | |
| results related to a certain module and phase</li> | |
| </ul> | |
| <h3 id="make-control-variables">Make Control Variables</h3> | |
| <p>It is possible to control <code>make</code> behavior by overriding | |
| the value of <code>make</code> variables, either on the command line or | |
| in the environment.</p> | |
| <p>Normally, this is <strong>not recommended</strong>. If used | |
| improperly, it can lead to a broken build. Unless you're well versed in | |
| the build system, this is hard to use properly. Therefore, | |
| <code>make</code> will print a warning if this is detected.</p> | |
| <p>However, there are a few <code>make</code> variables, known as | |
| <em>control variables</em> that are supposed to be overridden on the | |
| command line. These make up the "make time" configuration, as opposed to | |
| the "configure time" configuration.</p> | |
| <h4 id="general-make-control-variables">General Make Control | |
| Variables</h4> | |
| <ul> | |
| <li><code>JOBS</code> - Specify the number of jobs to build with. See <a | |
| href="#build-performance">Build Performance</a>.</li> | |
| <li><code>LOG</code> - Specify the logging level and functionality. See | |
| <a href="#checking-the-build-log-file">Checking the Build Log | |
| File</a></li> | |
| <li><code>CONF</code> and <code>CONF_NAME</code> - Selecting the | |
| configuration(s) to use. See <a | |
| href="#using-multiple-configurations">Using Multiple | |
| Configurations</a></li> | |
| </ul> | |
| <h4 id="test-make-control-variables">Test Make Control Variables</h4> | |
| <p>These make control variables only make sense when running tests. | |
| Please see <strong>Testing the JDK</strong> (<a | |
| href="testing.html">html</a>, <a href="testing.md">markdown</a>) for | |
| details.</p> | |
| <ul> | |
| <li><code>TEST</code></li> | |
| <li><code>TEST_JOBS</code></li> | |
| <li><code>TEST_OPTS</code></li> | |
| <li><code>TEST_VM_OPTS</code></li> | |
| <li><code>JTREG</code></li> | |
| <li><code>GTEST</code></li> | |
| <li><code>MICRO</code></li> | |
| </ul> | |
| <h4 id="advanced-make-control-variables">Advanced Make Control | |
| Variables</h4> | |
| <p>These advanced make control variables can be potentially unsafe. See | |
| <a href="#hints-and-suggestions-for-advanced-users">Hints and | |
| Suggestions for Advanced Users</a> and <a | |
| href="#understanding-the-build-system">Understanding the Build | |
| System</a> for details.</p> | |
| <ul> | |
| <li><code>SPEC</code></li> | |
| <li><code>CONF_CHECK</code></li> | |
| <li><code>COMPARE_BUILD</code></li> | |
| <li><code>JDK_FILTER</code></li> | |
| <li><code>SPEC_FILTER</code></li> | |
| </ul> | |
| <h2 id="running-tests">Running Tests</h2> | |
| <p>Most of the JDK tests are using the <a | |
| href="https://openjdk.org/jtreg">JTReg</a> test framework. Make sure | |
| that your configuration knows where to find your installation of JTReg. | |
| If this is not picked up automatically, use the | |
| <code>--with-jtreg=<path to jtreg home></code> option to point to | |
| the JTReg framework. Note that this option should point to the JTReg | |
| home, i.e. the top directory, containing <code>lib/jtreg.jar</code> | |
| etc.</p> | |
| <p>The <a href="https://wiki.openjdk.org/display/Adoption">Adoption | |
| Group</a> provides recent builds of jtreg <a | |
| href="https://ci.adoptium.net/view/Dependencies/job/dependency_pipeline/lastSuccessfulBuild/artifact/jtreg/">here</a>. | |
| Download the latest <code>.tar.gz</code> file, unpack it, and point | |
| <code>--with-jtreg</code> to the <code>jtreg</code> directory that you | |
| just unpacked.</p> | |
| <p>Building of Hotspot Gtest suite requires the source code of Google | |
| Test framework. The top directory, which contains both | |
| <code>googletest</code> and <code>googlemock</code> directories, should | |
| be specified via <code>--with-gtest</code>. The minimum supported | |
| version of Google Test is 1.14.0, whose source code can be obtained:</p> | |
| <ul> | |
| <li>by downloading and unpacking the source bundle from <a | |
| href="https://github.com/google/googletest/releases/tag/v1.14.0">here</a>, | |
| or</li> | |
| <li>by checking out <code>v1.14.0</code> tag of <code>googletest</code> | |
| project: | |
| <code>git clone -b v1.14.0 https://github.com/google/googletest</code></li> | |
| </ul> | |
| <p>To execute the most basic tests (tier 1), use:</p> | |
| <pre><code>make test-tier1</code></pre> | |
| <p>For more details on how to run tests, please see <strong>Testing the | |
| JDK</strong> (<a href="testing.html">html</a>, <a | |
| href="testing.md">markdown</a>).</p> | |
| <h2 id="signing">Signing</h2> | |
| <h3 id="macos-1">macOS</h3> | |
| <p>Modern versions of macOS require applications to be signed and | |
| notarized before distribution. See Apple's documentation for more | |
| background on what this means and how it works. To help support this, | |
| the JDK build can be configured to automatically sign all native | |
| binaries, and the JDK bundle, with all the options needed for successful | |
| notarization, as well as all the entitlements required by the JDK. To | |
| enable <code>hardened</code> signing, use configure parameter | |
| <code>--with-macosx-codesign=hardened</code> and configure the signing | |
| identity you wish to use with | |
| <code>--with-macosx-codesign-identity=<identity></code>. The | |
| identity refers to a signing identity from Apple that needs to be | |
| preinstalled on the build host.</p> | |
| <p>When not signing for distribution with the hardened option, the JDK | |
| build will still attempt to perform <code>adhoc</code> signing to add | |
| the special entitlement <code>com.apple.security.get-task-allow</code> | |
| to each binary. This entitlement is required to be able to dump core | |
| files from a process. Note that adding this entitlement makes the build | |
| invalid for notarization, so it is only added when signing in | |
| <code>debug</code> mode. To explicitly enable this kind of ad hoc | |
| signing, use configure parameter | |
| <code>--with-macosx-codesign=debug</code>. It will be enabled by default | |
| in most cases.</p> | |
| <p>It's also possible to completely disable any explicit codesign | |
| operations done by the JDK build using the configure parameter | |
| <code>--without-macosx-codesign</code>. The exact behavior then depends | |
| on the architecture. For macOS on x64, it (at least at the time of this | |
| writing) results in completely unsigned binaries that should still work | |
| fine for development and debugging purposes. On aarch64, the Xcode | |
| linker will apply a default "ad hoc" signing, without any entitlements. | |
| Such a build does not allow dumping core files.</p> | |
| <p>The default mode "auto" will try for <code>hardened</code> signing if | |
| the debug level is <code>release</code> and either the default identity | |
| or the specified identity is valid. If hardened isn't possible, then | |
| <code>debug</code> signing is chosen if it works. If nothing works, the | |
| codesign build step is disabled.</p> | |
| <h2 id="cross-compiling">Cross-Compiling</h2> | |
| <p>Cross-compiling means using one platform (the <em>build</em> | |
| platform) to generate output that can ran on another platform (the | |
| <em>target</em> platform).</p> | |
| <p>The typical reason for cross-compiling is that the build is performed | |
| on a more powerful desktop computer, but the resulting binaries will be | |
| able to run on a different, typically low-performing system. Most of the | |
| complications that arise when building for embedded is due to this | |
| separation of <em>build</em> and <em>target</em> systems.</p> | |
| <p>This requires a more complex setup and build procedure. This section | |
| assumes you are familiar with cross-compiling in general, and will only | |
| deal with the particularities of cross-compiling the JDK. If you are new | |
| to cross-compiling, please see the <a | |
| href="https://en.wikipedia.org/wiki/Cross_compiler#External_links">external | |
| links at Wikipedia</a> for a good start on reading materials.</p> | |
| <p>Cross-compiling the JDK requires you to be able to build both for the | |
| build platform and for the target platform. The reason for the former is | |
| that we need to build and execute tools during the build process, both | |
| native tools and Java tools.</p> | |
| <p>If all you want to do is to compile a 32-bit version, for the same | |
| OS, on a 64-bit machine, consider using | |
| <code>--with-target-bits=32</code> instead of doing a full-blown | |
| cross-compilation. (While this surely is possible, it's a lot more work | |
| and will take much longer to build.)</p> | |
| <p>Setting up a cross-compilation environment by hand is time-consuming | |
| and error prone. It is highly recommended that you use one of the | |
| automated methods described in <a | |
| href="#cross-compiling-the-easy-way">Cross compiling the easy | |
| way</a>.</p> | |
| <h3 id="specifying-the-target-platform">Specifying the Target | |
| Platform</h3> | |
| <p>You <em>must</em> specify the target platform when cross-compiling. | |
| Doing so will also automatically turn the build into a cross-compiling | |
| mode. The simplest way to do this is to use the | |
| <code>--openjdk-target</code> argument, e.g. | |
| <code>--openjdk-target=arm-linux-gnueabihf</code>. or | |
| <code>--openjdk-target=aarch64-oe-linux</code>. This will automatically | |
| set the <code>--host</code> and <code>--target</code> options for | |
| autoconf, which can otherwise be confusing. (In autoconf terminology, | |
| the "target" is known as "host", and "target" is used for building a | |
| Canadian cross-compiler.)</p> | |
| <p>If <code>--build</code> has not been explicitly passed to configure, | |
| <code>--openjdk-target</code> will autodetect the build platform and | |
| internally set the flag automatically, otherwise the platform that was | |
| explicitly passed to <code>--build</code> will be used instead.</p> | |
| <h3 id="boot-jdk-and-build-jdk">Boot JDK and Build JDK</h3> | |
| <p>When cross-compiling, make sure you use a boot JDK that runs on the | |
| <em>build</em> system, and not on the <em>target</em> system.</p> | |
| <p>To be able to build, we need a "Build JDK", which is a JDK built from | |
| the current sources (that is, the same as the end result of the entire | |
| build process), but able to run on the <em>build</em> system, and not | |
| the <em>target</em> system. (In contrast, the Boot JDK should be from an | |
| older release, e.g. JDK 8 when building JDK 9.)</p> | |
| <p>The build process will create a minimal Build JDK for you, as part of | |
| building. To speed up the build, you can use | |
| <code>--with-build-jdk</code> to <code>configure</code> to point to a | |
| pre-built Build JDK. Please note that the build result is unpredictable, | |
| and can possibly break in subtle ways, if the Build JDK does not | |
| <strong>exactly</strong> match the current sources.</p> | |
| <h3 id="toolchain-considerations">Toolchain Considerations</h3> | |
| <p>You will need two copies of your toolchain, one which generates | |
| output that can run on the target system (the normal, or | |
| <em>target</em>, toolchain), and one that generates output that can run | |
| on the build system (the <em>build</em> toolchain).</p> | |
| <p>If you are cross-compiling using gcc, it is recommended to use the | |
| gcc standard where you prefix cross-compiling tools with the target | |
| denominator. If you follow this standard, <code>configure</code> is | |
| likely to pick up the toolchain correctly.</p> | |
| <p>The <em>build</em> toolchain will be auto-detected just the same way | |
| the normal <em>build</em>/<em>target</em> toolchain will be | |
| auto-detected when not cross-compiling. If this is not what you want, or | |
| if the auto-detection fails, you can specify a devkit containing the | |
| <em>build</em> toolchain using <code>--with-build-devkit</code> to | |
| <code>configure</code>, or by giving <code>BUILD_CC</code> and | |
| <code>BUILD_CXX</code> arguments.</p> | |
| <p>It is often helpful to locate the cross-compilation tools, headers | |
| and libraries in a separate directory, outside the normal path, and | |
| point out that directory to <code>configure</code>. Do this by setting | |
| the sysroot (<code>--with-sysroot</code>) and appending the directory | |
| when searching for cross-compilations tools | |
| (<code>--with-toolchain-path</code>). As a compact form, you can also | |
| use <code>--with-devkit</code> to point to a single directory, if it is | |
| correctly setup. (See <code>make/autoconf/basics.m4</code> for | |
| details.)</p> | |
| <h3 id="native-libraries">Native Libraries</h3> | |
| <p>You will need copies of external native libraries for the | |
| <em>target</em> system present on the <em>build</em> machine while | |
| building.</p> | |
| <p>Take care not to replace the <em>build</em> system's version of these | |
| libraries by mistake, as that can render the <em>build</em> machine | |
| unusable.</p> | |
| <p>Make sure that the libraries you point to (ALSA, X11, etc) are for | |
| the <em>target</em> platform, not the <em>build</em> platform.</p> | |
| <h4 id="alsa-1">ALSA</h4> | |
| <p>You will need alsa libraries suitable for your <em>target</em> | |
| system. In most cases, using Debian's pre-built libraries work fine.</p> | |
| <p>Note that alsa is needed even if you only want to build a headless | |
| JDK.</p> | |
| <ul> | |
| <li><p>Go to <a href="https://www.debian.org/distrib/packages">Debian | |
| Package Search</a>, search for the <code>libasound2</code> and | |
| <code>libasound2-dev</code> packages for your <em>target</em> system, | |
| and download them to /tmp.</p></li> | |
| <li><p>Install the libraries into the cross-compilation toolchain. For | |
| instance:</p> | |
| <pre><code>cd /tools/gcc-linaro-arm-linux-gnueabihf-raspbian-2012.09-20120921_linux/arm-linux-gnueabihf/libc | |
| dpkg-deb -x /tmp/libasound2_1.0.25-4_armhf.deb . | |
| dpkg-deb -x /tmp/libasound2-dev_1.0.25-4_armhf.deb .</code></pre></li> | |
| <li><p>If alsa is not properly detected by <code>configure</code>, you | |
| can specify it by <code>--with-alsa</code>.</p></li> | |
| </ul> | |
| <h4 id="x11-1">X11</h4> | |
| <p>You will need X11 libraries suitable for your <em>target</em> system. | |
| In most cases, using Debian's pre-built libraries work fine.</p> | |
| <p>Note that X11 is needed even if you only want to build a headless | |
| JDK.</p> | |
| <ul> | |
| <li><p>Go to <a href="https://www.debian.org/distrib/packages">Debian | |
| Package Search</a>, search for the following packages for your | |
| <em>target</em> system, and download them to /tmp/target-x11:</p> | |
| <ul> | |
| <li><code>libxi</code></li> | |
| <li><code>libxi-dev</code></li> | |
| <li><code>x11proto-core-dev</code></li> | |
| <li><code>x11proto-input-dev</code></li> | |
| <li><code>x11proto-kb-dev</code></li> | |
| <li><code>x11proto-render-dev</code></li> | |
| <li><code>x11proto-xext-dev</code></li> | |
| <li><code>libice-dev</code></li> | |
| <li><code>libxrender</code></li> | |
| <li><code>libxrender-dev</code></li> | |
| <li><code>libxrandr-dev</code></li> | |
| <li><code>libsm-dev</code></li> | |
| <li><code>libxt-dev</code></li> | |
| <li><code>libx11</code></li> | |
| <li><code>libx11-dev</code></li> | |
| <li><code>libxtst</code></li> | |
| <li><code>libxtst-dev</code></li> | |
| <li><code>libxext</code></li> | |
| <li><code>libxext-dev</code></li> | |
| </ul></li> | |
| <li><p>Install the libraries into the cross-compilation toolchain. For | |
| instance:</p> | |
| <pre><code>cd /tools/gcc-linaro-arm-linux-gnueabihf-raspbian-2012.09-20120921_linux/arm-linux-gnueabihf/libc/usr | |
| mkdir X11R6 | |
| cd X11R6 | |
| for deb in /tmp/target-x11/*.deb ; do dpkg-deb -x $deb . ; done | |
| mv usr/* . | |
| cd lib | |
| cp arm-linux-gnueabihf/* .</code></pre> | |
| <p>You can ignore the following messages, since these libraries are not | |
| needed to successfully complete a full JDK build.</p> | |
| <pre><code>cp: cannot stat `arm-linux-gnueabihf/libICE.so': No such file or directory | |
| cp: cannot stat `arm-linux-gnueabihf/libSM.so': No such file or directory | |
| cp: cannot stat `arm-linux-gnueabihf/libXt.so': No such file or directory</code></pre></li> | |
| <li><p>If the X11 libraries are not properly detected by | |
| <code>configure</code>, you can point them out by | |
| <code>--with-x</code>.</p></li> | |
| </ul> | |
| <h3 id="verifying-the-build">Verifying the Build</h3> | |
| <p>The build will end up in a directory named like | |
| <code>build/linux-arm-normal-server-release</code>.</p> | |
| <p>Inside this build output directory, the <code>images/jdk</code> will | |
| contain the newly built JDK, for your <em>target</em> system.</p> | |
| <p>Copy these folders to your <em>target</em> system. Then you can run | |
| e.g. <code>images/jdk/bin/java -version</code>.</p> | |
| <h3 id="cross-compiling-the-easy-way">Cross-Compiling the Easy Way</h3> | |
| <p>Setting up a proper cross-compilation environment can be a lot of | |
| work. Fortunately there are ways that more or less automate this | |
| process. Here are two recommended methods, using the "devkits" that can | |
| be generated by the JDK build system, or by using the | |
| <code>debootstrap</code> command in Debian. The former works on all | |
| Linux distributions, the latter only on Debian and derivatives. Both | |
| solution only work for gcc.</p> | |
| <p>The devkit method is regularly used for testing by Oracle, and the | |
| debootstrap method is regularly used in GitHub Actions testing.</p> | |
| <h4 id="using-openjdk-devkits">Using OpenJDK Devkits</h4> | |
| <p>The JDK build system provides out-of-the box support for creating and | |
| using so called devkits. A <code>devkit</code> is basically a collection | |
| of a cross-compiling toolchain and a sysroot environment which can | |
| easily be used together with the <code>--with-devkit</code> configure | |
| option to cross compile the JDK. On Linux/x86_64, the following | |
| command:</p> | |
| <pre><code>bash configure --with-devkit=<devkit-path> --openjdk-target=ppc64-linux-gnu && make</code></pre> | |
| <p>will configure and build the JDK for Linux/ppc64 assuming that | |
| <code><devkit-path></code> points to a Linux/x86_64 to Linux/ppc64 | |
| devkit.</p> | |
| <p>Devkits can be created from the <code>make/devkit</code> directory by | |
| executing:</p> | |
| <pre><code>make [ TARGETS="<TARGET_TRIPLET>+" ] [ BASE_OS=<OS> ] [ BASE_OS_VERSION=<VER> ]</code></pre> | |
| <p>where <code>TARGETS</code> contains one or more | |
| <code>TARGET_TRIPLET</code>s of the form described in <a | |
| href="https://sourceware.org/autobook/autobook/autobook_17.html">section | |
| 3.4 of the GNU Autobook</a>. If no targets are given, a native toolchain | |
| for the current platform will be created. Currently, at least the | |
| following targets are known to work:</p> | |
| <table> | |
| <thead> | |
| <tr class="header"> | |
| <th>Supported devkit targets</th> | |
| </tr> | |
| </thead> | |
| <tbody> | |
| <tr class="odd"> | |
| <td>x86_64-linux-gnu</td> | |
| </tr> | |
| <tr class="even"> | |
| <td>aarch64-linux-gnu</td> | |
| </tr> | |
| <tr class="odd"> | |
| <td>arm-linux-gnueabihf</td> | |
| </tr> | |
| <tr class="even"> | |
| <td>ppc64-linux-gnu</td> | |
| </tr> | |
| <tr class="odd"> | |
| <td>ppc64le-linux-gnu</td> | |
| </tr> | |
| <tr class="even"> | |
| <td>s390x-linux-gnu</td> | |
| </tr> | |
| </tbody> | |
| </table> | |
| <p><code>BASE_OS</code> must be one of "OEL6" for Oracle Enterprise | |
| Linux 6 or "Fedora" (if not specified "OEL6" will be the default). If | |
| the base OS is "Fedora" the corresponding Fedora release can be | |
| specified with the help of the <code>BASE_OS_VERSION</code> option (with | |
| "27" as default version). If the build is successful, the new devkits | |
| can be found in the <code>build/devkit/result</code> subdirectory:</p> | |
| <pre><code>cd make/devkit | |
| make TARGETS="ppc64le-linux-gnu aarch64-linux-gnu" BASE_OS=Fedora BASE_OS_VERSION=21 | |
| ls -1 ../../build/devkit/result/ | |
| x86_64-linux-gnu-to-aarch64-linux-gnu | |
| x86_64-linux-gnu-to-ppc64le-linux-gnu</code></pre> | |
| <p>Notice that devkits are not only useful for targeting different build | |
| platforms. Because they contain the full build dependencies for a system | |
| (i.e. compiler and root file system), they can easily be used to build | |
| well-known, reliable and reproducible build environments. You can for | |
| example create and use a devkit with GCC 7.3 and a Fedora 12 sysroot | |
| environment (with glibc 2.11) on Ubuntu 14.04 (which doesn't have GCC | |
| 7.3 by default) to produce JDK binaries which will run on all Linux | |
| systems with runtime libraries newer than the ones from Fedora 12 (e.g. | |
| Ubuntu 16.04, SLES 11 or RHEL 6).</p> | |
| <h4 id="using-debian-debootstrap">Using Debian debootstrap</h4> | |
| <p>On Debian (or a derivative like Ubuntu), you can create sysroots for | |
| foreign architectures with tools provided by the OS. You can use | |
| <code>debootstrap</code> to create a <em>target</em> system chroot | |
| directory, which would have the native libraries and headers specific to | |
| that <em>target</em> system. After that, you can use the cross-compiler | |
| on the <em>build</em> system, pointing into the chroot to get the build | |
| dependencies right. This allows building for foreign architectures with | |
| native compilation speed.</p> | |
| <p>For example, cross-compiling to AArch64 from x86_64 could be done | |
| like this:</p> | |
| <ul> | |
| <li><p>Install cross-compiler on the <em>build</em> system:</p> | |
| <pre><code>apt install g++-aarch64-linux-gnu gcc-aarch64-linux-gnu</code></pre></li> | |
| <li><p>Create chroot on the <em>build</em> system, configuring it for | |
| <em>target</em> system:</p> | |
| <pre><code>sudo debootstrap \ | |
| --arch=arm64 \ | |
| --verbose \ | |
| --include=fakeroot,symlinks,build-essential,libx11-dev,libxext-dev,libxrender-dev,libxrandr-dev,libxtst-dev,libxt-dev,libcups2-dev,libfontconfig1-dev,libasound2-dev,libfreetype6-dev,libpng-dev,libffi-dev \ | |
| --resolve-deps \ | |
| buster \ | |
| ~/sysroot-arm64 \ | |
| https://httpredir.debian.org/debian/</code></pre></li> | |
| <li><p>To create an Ubuntu-based chroot:</p> | |
| <pre><code>sudo debootstrap \ | |
| --arch=arm64 \ | |
| --verbose \ | |
| --components=main,universe \ | |
| --include=fakeroot,symlinks,build-essential,libx11-dev,libxext-dev,libxrender-dev,libxrandr-dev,libxtst-dev,libxt-dev,libcups2-dev,libfontconfig1-dev,libasound2-dev,libfreetype6-dev,libpng-dev,libffi-dev \ | |
| --resolve-deps \ | |
| jammy \ | |
| ~/sysroot-arm64 \ | |
| http://ports.ubuntu.com/ubuntu-ports/</code></pre> | |
| <p>Note that <code>symlinks</code> is in the universe | |
| repository.</p></li> | |
| <li><p>Make sure the symlinks inside the newly created chroot point to | |
| proper locations:</p> | |
| <pre><code>sudo chroot ~/sysroot-arm64 symlinks -cr .</code></pre></li> | |
| <li><p>Configure and build with newly created chroot as | |
| sysroot/toolchain-path:</p> | |
| <pre><code>sh ./configure \ | |
| --openjdk-target=aarch64-linux-gnu \ | |
| --with-sysroot=~/sysroot-arm64 | |
| make images | |
| ls build/linux-aarch64-server-release/</code></pre></li> | |
| </ul> | |
| <p>The build does not create new files in that chroot, so it can be | |
| reused for multiple builds without additional cleanup.</p> | |
| <p>The build system should automatically detect the toolchain paths and | |
| dependencies, but sometimes it might require a little nudge with:</p> | |
| <ul> | |
| <li><p>Native compilers: override <code>CC</code> or <code>CXX</code> | |
| for <code>./configure</code></p></li> | |
| <li><p>Freetype lib location: override <code>--with-freetype-lib</code>, | |
| for example <code>${sysroot}/usr/lib/${target}/</code></p></li> | |
| <li><p>Freetype includes location: override | |
| <code>--with-freetype-include</code> for example | |
| <code>${sysroot}/usr/include/freetype2/</code></p></li> | |
| <li><p>X11 libraries location: override <code>--x-libraries</code>, for | |
| example <code>${sysroot}/usr/lib/${target}/</code></p></li> | |
| </ul> | |
| <p>Architectures that are known to successfully cross-compile like this | |
| are:</p> | |
| <table> | |
| <colgroup> | |
| <col style="width: 13%" /> | |
| <col style="width: 13%" /> | |
| <col style="width: 15%" /> | |
| <col style="width: 27%" /> | |
| <col style="width: 29%" /> | |
| </colgroup> | |
| <thead> | |
| <tr class="header"> | |
| <th>Target</th> | |
| <th>Debian tree</th> | |
| <th>Debian arch</th> | |
| <th><code>--openjdk-target=...</code></th> | |
| <th><code>--with-jvm-variants=...</code></th> | |
| </tr> | |
| </thead> | |
| <tbody> | |
| <tr class="odd"> | |
| <td>x86</td> | |
| <td>buster</td> | |
| <td>i386</td> | |
| <td>i386-linux-gnu</td> | |
| <td>(all)</td> | |
| </tr> | |
| <tr class="even"> | |
| <td>arm</td> | |
| <td>buster</td> | |
| <td>armhf</td> | |
| <td>arm-linux-gnueabihf</td> | |
| <td>(all)</td> | |
| </tr> | |
| <tr class="odd"> | |
| <td>aarch64</td> | |
| <td>buster</td> | |
| <td>arm64</td> | |
| <td>aarch64-linux-gnu</td> | |
| <td>(all)</td> | |
| </tr> | |
| <tr class="even"> | |
| <td>ppc64le</td> | |
| <td>buster</td> | |
| <td>ppc64el</td> | |
| <td>powerpc64le-linux-gnu</td> | |
| <td>(all)</td> | |
| </tr> | |
| <tr class="odd"> | |
| <td>s390x</td> | |
| <td>buster</td> | |
| <td>s390x</td> | |
| <td>s390x-linux-gnu</td> | |
| <td>(all)</td> | |
| </tr> | |
| <tr class="even"> | |
| <td>mipsle</td> | |
| <td>buster</td> | |
| <td>mipsel</td> | |
| <td>mipsel-linux-gnu</td> | |
| <td>zero</td> | |
| </tr> | |
| <tr class="odd"> | |
| <td>mips64le</td> | |
| <td>buster</td> | |
| <td>mips64el</td> | |
| <td>mips64el-linux-gnueabi64</td> | |
| <td>zero</td> | |
| </tr> | |
| <tr class="even"> | |
| <td>armel</td> | |
| <td>buster</td> | |
| <td>arm</td> | |
| <td>arm-linux-gnueabi</td> | |
| <td>zero</td> | |
| </tr> | |
| <tr class="odd"> | |
| <td>ppc</td> | |
| <td>sid</td> | |
| <td>powerpc</td> | |
| <td>powerpc-linux-gnu</td> | |
| <td>zero</td> | |
| </tr> | |
| <tr class="even"> | |
| <td>ppc64be</td> | |
| <td>sid</td> | |
| <td>ppc64</td> | |
| <td>powerpc64-linux-gnu</td> | |
| <td>(all)</td> | |
| </tr> | |
| <tr class="odd"> | |
| <td>m68k</td> | |
| <td>sid</td> | |
| <td>m68k</td> | |
| <td>m68k-linux-gnu</td> | |
| <td>zero</td> | |
| </tr> | |
| <tr class="even"> | |
| <td>alpha</td> | |
| <td>sid</td> | |
| <td>alpha</td> | |
| <td>alpha-linux-gnu</td> | |
| <td>zero</td> | |
| </tr> | |
| <tr class="odd"> | |
| <td>sh4</td> | |
| <td>sid</td> | |
| <td>sh4</td> | |
| <td>sh4-linux-gnu</td> | |
| <td>zero</td> | |
| </tr> | |
| <tr class="even"> | |
| <td>riscv64</td> | |
| <td>sid</td> | |
| <td>riscv64</td> | |
| <td>riscv64-linux-gnu</td> | |
| <td>(all)</td> | |
| </tr> | |
| </tbody> | |
| </table> | |
| <h3 id="considerations-for-specific-targets">Considerations for Specific | |
| Targets</h3> | |
| <h4 id="building-for-arm32">Building for ARM32</h4> | |
| <p>A common cross-compilation target is the ARM CPU. When building for | |
| ARM, it is recommended to set the ABI profile. A number of pre-defined | |
| ABI profiles are available using <code>--with-abi-profile</code>: | |
| <code>arm-vfp-sflt</code>, <code>arm-vfp-hflt</code>, | |
| <code>arm-sflt</code>, <code>armv5-vfp-sflt</code> and | |
| <code>armv6-vfp-hflt</code>. Note that soft-float ABIs are no longer | |
| properly supported by the JDK.</p> | |
| <h4 id="building-for-risc-v">Building for RISC-V</h4> | |
| <p>The RISC-V community provides a basic <a | |
| href="https://github.com/riscv-collab/riscv-gnu-toolchain">GNU compiler | |
| toolchain</a>, but the <a href="#external-library-requirements">external | |
| libraries</a> required by the JDK complicate the building process. The | |
| placeholder <code><toolchain-installed-path></code> shown below is | |
| the path where you want to install the toolchain.</p> | |
| <ul> | |
| <li><p>Install the RISC-V GNU compiler toolchain:</p> | |
| <pre><code>git clone --recursive https://github.com/riscv-collab/riscv-gnu-toolchain | |
| cd riscv-gnu-toolchain | |
| ./configure --prefix=<toolchain-installed-path> | |
| make linux | |
| export PATH=<toolchain-installed-path>/bin:$PATH</code></pre></li> | |
| <li><p>Cross-compile all the required libraries:</p> | |
| <pre><code># An example for libffi | |
| git clone https://github.com/libffi/libffi | |
| cd libffi | |
| ./configure --host=riscv64-unknown-linux-gnu --prefix=<toolchain-installed-path>/sysroot/usr | |
| make | |
| make install</code></pre></li> | |
| <li><p>Configure and build the JDK:</p> | |
| <pre><code>bash configure \ | |
| --with-boot-jdk=$BOOT_JDK \ | |
| --openjdk-target=riscv64-linux-gnu \ | |
| --with-sysroot=<toolchain-installed-path>/sysroot \ | |
| --with-toolchain-path=<toolchain-installed-path>/bin \ | |
| --with-extra-path=<toolchain-installed-path>/bin | |
| make images</code></pre></li> | |
| </ul> | |
| <h4 id="building-for-musl">Building for musl</h4> | |
| <p>Just like it's possible to cross-compile for a different CPU, it's | |
| possible to cross-compile for <code>musl</code> libc on a glibc-based | |
| <em>build</em> system. A devkit suitable for most target CPU | |
| architectures can be obtained from <a | |
| href="https://musl.cc">musl.cc</a>. After installing the required | |
| packages in the sysroot, configure the build with | |
| <code>--openjdk-target</code>:</p> | |
| <pre><code>sh ./configure --with-jvm-variants=server \ | |
| --with-boot-jdk=$BOOT_JDK \ | |
| --with-build-jdk=$BUILD_JDK \ | |
| --openjdk-target=x86_64-unknown-linux-musl \ | |
| --with-devkit=$DEVKIT \ | |
| --with-sysroot=$SYSROOT</code></pre> | |
| <p>and run <code>make</code> normally.</p> | |
| <h4 id="building-for-windows-aarch64">Building for Windows AArch64</h4> | |
| <p>The Visual Studio Build Tools can be used for building the JDK | |
| without a full Visual Studio installation. To set up the Visual Studio | |
| 2022 Build Tools on a Windows AArch64 machine for a native build, launch | |
| the installer as follows in a Windows command prompt:</p> | |
| <pre><code>vs_buildtools.exe --quiet --wait --norestart --nocache ^ | |
| --installPath "%ProgramFiles(x86)%\Microsoft Visual Studio\2022\BuildTools" ^ | |
| --add Microsoft.VisualStudio.Component.VC.CoreBuildTools ^ | |
| --add Microsoft.VisualStudio.Component.VC.Tools.ARM64 ^ | |
| --add Microsoft.VisualStudio.Component.Windows11SDK.22621</code></pre> | |
| <p>To generate Windows AArch64 builds using Cygwin on a Windows x64 | |
| machine, you must set the proper target platform by adding | |
| <code>--openjdk-target=aarch64-unknown-cygwin</code> to your configure | |
| command line.</p> | |
| <h2 id="build-performance">Build Performance</h2> | |
| <p>Building the JDK requires a lot of horsepower. Some of the build | |
| tools can be adjusted to utilize more or less of resources such as | |
| parallel threads and memory. The <code>configure</code> script analyzes | |
| your system and selects reasonable values for such options based on your | |
| hardware. If you encounter resource problems, such as out of memory | |
| conditions, you can modify the detected values with:</p> | |
| <ul> | |
| <li><p><code>--with-num-cores</code> -- number of cores in the build | |
| system, e.g. <code>--with-num-cores=8</code>.</p></li> | |
| <li><p><code>--with-memory-size</code> -- memory (in MB) available in | |
| the build system, e.g. <code>--with-memory-size=1024</code></p></li> | |
| </ul> | |
| <p>You can also specify directly the number of build jobs to use with | |
| <code>--with-jobs=N</code> to <code>configure</code>, or | |
| <code>JOBS=N</code> to <code>make</code>. Do not use the <code>-j</code> | |
| flag to <code>make</code>. In most cases it will be ignored by the | |
| makefiles, but it can cause problems for some make targets.</p> | |
| <p>It might also be necessary to specify the JVM arguments passed to the | |
| Boot JDK, using e.g. <code>--with-boot-jdk-jvmargs="-Xmx8G"</code>. | |
| Doing so will override the default JVM arguments passed to the Boot | |
| JDK.</p> | |
| <p>At the end of a successful execution of <code>configure</code>, you | |
| will get a performance summary, indicating how well the build will | |
| perform. Here you will also get performance hints. If you want to build | |
| fast, pay attention to those!</p> | |
| <p>If you want to tweak build performance, run with | |
| <code>make LOG=info</code> to get a build time summary at the end of the | |
| build process.</p> | |
| <h3 id="disk-speed">Disk Speed</h3> | |
| <p>If you are using network shares, e.g. via NFS, for your source code, | |
| make sure the build directory is situated on local disk (e.g. by | |
| <code>ln -s /localdisk/jdk-build $JDK-SHARE/build</code>). The | |
| performance penalty is extremely high for building on a network share; | |
| close to unusable.</p> | |
| <p>Also, make sure that your build tools (including Boot JDK and | |
| toolchain) is located on a local disk and not a network share.</p> | |
| <p>As has been stressed elsewhere, do use SSD for source code and build | |
| directory, as well as (if possible) the build tools.</p> | |
| <h3 id="virus-checking">Virus Checking</h3> | |
| <p>The use of virus checking software, especially on Windows, can | |
| <em>significantly</em> slow down building of the JDK. If possible, turn | |
| off such software, or exclude the directory containing the JDK source | |
| code from on-the-fly checking.</p> | |
| <h3 id="ccache">Ccache</h3> | |
| <p>The JDK build supports building with ccache when using gcc or clang. | |
| Using ccache can radically speed up compilation of native code if you | |
| often rebuild the same sources. Your mileage may vary however, so we | |
| recommend evaluating it for yourself. To enable it, make sure it's on | |
| the path and configure with <code>--enable-ccache</code>.</p> | |
| <h3 id="precompiled-headers">Precompiled Headers</h3> | |
| <p>By default, the Hotspot build uses pre-compiled headers (PCH) on the | |
| toolchains were it is properly supported (clang, gcc, and Visual | |
| Studio). Normally, this speeds up the build process, but in some | |
| circumstances, it can actually slow things down.</p> | |
| <p>You can experiment by disabling pre-compiled headers using | |
| <code>--disable-precompiled-headers</code>.</p> | |
| <h3 id="icecc-icecream">Icecc / Icecream</h3> | |
| <p><a href="https://github.com/icecc/icecream">icecc/icecream</a> is a | |
| simple way to setup a distributed compiler network. If you have multiple | |
| machines available for building the JDK, you can drastically cut | |
| individual build times by utilizing it.</p> | |
| <p>To use, setup an icecc network, and install icecc on the build | |
| machine. Then run <code>configure</code> using | |
| <code>--enable-icecc</code>.</p> | |
| <h3 id="using-the-javac-server">Using the javac Server</h3> | |
| <p>To speed up compilation of Java code, especially during incremental | |
| compilations, the javac server is automatically enabled in the | |
| configuration step by default. To explicitly enable or disable the javac | |
| server, use either <code>--enable-javac-server</code> or | |
| <code>--disable-javac-server</code>.</p> | |
| <h3 id="building-the-right-target">Building the Right Target</h3> | |
| <p>Selecting the proper target to build can have dramatic impact on | |
| build time. For normal usage, <code>jdk</code> or the default target is | |
| just fine. You only need to build <code>images</code> for shipping, or | |
| if your tests require it.</p> | |
| <p>See also <a href="#using-fine-grained-make-targets">Using | |
| Fine-Grained Make Targets</a> on how to build an even smaller subset of | |
| the product.</p> | |
| <h2 id="troubleshooting">Troubleshooting</h2> | |
| <p>If your build fails, it can sometimes be difficult to pinpoint the | |
| problem or find a proper solution.</p> | |
| <h3 id="locating-the-source-of-the-error">Locating the Source of the | |
| Error</h3> | |
| <p>When a build fails, it can be hard to pinpoint the actual cause of | |
| the error. In a typical build process, different parts of the product | |
| build in parallel, with the output interlaced.</p> | |
| <h4 id="build-failure-summary">Build Failure Summary</h4> | |
| <p>To help you, the build system will print a failure summary at the | |
| end. It looks like this:</p> | |
| <pre><code>ERROR: Build failed for target 'hotspot' in configuration 'linux-x64' (exit code 2) | |
| === Output from failing command(s) repeated here === | |
| * For target hotspot_variant-server_libjvm_objs_psMemoryPool.o: | |
| /src/jdk/hotspot/src/share/vm/services/psMemoryPool.cpp:1:1: error: 'failhere' does not name a type | |
| ... (rest of output omitted) | |
| * All command lines available in /src/jdk/build/linux-x64/make-support/failure-logs. | |
| === End of repeated output === | |
| === Make failed targets repeated here === | |
| lib/CompileJvm.gmk:207: recipe for target '/src/jdk/build/linux-x64/hotspot/variant-server/libjvm/objs/psMemoryPool.o' failed | |
| make/Main.gmk:263: recipe for target 'hotspot-server-libs' failed | |
| === End of repeated output === | |
| HELP: Try searching the build log for the name of the first failed target. | |
| HELP: Run 'make doctor' to diagnose build problems.</code></pre> | |
| <p>Let's break it down! First, the selected configuration, and the | |
| top-level target you entered on the command line that caused the failure | |
| is printed.</p> | |
| <p>Then, between the | |
| <code>Output from failing command(s) repeated here</code> and | |
| <code>End of repeated output</code> the first lines of output (stdout | |
| and stderr) from the actual failing command is repeated. In most cases, | |
| this is the error message that caused the build to fail. If multiple | |
| commands were failing (this can happen in a parallel build), output from | |
| all failed commands will be printed here.</p> | |
| <p>The path to the <code>failure-logs</code> directory is printed. In | |
| this file you will find a <code><target>.log</code> file that | |
| contains the output from this command in its entirety, and also a | |
| <code><target>.cmd</code>, which contain the complete command line | |
| used for running this command. You can re-run the failing command by | |
| executing <code>. <path to failure-logs>/<target>.cmd</code> | |
| in your shell.</p> | |
| <p>Another way to trace the failure is to follow the chain of make | |
| targets, from top-level targets to individual file targets. Between | |
| <code>Make failed targets repeated here</code> and | |
| <code>End of repeated output</code> the output from make showing this | |
| chain is repeated. The first failed recipe will typically contain the | |
| full path to the file in question that failed to compile. Following | |
| lines will show a trace of make targets why we ended up trying to | |
| compile that file.</p> | |
| <p>Finally, some hints are given on how to locate the error in the | |
| complete log. In this example, we would try searching the log file for | |
| "<code>psMemoryPool.o</code>". Another way to quickly locate make errors | |
| in the log is to search for "<code>] Error</code>" or | |
| "<code>***</code>".</p> | |
| <p>Note that the build failure summary will only help you if the issue | |
| was a compilation failure or similar. If the problem is more esoteric, | |
| or is due to errors in the build machinery, you will likely get empty | |
| output logs, and <code>No indication of failed target found</code> | |
| instead of the make target chain.</p> | |
| <h4 id="checking-the-build-log-file">Checking the Build Log File</h4> | |
| <p>The output (stdout and stderr) from the latest build is always stored | |
| in <code>$BUILD/build.log</code>. The previous build log is stored as | |
| <code>build.log.old</code>. This means that it is not necessary to | |
| redirect the build output yourself if you want to process it.</p> | |
| <p>You can increase the verbosity of the log file, by the | |
| <code>LOG</code> control variable to <code>make</code>. If you want to | |
| see the command lines used in compilations, use | |
| <code>LOG=cmdlines</code>. To increase the general verbosity, use | |
| <code>LOG=info</code>, <code>LOG=debug</code> or <code>LOG=trace</code>. | |
| Both of these can be combined with <code>cmdlines</code>, e.g. | |
| <code>LOG=info,cmdlines</code>. The <code>debug</code> log level will | |
| show most shell commands executed by make, and <code>trace</code> will | |
| show all. Beware that both these log levels will produce a massive build | |
| log!</p> | |
| <h3 id="fixing-unexpected-build-failures">Fixing Unexpected Build | |
| Failures</h3> | |
| <p>Most of the time, the build will fail due to incorrect changes in the | |
| source code.</p> | |
| <p>Sometimes the build can fail with no apparent changes that have | |
| caused the failure. If this is the first time you are building the JDK | |
| on this particular computer, and the build fails, the problem is likely | |
| with your build environment. But even if you have previously built the | |
| JDK with success, and it now fails, your build environment might have | |
| changed (perhaps due to OS upgrades or similar). But most likely, such | |
| failures are due to problems with the incremental rebuild.</p> | |
| <h4 id="running-make-doctor">Running "make doctor"</h4> | |
| <p>The build system comes with a built-in problem diagnosing system. If | |
| you encounter unexpected build failures, you are highly encouraged to | |
| run <code>make doctor</code>. The build system will check for common | |
| sources of build problems and suggest suitable actions to take to fix | |
| those problems.</p> | |
| <p>These checks are not done during normal build time since they are | |
| either too expensive performance-wise to perform, or since they are not | |
| conclusive and just an indication about a potential problem.</p> | |
| <p>The output from <code>make doctor</code> can look like this:</p> | |
| <pre><code>"make doctor" will help you analyze your build environment. It can highlight | |
| certain well-known problems, but it can never find all possible errors. | |
| * Verifying that configure has picked up git... | |
| * Checking for warnings from configure... | |
| --- | |
| The following warnings were produced. Repeated here for convenience: | |
| WARNING: pandoc is version 3.1.9, not the recommended version 2.19.2 | |
| --- | |
| ! Inspect the warnings, fix any problems, and re-run configure | |
| * Checking for left-over core files... | |
| Found these potential core files. They might interfere with the build process: | |
| --- | |
| src/hotspot/core.1337 | |
| --- | |
| ! Remove left-over core files | |
| * Checking for untracked files with illegal names... | |
| * If all else fails, try removing the entire build directory and re-creating | |
| the same configuration using: | |
| --- | |
| configure_command_line=$(make print-configuration) | |
| make dist-clean | |
| bash configure $configure_command_line | |
| --- | |
| * The build README (doc/building.md) is a great source of information, | |
| especially the chapter "Fixing Unexpected Build Failures". Check it out! | |
| * If you still need assistance please contact build-dev@openjdk.org.</code></pre> | |
| <h4 id="problems-with-the-build-environment">Problems with the Build | |
| Environment</h4> | |
| <p>Make sure your configuration is correct. Re-run | |
| <code>configure</code>, and look for any warnings. Warnings that appear | |
| in the middle of the <code>configure</code> output is also repeated at | |
| the end, after the summary. The entire log is stored in | |
| <code>$BUILD/configure.log</code>.</p> | |
| <p>Verify that the summary at the end looks correct. Are you indeed | |
| using the Boot JDK and native toolchain that you expect?</p> | |
| <p>By default, the JDK has a strict approach where warnings from the | |
| compiler is considered errors which fail the build. For very new or very | |
| old compiler versions, this can trigger new classes of warnings, which | |
| thus fails the build. Run <code>configure</code> with | |
| <code>--disable-warnings-as-errors</code> to turn of this behavior. (The | |
| warnings will still show, but not make the build fail.)</p> | |
| <h4 id="problems-with-incremental-rebuilds">Problems with Incremental | |
| Rebuilds</h4> | |
| <p>Incremental rebuilds mean that when you modify part of the product, | |
| only the affected parts get rebuilt. While this works great in most | |
| cases, and significantly speed up the development process, from time to | |
| time complex interdependencies will result in an incorrect build result. | |
| This is the most common cause for unexpected build problems.</p> | |
| <p>Here are a suggested list of things to try if you are having | |
| unexpected build problems. Each step requires more time than the one | |
| before, so try them in order. Most issues will be solved at step 1 or | |
| 2.</p> | |
| <ol type="1"> | |
| <li><p>Make sure your repository is up-to-date</p> | |
| <p>Run <code>git pull origin master</code> to make sure you have the | |
| latest changes.</p></li> | |
| <li><p>Clean build results</p> | |
| <p>The simplest way to fix incremental rebuild issues is to run | |
| <code>make clean</code>. This will remove all build results, but not the | |
| configuration or any build system support artifacts. In most cases, this | |
| will solve build errors resulting from incremental build | |
| mismatches.</p></li> | |
| <li><p>Completely clean the build directory.</p> | |
| <p>If this does not work, the next step is to run | |
| <code>make dist-clean</code>, or removing the build output directory | |
| (<code>$BUILD</code>). This will clean all generated output, including | |
| your configuration. You will need to re-run <code>configure</code> after | |
| this step. A good idea is to run <code>make print-configuration</code> | |
| before running <code>make dist-clean</code>, as this will print your | |
| current <code>configure</code> command line. Here's a way to do | |
| this:</p> | |
| <pre><code>make print-configuration > current-configuration | |
| make dist-clean | |
| bash configure $(cat current-configuration) | |
| make</code></pre></li> | |
| <li><p>Re-clone the Git repository</p> | |
| <p>Sometimes the Git repository gets in a state that causes the product | |
| to be un-buildable. In such a case, the simplest solution is often the | |
| "sledgehammer approach": delete the entire repository, and re-clone it. | |
| If you have local changes, save them first to a different location using | |
| <code>git format-patch</code>.</p></li> | |
| </ol> | |
| <h3 id="specific-build-issues">Specific Build Issues</h3> | |
| <h4 id="clock-skew">Clock Skew</h4> | |
| <p>If you get an error message like this:</p> | |
| <pre><code>File 'xxx' has modification time in the future. | |
| Clock skew detected. Your build may be incomplete.</code></pre> | |
| <p>then the clock on your build machine is out of sync with the | |
| timestamps on the source files. Other errors, apparently unrelated but | |
| in fact caused by the clock skew, can occur along with the clock skew | |
| warnings. These secondary errors may tend to obscure the fact that the | |
| true root cause of the problem is an out-of-sync clock.</p> | |
| <p>If you see these warnings, reset the clock on the build machine, run | |
| <code>make clean</code> and restart the build.</p> | |
| <h4 id="out-of-memory-errors">Out of Memory Errors</h4> | |
| <p>On Windows, you might get error messages like this:</p> | |
| <pre><code>fatal error - couldn't allocate heap | |
| cannot create ... Permission denied | |
| spawn failed</code></pre> | |
| <p>This can be a sign of a Cygwin problem. See the information about | |
| solving problems in the <a href="#cygwin">Cygwin</a> section. Rebooting | |
| the computer might help temporarily.</p> | |
| <h4 id="spaces-in-path">Spaces in Path</h4> | |
| <p>On Windows, when configuring, <code>fixpath.sh</code> may report that | |
| some directory names have spaces. Usually, it assumes those directories | |
| have <a | |
| href="https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/fsutil-8dot3name">short | |
| paths</a>. You can run <code>fsutil file setshortname</code> in | |
| <code>cmd</code> on directories to assign arbitrary short paths so | |
| <code>configure</code> can access them. If the result says "Access | |
| denied", it may be that there are processes running in that directory; | |
| in this case, you can reboot Windows in safe mode and run the command on | |
| those directories again.</p> | |
| <p>The only directories required to have short paths are | |
| <code>Microsoft Visual Studio</code> and <code>Windows Kits</code>; the | |
| rest of the "contains space" warnings from <code>configure</code>, such | |
| as <code>IntelliJ IDEA</code>, can be ignored. You can choose any short | |
| name; once it is set, <code>configure</code>'s tools like | |
| <code>cygpath</code> can convert the directory with spaces to your | |
| chosen short name and pass it to the build system.</p> | |
| <h3 id="getting-help">Getting Help</h3> | |
| <p>If none of the suggestions in this document helps you, or if you find | |
| what you believe is a bug in the build system, please contact the Build | |
| Group by sending a mail to <a | |
| href="mailto:build-dev@openjdk.org">build-dev@openjdk.org</a>. Please | |
| include the relevant parts of the configure and/or build log.</p> | |
| <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-the-jdk">Contributing to OpenJDK</a> for more | |
| information.</p> | |
| <h2 id="reproducible-builds">Reproducible Builds</h2> | |
| <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> | |
| <p>Currently, it is not possible to build the JDK fully reproducibly, | |
| but getting there is an ongoing effort.</p> | |
| <p>An absolute prerequisite for building reproducible is to specify 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> | |
| <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> | |
| <p>You must also make sure your build does not rely on | |
| <code>configure</code>'s default ad hoc version strings. Default ad hoc | |
| 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=<any fixed string></code>, or you | |
| can specify the entire version string using | |
| <code>--with-version-string=<your version></code>.</p> | |
| <p>This is a typical example of how to build the JDK in a reproducible | |
| way:</p> | |
| <pre><code>export SOURCE_DATE_EPOCH=946684800 | |
| bash configure --with-version-opt=adhoc | |
| make</code></pre> | |
| <p>Note that regardless of whether 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>current</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 configure time.</p> | |
| <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> | |
| <ul> | |
| <li><code>--with-source-date</code></li> | |
| </ul> | |
| <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> | |
| <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> | |
| <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>current</code>.</p> | |
| <ul> | |
| <li><code>--with-hotspot-build-time</code></li> | |
| </ul> | |
| <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>). If | |
| 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> | |
| <ul> | |
| <li><code>--with-copyright-year</code></li> | |
| </ul> | |
| <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=<year></code>.</p> | |
| <ul> | |
| <li><code>--enable-reproducible-build</code></li> | |
| </ul> | |
| <p>This option controls 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> | |
| <h2 id="hints-and-suggestions-for-advanced-users">Hints and Suggestions | |
| for Advanced Users</h2> | |
| <h3 id="bash-completion">Bash Completion</h3> | |
| <p>The <code>configure</code> and <code>make</code> commands try to play | |
| nice with bash command-line completion (using <code><tab></code> | |
| or <code><tab><tab></code>). To use this functionality, make | |
| sure you enable completion in your <code>~/.bashrc</code> (see | |
| instructions for bash in your operating system).</p> | |
| <p>Make completion will work out of the box, and will complete valid | |
| make targets. For instance, typing <code>make jdk-i<tab></code> | |
| will complete to <code>make jdk-image</code>.</p> | |
| <p>The <code>configure</code> script can get completion for options, but | |
| for this to work you need to help <code>bash</code> on the way. The | |
| standard way of running the script, <code>bash configure</code>, will | |
| not be understood by bash completion. You need <code>configure</code> to | |
| be the command to run. One way to achieve this is to add a simple helper | |
| script to your path:</p> | |
| <pre><code>cat << EOT > /tmp/configure | |
| #!/bin/bash | |
| if [ \$(pwd) = \$(cd \$(dirname \$0); pwd) ] ; then | |
| echo >&2 "Abort: Trying to call configure helper recursively" | |
| exit 1 | |
| fi | |
| bash \$PWD/configure "\$@" | |
| EOT | |
| chmod +x /tmp/configure | |
| sudo mv /tmp/configure /usr/local/bin</code></pre> | |
| <p>Now <code>configure --en<tab>-dt<tab></code> will result | |
| in <code>configure --enable-dtrace</code>.</p> | |
| <h3 id="using-multiple-configurations">Using Multiple | |
| Configurations</h3> | |
| <p>You can have multiple configurations for a single source repository. | |
| When you create a new configuration, run | |
| <code>configure --with-conf-name=<name></code> to create a | |
| configuration with the name <code><name></code>. Alternatively, | |
| you can create a directory under <code>build</code> and run | |
| <code>configure</code> from there, e.g. | |
| <code>mkdir build/<name> && cd build/<name> && bash ../../configure</code>.</p> | |
| <p>Then you can build that configuration using | |
| <code>make CONF=<selector></code>, where | |
| <code><selector></code> is interpreted as follows:</p> | |
| <ul> | |
| <li>If <code><selector></code> exacly matches the name of a | |
| configuration, this and only this configuration will be selected.</li> | |
| <li>If <code><selector></code> matches (i.e. is a substring of) | |
| the names of several configurations, then all these configurations will | |
| be selected.</li> | |
| <li>If <code><selector></code> is empty (i.e. <code>CONF=</code>), | |
| then all configurations will be selected.</li> | |
| <li>If <code><selector></code> begins with <code>!</code>, then | |
| all configurations <strong>not</strong> matching the string following | |
| <code>!</code> will be selected.</li> | |
| </ul> | |
| <p>A more specialized version, <code>CONF_NAME=<name></code> also | |
| exists, which will only match if the given <code><name></code> | |
| exactly matches a single configuration.</p> | |
| <p>Alternatively, you can execute <code>make</code> in the configuration | |
| directory, e.g. <code>cd build/<name> && make</code>.</p> | |
| <p><code>make CONF_NAME=<name></code> or</p> | |
| <h3 id="handling-reconfigurations">Handling Reconfigurations</h3> | |
| <p>If you update the repository and part of the configure script has | |
| changed, the build system will force you to re-run | |
| <code>configure</code>.</p> | |
| <p>Most of the time, you will be fine by running <code>configure</code> | |
| again with the same arguments as the last time, which can easily be | |
| performed by <code>make reconfigure</code>. To simplify this, you can | |
| use the <code>CONF_CHECK</code> make control variable, either as | |
| <code>make CONF_CHECK=auto</code>, or by setting an environment | |
| variable. For instance, if you add <code>export CONF_CHECK=auto</code> | |
| to your <code>.bashrc</code> file, <code>make</code> will always run | |
| <code>reconfigure</code> automatically whenever the configure script has | |
| changed.</p> | |
| <p>You can also use <code>CONF_CHECK=ignore</code> to skip the check for | |
| a needed configure update. This might speed up the build, but comes at | |
| the risk of an incorrect build result. This is only recommended if you | |
| know what you're doing.</p> | |
| <p>From time to time, you will also need to modify the command line to | |
| <code>configure</code> due to changes. Use | |
| <code>make print-configuration</code> to show the command line used for | |
| your current configuration.</p> | |
| <h3 id="using-fine-grained-make-targets">Using Fine-Grained Make | |
| Targets</h3> | |
| <p>The default behavior for make is to create consistent and correct | |
| output, at the expense of build speed, if necessary.</p> | |
| <p>If you are prepared to take some risk of an incorrect build, and know | |
| enough of the system to understand how things build and interact, you | |
| can speed up the build process considerably by instructing make to only | |
| build a portion of the product.</p> | |
| <h4 id="building-individual-modules">Building Individual Modules</h4> | |
| <p>The safe way to use fine-grained make targets is to use the module | |
| specific make targets. All source code in the JDK is organized so it | |
| belongs to a module, e.g. <code>java.base</code> or | |
| <code>jdk.jdwp.agent</code>. You can build only a specific module, by | |
| giving it as make target: <code>make jdk.jdwp.agent</code>. If the | |
| specified module depends on other modules (e.g. <code>java.base</code>), | |
| those modules will be built first.</p> | |
| <p>You can also specify a set of modules, just as you can always specify | |
| a set of make targets: | |
| <code>make jdk.crypto.cryptoki jdk.crypto.ec jdk.crypto.mscapi</code></p> | |
| <h4 id="building-individual-module-phases">Building Individual Module | |
| Phases</h4> | |
| <p>The build process for each module is divided into separate phases. | |
| Not all modules need all phases. Which are needed depends on what kind | |
| of source code and other artifact the module consists of. The phases | |
| are:</p> | |
| <ul> | |
| <li><code>gensrc</code> (Generate source code to compile)</li> | |
| <li><code>gendata</code> (Generate non-source code artifacts)</li> | |
| <li><code>copy</code> (Copy resource artifacts)</li> | |
| <li><code>java</code> (Compile Java code)</li> | |
| <li><code>launchers</code> (Compile native executables)</li> | |
| <li><code>libs</code> (Compile native libraries)</li> | |
| </ul> | |
| <p>You can build only a single phase for a module by using the notation | |
| <code>$MODULE-$PHASE</code>. For instance, to build the | |
| <code>gensrc</code> phase for <code>java.base</code>, use | |
| <code>make java.base-gensrc</code>.</p> | |
| <p>Note that some phases may depend on others, e.g. <code>java</code> | |
| depends on <code>gensrc</code> (if present). Make will build all needed | |
| prerequisites before building the requested phase.</p> | |
| <h4 id="skipping-the-dependency-check">Skipping the Dependency | |
| Check</h4> | |
| <p>When using an iterative development style with frequent quick | |
| rebuilds, the dependency check made by make can take up a significant | |
| portion of the time spent on the rebuild. In such cases, it can be | |
| useful to bypass the dependency check in make.</p> | |
| <p><strong>Note that if used incorrectly, this method can lead to a | |
| broken build!</strong></p> | |
| <p>To achieve this, append <code>-only</code> to the build target. For | |
| instance, <code>make jdk.jdwp.agent-java-only</code> will <em>only</em> | |
| build the <code>java</code> phase of the <code>jdk.jdwp.agent</code> | |
| module. If the required dependencies are not present, the build can | |
| fail. On the other hand, the execution time measures in | |
| milliseconds.</p> | |
| <p>A useful pattern is to build the first time normally (e.g. | |
| <code>make jdk.jdwp.agent</code>) and then on subsequent builds, use the | |
| <code>-only</code> make target.</p> | |
| <h4 id="rebuilding-part-of-java.base-jdk_filter">Rebuilding Part of | |
| java.base (JDK_FILTER)</h4> | |
| <p>In older versions of the JDK, inefficiencies when building | |
| <code>java.base</code> (by far the largest module in the JDK) could be | |
| overcome by using the make control variable <code>JDK_FILTER</code>. | |
| This is not needed anymore for performance reasons, but the | |
| functionality is still present.</p> | |
| <p>To use this, set the make control variable <code>JDK_FILTER</code> to | |
| specify a pattern that will be used to limit the set of files being | |
| recompiled. For instance, | |
| <code>make java.base JDK_FILTER=javax/crypto</code> will limit the | |
| compilation to files in the <code>javax.crypto</code> package.</p> | |
| <h2 id="understanding-the-build-system">Understanding the Build | |
| System</h2> | |
| <p>This section will give you a more technical description on the | |
| details of the build system.</p> | |
| <h3 id="configurations">Configurations</h3> | |
| <p>The build system expects to find one or more configuration. These are | |
| technically defined by the <code>spec.gmk</code> in a subdirectory to | |
| the <code>build</code> subdirectory. The <code>spec.gmk</code> file is | |
| generated by <code>configure</code>, and contains in principle the | |
| configuration (directly or by files included by | |
| <code>spec.gmk</code>).</p> | |
| <p>You can, in fact, select a configuration to build by pointing to the | |
| <code>spec.gmk</code> file with the <code>SPEC</code> make control | |
| variable, e.g. <code>make SPEC=$BUILD/spec.gmk</code>. While this is not | |
| the recommended way to call <code>make</code> as a user, it is what is | |
| used under the hood by the build system.</p> | |
| <h3 id="build-output-structure">Build Output Structure</h3> | |
| <p>The build output for a configuration will end up in | |
| <code>build/<configuration name></code>, which we refer to as | |
| <code>$BUILD</code> in this document. The <code>$BUILD</code> directory | |
| contains the following important directories:</p> | |
| <pre><code>buildtools/ | |
| configure-support/ | |
| hotspot/ | |
| images/ | |
| jdk/ | |
| make-support/ | |
| support/ | |
| test-results/ | |
| test-support/</code></pre> | |
| <p>This is what they are used for:</p> | |
| <ul> | |
| <li><p><code>images</code>: This is the directory were the output of the | |
| <code>*-image</code> make targets end up. For instance, | |
| <code>make jdk-image</code> ends up in <code>images/jdk</code>.</p></li> | |
| <li><p><code>jdk</code>: This is the "exploded image". After | |
| <code>make jdk</code>, you will be able to launch the newly built JDK by | |
| running <code>$BUILD/jdk/bin/java</code>.</p></li> | |
| <li><p><code>test-results</code>: This directory contains the results | |
| from running tests.</p></li> | |
| <li><p><code>support</code>: This is an area for intermediate files | |
| needed during the build, e.g. generated source code, object files and | |
| class files. Some noteworthy directories in <code>support</code> is | |
| <code>gensrc</code>, which contains the generated source code, and the | |
| <code>modules_*</code> directories, which contains the files in a | |
| per-module hierarchy that will later be collapsed into the | |
| <code>jdk</code> directory of the exploded image.</p></li> | |
| <li><p><code>buildtools</code>: This is an area for tools compiled for | |
| the build platform that are used during the rest of the build.</p></li> | |
| <li><p><code>hotspot</code>: This is an area for intermediate files | |
| needed when building hotspot.</p></li> | |
| <li><p><code>configure-support</code>, <code>make-support</code> and | |
| <code>test-support</code>: These directories contain files that are | |
| needed by the build system for <code>configure</code>, <code>make</code> | |
| and for running tests.</p></li> | |
| </ul> | |
| <h3 id="fixpath">Fixpath</h3> | |
| <p>Windows path typically look like <code>C:\User\foo</code>, while Unix | |
| paths look like <code>/home/foo</code>. Tools with roots from Unix often | |
| experience issues related to this mismatch when running on Windows.</p> | |
| <p>In the JDK build, we always use Unix paths internally, and only just | |
| before calling a tool that does not understand Unix paths do we convert | |
| them to Windows paths.</p> | |
| <p>This conversion is done by the <code>fixpath.sh</code> tool, which is | |
| a small wrapper that modifies Unix-style paths to Windows-style paths. | |
| The fixpath tool is called with the first argument as a sub-command | |
| describing the action it should take. Available actions are | |
| <code>import</code>, <code>exec</code>, <code>print</code> and | |
| <code>verify</code>.</p> | |
| <ul> | |
| <li><p><code>import</code> is called at configure time to convert a path | |
| given by the user and that might be in Windows format to Unix path, | |
| which is used internally.</p></li> | |
| <li><p><code>exec</code> is called at build time. This will take the | |
| command line provided, complete with arguments, converting the paths in | |
| the command line, and then execute the command.</p></li> | |
| <li><p><code>print</code> is called at build time, in the rare cases | |
| where a path might be needed in Windows format, but not as an argument | |
| to a command to execute.</p></li> | |
| <li><p><code>verify</code> is called at configure time to check that a | |
| path is correctly specified and reachable by Windows.</p></li> | |
| </ul> | |
| <p>The fixpath tool uses a somewhat complex heuristic to infer which | |
| part of the command line arguments refer to paths, and converts those. | |
| In some circumstances, these heuristics can fail.</p> | |
| <p>If you are having strange build issues related to path conversion, | |
| you might need to debug how fixpath treats your paths. Here are some | |
| ways to do this.</p> | |
| <p>One way is to define the environment variable | |
| <code>DEBUG_FIXPATH</code>, e.g. <code>DEBUG_FIXPATH=1 make jdk</code>. | |
| When set, any call to <code>fixpath exec</code> will result in an output | |
| like this:</p> | |
| <pre><code>fixpath: debug: input: ls /mnt/c/windows | |
| fixpath: debug: output: ls c:\windows</code></pre> | |
| <p>You can also call fixpath yourself manually with your paths to see | |
| how they are translated. For this, use <code>print</code> and | |
| <code>import</code>. For example:</p> | |
| <pre><code>$ bash make/scripts/fixpath.sh print /mnt/c/windows | |
| c:\windows | |
| $ bash make/scripts/fixpath.sh import "c:\\windows" | |
| /mnt/c/windows</code></pre> | |
| <p>Remember that backslash is used as an escape character in the shell, | |
| and needs to be doubled when used in Windows paths.</p> | |
| <h3 id="native-debug-symbols">Native Debug Symbols</h3> | |
| <p>Native libraries and executables can have debug symbol (and other | |
| debug information) associated with them. How this works is very much | |
| platform dependent, but a common problem is that debug symbol | |
| information takes a lot of disk space, but is rarely needed by the end | |
| user.</p> | |
| <p>The JDK supports different methods on how to handle debug symbols. | |
| The method used is selected by <code>--with-native-debug-symbols</code>, | |
| and available methods are <code>none</code>, <code>internal</code>, | |
| <code>external</code>, <code>zipped</code>.</p> | |
| <ul> | |
| <li><p><code>none</code> means that no debug symbols will be generated | |
| during the build.</p></li> | |
| <li><p><code>internal</code> means that debug symbols will be generated | |
| during the build, and they will be stored in the generated | |
| binary.</p></li> | |
| <li><p><code>external</code> means that debug symbols will be generated | |
| during the build, and after the compilation, they will be moved into a | |
| separate <code>.debuginfo</code> file. (This was previously known as | |
| FDS, Full Debug Symbols).</p></li> | |
| <li><p><code>zipped</code> is like <code>external</code>, but the | |
| .debuginfo file will also be zipped into a <code>.diz</code> | |
| file.</p></li> | |
| </ul> | |
| <p>When building for distribution, <code>zipped</code> is a good | |
| solution. Binaries built with <code>internal</code> is suitable for use | |
| by developers, since they facilitate debugging, but should be stripped | |
| before distributed to end users.</p> | |
| <h3 id="autoconf-details">Autoconf Details</h3> | |
| <p>The <code>configure</code> script is using the autoconf framework, | |
| but it has grown to deviate quite a lot from a traditional autoconf | |
| <code>configure</code> script.</p> | |
| <p>The <code>configure</code> script in the top level directory of the | |
| JDK is just a thin wrapper that calls | |
| <code>make/autoconf/configure</code>. This in turn will run | |
| <code>autoconf</code> to create the runnable (generated) configure | |
| script, as <code>.build/generated-configure.sh</code>. Apart from being | |
| responsible for the generation of the runnable script, the | |
| <code>configure</code> script also provides functionality that is not | |
| easily expressed in the normal Autoconf framework. As part of this | |
| functionality, the generated script is called.</p> | |
| <p>The build system will detect if the Autoconf source files have | |
| changed, and will trigger a regeneration of the generated script if | |
| needed. You can also manually request such an update by | |
| <code>bash configure autogen</code>.</p> | |
| <h3 id="developing-the-build-system-itself">Developing the Build System | |
| Itself</h3> | |
| <p>This section contains a few remarks about how to develop for the | |
| build system itself. It is not relevant if you are only making changes | |
| in the product source code.</p> | |
| <p>While technically using <code>make</code>, the make source files of | |
| the JDK does not resemble most other Makefiles. Instead of listing | |
| specific targets and actions (perhaps using patterns), the basic modus | |
| operandi is to call a high-level function (or properly, macro) from the | |
| API in <code>make/common</code>. For instance, to compile all classes in | |
| the <code>jdk.internal.foo</code> package in the <code>jdk.foo</code> | |
| module, a call like this would be made:</p> | |
| <pre><code>$(eval $(call SetupJavaCompilation, BUILD_FOO_CLASSES, \ | |
| SETUP := GENERATE_OLDBYTECODE, \ | |
| SRC := $(TOPDIR)/src/jkd.foo/share/classes, \ | |
| INCLUDES := jdk/internal/foo, \ | |
| BIN := $(SUPPORT_OUTPUTDIR)/foo_classes, \ | |
| ))</code></pre> | |
| <p>By encapsulating and expressing the high-level knowledge of | |
| <em>what</em> should be done, rather than <em>how</em> it should be done | |
| (as is normal in Makefiles), we can build a much more powerful and | |
| flexible build system.</p> | |
| <p>Correct dependency tracking is paramount. Sloppy dependency tracking | |
| will lead to improper parallelization, or worse, race conditions.</p> | |
| <p>To test for/debug race conditions, try running | |
| <code>make JOBS=1</code> and <code>make JOBS=100</code> and see if it | |
| makes any difference. (It shouldn't).</p> | |
| <p>To compare the output of two different builds and see if, and how, | |
| they differ, run <code>$BUILD1/compare.sh -o $BUILD2</code>, where | |
| <code>$BUILD1</code> and <code>$BUILD2</code> are the two builds you | |
| want to compare.</p> | |
| <p>To automatically build two consecutive versions and compare them, use | |
| <code>COMPARE_BUILD</code>. The value of <code>COMPARE_BUILD</code> is a | |
| set of variable=value assignments, like this:</p> | |
| <pre><code>make COMPARE_BUILD=CONF=--enable-new-hotspot-feature:MAKE=hotspot</code></pre> | |
| <p>See <code>make/InitSupport.gmk</code> for details on how to use | |
| <code>COMPARE_BUILD</code>.</p> | |
| <p>To analyze build performance, run with <code>LOG=trace</code> and | |
| check <code>$BUILD/build-trace-time.log</code>. Use <code>JOBS=1</code> | |
| to avoid parallelism.</p> | |
| <p>Please check that you adhere to the <a | |
| href="https://openjdk.org/groups/build/doc/code-conventions.html">Code | |
| Conventions for the Build System</a> before submitting patches.</p> | |
| <h2 id="contributing-to-the-jdk">Contributing to the JDK</h2> | |
| <p>So, now you've built your JDK, and made your first patch, and want to | |
| contribute it back to the OpenJDK Community.</p> | |
| <p>First of all: Thank you! We gladly welcome your contribution. | |
| However, please bear in mind that the JDK is a massive project, and we | |
| must ask you to follow our rules and guidelines to be able to accept | |
| your contribution.</p> | |
| <p>The official place to start is the <a | |
| href="https://openjdk.org/guide/">OpenJDK Developers’ Guide</a>.</p> | |
| <h2 id="editing-this-document">Editing This Document</h2> | |
| <p>If you want to contribute changes to this document, edit | |
| <code>doc/building.md</code> and then run | |
| <code>make update-build-docs</code> to generate the same changes in | |
| <code>doc/building.html</code>.</p> | |
| </body> | |
| </html> |