@@ -514,6 +514,8 @@ impl Config {
514
514
// Build up the first cmake command to build the build system.
515
515
let mut cmd = self . cmake_configure_command ( & target) ;
516
516
517
+ let version = Version :: from_command ( cmd. get_program ( ) ) . unwrap_or_default ( ) ;
518
+
517
519
if self . verbose_cmake {
518
520
cmd. arg ( "-Wdev" ) ;
519
521
cmd. arg ( "--debug-output" ) ;
@@ -812,9 +814,13 @@ impl Config {
812
814
813
815
cmd. arg ( "--config" ) . arg ( & profile) ;
814
816
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
+ }
818
824
}
819
825
820
826
if !& self . build_args . is_empty ( ) {
@@ -964,6 +970,52 @@ impl Config {
964
970
}
965
971
}
966
972
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
+
967
1019
fn run ( cmd : & mut Command , program : & str ) {
968
1020
println ! ( "running: {:?}" , cmd) ;
969
1021
let status = match cmd. status ( ) {
@@ -1001,3 +1053,22 @@ fn getenv_unwrap(v: &str) -> String {
1001
1053
fn fail ( s : & str ) -> ! {
1002
1054
panic ! ( "\n {}\n \n build script failed, must exit now" , s)
1003
1055
}
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