Skip to content

Commit 5c4e623

Browse files
committed
implement actual version checking for Linux LibC version.
1 parent be5230d commit 5c4e623

1 file changed

Lines changed: 71 additions & 8 deletions

File tree

  • clang-installer/src/downloader

clang-installer/src/downloader/pypi.rs

Lines changed: 71 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use std::{
99
io::{Read, Write},
1010
num::NonZero,
1111
path::PathBuf,
12+
process::Command,
1213
str::FromStr,
1314
time::Duration,
1415
};
@@ -121,14 +122,76 @@ enum LinuxLibC {
121122
}
122123

123124
impl LinuxLibC {
125+
fn get_musl_version() -> Option<Version> {
126+
// This is a simplified check for musl version.
127+
// In practice, determining the musl version may require more complex logic,
128+
// such as parsing the output of `ldd --version` or checking for specific symbols in the C library.
129+
if let Ok(output) = Command::new("ldd").arg("--version").output() {
130+
let stdout = String::from_utf8_lossy(&output.stdout);
131+
let mut is_musl = false;
132+
for line in stdout.lines() {
133+
let line = line.trim().to_lowercase();
134+
// Output of `ldd --version` on musl typically looks like:
135+
// ```shell
136+
// musl libc (x86_64)
137+
// Version 1.2.2
138+
// Dynamic Program Loader
139+
// ```
140+
// So, first look for "musl" in the output.
141+
// Then, look for a version number if "musl" is found.
142+
if !is_musl && line.contains("musl") {
143+
is_musl = true;
144+
}
145+
if is_musl
146+
&& line.contains("version")
147+
&& let Some(version_str) = line.split_whitespace().last()
148+
&& let Ok(version) = Version::parse(version_str)
149+
{
150+
return Some(version);
151+
}
152+
}
153+
}
154+
// If we can't determine the musl version, assume it's compatible with musllinux wheels.
155+
None
156+
}
157+
158+
fn get_glibc_version() -> Option<Version> {
159+
if let Ok(output) = Command::new("ldd").arg("--version").output() {
160+
let stdout = String::from_utf8_lossy(&output.stdout);
161+
for line in stdout.lines() {
162+
let line = line.trim().to_lowercase();
163+
// Output of `ldd --version` on glibc typically looks like:
164+
// ```shell
165+
// ldd (Ubuntu GLIBC 2.39-0ubuntu8.7) 2.39
166+
// Copyright (C) 2024 Free Software Foundation, Inc.
167+
// ```
168+
// So, look for the version on the line that contains "glibc" in the output.
169+
if line.contains("glibc")
170+
&& let Some(version_str) = line.split_whitespace().last()
171+
&& let Some((major, minor)) = version_str.split_once('.')
172+
&& let Ok(major) = major.parse::<u64>()
173+
&& let Ok(minor) = minor.parse::<u64>()
174+
{
175+
return Some(Version::new(major, minor, 0));
176+
}
177+
}
178+
}
179+
None
180+
}
181+
124182
/// Checks if the [LinuxLibC] is compatible with the current system.
125183
pub fn is_compatible_with_system(&self) -> bool {
126184
match self {
127-
#[cfg(target_env = "musl")]
128-
LinuxLibC::Musl { .. } => true,
129-
#[cfg(not(target_env = "musl"))]
130-
LinuxLibC::Glibc { .. } => true,
131-
_ => false,
185+
LinuxLibC::Musl {
186+
version: pkg_musl_version,
187+
} => Self::get_musl_version()
188+
.map(|sys_musl_version| *pkg_musl_version >= sys_musl_version)
189+
.unwrap_or(false),
190+
LinuxLibC::Glibc {
191+
version: pkg_glibc_version,
192+
} => Self::get_glibc_version()
193+
.map(|sys_glibc_version| *pkg_glibc_version >= sys_glibc_version)
194+
.unwrap_or(false),
132195
}
133196
}
134197
}
@@ -145,10 +208,10 @@ impl PlatformOs {
145208
/// Checks if the [PlatformOs] is compatible with the current system.
146209
pub fn is_compatible_with_system(&self) -> bool {
147210
match self {
148-
PlatformOs::Windows => std::env::consts::OS == "windows",
149-
PlatformOs::MacOS => std::env::consts::OS == "macos",
211+
PlatformOs::Windows => cfg!(target_os = "windows"),
212+
PlatformOs::MacOS => cfg!(target_os = "macos"),
150213
PlatformOs::Linux { lib_c } => {
151-
std::env::consts::OS == "linux" && lib_c.is_compatible_with_system()
214+
cfg!(target_os = "linux") && lib_c.is_compatible_with_system()
152215
}
153216
}
154217
}

0 commit comments

Comments
 (0)