Look for strip settings in inherited profiles and global configs (#4645)

* Look for strip settings in inherited profiles and global configs

* fix clippy

* use cargo home env var if it exists

* fix cargo home config path

* small stylistic changes

---------

Co-authored-by: Jonathan Kelley <jkelleyrtp@gmail.com>
This commit is contained in:
Evan AlmloffandJonathan Kelley authored and GitHub committed 2025-10-03 21:11:05 -07:00
1 parent c39cae6c57
commit c56bac04f4
4 files changed
+187 -5

No files matched your search

+22 -2
View File
@@ -326,6 +326,7 @@ use crate::{
};
use anyhow::{bail, Context};
use cargo_metadata::diagnostic::Diagnostic;
use cargo_toml::{Profile, Profiles, StripSetting};
use depinfo::RustcDepInfo;
use dioxus_cli_config::{format_base_path_meta_element, PRODUCT_NAME_ENV};
use dioxus_cli_config::{APP_TITLE_ENV, ASSET_ROOT_ENV};
@@ -3509,9 +3510,28 @@ impl BuildRequest {
(_, false) => ("dev", cargo_toml.profile.dev.as_ref()),
};
let Some(profile) = profile else { return };
let Some(profile) = profile else {
return;
};
let Some(strip) = profile.strip.as_ref() else {
// Get the strip setting from the profile or the profile it inherits from
fn get_strip(profile: &Profile, profiles: &Profiles) -> Option<StripSetting> {
profile.strip.clone().or_else(|| {
// If we can't find the strip setting, check if we inherit from another profile
profile.inherits.as_ref().and_then(|inherits| {
let profile = match inherits.as_str() {
"dev" => profiles.dev.as_ref(),
"release" => profiles.release.as_ref(),
"test" => profiles.test.as_ref(),
"bench" => profiles.bench.as_ref(),
other => profiles.custom.get(other),
};
profile.and_then(|p| get_strip(p, profiles))
})
})
}
let Some(strip) = get_strip(profile, &cargo_toml.profile) else {
// If the profile doesn't have a strip option, we don't need to warn
return;
};
+160
View File
@@ -0,0 +1,160 @@
//! The cargo_toml crate contains some logic for resolving Cargo.toml files with workspace inheritance, but it
//! doesn't handle global configs like ~/.cargo/config.toml. This module handles extending the manifest with those
//! settings if they exist.
use std::path::{Path, PathBuf};
use cargo_toml::{Manifest, Profile, Profiles};
/// Load the manifest from a path inheriting from the global config where needed
pub fn load_manifest_from_path(path: &Path) -> Result<Manifest, cargo_toml::Error> {
let mut original = Manifest::from_path(path)?;
// Merge the .cargo/config.toml if it exists
extend_manifest_config_toml(&mut original, &path.join(".cargo").join("config.toml"));
// Merge the global cargo config if it exists
if let Some(global_config) = global_cargo_config_path() {
extend_manifest_config_toml(&mut original, &global_config);
}
Ok(original)
}
/// Get the path to cargo home
fn cargo_home() -> Option<PathBuf> {
// If the cargo home env var is set, use that
if let Some(cargo_home) = std::env::var_os("CARGO_HOME") {
return Some(PathBuf::from(cargo_home));
}
// Otherwise, use the default location
if cfg!(windows) {
std::env::var_os("USERPROFILE")
.map(|user_profile| PathBuf::from(user_profile).join(".cargo"))
} else if cfg!(unix) {
dirs::home_dir().map(|home_dir| home_dir.join(".cargo"))
} else {
None
}
}
/// Get the global cargo config path if it exists
fn global_cargo_config_path() -> Option<PathBuf> {
cargo_home().map(|cargo_home| cargo_home.join("config.toml"))
}
// Extend a manifest with a config.toml if it exists
fn extend_manifest_config_toml(manifest: &mut Manifest, path: &Path) {
// Read the config.toml if it exists
let Ok(config) = std::fs::read_to_string(path) else {
return;
};
let Ok(config) = config.parse::<toml::Value>() else {
return;
};
// Try to parse profiles
if let Some(profiles) = config.get("profile").and_then(|p| p.as_table()) {
merge_profiles(
&mut manifest.profile,
toml::from_str::<cargo_toml::Profiles>(&profiles.to_string()).unwrap_or_default(),
);
}
}
/// Merge the new profiles into the target profiles. Keep the existing values if they exist.
fn merge_profiles(target: &mut Profiles, new: Profiles) {
if let Some(new_release) = new.release {
if target.release.is_none() {
target.release = Some(new_release);
} else {
merge_profile(target.release.as_mut().unwrap(), new_release);
}
}
if let Some(new_dev) = new.dev {
if target.dev.is_none() {
target.dev = Some(new_dev);
} else {
merge_profile(target.dev.as_mut().unwrap(), new_dev);
}
}
if let Some(new_test) = new.test {
if target.test.is_none() {
target.test = Some(new_test);
} else {
merge_profile(target.test.as_mut().unwrap(), new_test);
}
}
if let Some(new_bench) = new.bench {
if target.bench.is_none() {
target.bench = Some(new_bench);
} else {
merge_profile(target.bench.as_mut().unwrap(), new_bench);
}
}
if let Some(new_doc) = new.doc {
if target.doc.is_none() {
target.doc = Some(new_doc);
} else {
merge_profile(target.doc.as_mut().unwrap(), new_doc);
}
}
for (profile_name, profile) in new.custom {
if let Some(target_profile) = target.custom.get_mut(&profile_name) {
merge_profile(target_profile, profile);
} else {
target.custom.insert(profile_name, profile);
}
}
}
/// Merge the new profile into the target profile. Keep the existing values if they exist.
fn merge_profile(target: &mut Profile, new: Profile) {
if target.opt_level.is_none() {
target.opt_level = new.opt_level;
}
if target.debug.is_none() {
target.debug = new.debug;
}
if target.split_debuginfo.is_none() {
target.split_debuginfo = new.split_debuginfo;
}
if target.rpath.is_none() {
target.rpath = new.rpath;
}
if target.lto.is_none() {
target.lto = new.lto;
}
if target.debug_assertions.is_none() {
target.debug_assertions = new.debug_assertions;
}
if target.codegen_units.is_none() {
target.codegen_units = new.codegen_units;
}
if target.panic.is_none() {
target.panic = new.panic;
}
if target.incremental.is_none() {
target.incremental = new.incremental;
}
if target.overflow_checks.is_none() {
target.overflow_checks = new.overflow_checks;
}
if target.strip.is_none() {
target.strip = new.strip;
}
if target.build_override.is_none() {
target.build_override = new.build_override;
}
if target.inherits.is_none() {
target.inherits = new.inherits;
}
target.package.extend(new.package);
}
+1
View File
@@ -6,6 +6,7 @@
mod build;
mod bundle_utils;
mod cargo_toml;
mod cli;
mod config;
mod devcfg;
+4 -3
View File
@@ -96,9 +96,10 @@ impl Workspace {
let ignore = Self::workspace_gitignore(krates.workspace_root().as_std_path());
let cargo_toml =
cargo_toml::Manifest::from_path(krates.workspace_root().join("Cargo.toml"))
.context("Failed to load Cargo.toml")?;
let cargo_toml = crate::cargo_toml::load_manifest_from_path(
krates.workspace_root().join("Cargo.toml").as_std_path(),
)
.context("Failed to load Cargo.toml")?;
let android_tools = crate::build::get_android_tools();