Skip to content

Commit 00e6b22

Browse files
authored
Merge pull request #146 from taiki-e/version
Do not pass --parallel option to old cmake
2 parents 03c8f49 + 93856b2 commit 00e6b22

File tree

1 file changed

+74
-3
lines changed

1 file changed

+74
-3
lines changed

src/lib.rs

Lines changed: 74 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -514,6 +514,8 @@ impl Config {
514514
// Build up the first cmake command to build the build system.
515515
let mut cmd = self.cmake_configure_command(&target);
516516

517+
let version = Version::from_command(cmd.get_program()).unwrap_or_default();
518+
517519
if self.verbose_cmake {
518520
cmd.arg("-Wdev");
519521
cmd.arg("--debug-output");
@@ -812,9 +814,13 @@ impl Config {
812814

813815
cmd.arg("--config").arg(&profile);
814816

815-
if let Ok(s) = env::var("NUM_JOBS") {
816-
// See https://cmake.org/cmake/help/v3.12/manual/cmake.1.html#build-tool-mode
817-
cmd.arg("--parallel").arg(s);
817+
// --parallel requires CMake 3.12:
818+
// https://cmake.org/cmake/help/latest/release/3.12.html#command-line
819+
if version >= Version::new(3, 12) {
820+
if let Ok(s) = env::var("NUM_JOBS") {
821+
// See https://cmake.org/cmake/help/v3.12/manual/cmake.1.html#build-tool-mode
822+
cmd.arg("--parallel").arg(s);
823+
}
818824
}
819825

820826
if !&self.build_args.is_empty() {
@@ -964,6 +970,52 @@ impl Config {
964970
}
965971
}
966972

973+
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
974+
struct Version {
975+
major: u32,
976+
minor: u32,
977+
}
978+
979+
impl Version {
980+
fn new(major: u32, minor: u32) -> Self {
981+
Self { major, minor }
982+
}
983+
984+
fn parse(s: &str) -> Option<Self> {
985+
// As of 3.22, the format of the version output is "cmake version <major>.<minor>.<patch>".
986+
// ```
987+
// $ cmake --version
988+
// cmake version 3.22.2
989+
//
990+
// CMake suite maintained and supported by Kitware (kitware.com/cmake).
991+
// ```
992+
let version = s.lines().next()?.strip_prefix("cmake version ")?;
993+
let mut digits = version.splitn(3, '.'); // split version string to major minor patch
994+
let major = digits.next()?.parse::<u32>().ok()?;
995+
let minor = digits.next()?.parse::<u32>().ok()?;
996+
// Ignore the patch version because it does not change the API.
997+
Some(Version::new(major, minor))
998+
}
999+
1000+
fn from_command(executable: &OsStr) -> Option<Self> {
1001+
let output = Command::new(executable).arg("--version").output().ok()?;
1002+
if !output.status.success() {
1003+
return None;
1004+
}
1005+
let stdout = core::str::from_utf8(&output.stdout).ok()?;
1006+
Self::parse(stdout)
1007+
}
1008+
}
1009+
1010+
impl Default for Version {
1011+
fn default() -> Self {
1012+
// If the version parsing fails, we assume that it is the latest known
1013+
// version. This is because the failure of version parsing may be due to
1014+
// the version output being changed.
1015+
Self::new(3, 22)
1016+
}
1017+
}
1018+
9671019
fn run(cmd: &mut Command, program: &str) {
9681020
println!("running: {:?}", cmd);
9691021
let status = match cmd.status() {
@@ -1001,3 +1053,22 @@ fn getenv_unwrap(v: &str) -> String {
10011053
fn fail(s: &str) -> ! {
10021054
panic!("\n{}\n\nbuild script failed, must exit now", s)
10031055
}
1056+
1057+
#[cfg(test)]
1058+
mod tests {
1059+
use super::Version;
1060+
1061+
#[test]
1062+
fn test_cmake_version() {
1063+
let text = "cmake version 3.22.2
1064+
1065+
CMake suite maintained and supported by Kitware (kitware.com/cmake).
1066+
";
1067+
let v = Version::parse(text).unwrap();
1068+
assert_eq!(v, Version::new(3, 22));
1069+
assert!(Version::new(3, 22) > Version::new(3, 21));
1070+
assert!(Version::new(3, 22) < Version::new(3, 23));
1071+
1072+
let _v = Version::from_command("cmake".as_ref()).unwrap();
1073+
}
1074+
}

0 commit comments

Comments
 (0)