diff --git a/cargo-dist/src/config.rs b/cargo-dist/src/config.rs index d4ac625a6..e2fb8ef0f 100644 --- a/cargo-dist/src/config.rs +++ b/cargo-dist/src/config.rs @@ -126,6 +126,13 @@ pub struct DistMetadata { #[serde(rename = "auto-includes")] pub auto_includes: Option, + /// Whether msvc targets should statically link the crt + /// + /// Defaults to true. + #[serde(skip_serializing_if = "Option::is_none")] + #[serde(rename = "msvc-crt-static")] + pub msvc_crt_static: Option, + /// The archive format to use for windows builds (defaults .zip) #[serde(skip_serializing_if = "Option::is_none")] #[serde(rename = "windows-archive")] @@ -306,6 +313,7 @@ impl DistMetadata { pr_run_mode: _, allow_dirty: _, ssldotcom_windows_sign: _, + msvc_crt_static: _, } = self; if let Some(include) = include { for include in include { @@ -349,6 +357,7 @@ impl DistMetadata { pr_run_mode, allow_dirty, ssldotcom_windows_sign, + msvc_crt_static, } = self; // Check for global settings on local packages @@ -387,6 +396,9 @@ impl DistMetadata { if ssldotcom_windows_sign.is_some() { warn!("package.metadata.dist.ssldotcom-windows-sign is set, but this is only accepted in workspace.metadata (value is being ignored): {}", package_manifest_path); } + if msvc_crt_static.is_some() { + warn!("package.metadata.dist.msvc-crt-static is set, but this is only accepted in workspace.metadata (value is being ignored): {}", package_manifest_path); + } // Merge non-global settings if installers.is_none() { diff --git a/cargo-dist/src/init.rs b/cargo-dist/src/init.rs index 8d894a9c0..95b1d3c80 100644 --- a/cargo-dist/src/init.rs +++ b/cargo-dist/src/init.rs @@ -223,6 +223,7 @@ fn get_new_dist_metadata( pr_run_mode: None, allow_dirty: None, ssldotcom_windows_sign: None, + msvc_crt_static: None, } }; @@ -740,6 +741,7 @@ fn apply_dist_to_metadata(metadata: &mut toml_edit::Item, meta: &DistMetadata) { pr_run_mode, allow_dirty, ssldotcom_windows_sign, + msvc_crt_static, } = &meta; apply_optional_value( @@ -912,6 +914,13 @@ fn apply_dist_to_metadata(metadata: &mut toml_edit::Item, meta: &DistMetadata) { allow_dirty.as_ref(), ); + apply_optional_value( + table, + "msvc-crt-static", + "Whether +crt-static should be used on msvc\n", + *msvc_crt_static, + ); + apply_optional_value( table, "ssldotcom-windows-sign", diff --git a/cargo-dist/src/tasks.rs b/cargo-dist/src/tasks.rs index ab019f0b0..ed341bb29 100644 --- a/cargo-dist/src/tasks.rs +++ b/cargo-dist/src/tasks.rs @@ -209,6 +209,8 @@ pub struct DistGraph { pub publish_prereleases: bool, /// A GitHub repo to publish the Homebrew formula to pub tap: Option, + /// Whether msvc targets should statically link the crt + pub msvc_crt_static: bool, } /// Various tools we have found installed on the system @@ -663,11 +665,12 @@ impl<'pkg_graph> DistGraphBuilder<'pkg_graph> { publish_jobs: _, publish_prereleases, features, - default_features: no_default_features, + default_features, all_features, create_release, pr_run_mode: _, allow_dirty, + msvc_crt_static, } = &workspace_metadata; let desired_cargo_dist_version = cargo_dist_version.clone(); @@ -678,6 +681,7 @@ impl<'pkg_graph> DistGraphBuilder<'pkg_graph> { let merge_tasks = merge_tasks.unwrap_or(false); let fail_fast = fail_fast.unwrap_or(false); let create_release = create_release.unwrap_or(true); + let msvc_crt_static = msvc_crt_static.unwrap_or(true); let ssldotcom_windows_sign = ssldotcom_windows_sign.clone(); let mut packages_with_mismatched_features = vec![]; // Compute/merge package configs @@ -693,7 +697,7 @@ impl<'pkg_graph> DistGraphBuilder<'pkg_graph> { // Only do workspace builds if all the packages agree with the workspace feature settings if &package_config.features != features || &package_config.all_features != all_features - || &package_config.default_features != no_default_features + || &package_config.default_features != default_features { packages_with_mismatched_features.push(package.name.clone()); } @@ -779,6 +783,7 @@ impl<'pkg_graph> DistGraphBuilder<'pkg_graph> { user_publish_jobs, publish_prereleases, allow_dirty, + msvc_crt_static, }, package_metadata, workspace_metadata, @@ -1964,7 +1969,16 @@ impl<'pkg_graph> DistGraphBuilder<'pkg_graph> { // You're *supposed* to link libc statically on windows but Rust has a bad default. // See: https://rust-lang.github.io/rfcs/1721-crt-static.html - if target.contains("windows-msvc") { + // + // ... well ok it's actually more complicated than that. Most rust applications + // don't dynamically link anything non-trivial, so statically linking libc is fine. + // However if you need to dynamically link stuff there starts to be issues about + // agreeing to the crt in play. At that point you should ship a + // Visual C(++) Redistributable that installs the version of the runtime you depend + // on. Not doing that is basically rolling some dice and hoping the user already + // has it installed, which isn't great. We should support redists eventually, + // but for now this hacky global flag is here to let you roll dice. + if self.inner.msvc_crt_static && target.contains("windows-msvc") { rustflags.push_str(" -Ctarget-feature=+crt-static"); }