[PATCH] Support for building using WSL (Windows Subsystem for Linux) on Windows
Andrew Luo
andrewluotechnologies at outlook.com
Wed Dec 12 06:44:46 UTC 2018
For the stdin/stdout redirection: basically, the issue was only occurring with those two executables. Oddly enough, it would occur every time I tried (for SPP the output would be cutoff, presumably because the input was cutoff, and for the other executable, available0 would throw an exception consistently for System.in). I have a hunch this is due to using WINAPI console functions for reading from a WSL shell, but I'm not 100% certain. I plan to try to build a smaller sample that can reproduce the issue, and if it seems to be a Windows bug I will file a bug with Microsoft.
As for the short paths, calling cmd.exe from WSL bash seems to be a bit buggy. cmd.exe, when called from a standard Windows environment, works properly and prints the path, however, when called from WSL, I get:
"(C:\Program Files (x86))" was unexpected at this time.
I verified that the correct path was being passed to cmd.exe (not a bash escaping issue) by creating my own test executable (C++) that just prints argv[0] ... argv[argc - 1] and when running my text executable from both Windows and WSL I get the same result, however when running cmd.exe with the exact same arguments, it works in Windows but not WSL. I will file a bug with Microsoft for this issue.
Thanks,
-Andrew
-----Original Message-----
From: Magnus Ihse Bursie <magnus.ihse.bursie at oracle.com>
Sent: Tuesday, December 11, 2018 6:18 AM
To: Andrew Luo <andrewluotechnologies at outlook.com>; Erik Joelsson <erik.joelsson at oracle.com>; build-dev at openjdk.java.net
Subject: Re: [PATCH] Support for building using WSL (Windows Subsystem for Linux) on Windows
On 2018-12-11 14:37, Magnus Ihse Bursie wrote:
> On 2018-12-11 06:25, Andrew Luo wrote:
>> Hi,
>>
>> Yes, I've signed an OCA (I've also contributed changes to other
>> groups before, but not build).
>>
>> Okay, I have fixed the autconf-config* files.
>>
>> Unfortunately, as Erik mentioned, there is no (supported/reliable)
>> way to access the WSL root / from /cygdrive/c, or even from Windows
>> (there is a way in reality, however, it's not documented/supported by
>> Microsoft and the location changes depending on the
>> distribution/store app id/etc. so best to avoid using it.) I can see
>> if we can print information about versions however.
>>
>> Right, WSL requires the .exe extension when accessing an executable,
>> as this is Linux behavior (Linux doesn't have extensions for
>> executables generally, but that's besides the point)...
>>
>> I fixed BASIC_REMOVE_SYMBOLIC_LINKS - a leftover from another
>> approach I tried.
>>
>> For the redirect, redirect doesn't seem to be working when you have a
>> bash shell input piped into a Win32 executable reading from stdin
>> using WINAPI. I'm not sure this is supported by the OpenJDK, more
>> likely it might be a Microsoft issue. For some reason, the stdin
>> would be cut off (or I would see an exception thrown from available0
>> in FileInputStream). I personally didn't see any harm in changing
>> piping into input/output files (since all the inputs/outputs are
>> files anyways!).
> Ok, let me be sure I get this right. It is only the redirect of
> *input* that fails? (But you fixed both because of consistency). I
> agree that the change itself is fine, even better than it is right now
> -- I was mostly worried about the consequences of redirects is not
> working; there might be other places that fail. But if redirecting
> output works, I think we're mostly fine. That's something we do all
> the time, for each executed command, so if that did not work reliably
> it would be really bad.
>
> But still... I tried greping for "<" and there's a lot of places, 20+,
> that redirects input.
>
> Or did this problem only happen when running *java* as the recipient
> of the redirected input?
>
> This worries me, and while I do think your change makes the tools have
> a better UI, I don't like this as a workaround that will not solve all
> potential problems. :(
>
>>
>> I fixed TOOLCHAIN_FIND_VISUAL_STUDIO_BAT_FILE - this was also from a
>> few things I had tried earlier.
>>
>> I disabled the $BASH code because to call bash from Win32 the correct
>> way is either "wsl /bin/bash" or just "bash". $BASH correctly
>> evaluates to /bin/bash, however
>> BASIC_WINDOWS_REWRITE_AS_WINDOWS_MIXED_PATH is implemented in terms
>> of wslpath, which can only convert a path under /mnt/c back to a
>> Windows path. Other files under /, for example /bin and /bin/bash,
>> cannot be converted to a Windwos path.
>>
>> The escaping changes I made because it wasn't working. This does
>> work with spaces in the path on WSL. I don't have a Cygwin
>> environment to check, perhaps someone else here could help out?
>> Otherwise I can refactor that code to use that echo statement for WSL
>> and use the old echo statement for Cygwin.
> I can check it out the next time I'm on a Windows machine.
>
>>
>> I have fixed the extraneous debug print statement.
>>
>> As for Windows vs Linux output - you can still force it to build a
>> Linux output binary. You just need to run configure as follows:
>>
>> ./configure --with-boot-jdk=/home/andrew/jdk-11.0.1
>> ----build=x86_64-unknown-linux-gnu --host=x86_64-unknown-linux-gnu
>>
>> However, there is a behavior change: now, on WSL, by default, Windows
>> binaries are targeted. Previously, Linux binaries were the default
>> target. (Also, you can run configure twice and two sets of
>> configurations will be generated, you can actually build both images
>> by setting CONF=linux-x86_64-server-release or
>> CONF=windows-x86_64-server-release)
> If you run on WLS, it's reasonable that the default is Windows. The
> --build --host combo is good enough for me as a way to force a linux
> build; we don't need an extra flag for this somewhat odd build
> configuration.
>
>>
>> As for BASIC_MAKE_WINDOWS_SPACE_SAFE_CYGWIN, wslpath does not support
>> 8.3 names. But perhaps the symlink workaround is acceptable for now
>> and we can handle the 8.3 naming on WSL in a separate change, what do
>> you guys think - personally I think what we have (assuming Cygwin
>> still works) is at least a MVP for WSL devs. Anyways, at least some
>> people may have to use the symlink workaround if they've disabled 8.3
>> on NTFS.
> That's too bad, since it really helped with getting around the issue
> with spaces in path that's mandatory on Windows using default
> installation of Visual Studio. :(
>
> Again, sorry if I don't know enough about WSL to know if this is
> possible, but on msys we do the following:
> new_path=`cmd /c "for %A in (\"$input_path\") do @echo %~sA"|$TR
> \\\\\\\\ / | $TR 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
> 'abcdefghijklmnopqrstuvwxyz'`
>
> That is, we call the Windows cmd.exe using the "%~sA" variable syntax
> to print the 8.3 version of the path (input_path is a "normal" Windows
> path). Is there any way it's possible to do this on WSL? It seems
> reasonable that you should be able to call cmd.exe and redirect the
> output.
>
> I think it will be worth trying to jump through some loops or doing
> some dirty tricks to get this to work, because everything will be
> *soooo* much simpler if you can reliably turn paths into space-safe
> paths; our normal Windows build depends on it.
I also realized that if you make a WSL version of BASIC_FIXUP_EXECUTABLE, then you might be able to add .exe in it. You will still need the EXE_SUFFIX when e.g. looking for the java.exe binary in locating the Boot JDK, but perhaps it will simplify some of the places.
I see now that the call to java in Images.gmk really should have been prefixed with $(FIXPATH) instead. Then you would not have needed the EXE_SUFFIX fix there.
Also, I suggest you look more closely on how we do things on msys than on cygwin; I have the feeling wsl is closer to msys (in terms of functionality from our perspective) than cygwin.
>
> /Magnus
>>
>> Attaching my latest patch (generated using powershell, so to properly
>> import you may need to convert UTF16 -> UTF8 and change CRLF to just
>> LF, hg tends to be picky)...
Looks much better now!
Before accepting it, I'd like to understand more about the redirect issue, and see if there really is no way to rewrite the paths in a space-safe manner. Then I think this is good to go.
/Magnus
>>
>> Thanks,
>>
>> -Andrew
>>
>>
>> -----Original Message-----
>> From: Erik Joelsson <erik.joelsson at oracle.com>
>> Sent: Monday, December 10, 2018 9:19 AM
>> To: Magnus Ihse Bursie <magnus.ihse.bursie at oracle.com>; Andrew Luo
>> <andrewluotechnologies at outlook.com>; build-dev at openjdk.java.net
>> Subject: Re: [PATCH] Support for building using WSL (Windows
>> Subsystem for Linux) on Windows
>>
>> Hello,
>>
>> On 2018-12-10 02:06, Magnus Ihse Bursie wrote:
>>> On 2018-12-09 20:11, Andrew Luo wrote:
>>>> One important thing to note is that the WSL build targets Windows.
>>>> It is also possible to use WSL to target itself (a WSL Linux
>>>> binary) or even other distributions of Linux. I have not
>>>> implemented that yet, but I think I could do that as a next step if
>>>> you guys think it would be useful (at least I think it would be
>>>> useful, then you can test your changes for both Windows and Linux on one system...).
>>> I think if you just run configure ordinarily, it will behave like a
>>> Linux system and build the Linux image right out-of-the-box..? But
>>> then again, maybe that behavior is negated by your changes to
>>> config.guess and platform.m4. So maybe we need a flag to configure
>>> to control this...
>> It is indeed possible to build a pure Linux binary in WSL today so I
>> think it would be bad to lose that functionality. We certainly need a
>> configure flag to control if a Windows or Linux build should be
>> produced in this case. This is something I have been thinking about
>> when I started tackling WSL builds some time ago but didn't really
>> come up with a good solution. I didn't have the time to spend to
>> really see it through though, so it's nice to see that someone else
>> is trying.
>>
>> We could simply use the --with-openjdk-target, that would perhaps be
>> the cleanest, but it's also a bit cumbersome. We may need some
>> simplification similar to how we have --with-target-bits=32/64 as a
>> simple switch (e.g. --with-wsl-target=linux/windows?).
>>
>>>> Steps in case you want to try this out:
>>>>
>>>>
>>>> 1. Due to autotools not handling spaces well, you have to
>>>> create symlinks in Windows that will allow you to access Windows
>>>> Kits and the VC++ compiler without spaces in the path:
>>>>
>>>> mklink /D C:\VS "C:\Program Files (x86)\Microsoft Visual Studio"
>>>>
>>>> mklink /D C:\WindowsKits "C:\Program Files (x86)\Windows Kits"
>>> That's a bit odd. We encounter spaces in paths on Windows normally
>>> on cygwin and msys, and that works fine. I suspect there is
>>> something missing with the rewriting functions. What we do, is that
>>> we rewrite paths with spaces to paths without spaces, by using the
>>> old 8+3 compatibility names, so we get something like
>>> "/cygdrive/c/progra~1/microso~2" from "C:\Program Files
>>> (x86)\Microsoft Visual Studio". Have a look at
>>> BASIC_MAKE_WINDOWS_SPACE_SAFE_CYGWIN. I think you need a WSL version
>>> of that, as well as of BASIC_FIXUP_PATH_CYGWIN. (And you need to
>>> call the BASIC_FIXUP_PATH_WSL from BASIC_FIXUP_PATH.)
>>>
>>> If you get these parts right, I don't think you will need any of the
>>> special instructions below to build. In fact, as long as C:\... is
>>> properly remapped, the normal VS autodetect code should work just
>>> fine. And perhaps you can even revert some of the scarier changes in
>>> toolchain_windows.m4.
>>>
>> I definitely agree with Magnus that to make WSL truly supported, the
>> path handling macros need to be replicated. I'm not sure how to solve
>> it properly. The root path Magnus is asking for is not defined in
>> WSL. In fact, from windows you cannot reach any path in the WSL
>> filesystem. Only Windows drives are mounted in WSL, not the other way
>> around. To convert to old style paths in Cygwin we rely on the
>> cygpath utility. There is a wslpath utility but does it support old
>> style path conversions? If not, maybe it's possible to write such a tool in CMD/PowerShell?
>>
>> /Erik
>>
>>
>>>> 2. wsl must be started from a Windows Developer command
>>>> prompt. To ensure the correct environment variables are propagated
>>>> from Windows to WSL, you can run the following commands:
>>>>
>>>> set WSLENV=INCLUDE/l:LIBPATH/l
>>>>
>>>> 3. Start wsl (bash):
>>>>
>>>> wsl
>>>>
>>>> 4. After starting bash you must set your compiler variables to
>>>> explicitly point to the correct tools:
>>>>
>>>> export
>>>> AR=/mnt/c/VS/2017/Enterprise/VC/Tools/MSVC/14.16.27023/bin/Hostx64/
>>>> x64/lib.exe
>>>>
>>>>
>>>> export
>>>> CC=/mnt/c/VS/2017/Enterprise/VC/Tools/MSVC/14.16.27023/bin/Hostx64/
>>>> x64/cl.exe
>>>>
>>>>
>>>> export
>>>> CXX=/mnt/c/VS/2017/Enterprise/VC/Tools/MSVC/14.16.27023/bin/Hostx64
>>>> /x64/cl.exe
>>>>
>>>>
>>>> export
>>>> LD=/mnt/c/VS/2017/Enterprise/VC/Tools/MSVC/14.16.27023/bin/Hostx64/
>>>> x64/link.exe
>>>>
>>>>
>>>> export RC=/mnt/c/WindowsKits/10/bin/10.0.17763.0/x64/rc.exe
>>>>
>>>> export MT=/mnt/c/WindowsKits/10/bin/10.0.17763.0/x64/mt.exe
>>>>
>>>> export
>>>> DUMPBIN=/mnt/c/VS/2017/Enterprise/VC/Tools/MSVC/14.16.27023/bin/Hos
>>>> tx64/x64/dumpbin.exe
>>>>
>>>>
>>>> 5. Run configure:
>>>>
>>>> ./configure
>>>> --with-boot-jdk=/mnt/c/Users/Andrew/Downloads/openjdk-11.0.1_window
>>>> s-x64_bin/jdk-11.0.1
>>>>
>>>> --with-tools-dir="C:\VS\2017\Enterprise\VC\Auxiliary"
>>>> --with-ucrt-dll-dir="/mnt/c/WindowsKits/10/Redist/ucrt/DLLs/x64"
>>>>
>>>> 6. Run make
>>>>
>>>> I've tested make with the default target as well as "make images"
>>>>
>>>> Let me know if you have any feedback/comments.
>>>>
>>>> Thanks,
>>>>
>>>> -Andrew
>>>>
>
More information about the build-dev
mailing list