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:
parent
925464cfc6
commit
263080c4c4
3 changed files with 146 additions and 135 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -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",
|
||||||
|
|
|
@ -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,70 +2069,37 @@ 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([
|
|
||||||
"build",
|
|
||||||
"--package",
|
|
||||||
"remote_server",
|
|
||||||
"--features",
|
|
||||||
"debug-embed",
|
|
||||||
"--target-dir",
|
|
||||||
"target/remote_server",
|
|
||||||
]))
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
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") {
|
|
||||||
#[cfg(target_os = "windows")]
|
|
||||||
use util::paths::SanitizedPath;
|
|
||||||
|
|
||||||
delegate.set_status(Some("Installing cross.rs for cross-compilation"), cx);
|
|
||||||
log::info!("installing cross");
|
|
||||||
run_cmd(Command::new("cargo").args([
|
|
||||||
"install",
|
|
||||||
"cross",
|
|
||||||
"--git",
|
|
||||||
"https://github.com/cross-rs/cross",
|
|
||||||
]))
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
delegate.set_status(
|
|
||||||
Some(&format!(
|
|
||||||
"Building remote server binary from source for {} with Docker",
|
|
||||||
&triple
|
|
||||||
)),
|
|
||||||
cx,
|
|
||||||
);
|
|
||||||
log::info!("building remote server binary from source for {}", &triple);
|
|
||||||
|
|
||||||
// On Windows, the binding needs to be set to the canonical path
|
|
||||||
#[cfg(target_os = "windows")]
|
|
||||||
let src =
|
|
||||||
SanitizedPath::from(smol::fs::canonicalize("./target").await?).to_glob_string();
|
|
||||||
#[cfg(not(target_os = "windows"))]
|
|
||||||
let src = "./target";
|
|
||||||
run_cmd(
|
run_cmd(
|
||||||
Command::new("cross")
|
Command::new("cargo")
|
||||||
.args([
|
.args([
|
||||||
"build",
|
"build",
|
||||||
"--package",
|
"--package",
|
||||||
|
@ -2157,73 +2111,126 @@ impl SshRemoteConnection {
|
||||||
"--target",
|
"--target",
|
||||||
&triple,
|
&triple,
|
||||||
])
|
])
|
||||||
.env(
|
.env("RUSTFLAGS", &rust_flags),
|
||||||
"CROSS_CONTAINER_OPTS",
|
|
||||||
format!("--mount type=bind,src={src},dst=/app/target"),
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
} else {
|
} else {
|
||||||
let which = cx
|
if build_remote_server.contains("cross") {
|
||||||
.background_spawn(async move { which::which("zig") })
|
|
||||||
.await;
|
|
||||||
|
|
||||||
if which.is_err() {
|
|
||||||
#[cfg(not(target_os = "windows"))]
|
|
||||||
{
|
|
||||||
anyhow::bail!(
|
|
||||||
"zig not found on $PATH, install zig (see https://ziglang.org/learn/getting-started or use zigup) or pass ZED_BUILD_REMOTE_SERVER=cross to use cross"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
#[cfg(target_os = "windows")]
|
#[cfg(target_os = "windows")]
|
||||||
{
|
use util::paths::SanitizedPath;
|
||||||
anyhow::bail!(
|
|
||||||
"zig not found on $PATH, install zig (use `winget install -e --id zig.zig` or see https://ziglang.org/learn/getting-started or use zigup) or pass ZED_BUILD_REMOTE_SERVER=cross to use cross"
|
delegate.set_status(Some("Installing cross.rs for cross-compilation"), cx);
|
||||||
)
|
log::info!("installing cross");
|
||||||
|
run_cmd(Command::new("cargo").args([
|
||||||
|
"install",
|
||||||
|
"cross",
|
||||||
|
"--git",
|
||||||
|
"https://github.com/cross-rs/cross",
|
||||||
|
]))
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
delegate.set_status(
|
||||||
|
Some(&format!(
|
||||||
|
"Building remote server binary from source for {} with Docker",
|
||||||
|
&triple
|
||||||
|
)),
|
||||||
|
cx,
|
||||||
|
);
|
||||||
|
log::info!("building remote server binary from source for {}", &triple);
|
||||||
|
|
||||||
|
// On Windows, the binding needs to be set to the canonical path
|
||||||
|
#[cfg(target_os = "windows")]
|
||||||
|
let src =
|
||||||
|
SanitizedPath::from(smol::fs::canonicalize("./target").await?).to_glob_string();
|
||||||
|
#[cfg(not(target_os = "windows"))]
|
||||||
|
let src = "./target";
|
||||||
|
run_cmd(
|
||||||
|
Command::new("cross")
|
||||||
|
.args([
|
||||||
|
"build",
|
||||||
|
"--package",
|
||||||
|
"remote_server",
|
||||||
|
"--features",
|
||||||
|
"debug-embed",
|
||||||
|
"--target-dir",
|
||||||
|
"target/remote_server",
|
||||||
|
"--target",
|
||||||
|
&triple,
|
||||||
|
])
|
||||||
|
.env(
|
||||||
|
"CROSS_CONTAINER_OPTS",
|
||||||
|
format!("--mount type=bind,src={src},dst=/app/target"),
|
||||||
|
)
|
||||||
|
.env("RUSTFLAGS", &rust_flags),
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
} else {
|
||||||
|
let which = cx
|
||||||
|
.background_spawn(async move { which::which("zig") })
|
||||||
|
.await;
|
||||||
|
|
||||||
|
if which.is_err() {
|
||||||
|
#[cfg(not(target_os = "windows"))]
|
||||||
|
{
|
||||||
|
anyhow::bail!(
|
||||||
|
"zig not found on $PATH, install zig (see https://ziglang.org/learn/getting-started or use zigup) or pass ZED_BUILD_REMOTE_SERVER=cross to use cross"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
#[cfg(target_os = "windows")]
|
||||||
|
{
|
||||||
|
anyhow::bail!(
|
||||||
|
"zig not found on $PATH, install zig (use `winget install -e --id zig.zig` or see https://ziglang.org/learn/getting-started or use zigup) or pass ZED_BUILD_REMOTE_SERVER=cross to use cross"
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
delegate.set_status(Some("Adding rustup target for cross-compilation"), cx);
|
||||||
|
log::info!("adding rustup target");
|
||||||
|
run_cmd(Command::new("rustup").args(["target", "add"]).arg(&triple)).await?;
|
||||||
|
|
||||||
|
delegate.set_status(Some("Installing cargo-zigbuild for cross-compilation"), cx);
|
||||||
|
log::info!("installing cargo-zigbuild");
|
||||||
|
run_cmd(Command::new("cargo").args(["install", "--locked", "cargo-zigbuild"]))
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
delegate.set_status(
|
||||||
|
Some(&format!(
|
||||||
|
"Building remote binary from source for {triple} with Zig"
|
||||||
|
)),
|
||||||
|
cx,
|
||||||
|
);
|
||||||
|
log::info!("building remote binary from source for {triple} with Zig");
|
||||||
|
run_cmd(
|
||||||
|
Command::new("cargo")
|
||||||
|
.args([
|
||||||
|
"zigbuild",
|
||||||
|
"--package",
|
||||||
|
"remote_server",
|
||||||
|
"--features",
|
||||||
|
"debug-embed",
|
||||||
|
"--target-dir",
|
||||||
|
"target/remote_server",
|
||||||
|
"--target",
|
||||||
|
&triple,
|
||||||
|
])
|
||||||
|
.env("RUSTFLAGS", &rust_flags),
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
}
|
}
|
||||||
|
|
||||||
delegate.set_status(Some("Adding rustup target for cross-compilation"), cx);
|
|
||||||
log::info!("adding rustup target");
|
|
||||||
run_cmd(Command::new("rustup").args(["target", "add"]).arg(&triple)).await?;
|
|
||||||
|
|
||||||
delegate.set_status(Some("Installing cargo-zigbuild for cross-compilation"), cx);
|
|
||||||
log::info!("installing cargo-zigbuild");
|
|
||||||
run_cmd(Command::new("cargo").args(["install", "--locked", "cargo-zigbuild"])).await?;
|
|
||||||
|
|
||||||
delegate.set_status(
|
|
||||||
Some(&format!(
|
|
||||||
"Building remote binary from source for {triple} with Zig"
|
|
||||||
)),
|
|
||||||
cx,
|
|
||||||
);
|
|
||||||
log::info!("building remote binary from source for {triple} with Zig");
|
|
||||||
run_cmd(Command::new("cargo").args([
|
|
||||||
"zigbuild",
|
|
||||||
"--package",
|
|
||||||
"remote_server",
|
|
||||||
"--features",
|
|
||||||
"debug-embed",
|
|
||||||
"--target-dir",
|
|
||||||
"target/remote_server",
|
|
||||||
"--target",
|
|
||||||
&triple,
|
|
||||||
]))
|
|
||||||
.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",
|
.await?;
|
||||||
"-f",
|
|
||||||
&format!("target/remote_server/{}/debug/remote_server", triple),
|
|
||||||
]))
|
|
||||||
.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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
@ -85,7 +86,7 @@ node_runtime = { workspace = true, features = ["test-support"] }
|
||||||
project = { workspace = true, features = ["test-support"] }
|
project = { workspace = true, features = ["test-support"] }
|
||||||
remote = { workspace = true, features = ["test-support"] }
|
remote = { workspace = true, features = ["test-support"] }
|
||||||
language_model = { workspace = true, features = ["test-support"] }
|
language_model = { workspace = true, features = ["test-support"] }
|
||||||
lsp = { workspace = true, features=["test-support"] }
|
lsp = { workspace = true, features = ["test-support"] }
|
||||||
unindent.workspace = true
|
unindent.workspace = true
|
||||||
serde_json.workspace = true
|
serde_json.workspace = true
|
||||||
zlog.workspace = true
|
zlog.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"]
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue