Skip to content

remote: Use cargo-xwin to cross build Windows remote server on Unix system - #64787

Open
lingyaochu wants to merge 1 commit into
zed-industries:mainfrom
lingyaochu:remote-windows-xwin
Open

lingyaochu wants to merge 1 commit into
zed-industries:mainfrom
lingyaochu:remote-windows-xwin

Conversation

@lingyaochu

@lingyaochu lingyaochu commented Sep 25, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

When running the dev version of Zed and trying to connect to a remote server, Zed triggers a local build of remote_server and uploads it to the remote. When the local host is different from the remote, Zed uses cargo-zigbuild to cross-build the remote_server binary. When the local host is Windows and the remote is a Unix system, it just works, but in reverse, it does not.

The truth is, I have never been able to cross-build the Windows remote_server binary on my Linux machine; it always throws an error in the linking stage. Apart from that, even when using some dirty hacks, I can have the binary built and uploaded, but there are still two problems:

  • the remote_server binary size is very big, larger than 1.0 GB
  • it is very unstable, always exiting shortly after the connection. Partly it is because we are cross-building a gnu version binary:
    let triple = format!(
    "{}-{}",
    platform.arch,
    match platform.os {
    RemoteOs::Linux =>
    if use_musl {
    "unknown-linux-musl"
    } else {
    "unknown-linux-gnu"
    },
    RemoteOs::MacOs => "apple-darwin",
    RemoteOs::Windows if cfg!(windows) => "pc-windows-msvc",
    RemoteOs::Windows => "pc-windows-gnu",
    }
    );

So in the past, to test if a remote fix works, I needed to first push the fix, ssh to the remote Windows server, pull the changes, and build the remote_server directly on that Windows machine, then manually copy the binary to the directory where Zed stores remote servers. Not a fan of this at all anymore.

So here, instead of using cargo-zigbuild to cross-build the Windows remote_server on Unix-like platforms, we change to cargo-xwin, which is designed to cross-build the msvc version of Windows programs from Unix-like systems. From my local test, it can do the work perfectly, and the produced binary size is about 200 MB, the same as the binary built directly on a Windows machine, and more importantly, it is very stable, with no dropped connections or crashes.

I suspect there are some concerns:

  1. When first running cargo xwin, some Windows-sdk files are downloaded and cached.
  2. If we need to use cargo-xwin, we need to accept the Microsoft license: https://go.microsoft.com/fwlink/?LinkId=2086102
  3. In the final linking process, there are always some warnings, typically:
         lld-link: Cannot use debug info for 'libcmt.lib(dyn_tls_dtor.obj)' [LNK4099]
         >>> failed to load reference 'D:\a\_work\1\s\binaries\amd64ret\lib\amd64\libcmt.amd64.pdb': No such file or directory

         lld-link: Cannot use debug info for 'libcmt.lib(initsect.obj)' [LNK4099]
         >>> failed to load reference 'D:\a\_work\1\s\binaries\amd64ret\lib\amd64\libcmt.amd64.pdb': No such file or directory

         lld-link: Cannot use debug info for 'libvcruntime.lib(softmemtag.obj)' [LNK4099]
         >>> failed to load reference 'D:\a\_work\1\s\binaries\amd64ret\lib\amd64\libvcruntime.amd64.pdb': No such file or directory

Testing

You can just run the following commands on a Linux or Mac machine to test the cargo-xwin build of remote_server:

rustup target add x86_64-pc-windows-msvc

cargo install --locked cargo-xwin

cargo xwin build -p remote_server --target x86_64-pc-windows-msvc

Self-review

  • I've reviewed my diff for quality, security, reliability, and performance.
  • UI changes follow the checklist.
  • Tests cover the new or changed behavior.

Release Notes:

  • N/A

@cla-bot cla-bot Bot added the cla-signed The user has signed the Contributor License Agreement label Sep 25, 2026
@zed-community-bot zed-community-bot Bot added the community champion Issues filed by our amazing community champions! 🫶 label Sep 25, 2026
@SomeoneToIgnore SomeoneToIgnore added the area:tooling An umbrella label for language tools, linters, formatters, etc label Sep 25, 2026

@SomeoneToIgnore SomeoneToIgnore left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice idea, thank you, one note.

);
log::info!("building remote binary from source for {triple} with Zig");
}
RemoteServerBuildMode::Xwin => {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This branch installs the Rust target and cargo-xwin, but does not check the required native tools.
The documented macOS development setup does not require full LLVM, and the repository’s minimal Rust toolchain does not include llvm-tools.
Meanwhile, cargo-xwin sets the target archiver to llvm-lib, with a fallback that depends on Rust’s optional LLVM tools.

Let's add an actionable prerequisite check and setup instructions, analogous to the existing Zig check, rather than proceeding with an incomplete toolchain.

@SomeoneToIgnore

Copy link
Copy Markdown
Contributor

The automatic installation/invocation also needs an explicit policy decision.
Cargo-xwin’s README states that use constitutes acceptance of Microsoft’s license.
Requiring documented manual setup would make that requirement visible without adding UI.

@SomeoneToIgnore SomeoneToIgnore self-assigned this Sep 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:tooling An umbrella label for language tools, linters, formatters, etc cla-signed The user has signed the Contributor License Agreement community champion Issues filed by our amazing community champions! 🫶

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants