diff --git a/Cargo.lock b/Cargo.lock index 0f6cf8b071..89cc4aa874 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -159,9 +159,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.3.3" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "630be753d4e58660abd17930c71b647fe46c27ea6b63cc59e1e3851406972e42" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "block-buffer" @@ -592,23 +592,12 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b30f669a7961ef1631673d2766cc92f52d64f7ef354d4fe0ddfd30ed52f0f4f" -dependencies = [ - "errno-dragonfly", - "libc", - "windows-sys 0.48.0", -] - -[[package]] -name = "errno-dragonfly" -version = "0.1.2" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" dependencies = [ - "cc", "libc", + "windows-sys 0.52.0", ] [[package]] @@ -956,6 +945,7 @@ dependencies = [ "semver", "serde", "serde_json", + "tempfile", "toml", ] @@ -1027,9 +1017,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.149" +version = "0.2.153" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b" +checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" [[package]] name = "libloading" @@ -1049,9 +1039,9 @@ checksum = "f7012b1bbb0719e1097c47611d3898568c546d597c2e74d66f6087edd5233ff4" [[package]] name = "linux-raw-sys" -version = "0.4.5" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57bcfdad1b858c2db7c38303a6d2ad4dfaf5eb53dfeb0910128b2c26d6158503" +checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" [[package]] name = "log" @@ -1123,7 +1113,7 @@ version = "2.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "54a63d0570e4c3e0daf7a8d380563610e159f538e20448d6c911337246f40e84" dependencies = [ - "bitflags 2.3.3", + "bitflags 2.5.0", "ctor", "napi-derive", "napi-sys", @@ -1250,7 +1240,7 @@ version = "0.10.60" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "79a4c6c3a2b158f7f8f2a2fc5a969fa3a068df6fc9dbb4a43845436e3af7c800" dependencies = [ - "bitflags 2.3.3", + "bitflags 2.5.0", "cfg-if", "foreign-types", "libc", @@ -1489,15 +1479,6 @@ dependencies = [ "crossbeam-utils", ] -[[package]] -name = "redox_syscall" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" -dependencies = [ - "bitflags 1.3.2", -] - [[package]] name = "regex" version = "1.10.4" @@ -1581,15 +1562,15 @@ checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" [[package]] name = "rustix" -version = "0.38.7" +version = "0.38.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "172891ebdceb05aa0005f533a6cbfca599ddd7d966f6f5d4d9b2e70478e70399" +checksum = "65e04861e65f21776e67888bfbea442b3642beaa0138fdb1dd7a84a52dffdb89" dependencies = [ - "bitflags 2.3.3", + "bitflags 2.5.0", "errno", "libc", "linux-raw-sys", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -2033,15 +2014,14 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.8.0" +version = "3.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb94d2f3cc536af71caac6b6fcebf65860b347e7ce0cc9ebe8f70d3e521054ef" +checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" dependencies = [ "cfg-if", "fastrand", - "redox_syscall", "rustix", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 4795cc9a76..fa6e37ef2b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -79,6 +79,7 @@ anyhow = { version = "1.0.81", features = ["backtrace", "std"] } ariadne = { version = "0.2.0" } cargo-emit = { version = "0.2.1" } cargo-xwin = { version = "0.14.2" } +cargo-zigbuild = { version = "0.18.3" } clap = { version = "4.5.3", features = ["derive", "wrap_help"] } clap_complete = { version = "4.5.1" } console = { version = "0.15.8" } @@ -115,6 +116,7 @@ syn = { version = "2.0.55", features = [ "printing", ] } tera = { version = "1.19.1" } +tempfile = { version = "3.10.1" } thiserror = { version = "1.0.58" } trybuild = { version = "1.0.90" } toml = { version = "0.8.2" } diff --git a/crates/infra/cli/Cargo.toml b/crates/infra/cli/Cargo.toml index d322337663..188c220d64 100644 --- a/crates/infra/cli/Cargo.toml +++ b/crates/infra/cli/Cargo.toml @@ -17,6 +17,7 @@ markdown = { workspace = true } semver = { workspace = true } serde = { workspace = true } serde_json = { workspace = true } +tempfile = { workspace = true } toml = { workspace = true } [lints] diff --git a/crates/infra/cli/src/toolchains/napi/cli.rs b/crates/infra/cli/src/toolchains/napi/cli.rs index 42670d9111..1d2c5f92e5 100644 --- a/crates/infra/cli/src/toolchains/napi/cli.rs +++ b/crates/infra/cli/src/toolchains/napi/cli.rs @@ -5,6 +5,7 @@ use infra_utils::commands::Command; use infra_utils::paths::PathExtensions; use crate::toolchains::napi::resolver::NapiResolver; +use crate::toolchains::napi::NapiConfig; pub enum BuildTarget { Debug, @@ -61,6 +62,9 @@ impl NapiCli { command.run()?; + #[cfg(target_env = "gnu")] + ensure_correct_glibc_for_vscode(resolver, output_dir, target)?; + let mut source_files = vec![]; let mut node_binary = None; @@ -114,3 +118,59 @@ impl NapiCli { .run(); } } + +#[cfg(target_env = "gnu")] +/// On a GNU host, cross-compile the native addon to only target the oldest supported GLIBC version by VS Code. +/// +/// By default, compiling on the host targets the host's GLIBC version, which is usually newer. +/// To prevent that, we need to explicitly cross-compile for the desired GLIBC version. +/// +/// This is necessary to retain extension compatibility with as many systems as possible: +/// . +fn ensure_correct_glibc_for_vscode( + resolver: &NapiResolver, + output_dir: &Path, + target: &BuildTarget, +) -> Result<()> { + let compiling_for_gnu_on_host = + |target: &str| target.ends_with("-linux-gnu") && target.starts_with(std::env::consts::ARCH); + + let gnu_host_target = match target { + BuildTarget::ReleaseTarget(target) if compiling_for_gnu_on_host(target) => target, + _ => return Ok(()), + }; + + let glibc = NapiConfig::target_glibc(resolver)?; + let rust_crate_name = resolver.rust_crate_name(); + + // Don't clobber the existing output directory. + let zigbuild_output = tempfile::tempdir()?; + + // Until `@napi-rs/cli` v3 is released with a fixed `zig` support and a new `--cross-compile`, + // we explicitly compile ourselves again with `cargo-zigbuild` to target the desired GLIBC + // version, without having to separately compile on the target platform (e.g. via Docker). + Command::new("cargo") + .arg("zigbuild") + .property("-p", rust_crate_name) + .flag("--release") + .property("--target", format!("{gnu_host_target}.{glibc}")) + .property("--target-dir", zigbuild_output.path().to_string_lossy()) + .run()?; + + // Overwrite the existing artifact with the cross-compiled one. + let zigbuild_output = zigbuild_output.into_path(); + let artifact_path = zigbuild_output + .join(gnu_host_target) + .join("release") + .join(format!("lib{rust_crate_name}.so")); + + let output_artifact = match gnu_host_target.split('-').next() { + Some("x86_64") => "index.linux-x64-gnu.node", + Some("aarch64") => "index.linux-arm64-gnu.node", + _ => bail!("Unsupported target {gnu_host_target} for `cargo-zigbuild`."), + }; + + std::fs::copy(artifact_path, output_dir.join(output_artifact))?; + + Ok(()) +} diff --git a/crates/infra/cli/src/toolchains/napi/compiler.rs b/crates/infra/cli/src/toolchains/napi/compiler.rs index 11a0e56707..c892790bad 100644 --- a/crates/infra/cli/src/toolchains/napi/compiler.rs +++ b/crates/infra/cli/src/toolchains/napi/compiler.rs @@ -66,6 +66,8 @@ fn compile_all_targets(resolver: &NapiResolver) -> Result> { // Needed for cross-compiling windows targets: CargoWorkspace::install_binary("cargo-xwin")?; + // Needed to reliably target older GBLIC on `-linux-gnu` targets when host-compiling: + CargoWorkspace::install_binary("cargo-zigbuild")?; let mut node_binaries = vec![]; diff --git a/crates/infra/cli/src/toolchains/napi/config.rs b/crates/infra/cli/src/toolchains/napi/config.rs index 8fcf6396ab..2920d43ca5 100644 --- a/crates/infra/cli/src/toolchains/napi/config.rs +++ b/crates/infra/cli/src/toolchains/napi/config.rs @@ -24,6 +24,7 @@ struct NapiEntry { struct NapiTriples { defaults: bool, additional: Vec, + glibc: String, } pub struct NapiConfig; @@ -60,6 +61,16 @@ impl NapiConfig { Ok(triples.additional) } + + pub fn target_glibc(resolver: &NapiResolver) -> Result { + let package = load_package(&resolver.main_package_dir())?; + + Ok(package + .napi + .context("Failed to find NAPI config section")? + .triples + .glibc) + } } fn load_package(package_dir: &Path) -> Result { diff --git a/crates/infra/cli/src/toolchains/napi/resolver.rs b/crates/infra/cli/src/toolchains/napi/resolver.rs index 9fda5f4d58..7772a13534 100644 --- a/crates/infra/cli/src/toolchains/napi/resolver.rs +++ b/crates/infra/cli/src/toolchains/napi/resolver.rs @@ -29,6 +29,10 @@ impl NapiResolver { } } + pub fn rust_crate_name(&self) -> &'static str { + self.rust_crate + } + pub fn crate_dir(&self) -> PathBuf { CargoWorkspace::locate_source_crate(self.rust_crate).unwrap() } diff --git a/crates/solidity/outputs/npm/package/package.json b/crates/solidity/outputs/npm/package/package.json index 69cdfc5421..7c1aab7376 100644 --- a/crates/solidity/outputs/npm/package/package.json +++ b/crates/solidity/outputs/npm/package/package.json @@ -55,7 +55,8 @@ "x86_64-pc-windows-msvc", "x86_64-unknown-linux-gnu", "x86_64-unknown-linux-musl" - ] + ], + "glibc": "2.28" } }, "engines": {