rules_swift icon indicating copy to clipboard operation
rules_swift copied to clipboard

Windows support

Open jesseschalken opened this issue 3 years ago • 11 comments

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?

jesseschalken avatar Jun 08 '21 05:06 jesseschalken

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.

brentleyjones avatar Jun 08 '21 12:06 brentleyjones

@compnerd is looking at this now

keith avatar Apr 16 '22 02:04 keith

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

compnerd avatar Apr 21 '22 04:04 compnerd

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.

compnerd avatar Apr 25 '22 03:04 compnerd

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.

compnerd avatar Apr 30 '22 17:04 compnerd

I'm surprised swift doesn't infer the debug info type?

keith avatar Apr 30 '22 17:04 keith

Note I think google plans to drop the grpc rule soon. And I think we will follow suite

keith avatar Apr 30 '22 17:04 keith

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.

compnerd avatar Apr 30 '22 17:04 compnerd

Hi! What we should implement to run swift bazel rules on windows?

SpectralDragon avatar Feb 17 '24 23:02 SpectralDragon

@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!

keith avatar Feb 20 '24 17:02 keith

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.

compnerd avatar Feb 20 '24 17:02 compnerd