cmake: Better error message when configuring a CMake subproject fails.

pull/10152/head
Daniel Mensinger 3 years ago committed by Eli Schwartz
parent 2c4c7f6e64
commit 4dd6cb8469
  1. 12
      mesonbuild/cmake/interpreter.py
  2. 15
      mesonbuild/cmake/traceparser.py
  3. 8
      test cases/failing/122 cmake subproject error/meson.build
  4. 5
      test cases/failing/122 cmake subproject error/subprojects/cmlib/CMakeLists.txt
  5. 10
      test cases/failing/122 cmake subproject error/test.json

@ -777,7 +777,7 @@ class CMakeInterpreter:
# Raw CMake results # Raw CMake results
self.bs_files = [] # type: T.List[Path] self.bs_files = [] # type: T.List[Path]
self.codemodel_configs = None # type: T.Optional[T.List[CMakeConfiguration]] self.codemodel_configs = None # type: T.Optional[T.List[CMakeConfiguration]]
self.raw_trace = None # type: T.Optional[str] self.cmake_stderr = None # type: T.Optional[str]
# Analysed data # Analysed data
self.project_name = '' self.project_name = ''
@ -841,13 +841,17 @@ class CMakeInterpreter:
final_args = cmake_args + trace_args + cmcmp_args + toolchain.get_cmake_args() + [self.src_dir.as_posix()] final_args = cmake_args + trace_args + cmcmp_args + toolchain.get_cmake_args() + [self.src_dir.as_posix()]
cmake_exe.set_exec_mode(print_cmout=True, always_capture_stderr=self.trace.requires_stderr()) cmake_exe.set_exec_mode(print_cmout=True, always_capture_stderr=self.trace.requires_stderr())
rc, _, self.raw_trace = cmake_exe.call(final_args, self.build_dir, env=os_env, disable_cache=True) rc, _, self.cmake_stderr = cmake_exe.call(final_args, self.build_dir, env=os_env, disable_cache=True)
mlog.log() mlog.log()
h = mlog.green('SUCCEEDED') if rc == 0 else mlog.red('FAILED') h = mlog.green('SUCCEEDED') if rc == 0 else mlog.red('FAILED')
mlog.log('CMake configuration:', h) mlog.log('CMake configuration:', h)
if rc != 0: if rc != 0:
raise CMakeException('Failed to configure the CMake subproject') # get the last CMake error - We only need the message function for this:
self.trace.functions = {'message': self.trace.functions['message']}
self.trace.parse(self.cmake_stderr)
error = f': {self.trace.errors[-1]}' if self.trace.errors else ''
raise CMakeException(f'Failed to configure the CMake subproject{error}')
return cmake_exe return cmake_exe
@ -879,7 +883,7 @@ class CMakeInterpreter:
self.custom_targets = [] self.custom_targets = []
# Parse the trace # Parse the trace
self.trace.parse(self.raw_trace) self.trace.parse(self.cmake_stderr)
# Find all targets # Find all targets
added_target_names = [] # type: T.List[str] added_target_names = [] # type: T.List[str]

@ -111,6 +111,8 @@ class CMakeTraceParser:
self.trace_file_path = build_dir / self.trace_file self.trace_file_path = build_dir / self.trace_file
self.trace_format = 'json-v1' if version_compare(cmake_version, '>=3.17') else 'human' self.trace_format = 'json-v1' if version_compare(cmake_version, '>=3.17') else 'human'
self.errors: T.List[str] = []
# State for delayed command execution. Delayed command execution is realised # State for delayed command execution. Delayed command execution is realised
# with a custom CMake file that overrides some functions and adds some # with a custom CMake file that overrides some functions and adds some
# introspection information to the trace. # introspection information to the trace.
@ -133,6 +135,7 @@ class CMakeTraceParser:
'target_link_libraries': self._cmake_target_link_libraries, 'target_link_libraries': self._cmake_target_link_libraries,
'target_link_options': self._cmake_target_link_options, 'target_link_options': self._cmake_target_link_options,
'add_dependencies': self._cmake_add_dependencies, 'add_dependencies': self._cmake_add_dependencies,
'message': self._cmake_message,
# Special functions defined in the preload script. # Special functions defined in the preload script.
# These functions do nothing in the CMake code, but have special # These functions do nothing in the CMake code, but have special
@ -639,6 +642,18 @@ class CMakeTraceParser:
# DOC: https://cmake.org/cmake/help/latest/command/target_link_libraries.html # DOC: https://cmake.org/cmake/help/latest/command/target_link_libraries.html
self._parse_common_target_options('target_link_options', 'LINK_LIBRARIES', 'INTERFACE_LINK_LIBRARIES', tline) self._parse_common_target_options('target_link_options', 'LINK_LIBRARIES', 'INTERFACE_LINK_LIBRARIES', tline)
def _cmake_message(self, tline: CMakeTraceLine) -> None:
# DOC: https://cmake.org/cmake/help/latest/command/message.html
args = list(tline.args)
if len(args) < 1:
return self._gen_exception('message', 'takes at least 1 argument', tline)
if args[0].upper().strip() not in ['FATAL_ERROR', 'SEND_ERROR']:
return
self.errors += [' '.join(args[1:])]
def _parse_common_target_options(self, func: str, private_prop: str, interface_prop: str, tline: CMakeTraceLine, ignore: T.Optional[T.List[str]] = None, paths: bool = False) -> None: def _parse_common_target_options(self, func: str, private_prop: str, interface_prop: str, tline: CMakeTraceLine, ignore: T.Optional[T.List[str]] = None, paths: bool = False) -> None:
if ignore is None: if ignore is None:
ignore = ['BEFORE'] ignore = ['BEFORE']

@ -0,0 +1,8 @@
project('cmake-executable-dependency', ['c', 'cpp'])
if not find_program('cmake', required: false).found()
error('MESON_SKIP_TEST CMake is not installed')
endif
cmake = import('cmake')
cmlib = cmake.subproject('cmlib')

@ -0,0 +1,5 @@
cmake_minimum_required(VERSION 3.5)
project(cmlib)
message(FATAL_ERROR "Fancy error message")

@ -0,0 +1,10 @@
{
"stdout": [
{
"line": "test cases/failing/122 cmake subproject error/meson.build:8:0: ERROR: Failed to configure the CMake subproject: Fancy error message"
}
],
"tools": {
"cmake": ">=3.14"
}
}
Loading…
Cancel
Save