Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@ jobs:
run: cargo build
- name: Run tests
run: cargo test
- name: Run tests with static CRT
if: matrix.config.os == 'windows-latest'
env:
RUSTFLAGS: -C target-feature=+crt-static
run: cargo test
- name: Build with system-installed HiGHS
if: matrix.config.os != 'windows-latest'
run: |
Expand Down
32 changes: 30 additions & 2 deletions build.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
use std::env;
use std::path::{Path, PathBuf};

fn target_has_feature(feature: &str) -> bool {
env::var("CARGO_CFG_TARGET_FEATURE")
.unwrap_or_default()
.split(',')
.any(|enabled_feature| enabled_feature == feature)
}

/// Used to exclude autogenerated files in the output dir from `cargo:rerun-if-changed` directives.
#[derive(Debug)]
pub struct CustomCargoCallbacks {
Expand Down Expand Up @@ -86,6 +93,7 @@ fn build() -> bool {
let target = env::var("TARGET").unwrap();
let emscripten = target.contains("emscripten");
let mut dst = Config::new("HiGHS");
let crt_static = target_has_feature("crt-static");

if cfg!(feature = "ninja") {
dst.generator("Ninja");
Expand All @@ -109,7 +117,14 @@ fn build() -> bool {
let dst = dst
.define("FAST_BUILD", "ON")
.define("BUILD_SHARED_LIBS", "OFF")
.define("CMAKE_MSVC_RUNTIME_LIBRARY", "MultiThreadedDLL")
.define(
"CMAKE_MSVC_RUNTIME_LIBRARY",
if crt_static {
"MultiThreaded"
} else {
"MultiThreadedDLL"
},
)
.define("CMAKE_INTERPROCEDURAL_OPTIMIZATION", "FALSE")
.define("ZLIB", if cfg!(feature = "libz") { "ON" } else { "OFF" })
.build();
Expand Down Expand Up @@ -164,6 +179,10 @@ fn discover() -> bool {
}

fn main() {
println!("cargo:rerun-if-env-changed=CARGO_CFG_TARGET_FEATURE");

let crt_static = target_has_feature("crt-static");

if cfg!(all(
any(
feature = "highs_release",
Expand All @@ -173,11 +192,20 @@ fn main() {
not(feature = "build")
)) {
panic!(
"You have enabled features that control how HiGHS is built, but have not enabled the 'build' feature.\n\
"You have enabled features that control how HiGHS is built, but have not enabled the 'build' feature.
\
Thus, your features will never have any effect. Please enable the 'build' feature on highs-sys if you want to build HiGHS or disable the 'libz', 'ninja' and 'highs_release' features."
);
}

if cfg!(feature = "discover") && crt_static {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Gate crt-static discover panic to MSVC targets

This guard now panics for every discover + crt-static build, but crt-static is also used on non-MSVC targets (for example static Linux/musl builds) where the MSVC runtime mismatch described here does not apply. Because the panic runs before discover()/build(), it also blocks valid discover+build fallback configurations that could still safely build the bundled HiGHS library. Restricting this check to MSVC contexts (or to cases where discovery is actually used) would avoid breaking those legitimate builds.

Useful? React with 👍 / 👎.

panic!(
"You have enabled Rust's 'crt-static' target feature, but also enabled the 'discover' feature.
\
Discovering a system-installed HiGHS bypasses the bundled build, so highs-sys cannot ensure that HiGHS uses the same MSVC runtime. Please disable 'discover' when using '-C target-feature=+crt-static'."
);
}

Comment on lines +202 to +208
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think using warning would make more sense here. We do not know which runtime configuration users are using, and if the build passes successfully, that should be fine.

if !discover() && !build() {
panic!("Could neither discover nor build HiGHS");
}
Expand Down
Loading