Skip to content

Commit

Permalink
fix: Ensure that host-compiled Node addon targets at most GLIBC 2.28
Browse files Browse the repository at this point in the history
  • Loading branch information
Xanewok committed Mar 28, 2024
1 parent b9b946e commit e0e3509
Show file tree
Hide file tree
Showing 8 changed files with 101 additions and 40 deletions.
58 changes: 19 additions & 39 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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" }
Expand Down Expand Up @@ -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" }
Expand Down
1 change: 1 addition & 0 deletions crates/infra/cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ markdown = { workspace = true }
semver = { workspace = true }
serde = { workspace = true }
serde_json = { workspace = true }
tempfile = { workspace = true }
toml = { workspace = true }

[lints]
Expand Down
60 changes: 60 additions & 0 deletions crates/infra/cli/src/toolchains/napi/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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:
/// <https://code.visualstudio.com/docs/supporting/requirements#_additional-linux-requirements>.
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(())
}
2 changes: 2 additions & 0 deletions crates/infra/cli/src/toolchains/napi/compiler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ fn compile_all_targets(resolver: &NapiResolver) -> Result<Vec<PathBuf>> {

// 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![];

Expand Down
11 changes: 11 additions & 0 deletions crates/infra/cli/src/toolchains/napi/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ struct NapiEntry {
struct NapiTriples {
defaults: bool,
additional: Vec<String>,
glibc: String,
}

pub struct NapiConfig;
Expand Down Expand Up @@ -60,6 +61,16 @@ impl NapiConfig {

Ok(triples.additional)
}

pub fn target_glibc(resolver: &NapiResolver) -> Result<String> {
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<Package> {
Expand Down
4 changes: 4 additions & 0 deletions crates/infra/cli/src/toolchains/napi/resolver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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()
}
Expand Down
3 changes: 2 additions & 1 deletion crates/solidity/outputs/npm/package/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@
"x86_64-pc-windows-msvc",
"x86_64-unknown-linux-gnu",
"x86_64-unknown-linux-musl"
]
],
"glibc": "2.28"
}
},
"engines": {
Expand Down

0 comments on commit e0e3509

Please sign in to comment.