8244533: Configure should abort on missing short names in Windows

Co-authored-by: Jorn Vernee <jvernee@openjdk.org>
Co-authored-by: Magnus Ihse Bursie <ihse@openjdk.org>
Reviewed-by: erikj
This commit is contained in:
Magnus Ihse Bursie 2025-05-07 21:33:39 +00:00
parent 8c1b915c7e
commit 493ac93606
6 changed files with 117 additions and 46 deletions

View File

@ -282,9 +282,29 @@ possible, use an SSD. The build process is very disk intensive, and
having slow disk access will significantly increase build times. If you having slow disk access will significantly increase build times. If you
need to use a network share for the source code, see below for 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> suggestions on how to keep the build artifacts on a local disk.</p></li>
<li><p>On Windows, if using <a href="#cygwin">Cygwin</a>, extra care <li><p>On Windows, extra care must be taken to have a smooth building
must be taken to make sure the environment is consistent. It is experience:</p>
recommended that you follow this procedure:</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 &lt;drive letter&gt;: 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 &lt;path&gt; &lt;short name&gt;</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> <ul>
<li><p>Create the directory that is going to contain the top directory <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 of the JDK clone by using the <code>mkdir</code> command in the Cygwin
@ -294,6 +314,9 @@ it's children will inherit those attributes.</p></li>
<li><p>Do not put the JDK clone in a path under your Cygwin home <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 directory. This is especially important if your user name contains
spaces and/or mixed upper and lower case letters.</p></li> 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 <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 git or Git for Windows. Unfortunately there are pros and cons with each
choice.</p> choice.</p>
@ -311,9 +334,7 @@ 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 line ending problems, make sure you set <code>core.autocrlf</code> to
<code>false</code> (this is asked during installation).</p></li> <code>false</code> (this is asked during installation).</p></li>
</ul></li> </ul></li>
</ul> </ul></li>
<p>Failure to follow this procedure might result in hard-to-debug build
problems.</p></li>
</ul> </ul>
<h2 id="build-hardware-requirements">Build Hardware Requirements</h2> <h2 id="build-hardware-requirements">Build Hardware Requirements</h2>
<p>The JDK is a massive project, and require machines ranging from <p>The JDK is a massive project, and require machines ranging from

View File

