scripts: west_commands: verify minimum cmake version
A recent developer experience study has pointed out that it's very
common for people to miss that the minimum cmake version required by
zephyr is higher than that which is commonly packaged by Linux
distributions.
Since this is a serious usability issue, it's worth adding extra
checking from zcmake.py to make sure that west commands which run
cmake always print a sensible error message if the cmake version used
is too old. Make that happen.
Signed-off-by: Marti Bolivar <marti.bolivar@nordicsemi.no>
diff --git a/scripts/west_commands/zcmake.py b/scripts/west_commands/zcmake.py
index a05e21f..7e705f6 100644
--- a/scripts/west_commands/zcmake.py
+++ b/scripts/west_commands/zcmake.py
@@ -16,6 +16,7 @@
import shutil
import sys
+import packaging.version
from west import log
from west.util import quote_sh_list
@@ -41,6 +42,8 @@
cmake = shutil.which('cmake')
if cmake is None and not dry_run:
log.die('CMake is not installed or cannot be found; cannot build.')
+ _ensure_min_version(cmake, dry_run)
+
cmd = [cmake] + args
kwargs = dict()
if capture_output:
@@ -260,3 +263,34 @@
def __iter__(self):
return iter(self._entries.values())
+
+def _ensure_min_version(cmake, dry_run):
+ cmd = [cmake, '--version']
+ if dry_run:
+ log.inf('Dry run:', quote_sh_list(cmd))
+ return
+
+ try:
+ version_out = subprocess.check_output(cmd, stderr=subprocess.DEVNULL)
+ except subprocess.CalledProcessError as cpe:
+ log.die('cannot get cmake version:', str(cpe))
+ decoded = version_out.decode('utf-8')
+ lines = decoded.splitlines()
+ if not lines:
+ log.die('can\'t get cmake version: ' +
+ 'unexpected "cmake --version" output:\n{}\n'.
+ format(decoded) +
+ 'Please install CMake ' + _MIN_CMAKE_VERSION_STR +
+ ' or higher (https://cmake.org/download/).')
+ version = lines[0].split()[2]
+ if packaging.version.parse(version) < _MIN_CMAKE_VERSION:
+ log.die('cmake version', version,
+ 'is less than minimum version {};'.
+ format(_MIN_CMAKE_VERSION_STR),
+ 'please update your CMake (https://cmake.org/download/).')
+ else:
+ log.dbg('cmake version', version, 'is OK; minimum version is',
+ _MIN_CMAKE_VERSION_STR)
+
+_MIN_CMAKE_VERSION_STR = '3.13.1'
+_MIN_CMAKE_VERSION = packaging.version.parse(_MIN_CMAKE_VERSION_STR)