I ran into a few issues installing and using the Swift 5.3.3 toolchain on Windows 10, some of which are mentioned in other posts but never fully explained. I did some troubleshooting and learned a few things that helped me get it all working. Some of the issues were caused by errors in the documentation. I thought I would share my notes here in case anyone else runs into the same or similar issues. Here are some things to look at or try.
Problems with %SWIFTFLAGS%
The Getting Started - On Windows documentation says extra parameters are needed on the command line for REPL, and recommends defining a SWIFTFLAGS
environment variable:
set SWIFTFLAGS=-sdk %SDKROOT% -I %SDKROOT%/usr/lib/swift -L SDKROOT%/usr/lib/swift/windows
The intent is to add %SWIFTFLAGS%
on the end of any command line. For example:
> swiftc hello.swift -o hello.exe %SWIFTFLAGS%
> swift repl %SWIFTFLAGS%
First of all, notice there is a '%' character missing in front of SDKROOT
in the "-L" option. This ends up passing an invalid path for the option. I corrected this right away, although I'm not sure it had an effect at all (see below).
Next, I found out the "-sdk" option doesn't seem to be always necessary for REPL (it seems to run fine without it); however, you do need it to run the compiler (swiftc
), otherwise you get errors like this:
> swiftc hello.swift -o hello.exe
clang: error: no such file or directory: 'C:\Library\Developer\Toolchains\unknown-Asserts-development.xctoolchain\usr\lib\swift\windows\x86_64\swiftrt.obj'
<unknown>:0: error: link command failed with exit code 1 (use -v to see invocation)
Now I could be wrong about REPL; perhaps you do need the "-sdk" option in some use cases of REPL. So it doesn't hurt to include %SWIFTFLAGS%
on the REPL command line, granted. Anyway, since you definitely need the "-sdk" option when running the compiler, I think it would help if this was mentioned earlier (and more prominently) in the documentation, rather than being buried all the way down the section about REPL.
Another weird thing you might run into is "redefinition of module" errors trying to use swiftc
to compile a simple one-line "hello world" program. This happened to me initially, and while experimenting trying to fix it, I found that shortening the %SWIFTFLAGS%
environment variable down to just the "-sdk" option made the errors go away:
set SWIFTFLAGS=-sdk %SDKROOT%
Interestingly, I was unable to reproduce the problem later by adding the "-I" and "-L" options back. So I'm not sure if these options are really needed. Perhaps they're needed for more use cases more advanced than simply running REPL or compiling a "hello world" program? If someone could explain if/why they're still necessary, I'd like to know.
Problems with Python version
The Getting Started - On Windows documentation lists Python 3 64-bit (3.7.8)
as a "recommended additional component". I found that actually Python 3.9 is required, because the lldb.exe
bundled with Swift 5.3.3 depends on python39.dll
directly. If you have even a slightly older version of Python, such as 3.8, some tools won't work (notably, REPL). I think closer attention to this should be given when building the tools and documenting how to install and use them. The dependency is much more strict and seems to change from one build of the toolchain to the next, whereas the documentation seems out of date. Alternatively, consider either bundling a copy of Python with the toolchain, or loosen the dependency by dynamically trying several candidate versions of the Python DLL or having the toolchain installer detect what version of Python you have and customize lldb.exe
accordingly.
The main reason I think the LLDB-Python version dependency should be more clearly documented and/or improved upon is it leads to a problem that is more difficult to track down. There is no error message printed/displayed if you run swift.exe
without the correct version of Python in the path. Tracking the activity of swift.exe
with something like Process Monitor
doesn't reveal the issue either. What I found actually happens is swift.exe
launches lldb.exe
as a child process, but that process (rather silently!) dies with the Windows error code STATUS_DLL_NOT_FOUND
(0xc0000135). To detect if this happens, you have to inspect the process exit code which is available through the variable %ERRORLEVEL%
immediately after running the command. 0xc0000135
will be interpreted as a signed integer -1073741515
:
> swift.exe
> echo %ERRORLEVEL%
-1073741515
To find the missing DLL I first had to figure out that swift.exe
was launching lldb.exe
, and then I tried running lldb.exe
directly:
> lldb.exe
In Windows 10 this causes a pop-up window to appear which says:
lldb.exe - System Error
The code execution cannot proceed because python39.dll was
not found. Reinstalling the program may fix this problem.
I verified that lldb.exe
has been linked to depend directly on python39.dll
by opening lldb.exe
in Dependency Walker:
No Package Manager
I found out the hard way that there's no Swift Package Manager yet on Windows. You get a rather cryptic (for a Swift newbie) error if you try to run swift package
for example:
> swift package
error: unable to invoke subcommand: C:\Library\Developer\Toolchains\unknown-Asserts-development.xctoolchain\usr\bin\swift-package ()
I think the documentation should include a disclaimer in the "Using the Package Manager" section that it's not available at all on Windows yet. Alternatively, perhaps deploy a "dummy" swift-package.exe that simply prints a message to the console like this:
> swift package
Sorry, the Swift Package Manager is not yet available for the Windows platform.