@ -83,19 +83,39 @@ on where and how to check out the source code.
for the source code, see below for suggestions on how to keep the build for the source code, see below for suggestions on how to keep the build
artifacts on a local disk. artifacts on a local disk.
* On Windows, if using [Cygwin](#cygwin), extra care must be taken to make sure * On Windows, extra care must be taken to have a smooth building experience:
the environment is consistent. It is recommended that you follow this
procedure:
* Create the directory that is going to contain the top directory of the JDK * Make sure that all relevant paths have short names. Short names are used by
clone by using the `mkdir` command in the Cygwin bash shell. That is, do the build system to create space-free alternative paths. Short name
*not* create it using Windows Explorer. This will ensure that it will have creation is enabled per volume. The default setting can be checked with the
proper Cygwin attributes, and that it's children will inherit those command: `fsutil 8dot3name query`. If short name creation was turned off
attributes. when a directory was created, it will not have a short name. Whether a
short name exists can be checked by running `dir /X` 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 `fsutil 8dot3name set <drive
letter>: 0` (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 `fsutil file setShortName <path> <short name>`.
* Do not put the JDK clone in a path under your Cygwin home directory. This * If using [Cygwin](#cygwin), you must make sure the file permissions and
is especially important if your user name contains spaces and/or mixed attributes between Windows and Cygwin are consistent. It is recommended
upper and lower case letters. that you follow this procedure:
* Create the directory that is going to contain the top directory of the
JDK clone by using the `mkdir` command in the Cygwin bash shell. That is,
do *not* create it using Windows Explorer. This will ensure that it will
have proper Cygwin attributes, and that it's children will inherit those
attributes.
* 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.
Failure to follow these procedures might result in hard-to-debug build
problems.
* You need to install a git client. You have two choices, Cygwin git or Git * 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. for Windows. Unfortunately there are pros and cons with each choice.
@ -113,9 +133,6 @@ on where and how to check out the source code.
make sure you set `core.autocrlf` to `false` (this is asked during make sure you set `core.autocrlf` to `false` (this is asked during
installation). installation).
Failure to follow this procedure might result in hard-to-debug build
problems.
## Build Hardware Requirements ## Build Hardware Requirements
The JDK is a massive project, and require machines ranging from decent to The JDK is a massive project, and require machines ranging from decent to

View File

@ -189,7 +189,7 @@ wants to find) and design tests using those models.</p>
<p>Prefer having checks inside test code.</p> <p>Prefer having checks inside test code.</p>
<p>Not only does having test logic outside, e.g. verification method, <p>Not only does having test logic outside, e.g. verification method,
depending on asserts in product code contradict with several items above depending on asserts in product code contradict with several items above
but also decreases tests readability and stability. It is much easier but also decreases test's readability and stability. It is much easier
to understand that a test is testing when all testing logic is located to understand that a test is testing when all testing logic is located
inside a test or nearby in shared test libraries. As a rule of thumb, inside a test or nearby in shared test libraries. As a rule of thumb,
the closer a check to a test, the better.</p> the closer a check to a test, the better.</p>
@ -198,7 +198,7 @@ the closer a check to a test, the better.</p>
<p>Prefer <code>EXPECT</code> over <code>ASSERT</code> if possible.</p> <p>Prefer <code>EXPECT</code> over <code>ASSERT</code> if possible.</p>
<p>This is related to the <a href="#informativeness">informativeness</a> <p>This is related to the <a href="#informativeness">informativeness</a>
property of tests, information for other checks can help to better property of tests, information for other checks can help to better
localize a defects root-cause. One should use <code>ASSERT</code> if it localize a defect's root-cause. One should use <code>ASSERT</code> if it
is impossible to continue test execution or if it does not make much is impossible to continue test execution or if it does not make much
sense. Later in the text, <code>EXPECT</code> forms will be used to sense. Later in the text, <code>EXPECT</code> forms will be used to
refer to both <code>ASSERT/EXPECT</code>.</p> refer to both <code>ASSERT/EXPECT</code>.</p>
@ -235,7 +235,7 @@ which checks that the absolute value of the difference between
<code>eps</code>.</p> <code>eps</code>.</p>
<h3 id="c-string-comparison">C string comparison</h3> <h3 id="c-string-comparison">C string comparison</h3>
<p>Use string special macros for C strings comparisons.</p> <p>Use string special macros for C strings comparisons.</p>
<p><code>EXPECT_EQ</code> just compares pointers values, which is <p><code>EXPECT_EQ</code> just compares pointers' values, which is
hardly what one wants comparing C strings. GoogleTest provides hardly what one wants comparing C strings. GoogleTest provides
<code>EXPECT_STREQ</code> and <code>EXPECT_STRNE</code> macros to <code>EXPECT_STREQ</code> and <code>EXPECT_STRNE</code> macros to
compare C string contents. There are also case-insensitive versions compare C string contents. There are also case-insensitive versions
@ -293,7 +293,7 @@ subsystem, etc.</p>
<p>This naming scheme helps to find tests, filter them and simplifies <p>This naming scheme helps to find tests, filter them and simplifies
test failure analysis. For example, class <code>Foo</code> - test group test failure analysis. For example, class <code>Foo</code> - test group
<code>Foo</code>, compiler logging subsystem - test group <code>Foo</code>, compiler logging subsystem - test group
<code>CompilerLogging</code>, G1 GC test group <code>G1GC</code>, and <code>CompilerLogging</code>, G1 GC - test group <code>G1GC</code>, and
so forth.</p> so forth.</p>
<h3 id="filename">Filename</h3> <h3 id="filename">Filename</h3>
<p>A test file must have <code>test_</code> prefix and <code>.cpp</code> <p>A test file must have <code>test_</code> prefix and <code>.cpp</code>
@ -345,7 +345,7 @@ name starts or ends with an underscore are enough to be safe.</p>
<h3 id="friend-classes">Friend classes</h3> <h3 id="friend-classes">Friend classes</h3>
<p>All test purpose friends should have either <code>Test</code> or <p>All test purpose friends should have either <code>Test</code> or
<code>Testable</code> suffix.</p> <code>Testable</code> suffix.</p>
<p>It greatly simplifies understanding of friendships purpose and <p>It greatly simplifies understanding of friendship's purpose and
allows statically check that private members are not exposed allows statically check that private members are not exposed
unexpectedly. Having <code>FooTest</code> as a friend of unexpectedly. Having <code>FooTest</code> as a friend of
<code>Foo</code> without any comments will be understood as a necessary <code>Foo</code> without any comments will be understood as a necessary
@ -435,7 +435,7 @@ inapplicable tests.</p>
<h3 id="flag-restoring">Flag restoring</h3> <h3 id="flag-restoring">Flag restoring</h3>
<p>Restore changed flags.</p> <p>Restore changed flags.</p>
<p>It is quite common for tests to configure JVM in a certain way <p>It is quite common for tests to configure JVM in a certain way
changing flags values. GoogleTest provides two ways to set up changing flags' values. GoogleTest provides two ways to set up
environment before a test and restore it afterward: using either environment before a test and restore it afterward: using either
constructor and destructor or <code>SetUp</code> and constructor and destructor or <code>SetUp</code> and
<code>TearDown</code> functions. Both ways require to use a test fixture <code>TearDown</code> functions. Both ways require to use a test fixture
@ -444,7 +444,7 @@ class, which sometimes is too wordy. The simpler facilities like
be used in such cases to restore/set values.</p> be used in such cases to restore/set values.</p>
<p>Caveats:</p> <p>Caveats:</p>
<ul> <ul>
<li><p>Changing a flags value could break the invariants between flags' <li><p>Changing a flag's value could break the invariants between flags'
values and hence could lead to unexpected/unsupported JVM values and hence could lead to unexpected/unsupported JVM
state.</p></li> state.</p></li>
<li><p><code>FLAG_SET_*</code> macros can change more than one flag (in <li><p><code>FLAG_SET_*</code> macros can change more than one flag (in

View File

@ -1,5 +1,5 @@
# #
# Copyright (c) 2011, 2022, Oracle and/or its affiliates. All rights reserved. # Copyright (c) 2011, 2025, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
# #
# This code is free software; you can redistribute it and/or modify it # This code is free software; you can redistribute it and/or modify it
@ -159,7 +159,7 @@ AC_DEFUN([BASIC_SETUP_PATHS_WINDOWS],
else else
WINENV_PREFIX_ARG="$WINENV_PREFIX" WINENV_PREFIX_ARG="$WINENV_PREFIX"
fi fi
FIXPATH_ARGS="-e $PATHTOOL -p $WINENV_PREFIX_ARG -r ${WINENV_ROOT//\\/\\\\} -t $WINENV_TEMP_DIR -c $CMD -q" FIXPATH_ARGS="-e $PATHTOOL -p $WINENV_PREFIX_ARG -r ${WINENV_ROOT//\\/\\\\} -t $WINENV_TEMP_DIR -c $CMD"
FIXPATH_BASE="$BASH $FIXPATH_DIR/fixpath.sh $FIXPATH_ARGS" FIXPATH_BASE="$BASH $FIXPATH_DIR/fixpath.sh $FIXPATH_ARGS"
FIXPATH="$FIXPATH_BASE exec" FIXPATH="$FIXPATH_BASE exec"
@ -215,7 +215,7 @@ AC_DEFUN([BASIC_WINDOWS_FINALIZE_FIXPATH],
if test "x$OPENJDK_BUILD_OS" = xwindows; then if test "x$OPENJDK_BUILD_OS" = xwindows; then
FIXPATH_CMDLINE=". $TOPDIR/make/scripts/fixpath.sh -e $PATHTOOL \ FIXPATH_CMDLINE=". $TOPDIR/make/scripts/fixpath.sh -e $PATHTOOL \
-p $WINENV_PREFIX_ARG -r ${WINENV_ROOT//\\/\\\\} -t $WINENV_TEMP_DIR \ -p $WINENV_PREFIX_ARG -r ${WINENV_ROOT//\\/\\\\} -t $WINENV_TEMP_DIR \
-c $CMD -q" -c $CMD"
$ECHO > $OUTPUTDIR/fixpath '#!/bin/bash' $ECHO > $OUTPUTDIR/fixpath '#!/bin/bash'
$ECHO >> $OUTPUTDIR/fixpath export PATH='"[$]PATH:'$PATH'"' $ECHO >> $OUTPUTDIR/fixpath export PATH='"[$]PATH:'$PATH'"'
$ECHO >> $OUTPUTDIR/fixpath $FIXPATH_CMDLINE '"[$]@"' $ECHO >> $OUTPUTDIR/fixpath $FIXPATH_CMDLINE '"[$]@"'

View File

@ -58,21 +58,32 @@ AC_DEFUN([UTIL_PREPEND_TO_PATH],
# 2) The path will be absolute, and it will be in unix-style (on # 2) The path will be absolute, and it will be in unix-style (on
# cygwin). # cygwin).
# $1: The name of the variable to fix # $1: The name of the variable to fix
# $2: if NOFAIL, errors will be silently ignored # $2: if NOFAIL, if the path cannot be resolved then errors will not be
# reported and an empty path will be set
AC_DEFUN([UTIL_FIXUP_PATH], AC_DEFUN([UTIL_FIXUP_PATH],
[ [
# Only process if variable expands to non-empty # Only process if variable expands to non-empty
path="[$]$1" path="[$]$1"
if test "x$path" != x; then if test "x$path" != x; then
if test "x$OPENJDK_BUILD_OS" = "xwindows"; then if test "x$OPENJDK_BUILD_OS" = "xwindows"; then
if test "x$2" = "xNOFAIL"; then imported_path=`$FIXPATH_BASE -q import "$path"`
quiet_option="-q" if test $? -ne 0 || test ! -e $imported_path; then
if test "x$2" != "xNOFAIL"; then
AC_MSG_NOTICE([The path of $1, which is given as "$path", can not be properly resolved.])
AC_MSG_NOTICE([Please see the section "Special Considerations" in building.md.])
AC_MSG_NOTICE([This is the error message given by fixpath:])
# Rerun fixpath without -q to get an error message
$FIXPATH_BASE import "$path"
AC_MSG_ERROR([Cannot continue])
else
imported_path=""
fi
fi fi
imported_path=`$FIXPATH_BASE $quiet_option import "$path"`
$FIXPATH_BASE verify "$imported_path" $FIXPATH_BASE -q verify "$imported_path"
if test $? -ne 0; then if test $? -ne 0; then
if test "x$2" != "xNOFAIL"; then if test "x$2" != "xNOFAIL"; then
AC_MSG_ERROR([The path of $1, which resolves as "$path", could not be imported.]) AC_MSG_ERROR([The path of $1, which resolves as "$path", could not be verified.])
else else
imported_path="" imported_path=""
fi fi
@ -83,7 +94,7 @@ AC_DEFUN([UTIL_FIXUP_PATH],
if test "x$imported_path_lower" != "x$orig_path_lower"; then if test "x$imported_path_lower" != "x$orig_path_lower"; then
$1="$imported_path" $1="$imported_path"
fi fi
else else # non-Windows
[ if [[ "$path" =~ " " ]]; then ] [ if [[ "$path" =~ " " ]]; then ]
if test "x$2" != "xNOFAIL"; then if test "x$2" != "xNOFAIL"; then
AC_MSG_NOTICE([The path of $1, which resolves as "$path", is invalid.]) AC_MSG_NOTICE([The path of $1, which resolves as "$path", is invalid.])
@ -232,15 +243,19 @@ AC_DEFUN([UTIL_FIXUP_EXECUTABLE],
# This is a path with slashes, don't look at $PATH # This is a path with slashes, don't look at $PATH
if test "x$OPENJDK_BUILD_OS" = "xwindows"; then if test "x$OPENJDK_BUILD_OS" = "xwindows"; then
# fixpath.sh import will do all heavy lifting for us # fixpath.sh import will do all heavy lifting for us
new_path=`$FIXPATH_BASE import "$path"` new_path=`$FIXPATH_BASE -q import "$path"`
if test ! -e $new_path; then if test $? -ne 0 || test ! -e $new_path; then
# It failed, but maybe spaces were part of the path and not separating # It failed, but maybe spaces were part of the path and not separating
# the command and argument. Retry using that assumption. # the command and argument. Retry using that assumption.
new_path=`$FIXPATH_BASE import "$input"` new_path=`$FIXPATH_BASE -q import "$input"`
if test ! -e $new_path; then if test $? -ne 0 || test ! -e $new_path; then
AC_MSG_NOTICE([The command for $1, which resolves as "$input", can not be found.]) AC_MSG_NOTICE([The command for $1, which is given as "$input", can not be properly resolved.])
AC_MSG_ERROR([Cannot locate $input]) AC_MSG_NOTICE([Please see the section "Special Considerations" in building.md.])
AC_MSG_NOTICE([This is the error message given by fixpath:])
# Rerun fixpath without -q to get an error message
$FIXPATH_BASE import "$input"
AC_MSG_ERROR([Cannot continue])
fi fi
# It worked, clear all "arguments" # It worked, clear all "arguments"
arguments="" arguments=""
@ -348,7 +363,15 @@ AC_DEFUN([UTIL_SETUP_TOOL],
else else
# Otherwise we believe it is a complete path. Use it as it is. # Otherwise we believe it is a complete path. Use it as it is.
if test ! -x "$tool_command" && test ! -x "${tool_command}.exe"; then if test ! -x "$tool_command" && test ! -x "${tool_command}.exe"; then
AC_MSG_ERROR([User supplied tool $1="$tool_command" does not exist or is not executable]) # Maybe the path had spaces in it; try again with the entire argument
if test ! -x "$tool_override" && test ! -x "${tool_override}.exe"; then
AC_MSG_ERROR([User supplied tool $1="$tool_override" does not exist or is not executable])
else
# We successfully located the executable assuming the spaces were part of the path.
# We can't combine using paths with spaces and arguments, so assume tool_args is empty.
tool_command="$tool_override"
tool_args=""
fi
fi fi
if test ! -x "$tool_command"; then if test ! -x "$tool_command"; then
tool_command="${tool_command}.exe" tool_command="${tool_command}.exe"

View File

@ -1,6 +1,6 @@
#!/bin/bash #!/bin/bash
# #
# Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. # Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
# #
# This code is free software; you can redistribute it and/or modify it # This code is free software; you can redistribute it and/or modify it
@ -157,11 +157,21 @@ function import_path() {
if [[ $? -eq 0 && -e "$unixpath" ]]; then if [[ $? -eq 0 && -e "$unixpath" ]]; then
if [[ ! "$winpath" =~ ^"$ENVROOT"\\.*$ ]] ; then if [[ ! "$winpath" =~ ^"$ENVROOT"\\.*$ ]] ; then
# If it is not in envroot, it's a generic windows path # If it is not in envroot, it's a generic windows path
if [[ ! $winpath =~ ^[-_.:\\a-zA-Z0-9]*$ ]] ; then if [[ ! $winpath =~ ^[-_.:~\\a-zA-Z0-9]*$ ]] ; then
# Path has forbidden characters, rewrite as short name # Path has forbidden characters, rewrite as short name
# This monster of a command uses the %~s support from cmd.exe to # This monster of a command uses the %~s support from cmd.exe to
# reliably convert to short paths on all winenvs. # reliably convert to short paths on all winenvs.
shortpath="$($CMD /q /c for %I in \( "$winpath" \) do echo %~sI 2>/dev/null | tr -d \\n\\r)" shortpath="$($CMD /q /c for %I in \( "$winpath" \) do echo %~sI 2>/dev/null | tr -d \\n\\r)"
if [[ ! $shortpath =~ ^[-_.:~\\a-zA-Z0-9]*$ ]] ; then
if [[ $QUIET != true ]]; then
echo fixpath: failure: Path "'"$path"'" could not be converted to short path >&2
fi
if [[ $IGNOREFAILURES != true ]]; then
exit 1
else
shortpath=""
fi
fi
unixpath="$($PATHTOOL -u "$shortpath")" unixpath="$($PATHTOOL -u "$shortpath")"
# unixpath is based on short name # unixpath is based on short name
fi fi