Skip to content

Commit 16a6a2a

Browse files
committed
feat(backend): add global libc preference
1 parent 47a71fd commit 16a6a2a

18 files changed

Lines changed: 439 additions & 75 deletions

File tree

crates/vfox/src/config.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ pub(crate) fn env_type() -> Option<String> {
5555
if let Ok(val) = std::env::var("MISE_LIBC") {
5656
match val.to_lowercase().as_str() {
5757
"musl" => return Some("musl".to_string()),
58-
"gnu" => return Some("gnu".to_string()),
58+
"glibc" | "gnu" => return Some("gnu".to_string()),
5959
_ => {} // invalid value ignored, fall through to runtime detection
6060
}
6161
}

crates/vfox/src/plugin.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ pub enum PluginSource {
2424
pub struct Plugin {
2525
pub name: String,
2626
pub dir: PathBuf,
27+
pub runtime_env_type: Option<String>,
2728
source: PluginSource,
2829
lua: Lua,
2930
metadata: OnceCell<Metadata>,
@@ -41,6 +42,7 @@ impl Plugin {
4142
Ok(Self {
4243
name,
4344
dir: dir.to_path_buf(),
45+
runtime_env_type: None,
4446
source: PluginSource::Filesystem(dir.to_path_buf()),
4547
lua,
4648
metadata: OnceCell::new(),
@@ -57,6 +59,7 @@ impl Plugin {
5759
Ok(Self {
5860
name: name.to_string(),
5961
dir: dummy_dir,
62+
runtime_env_type: None,
6063
source: PluginSource::Embedded(embedded),
6164
lua,
6265
metadata: OnceCell::new(),
@@ -209,7 +212,10 @@ impl Plugin {
209212

210213
let metadata = self.load_metadata()?;
211214
self.set_global("PLUGIN", metadata.clone())?;
212-
self.set_global("RUNTIME", Runtime::get(self.dir.clone()))?;
215+
self.set_global(
216+
"RUNTIME",
217+
Runtime::get(self.dir.clone(), self.runtime_env_type.as_deref()),
218+
)?;
213219
self.set_global("OS_TYPE", config::os())?;
214220
self.set_global("ARCH_TYPE", config::arch())?;
215221

crates/vfox/src/runtime.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,17 @@ static RUNTIME: Lazy<Mutex<Runtime>> = Lazy::new(|| {
2424
});
2525

2626
impl Runtime {
27-
pub(crate) fn get(plugin_dir_path: PathBuf) -> Runtime {
27+
pub(crate) fn get(plugin_dir_path: PathBuf, env_type_override: Option<&str>) -> Runtime {
2828
let mut runtime = RUNTIME.lock().unwrap().clone();
2929
runtime.plugin_dir_path = plugin_dir_path;
30+
if let Some(env_type) = env_type_override {
31+
runtime.env_type = Some(env_type.to_string());
32+
}
3033
runtime
3134
}
3235

3336
pub(crate) fn with_platform(plugin_dir_path: PathBuf, os: &str, arch: &str) -> Runtime {
34-
let mut runtime = Self::get(plugin_dir_path);
37+
let mut runtime = Self::get(plugin_dir_path, None);
3538
runtime.os = os.to_string();
3639
runtime.arch = arch.to_string();
3740
runtime.env_type = None; // target libc is unknown in cross-platform context

crates/vfox/src/vfox.rs

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ pub struct Vfox {
5555
pub cmd_env: Option<IndexMap<String, String>>,
5656
/// Optional GitHub token for Lua http requests to GitHub API endpoints.
5757
pub github_token: Option<String>,
58+
/// Optional runtime env type (`gnu` or `musl`) exposed to plugin hooks.
59+
pub runtime_env_type: Option<String>,
5860
log_tx: Option<mpsc::Sender<String>>,
5961
}
6062

@@ -123,7 +125,9 @@ impl Vfox {
123125
}
124126

125127
pub fn get_sdk(&self, name: &str) -> Result<Plugin> {
126-
Plugin::from_name_or_dir(name, &self.plugin_dir.join(name))
128+
let mut plugin = Plugin::from_name_or_dir(name, &self.plugin_dir.join(name))?;
129+
plugin.runtime_env_type = self.runtime_env_type.clone();
130+
Ok(plugin)
127131
}
128132

129133
fn get_sdk_with_env(&self, name: &str) -> Result<Plugin> {
@@ -146,12 +150,16 @@ impl Vfox {
146150
// Check filesystem first - allows user to override embedded plugins
147151
let plugin_dir = self.plugin_dir.join(sdk);
148152
if plugin_dir.exists() {
149-
return Plugin::from_dir(&plugin_dir);
153+
let mut plugin = Plugin::from_dir(&plugin_dir)?;
154+
plugin.runtime_env_type = self.runtime_env_type.clone();
155+
return Ok(plugin);
150156
}
151157

152158
// Fall back to embedded plugin if available
153159
if let Some(embedded) = crate::embedded_plugins::get_embedded_plugin(sdk) {
154-
return Plugin::from_embedded(sdk, embedded);
160+
let mut plugin = Plugin::from_embedded(sdk, embedded)?;
161+
plugin.runtime_env_type = self.runtime_env_type.clone();
162+
return Ok(plugin);
155163
}
156164

157165
// Otherwise install from registry
@@ -175,7 +183,9 @@ impl Vfox {
175183
debug!("Installing plugin {sdk}");
176184
xx::git::clone(url.as_ref(), &plugin_dir, &Default::default())?;
177185
}
178-
Plugin::from_dir(&plugin_dir)
186+
let mut plugin = Plugin::from_dir(&plugin_dir)?;
187+
plugin.runtime_env_type = self.runtime_env_type.clone();
188+
Ok(plugin)
179189
}
180190

181191
pub fn uninstall_plugin(&self, sdk: &str) -> Result<()> {
@@ -588,6 +598,7 @@ impl Default for Vfox {
588598
skip_verification: false,
589599
cmd_env: None,
590600
github_token: None,
601+
runtime_env_type: None,
591602
log_tx: None,
592603
}
593604
}
@@ -615,6 +626,7 @@ mod tests {
615626
skip_verification: false,
616627
cmd_env: None,
617628
github_token: None,
629+
runtime_env_type: None,
618630
log_tx: None,
619631
}
620632
}

docs/lang/node.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,9 @@ mise settings node.flavor=musl
108108
mise settings node.flavor=glibc-217
109109
```
110110

111+
For the common musl case, `mise settings libc=musl` also selects Node's `musl`
112+
flavor when `node.flavor` is unset.
113+
111114
## Settings
112115

113116
<script setup>

docs/mise-cookbook/docker.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -90,21 +90,21 @@ When the container starts with `~` mounted, users still see the system tools aut
9090
Any tools they install normally go to `~/.local/share/mise/installs` (on the mount) and
9191
take priority over system versions.
9292

93-
## Overriding libc detection with MISE_LIBC
93+
## Overriding libc detection
9494

9595
In minimal Docker images (scratch, busybox, distroless) where no dynamic linker
96-
files exist, mise may not detect whether the system uses musl or glibc. Set `MISE_LIBC`
97-
to force the detection:
96+
files exist, mise may not detect whether the system uses musl or glibc. Set `libc`
97+
or `MISE_LIBC` to force the detection:
9898

9999
```Dockerfile
100100
ENV MISE_LIBC=musl
101101
RUN mise install
102102
```
103103

104-
Valid values are `musl` and `gnu` (case-insensitive). Invalid values are silently
105-
ignored and mise falls back to runtime detection. When the mise binary is compiled
106-
for musl (the default for Linux releases), it will also fall back to musl
107-
automatically when no linker is detected.
104+
Valid values are `musl`, `glibc`, and `gnu` (case-insensitive, with `gnu` treated
105+
as glibc). Invalid values are silently ignored and mise falls back to runtime
106+
detection. When the mise binary is compiled for musl (the default for Linux
107+
releases), it will also fall back to musl automatically when no linker is detected.
108108

109109
## Task to run mise in a Docker container
110110

schema/mise.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1046,6 +1046,11 @@
10461046
"type": "string"
10471047
}
10481048
},
1049+
"libc": {
1050+
"description": "Libc implementation to use for precompiled Linux binaries.",
1051+
"type": "string",
1052+
"enum": ["glibc", "gnu", "musl"]
1053+
},
10491054
"libgit2": {
10501055
"default": true,
10511056
"description": "Use libgit2 for git operations, set to false to shell out to git.",

settings.toml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1065,6 +1065,20 @@ parse_env = "set_by_comma"
10651065
rust_type = "BTreeSet<String>"
10661066
type = "SetString"
10671067

1068+
[libc]
1069+
default_docs = '"glibc" | "musl"'
1070+
description = "Libc implementation to use for precompiled Linux binaries."
1071+
docs = """
1072+
Libc implementation to use for precompiled Linux binaries. This is used by backends that publish
1073+
separate glibc and musl builds. If unset, mise will detect the current system's libc.
1074+
1075+
`gnu` is accepted as an alias for `glibc`.
1076+
"""
1077+
enum = ["glibc", "gnu", "musl"]
1078+
env = "MISE_LIBC"
1079+
optional = true
1080+
type = "String"
1081+
10681082
[libgit2]
10691083
default = true
10701084
description = "Use libgit2 for git operations, set to false to shell out to git."

0 commit comments

Comments
 (0)