diff options
author | Daniel Mensinger <daniel@mensinger-ka.de> | 2020-02-19 20:05:19 +0100 |
---|---|---|
committer | Daniel Mensinger <daniel@mensinger-ka.de> | 2020-02-20 11:16:37 +0100 |
commit | 113ec96626fe7cd2edc0bc4815ae2fc21cfb0546 (patch) | |
tree | c793ed45ea352e1f4ceb9ef279f6f96ab64e526c /mesonbuild/cmake/traceparser.py | |
parent | 31eb41ec2fd2c7ed06406fb4e5ea87af5010d4e5 (diff) | |
download | meson-113ec96626fe7cd2edc0bc4815ae2fc21cfb0546.zip meson-113ec96626fe7cd2edc0bc4815ae2fc21cfb0546.tar.gz meson-113ec96626fe7cd2edc0bc4815ae2fc21cfb0546.tar.bz2 |
cmake: Fix relative paths for add_custom_{command,target}
Do this by tracking CMAKE_CURRENT_{SOURCE,BINARY}_DIR variables.
This is achieved by injecting CMake code with CMAKE_PROJECT_INCLUDE
and overriding some builtin functions with a wrapper that adds
additional trace information.
Diffstat (limited to 'mesonbuild/cmake/traceparser.py')
-rw-r--r-- | mesonbuild/cmake/traceparser.py | 77 |
1 files changed, 58 insertions, 19 deletions
diff --git a/mesonbuild/cmake/traceparser.py b/mesonbuild/cmake/traceparser.py index 28f22b3..8eb8605 100644 --- a/mesonbuild/cmake/traceparser.py +++ b/mesonbuild/cmake/traceparser.py @@ -47,6 +47,8 @@ class CMakeTarget: self.imported = imported self.tline = tline self.depends = [] + self.current_bin_dir = None + self.current_src_dir = None def __repr__(self): s = 'CMake TARGET:\n -- name: {}\n -- type: {}\n -- imported: {}\n -- properties: {{\n{} }}\n -- tline: {}' @@ -83,6 +85,36 @@ class CMakeTraceParser: self.trace_file_path = Path(build_dir) / self.trace_file self.trace_format = 'json-v1' if version_compare(cmake_version, '>=3.17') else 'human' + # State for delayed command execution. Delayed command execution is realised + # with a custom CMake file that overrides some functions and adds some + # introspection information to the trace. + self.delayed_commands = [] # type: T.List[str] + self.stored_commands = [] # type: T.List[CMakeTraceLine] + + # All supported functions + self.functions = { + 'set': self._cmake_set, + 'unset': self._cmake_unset, + 'add_executable': self._cmake_add_executable, + 'add_library': self._cmake_add_library, + 'add_custom_command': self._cmake_add_custom_command, + 'add_custom_target': self._cmake_add_custom_target, + 'set_property': self._cmake_set_property, + 'set_target_properties': self._cmake_set_target_properties, + 'target_compile_definitions': self._cmake_target_compile_definitions, + 'target_compile_options': self._cmake_target_compile_options, + 'target_include_directories': self._cmake_target_include_directories, + 'target_link_libraries': self._cmake_target_link_libraries, + 'target_link_options': self._cmake_target_link_options, + 'add_dependencies': self._cmake_add_dependencies, + + # Special functions defined in the preload script. + # These functions do nothing in the CMake code, but have special + # meaning here in the trace parser. + 'meson_ps_execute_delayed_calls': self._meson_ps_execute_delayed_calls, + 'meson_ps_reload_vars': self._meson_ps_reload_vars, + } + def trace_args(self) -> T.List[str]: arg_map = { 'human': ['--trace', '--trace-expand'], @@ -116,28 +148,15 @@ class CMakeTraceParser: else: raise CMakeException('CMake: Internal error: Invalid trace format {}. Expected [human, json-v1]'.format(self.trace_format)) - # All supported functions - functions = { - 'set': self._cmake_set, - 'unset': self._cmake_unset, - 'add_executable': self._cmake_add_executable, - 'add_library': self._cmake_add_library, - 'add_custom_command': self._cmake_add_custom_command, - 'add_custom_target': self._cmake_add_custom_target, - 'set_property': self._cmake_set_property, - 'set_target_properties': self._cmake_set_target_properties, - 'target_compile_definitions': self._cmake_target_compile_definitions, - 'target_compile_options': self._cmake_target_compile_options, - 'target_include_directories': self._cmake_target_include_directories, - 'target_link_libraries': self._cmake_target_link_libraries, - 'target_link_options': self._cmake_target_link_options, - 'add_dependencies': self._cmake_add_dependencies, - } - # Primary pass -- parse everything for l in lexer1: + # store the function if its execution should be delayed + if l.func in self.delayed_commands: + self.stored_commands += [l] + continue + # "Execute" the CMake function if supported - fn = functions.get(l.func, None) + fn = self.functions.get(l.func, None) if(fn): fn(l) @@ -160,6 +179,12 @@ class CMakeTraceParser: return [] + def var_to_str(self, var: str) -> T.Optional[str]: + if var in self.vars and self.vars[var]: + return self.vars[var][0] + + return None + def var_to_bool(self, var): if var not in self.vars: return False @@ -337,6 +362,8 @@ class CMakeTraceParser: if fn is not None: fn(i, target) + target.current_bin_dir = self.var_to_str('MESON_PS_CMAKE_CURRENT_BINARY_DIR') + target.current_src_dir = self.var_to_str('MESON_PS_CMAKE_CURRENT_SOURCE_DIR') target.outputs = self._guess_files(target.outputs) target.depends = self._guess_files(target.depends) target.command = [self._guess_files(x) for x in target.command] @@ -532,6 +559,18 @@ class CMakeTraceParser: self.targets[target].properties[i[0]] += i[1] + def _meson_ps_execute_delayed_calls(self, tline: CMakeTraceLine) -> None: + for l in self.stored_commands: + fn = self.functions.get(l.func, None) + if(fn): + fn(l) + + # clear the stored commands + self.stored_commands = [] + + def _meson_ps_reload_vars(self, tline: CMakeTraceLine) -> None: + self.delayed_commands = self.get_cmake_var('MESON_PS_DELAYED_CALLS') + def _lex_trace_human(self, trace): # The trace format is: '<file>(<line>): <func>(<args -- can contain \n> )\n' reg_tline = re.compile(r'\s*(.*\.(cmake|txt))\(([0-9]+)\):\s*(\w+)\(([\s\S]*?) ?\)\s*\n', re.MULTILINE) |