Missing Swift standard library (+Foundation)?

Hi,
I wanted to try the newly released windows toolchain.

I first installed up-to-date Visual Studio dependencies listed here: Swift.org - Getting Started. Afterwards I run the swift installer that installes the toolchain to %SystemDrive%\Library\Developer\Toolchains.

When I try to compile a basic hello world program the compiler returns the error:

D:\Dev>swiftc hello.swift
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)

Also, when I try to import Foundation I get an error

cannot load underlying module for "WinSDK"

Based on those errors I suspect that the swift installer left me without the standard library + Foundation etc. While I don't exactly know what should be contained in the Toolchains\unknown-Asserts-development.xctoolchain\usr\lib\ directory, it does look like it's missing essential files. For example, the swift subdirectory only contains a mitigator folder with json files that reference verious Apple OS.

I would really appreciate it If anyone could point out where did I something wrong, and how I can install the toolchain correctly.

Had the same problem, check @compnerd's reply here:

Thank you for the reply, I think that resolved the second error.

However, my 'core' problem is that the swift installer didn't seem to have installed the swift standard library.

The split model on windows (which is to enable future work) currently requires some additional flags to be passed to the compiler. Something like this should do the trick:

set SWIFTFLAGS=-sdk %SDKROOT% -resource-dir %SDKROOT%\usr\lib\swift -I %SDKROOT%\usr\lib\swift -L %SDKROOT%\usr\lib\swift\windows
swiftc %SWIFTFLAGS% -emit-executable -o executable.exe main.swift

One normally builds with tooling, which would could derive the flags or set them by default. I hope to improve the direct invocation of swift soonish to ease the direct invocation of the compiler though.

2 Likes

Thank you for the response. My bad, I hadn't read the REPL part of the getting started section where the separation between SDK and toolchain is mentioned.

Yes, I guess most people use some tooling for their builds. Though I think invoking the compiler directly should be reasonably simple. Default flags seem like a good idea.

That being said I'm still experiencing some problems. With your flags+invocation the linker throws the error:

LINK : error LNK2001: unresolved external symbol mainCRTStartup

In this case the main.swift file contains only 'global-level' code.
If I wrap the code it in a main function I get the same error as in this bug report: [SR-12683] `@main` is no longer usable due to misdetection of top level code · Issue #55127 · apple/swift · GitHub.

I also get warnings stating that host and target machine types differ. Apparently x86 MSVC build tools are used, even though x64 libraries are available.

At last - and not directly related, the REPL doesn't start and just quits without an error message when I start it using the command listed in the tutorial.

I guess I have to read up a bit more to actually be able to do something and not bother someone for every problem I encounter. It would be nice if there was a "common problems" section or a longer (windows specific) tutorial. However, I understand that this is probably not a priority and difficult to do considering the windows tooling is still very much in development.

While I agree that invoking the compiler directly should be reasonably simple, I don't think that default flags are the right way to go about that. Embedding flags into the driver is a very difficult thing to do well. A single set of defaults may not apply well to all situations - so now you need a series of default flags to apply. As things evolve, the flags may need to change, but existing builds may have come to depend on the builtin flags, providing difficulty for future work. When more advanced use cases are involved, the defaults may interfere and thus require additional options to disable or negate the original defaults. All in all, this really just leads to a lot of complexity in the driver to simplify something which normally the tooling already has the ability to infer. If you have an idea on how improve this generally - not specifically for Windows - then I am definitely interested.

I agree that the current flag set is less than ideal, but that is the current state. Future work does simplify the flag set to something more reasonable: -sdk %SDKROOT% which is really I think a very reasonable set of flags to expect. This enables cross-compilation and allows for relocatable installations.

This is an environment issue. You are using the x86 Developer Command Prompt rather than the x64 Developer Command Prompt.

Yes, this was a bug that slipped through. There are actually two issues at play. One of them is a missing change on the release branch (should be easy to address). The second is currently an issue with the 5.3 release branch that I am trying to figure out how to work around: integrating with Python3 (it is currently using Python 3.8 when the expectation is that it would use Python 3.7).

This is an interesting idea. I think that if someone were to collect an issue set as a document, that could be very useful. I think part of the problem will also be how to clearly delineate things for a specific version.

2 Likes

I'd like point out that working to help improve these types of issues with the experience is IMO one of the most impactful way to get involved. These issues become lost once you have a certain amount of experience with the system. Constantly improving them is very important, but it requires a fresh pair of eyes to continually find them. The great thing is that once a solution is found, it is often relatively easy to implement, and you can get immediate results.

2 Likes

This is something I know much about but it seems to me like a problem other cross platform languages also face. Maybe there exists already a solution that is in some variation suited for this case. Similar with more in-depth introductions to the tooling.

Thanks! It now works as expected :slight_smile:
On my system the prompt is called x64 Native Tools Command Prompt for VS 2019 which apparently is why windows didn't found it when I searched for the exact name listed in the getting started page (x64 Native Tools for VS2019 Command Prompt). I should have definitely found it on my own though. It literally shows up when I search for x64.

1 Like

Pointers for that would be really welcome. I have my own set of gripes about the state on Windows. However, all of the approaches that I've though of so far fail to hold water - I find ways to break them far too easily. The "best" solution that I've thought of so far is to actually do exactly what Microsoft does - provide an equivalent to DevEnv.cmd to setup the environment. However, that is a lot of work to get right because you must first ensure that you pick up the correct toolset from MSVC and setup the rest of the environment.

I think that part of the solution here lies in SR-13572 which would cleave the singluar dependency on the MSVC toolset. The reason for this dependency is https://github.com/apple/swift/blob/master/stdlib/public/Platform/msvcrt.swift#L14 which I think should be possible to remove, but requires testing that I've not yet gotten around to doing (it just needs a complete build + test of the toolchain). With that done, -use-ld=lld provides the linker and the only dependencies become the Windows SDK. That work actually has a significant ripple effect - reducing the needed support files by half, dropping the dependency to just the Windows SDK by removing the need for the MSVC toolset for the Visual C headers, and enabling a solution where a DevEnv equivalent would be sufficient to actually setup the environment. Getting to a point where that is tractable is within reach I think.

4 Likes

I managed to proceeed int the x64 NativeTools Command prompt for VS 2019. But the repl is not working ```
swift repl -target x86_64-unknown-windows-msvc %SWIFTFLAGS%


Should open `1>` and allow me to type in swift no? But it immediatly quits without error. Any solutions or should I just wait for full support with SPM and swift build? Thanks

@doozMen Is this [SR-13804] REPL crashes on Windows · Issue #4328 · apple/llvm-project · GitHub ?
That's as far as I've gotten with the REPL on Windows.

1 Like

Interesting to see that people are building a setup for windows into github actions now Windows support by fwal · Pull Request #140 · swift-actions/setup-swift · GitHub

I believe this might be caused by missing the exact version of Python. For Swift 5.3.3 release it requires Python 3.9. Python 3.8 or earlier will not work.

To verify this is the case, type echo %ERRORLEVEL% after trying to run REPL. If you get -1073741515, this is 0xc0000135 which is the Windows status STATUS_DLL_NOT_FOUND. What's happening is swift.exe is executing lldb.exe, which is loading a DLL which requires python39.dll to be in your path.

See my post for more details.