rules_swift
rules_swift copied to clipboard
Windows support
- Swift publishes official toolchains for Windows here since Swift 5.3 (blog post).
- Bazel also supports Windows (I believe it always has).
- The Swift plugin for CLion 2021.1 also supports Windows (blog post).
- The Bazel plugin for IntelliJ also supports CLion.
Therefore there appears to be potential now for a Swift/Bazel/CLion developer environment on Windows.
- Is there any intent for
rules_swift
to support Windows as a host and target? - If someone were to pursue this, where should they start?
Is there any intent for rules_swift to support Windows as a host and target?
I believe it was only not supported to begin with since Swift itself didn't support Swift. I believe we want to support Windows.
If someone were to pursue this, where should they start?
There are a couple TODOs that mention Windows, I would start there. Getting it working locally would be the first step (I have a guide for easily working on bazel dependencies), then we would ideally setup some CI jobs for it as well.
@compnerd is looking at this now
I think that most of the C++ work is now complete - so the remainder of the work I expect that anyone should be easily able to help with.
Core bazel
- [x] fix bazel client build on Windows (bazelbuild/bazel#15300)
- [x] support vendor'ed clang (bazelbuild/bazel#15269)
swift-driver
- [x] fix response file writing (.param files)
rules_swift
- [x] fix off by one error #807
- [x] add support for windows toolchain #808
- [x] handle tool names - the tools need the
.exe
suffix for execution #809 - [x] fix worker debug mode
- [x] map
SDKROOT
to-sdk ...
(#814) - [x] rename
swiftrt.o
(swiftrt.obj
) (#814) - [x] fix linker invocation (#814)
- [x] read Info.plist to determine XCTest version (
%SDKROOT%\..\..\..\Info.plist
) (#814) - [x] inject XCTest module path into compilation (
-I%SDKROOT%\..\..\Library\XCTest-[XCTEST_VERSION]\usr\lib\swift\windows
, for compatibility:-I%SDKROOT%\..\..\Library\XCTest-[XCTEST_VERSION]\usr\lib\swift\windows\lib
) (#814) - [x] disable old driver feature (#814)
- [x] remove autolink-extract job (#814)
- [x] remove modulewrap job (#814)
- [x] handle library builds (#814)
- [x] preserve environment (
Path
,ProgramData
) (#814) - [x] inject XCTest dlls when running tests (add to
Path
%SDKROOT%\..\..\Library\XCTest-[XCTEST_VERSION]\usr\[BIN_DIR]
, for compatibility:%SDKROOT%\..\..\Library\XCTest-[XCTEST_VERSION]\usr\bin
) (#814) BIN_DIR is mapped from arch:
arch | BIN_DIR |
---|---|
x86 | bin32 |
x64 | bin64 |
arm | bin32a |
arm64 | bin64a |
- [x] provide features for DWARF and CodeView debug information on Windows (#824)
- [ ] enable CI coverage for examples (#832)
- [ ] dynamically determine arch (Windows ARM64 toolchain support)
- [ ] investigate the never-dying persistent worker
- [ ] figure out C++ interop story
- [ ] ensure hermeticity
As a status check, with the latest main build, I have the following hacks applied locally which nearly works:
diff --git a/swift/internal/swift_toolchain.bzl b/swift/internal/swift_toolchain.bzl
index 3063111..0bd59db 100644
--- a/swift/internal/swift_toolchain.bzl
+++ b/swift/internal/swift_toolchain.bzl
@@ -89,6 +89,10 @@ def _all_tool_configs(
tool_executable_suffix = tool_executable_suffix,
use_param_file = use_param_file,
worker_mode = "persistent",
+ env = {
+ "Path": "C:/Program Files/swift/icu-69.1/usr/bin;C:/Program Files/swift/runtime-development/usr/bin;C:/Library/Developer/Toolchains/unknown-Asserts-development.xctoolchain/usr/bin",
+ "ProgramData": "C:/ProgramData",
+ },
)
configs = {
@@ -303,7 +307,10 @@ def _swift_toolchain_impl(ctx):
root_dir = toolchain_root,
swift_worker = ctx.executable._worker,
test_configuration = struct(
- env = {},
+ env = {
+ "Path": "C:/Library/Developer/Platforms/Windows.platform/Developer/Library/XCTest-development/usr/bin64;C:/Program Files/swift/icu-69.1/usr/bin;C:/Program Files/swift/runtime-development/usr/bin;C:/Library/Developer/Toolchains/unknown-Asserts-development.xctoolchain/usr/bin",
+ "ProgramData": "C:/ProgramData",
+ },
execution_requirements = {},
),
tool_configs = all_tool_configs,
With that workaround applied, I can almost run the following (the same as the CI checks):
bazel-dev --verbose_failures -- //examples/xplatform/... -//examples/xplatform/grpc/...
Unfortunately, this seems to be failing, from what I can tell, due to path limitations:
LINK : fatal error LNK1181: cannot open input file 'bazel-out\x64_windows-opt-exec-2B5CBBC6\bin\external\com_github_apple_swift_protobuf\SwiftProtobufPluginLibrary_objs\Sources\SwiftProtobufPluginLibrary\Google_Protobuf_Compiler_CodeGeneratorResponse+Extensions.swift.o'
I believe that lld deals better with this, but I've been struggling to get the build to work with BAZEL_LLVM
set and --compiler=clang-cl
which does use the Swift toolchain for C/C++ but then fails due to DWARF debug information being generated which is problematic for Windows because of its poor representation of the Windows code layout and because of its assumptions around section names which are invalid on Windows. As an example:
lld-link: error: section name .debug_abbrev is longer than 8 characters and will use a non-standard string table
lld-link: error: section name .debug_info is longer than 8 characters and will use a non-standard string table
lld-link: error: section name .debug_line is longer than 8 characters and will use a non-standard string table
lld-link: error: section name .debug_names is longer than 8 characters and will use a non-standard string table
lld-link: error: section name .debug_ranges is longer than 8 characters and will use a non-standard string table
lld-link: error: section name .debug_str is longer than 8 characters and will use a non-standard string table
Working around that (by accidentally disabling debug information), hits the next set of issues - mkdir_and_run.sh
; porting that to cmd seems to be insufficient as the subsequent command fails. However, this seems to be wandering into the weeds of the protobuf build, but, seems that with debug information and environment handled, we should have sufficient progress here to claim Windows support.
Latest update: the current version is able to build and test //examples/xplatform/xctest:xctest
with a workaround of --swiftcopt=-g --swiftcopt=-debug-info-format=codeview
.
With a workaround applied for long paths (something which the CI builders forcefully enable) I get further with eventual failures in gRPC due to hardcoded path separator assumptions and subsequently a tool invocation that fails somewhere within the protobuf compiler.
I'm surprised swift doesn't infer the debug info type?
Note I think google plans to drop the grpc rule soon. And I think we will follow suite
No, Swift does not (and cannot) infer the debug info type for multiple reasons.
If you use LINK, you cannot use DWARF period. If you use LLD, you can potentially get a partially correct DWARF binary that will likely confuse LLDB and may kind of work (except when it doesn't).
You cannot use CodeView if you use link
because the generated CodeView is incorrect. You can work around that by using LLD and ignoring the errors and get a binary that works most of the time. However, attempting to use that with LLDB will fail miserably, but WinDBG will usually try to cope with it.
The secondary reason is that the correct Debug Info format cannot be determined until link time - because that is when we know what linker you are using.
The tertiary reason is that CodeView is preferable when interacting with system libraries, but DWARF is preferable when working with LLDB. Unfortunately, LLDB does not deal well with CodeView and WinDBG does not deal well with DWARF (for various reasons that will eventually become solvable).
This is less problematic for individual packages, but would be a problem were you to try to build something large and complicated that spanned multiple languages.
Hi! What we should implement to run swift bazel rules on windows?
@SpectralDragon thanks to @compnerd I think a lot of things are working here now, I would suggest trying it out and reporting any issues you hit!
Completely agreed @keith! I think that we should take another pass at the CI situation for Windows with 5.10. The installer was completely overhauled and now does per-user installation, so there should be no need for administrative rights. This might be sufficient to get us past the sticking point in the past.