Allow local build of remote_server dev to be deployed to different linux than local (#33395)

setup local build of `remote_server` to not depend of the local linux
libraries by :
- enable `vendored-libgit2` feature of git2
- setup target triple to `unknown-linux-musl` (mirror bundle-linux
script)
- add flag ` -C target-feature=+crt-static` in `RUSTFLAGS` env var
(mirror bundle-linux script)

Bonus:
Add an option to setup mold as linker of local build.

Closes #33341

Release Notes:

 - N/A
This commit is contained in:
Gwen Lg 2025-07-08 18:31:20 +02:00 committed by GitHub
parent 925464cfc6
commit 263080c4c4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 146 additions and 135 deletions

1
Cargo.lock generated
View file

@ -13213,6 +13213,7 @@ dependencies = [
"fs", "fs",
"futures 0.3.31", "futures 0.3.31",
"git", "git",
"git2",
"git_hosting_providers", "git_hosting_providers",
"gpui", "gpui",
"gpui_tokio", "gpui_tokio",

View file

@ -314,20 +314,6 @@ pub struct SshPlatform {
pub arch: &'static str, pub arch: &'static str,
} }
impl SshPlatform {
pub fn triple(&self) -> Option<String> {
Some(format!(
"{}-{}",
self.arch,
match self.os {
"linux" => "unknown-linux-gnu",
"macos" => "apple-darwin",
_ => return None,
}
))
}
}
pub trait SshClientDelegate: Send + Sync { pub trait SshClientDelegate: Send + Sync {
fn ask_password(&self, prompt: String, tx: oneshot::Sender<String>, cx: &mut AsyncApp); fn ask_password(&self, prompt: String, tx: oneshot::Sender<String>, cx: &mut AsyncApp);
fn get_download_params( fn get_download_params(
@ -2068,6 +2054,7 @@ impl SshRemoteConnection {
cx: &mut AsyncApp, cx: &mut AsyncApp,
) -> Result<PathBuf> { ) -> Result<PathBuf> {
use smol::process::{Command, Stdio}; use smol::process::{Command, Stdio};
use std::env::VarError;
async fn run_cmd(command: &mut Command) -> Result<()> { async fn run_cmd(command: &mut Command) -> Result<()> {
let output = command let output = command
@ -2082,12 +2069,38 @@ impl SshRemoteConnection {
Ok(()) Ok(())
} }
let triple = format!(
"{}-{}",
self.ssh_platform.arch,
match self.ssh_platform.os {
"linux" => "unknown-linux-musl",
"macos" => "apple-darwin",
_ => anyhow::bail!("can't cross compile for: {:?}", self.ssh_platform),
}
);
let mut rust_flags = match std::env::var("RUSTFLAGS") {
Ok(val) => val,
Err(VarError::NotPresent) => String::new(),
Err(e) => {
log::error!("Failed to get env var `RUSTFLAGS` value: {e}");
String::new()
}
};
if self.ssh_platform.os == "linux" {
rust_flags.push_str(" -C target-feature=+crt-static");
}
if build_remote_server.contains("mold") {
rust_flags.push_str(" -C link-arg=-fuse-ld=mold");
}
if self.ssh_platform.arch == std::env::consts::ARCH if self.ssh_platform.arch == std::env::consts::ARCH
&& self.ssh_platform.os == std::env::consts::OS && self.ssh_platform.os == std::env::consts::OS
{ {
delegate.set_status(Some("Building remote server binary from source"), cx); delegate.set_status(Some("Building remote server binary from source"), cx);
log::info!("building remote server binary from source"); log::info!("building remote server binary from source");
run_cmd(Command::new("cargo").args([ run_cmd(
Command::new("cargo")
.args([
"build", "build",
"--package", "--package",
"remote_server", "remote_server",
@ -2095,26 +2108,13 @@ impl SshRemoteConnection {
"debug-embed", "debug-embed",
"--target-dir", "--target-dir",
"target/remote_server", "target/remote_server",
])) "--target",
&triple,
])
.env("RUSTFLAGS", &rust_flags),
)
.await?; .await?;
} else {
delegate.set_status(Some("Compressing binary"), cx);
run_cmd(Command::new("gzip").args([
"-9",
"-f",
"target/remote_server/debug/remote_server",
]))
.await?;
let path = std::env::current_dir()?.join("target/remote_server/debug/remote_server.gz");
return Ok(path);
}
let Some(triple) = self.ssh_platform.triple() else {
anyhow::bail!("can't cross compile for: {:?}", self.ssh_platform);
};
smol::fs::create_dir_all("target/remote_server").await?;
if build_remote_server.contains("cross") { if build_remote_server.contains("cross") {
#[cfg(target_os = "windows")] #[cfg(target_os = "windows")]
use util::paths::SanitizedPath; use util::paths::SanitizedPath;
@ -2160,7 +2160,8 @@ impl SshRemoteConnection {
.env( .env(
"CROSS_CONTAINER_OPTS", "CROSS_CONTAINER_OPTS",
format!("--mount type=bind,src={src},dst=/app/target"), format!("--mount type=bind,src={src},dst=/app/target"),
), )
.env("RUSTFLAGS", &rust_flags),
) )
.await?; .await?;
} else { } else {
@ -2189,7 +2190,8 @@ impl SshRemoteConnection {
delegate.set_status(Some("Installing cargo-zigbuild for cross-compilation"), cx); delegate.set_status(Some("Installing cargo-zigbuild for cross-compilation"), cx);
log::info!("installing cargo-zigbuild"); log::info!("installing cargo-zigbuild");
run_cmd(Command::new("cargo").args(["install", "--locked", "cargo-zigbuild"])).await?; run_cmd(Command::new("cargo").args(["install", "--locked", "cargo-zigbuild"]))
.await?;
delegate.set_status( delegate.set_status(
Some(&format!( Some(&format!(
@ -2198,7 +2200,9 @@ impl SshRemoteConnection {
cx, cx,
); );
log::info!("building remote binary from source for {triple} with Zig"); log::info!("building remote binary from source for {triple} with Zig");
run_cmd(Command::new("cargo").args([ run_cmd(
Command::new("cargo")
.args([
"zigbuild", "zigbuild",
"--package", "--package",
"remote_server", "remote_server",
@ -2208,21 +2212,24 @@ impl SshRemoteConnection {
"target/remote_server", "target/remote_server",
"--target", "--target",
&triple, &triple,
])) ])
.env("RUSTFLAGS", &rust_flags),
)
.await?; .await?;
}
}; };
let bin_path = Path::new("target")
.join("remote_server")
.join(&triple)
.join("debug")
.join("remote_server");
let mut path = format!("target/remote_server/{triple}/debug/remote_server").into(); let path = if !build_remote_server.contains("nocompress") {
if !build_remote_server.contains("nocompress") {
delegate.set_status(Some("Compressing binary"), cx); delegate.set_status(Some("Compressing binary"), cx);
#[cfg(not(target_os = "windows"))] #[cfg(not(target_os = "windows"))]
{ {
run_cmd(Command::new("gzip").args([ run_cmd(Command::new("gzip").args(["-9", "-f", &bin_path.to_string_lossy()]))
"-9",
"-f",
&format!("target/remote_server/{}/debug/remote_server", triple),
]))
.await?; .await?;
} }
#[cfg(target_os = "windows")] #[cfg(target_os = "windows")]
@ -2237,17 +2244,19 @@ impl SshRemoteConnection {
"a", "a",
"-tgzip", "-tgzip",
&gz_path, &gz_path,
&format!("target/remote_server/{}/debug/remote_server", triple), &bin_path.to_string_lossy(),
])) ]))
.await?; .await?;
} }
path = std::env::current_dir()?.join(format!( let mut archive_path = bin_path;
"target/remote_server/{triple}/debug/remote_server.gz" archive_path.set_extension("gz");
)); std::env::current_dir()?.join(archive_path)
} } else {
bin_path
};
return Ok(path); Ok(path)
} }
} }

View file

@ -37,6 +37,7 @@ fs.workspace = true
futures.workspace = true futures.workspace = true
git.workspace = true git.workspace = true
git_hosting_providers.workspace = true git_hosting_providers.workspace = true
git2 = { workspace = true, features = ["vendored-libgit2"] }
gpui.workspace = true gpui.workspace = true
gpui_tokio.workspace = true gpui_tokio.workspace = true
http_client.workspace = true http_client.workspace = true
@ -95,4 +96,4 @@ cargo_toml.workspace = true
toml.workspace = true toml.workspace = true
[package.metadata.cargo-machete] [package.metadata.cargo-machete]
ignored = ["rust-embed", "paths"] ignored = ["git2", "rust-embed", "paths"]