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
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
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
> 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
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.