-
Notifications
You must be signed in to change notification settings - Fork 5.8k
8257679: Improved unix compatibility layer in Windows build (winenv) #1597
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
👋 Welcome back ihse! A progress list of the required criteria for merging this PR into |
@magicus The following labels will be automatically applied to this pull request:
When this pull request is ready to be reviewed, an "RFR" email will be sent to the corresponding mailing lists. If you would like to change these labels, use the /label pull request command. |
/label remove i18n |
@magicus |
@magicus |
Webrevs
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall this is very nice. Some comments and questions inline.
make/CreateJmods.gmk
Outdated
@@ -169,7 +169,7 @@ ifeq ($(MODULE), java.base) | |||
endif | |||
endif | |||
else # not java.base | |||
ifeq ($(call isTargetOs, windows), true) | |||
ifeq ($(call isTargetOs, windows)+$(CREATING_BUILDJDK), true+false) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks strange. Why would CREATING_BUILDJDK be relevant here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we are creating a buildjdk (which really means we are cross-compiling), we must not meddle with the Windows runtime dll:s, since they are for the target CPU architecture. To be fully correct, we should really turn the Windows runtime dll:s into a "normal"/BUILD_ split version, like with SYSROOT etc.
But since this is just used locally for building, I'm assuming the build system has these runtime DLLs installed already. There seems to be no point in wasting time preparing a buildjdk with files that are just bundled for installation.
Maybe there's a better way to express this, but the only thing I could get a hold of for the fact that we are creating a build-JDK (that is, not targeting the normal OPENJDK_TARGET_CPU) was the CREATING_BUILDJDK variable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I reverted this change, and added a comment when we copy the libs.
|
||
if test "x$4" != xNOFIXPATH; then | ||
[ if [[ $FIXPATH != "" && $result =~ ^"$FIXPATH " ]]; then ] | ||
result="\$FIXPATH ${result#"$FIXPATH "}" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe I'm missing something, but is this unconditionally adding fixpath to any executable based just on if FIXPATH is set? Shouldn't there be a conditional on if the executable is Windows or Unix type?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree it is a bit hairy. Perhaps not ideal; even though this is a rewrite it has suffered some legacy "lava flow" itself, being in development for so long.
The idea here is. that NOFIXPATH (or not) as $4 is passed to UTIL_FIXUP_EXECUTABLE. If it is set, then UTIL_FIXUP_EXECUTABLE will never prepend FIXPATH. Otherwise, UTIL_FIXUP_EXECUTABLE will do the check you are requesting, and see if we are on Windows and it is a non-unix-aware executable, and if so, prepend FIXPATH.
So when we come back to UTIL_LOOKUP_PROGS, if we don't have NOFIXPATH, and we are on Windows (FIXPATH is non-empty) and the path we got from UTIL_FIXUP_EXECUTABLE starts with FIXPATH, then we remove all instances of FIXPATH, and prepend a single FIXPATH instance.
While seems like unneccessary work. I ran into situations where I got a double FIXPATH prefix. It might have been the result of some other bug that is fixed by now, but costs very little to keep this as a safeguard. It should get a comment, though, describing what it does.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Comment is good for me, thanks.
$$($1_JAVAC_SERVER_CONFIG): $$($1_CONFIG_VARDEPS_FILE) | ||
$$($1_ECHO_COMMAND) portfile=$$($1_JAVAC_PORT_FILE) > $$@ | ||
$$($1_ECHO_COMMAND) servercmd=$$($1_JAVAC_SERVER_CMD) >> $$@ | ||
$(ECHO) portfile=$$($1_JAVAC_PORT_FILE) > $$@ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did you consider using WriteFile here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I tried that first. And pulled my hair a couple of times. Turns out there is no way (that I could find, at least) to get WriteFile to write multiple lines.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fair enough.
@@ -45,7 +45,7 @@ endif | |||
|
|||
################################################################################ | |||
# Copy the microsoft runtime libraries on windows | |||
ifeq ($(call isTargetOs, windows), true) | |||
ifeq ($(call isTargetOs, windows)+$(CREATING_BUILDJDK), true+false) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the problem here that we don't have build versions of the runtime libraries so we simply trust that they are present on the build host instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. And this applies to the other fix above as well. Hm. Maybe it is enough to avoid copying them here, and then I don't need the patch in CreateJmods.gmk
Hey, Since I often work on Windows I'm taking this for a spin, but the current patch fails during
I think this is because I have my VS installation in a non-default directory passed to
(Note that Cross-compiling to Linux with WSL works with:
But trying to configure for Windows on WSL with:
Fails with:
This is not a configuration I normally use though. Since I've had problems with WSL I usually use Cygwin, so the configure command might not be right (am I missing a target platform flag here? According to the build docs Windows is the default). (I'll continue investigating as well) |
@JornVernee Thanks for your feedback! I'll have a closer look at your examples, and see if I can reproduce them in my own environment. One question, your first example, was this from a Cygwin environment? As a general comment, the idea is that paths to configure options should be in "unix" style. If that is not accepted, it is a bug. (Otoh, I try hard to be tolerant and accept Windows style or mixed-style ("c:/windows") paths as well, but this is not guaranteed to work.) |
Yes, sorry, the first example is from running in Cygwin. The problem might be with the Windows path then.
Okay, the problem might be with the Windows path then. I'll see if I can make some changes and get it to accept a unix path as well. |
@magicus Ah dang, I tested passing |
@JornVernee Yes, this can certainly have been wrong in the past. That's one of the things that I've fixed with this patch, making sure we handle paths correctly :-) Does this mean the patch works for you on both Cygwin and WSL now? |
@magicus No, the same problems still remain. I seem to have narrowed down the first error to the
|
Ok, it seems to have been caused by But the same command fails later on a path with a space in it:
Looks like a missing short/8dot3 path for one directory. I'll try to get it working on my end. I'll take further questions offline to keep this thread focused on the review. |
@JornVernee I have now pushed a fix that will make |
This looks good to me now, but seems GHA aren't completely ok with it yet. |
@magicus Thanks! But, now I get the same error as the GH action: https://github.com/magicus/openjdk-sandbox/runs/1498822974#step:11:80 Looks like
But I'm not sure that does the same thing. After that, I can confirm that both path issues with Cygwin are resolved ( The issue with WSL still remains though:
Line 57167 in generated-configure.sh is this:
|
Ok, after looking at With that I can build |
Do you see any significant difference in build times compared to before the patch? |
The line numbers in the generated configure script seems to be mismatched; that can't have been the actual failing line. This actual failing line is line 79 in boot-jdk.m4:
If $java_to_test (and $USER_BOOT_JDK_OPTIONS) is empty, then we try to execute
Sp java_to_test should be |
@JornVernee Ah, sorry, I missed that you had added yet another comment, with the solution! :-) I'll have a look at why the space is problematic. Do I understand you correctly that the same path to Java worked on Cygwin but failed on WSL? |
@magicus Yes, that is correct. The path worked on Cygwin but not on WSL. |
@erikj79 The big difference is the shell script fixpath, as opposed to a native fixpath.exe. I've gone to great pains to make sure the "exec" pathway in fixpath.sh contains no external calls, but only native bash constructs, to avoid forks, which are expensive at Windows. With that said, fixpath.sh is still slower than fixpath.exe. A typical invocation with fixpath.sh is about 30 ms slower than fixpath.exe; that is, in average 0.079 s instead of 0.047 s. (This is on Cygwin; on WSL fixpath.sh executes basically instantaneously.) This do translate to longer build times, but I have a hard time getting a proper value. The fluctuation in build times is so large so it's hard to say with certainty, but e.g. on GitHub Actions the build time increased from 53-57 minutes typically, to 58-62 minutes typically. On my personal machine, I could get more reliable and repeatable results. There the time taken to build hotspot increased from 4 min 45 s to 4 min 53 s. All these values are from running on Cygwin. The build times on WSL noticeably faster. (As a follow-up bug, I intend to migrate the GitHub Action script to running on WSL instead of Cygwin.) On machine, the build time decreased from over. 15 minutes, to under 13, when going from Cygwin to WSL. |
@erikj79 I don't really see a significant difference in the build time of |
@JornVernee I have reproed the issue, identified the problem and pushed a patch. Please try again! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the fixes! "Works on my machine" now (Cygwin and WSL).
(FWIW, next week is the fork for RDP1 I believe, so might want to wait with pushing until after that)
@@ -63,19 +63,23 @@ AC_DEFUN([BOOTJDK_DO_CHECK], | |||
# If previous step claimed to have found a JDK, check it to see if it seems to be valid. | |||
if test "x$BOOT_JDK_FOUND" = xmaybe; then | |||
# Do we have a bin/java? | |||
if test ! -x "$BOOT_JDK/bin/java$EXE_SUFFIX"; then | |||
if test ! -x "$BOOT_JDK/bin/java" && test ! -x "$BOOT_JDK/bin/java.exe"; then |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
BOOTJDK_CHECK_BUILD_JDK
also needs those updates I believe
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tested the cross compilation bits with a win-aarch64 build from win-x86_64:
- Cygwin:
--openjdk-target=aarch64-unknown-cygwin --with-boot-jdk=/cygdrive/c/work/jdk-16+22
- WSL1:
--openjdk-target=aarch64-unknown-cygwin --with-boot-jdk=/mnt/c/work/jdk-16+22
And smoke tested each one on win-aarch64 with jtreg:tier1_compiler_1
.
Cosmetic: I get a bunch of warnings for non-existing paths in $PATH
during configure on the wsl1 build, e.g.:
configure: Setting extracted environment variables for x86_64
/usr/bin/wslpath: \\wsl$\uwsl1\home\lewurm\riscv\bin: No such file or directory
/usr/bin/wslpath: \\wsl$\uwsl1\home\lewurm\mate: No such file or directory
I'll give the "native compilation" on win-aarch64 a try again when this change has landed. Some bits (e.g. config.guess) required for it have made it into this PR, but some things are still missing (e.g. choose x86 binaries for MSVC, since no native bits are available for MSVC).
Thank you for the hard work on this!
|
||
AC_ARG_WITH(ucrt-dll-dir, [AS_HELP_STRING([--with-ucrt-dll-dir], | ||
[path to Microsoft Windows Kit UCRT DLL dir (Windows only) @<:@probed@:>@])]) | ||
|
||
if test "x$USE_UCRT" = "xtrue"; then | ||
if test "x$USE_UCRT" = "xtrue" && test "x$OPENJDK_TARGET_CPU" != xaarch64; then |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
@magicus This change now passes all automated pre-integration checks. ℹ️ This project also has non-automated pre-integration requirements. Please see the file CONTRIBUTING.md for details. After integration, the commit message for the final commit will be:
You can use pull request commands such as /summary, /contributor and /issue to adjust it as needed. At the time when this comment was updated there had been 63 new commits pushed to the
As there are no conflicts, your changes will automatically be rebased on top of these commits when integrating. If you prefer to avoid this automatic rebasing, please check the documentation for the /integrate command for further details. ➡️ To integrate this PR with the above commit message to the |
/integrate |
@magicus Since your change was applied there have been 64 commits pushed to the
Your commit was automatically rebased without conflicts. Pushed as commit d29c78d. 💡 You may see a message that your pull request was closed with unmerged commits. This can be safely ignored. |
For the build to work on Windows, we need a unix compatibility layer (known as the "winenv" in the build system). This can be e.g. Cygwin or Msys. The build system then needs to adapt various aspect to get the build to work in this winenv. Over time, our current solutions (which were never that well-designed) has collapsed into an unmaintainable mess.
This rewrite takes on a fresh approach, by giving up on the native "fixpath.exe" converter, and instead relying on a platform-independent shell script "fixpath.sh", which can dynamically adapt to the current winenv. It also provides a proper framework on how to categorize, and support, different winenvs. As a result, we now easily support Cygwin, Msys2, WSL1 and WSL2 (the latter is unfortunately not mature enough to be able to compile the JDK).
Furthermore, this rewrite removes all the kludges and hacks that were put in place all over the code base, and consolidates all tricky part of handling the winenv to basically two places: setting up in configure, and run-time handling by fixpath.sh.
This patch also cleans up our handling of how we detect tools in configure, and makes a proper framework for cross-compilation on Windows.
Progress
Issue
Reviewers
Download
$ git fetch https://git.openjdk.java.net/jdk pull/1597/head:pull/1597
$ git checkout pull/1597