aboutsummaryrefslogtreecommitdiff
path: root/mesonbuild/cmake/interpreter.py
diff options
context:
space:
mode:
authorDaniel Mensinger <daniel@mensinger-ka.de>2019-10-18 23:41:16 +0200
committerDaniel Mensinger <daniel@mensinger-ka.de>2019-10-20 12:04:15 +0200
commit902ed589a58055ef657533536615c58555ca1647 (patch)
treebe751a97680f8fb1f74c504d573e1345874db179 /mesonbuild/cmake/interpreter.py
parent4ec82040c8c81a7203785a2527bfc7cd1964cd17 (diff)
downloadmeson-902ed589a58055ef657533536615c58555ca1647.zip
meson-902ed589a58055ef657533536615c58555ca1647.tar.gz
meson-902ed589a58055ef657533536615c58555ca1647.tar.bz2
cmake: Add CMake file API support
The file API will automatically be used when CMake >= 3.14 is detected. This new API is meant as a replacement for the now deprecated CMake server API. The new API (mostly) provides the same information in a different format. Thus only a slight bit of refactoring was necessary to implement this new backend
Diffstat (limited to 'mesonbuild/cmake/interpreter.py')
-rw-r--r--mesonbuild/cmake/interpreter.py53
1 files changed, 48 insertions, 5 deletions
diff --git a/mesonbuild/cmake/interpreter.py b/mesonbuild/cmake/interpreter.py
index aa13171..1b40dc9 100644
--- a/mesonbuild/cmake/interpreter.py
+++ b/mesonbuild/cmake/interpreter.py
@@ -17,15 +17,17 @@
from .common import CMakeException, CMakeTarget
from .client import CMakeClient, RequestCMakeInputs, RequestConfigure, RequestCompute, RequestCodeModel
+from .fileapi import CMakeFileAPI
from .executor import CMakeExecutor
from .traceparser import CMakeTraceParser, CMakeGeneratorTarget
from .. import mlog
from ..environment import Environment
-from ..mesonlib import MachineChoice
+from ..mesonlib import MachineChoice, version_compare
from ..compilers.compilers import lang_suffixes, header_suffixes, obj_suffixes, lib_suffixes, is_header
from subprocess import Popen, PIPE
from typing import Any, List, Dict, Optional, TYPE_CHECKING
from threading import Thread
+from enum import Enum
import os, re
from ..mparser import (
@@ -457,6 +459,10 @@ class ConverterCustomTarget:
mlog.log(' -- inputs: ', mlog.bold(str(self.inputs)))
mlog.log(' -- depends: ', mlog.bold(str(self.depends)))
+class CMakeAPI(Enum):
+ SERVER = 1
+ FILE = 2
+
class CMakeInterpreter:
def __init__(self, build: 'Build', subdir: str, src_dir: str, install_prefix: str, env: Environment, backend: 'Backend'):
assert(hasattr(backend, 'name'))
@@ -468,11 +474,13 @@ class CMakeInterpreter:
self.install_prefix = install_prefix
self.env = env
self.backend_name = backend.name
+ self.cmake_api = CMakeAPI.SERVER
self.client = CMakeClient(self.env)
+ self.fileapi = CMakeFileAPI(self.build_dir)
# Raw CMake results
self.bs_files = []
- self.codemodel = None
+ self.codemodel_configs = None
self.raw_trace = None
# Analysed data
@@ -495,6 +503,10 @@ class CMakeInterpreter:
generator = backend_generator_map[self.backend_name]
cmake_args = cmake_exe.get_command()
+ if version_compare(cmake_exe.version(), '>=3.14'):
+ self.cmake_api = CMakeAPI.FILE
+ self.fileapi.setup_request()
+
# Map meson compiler to CMake variables
for lang, comp in self.env.coredata.compilers[for_machine].items():
if lang not in language_map:
@@ -551,8 +563,24 @@ class CMakeInterpreter:
def initialise(self, extra_cmake_options: List[str]) -> None:
# Run configure the old way becuse doing it
# with the server doesn't work for some reason
+ # Aditionally, the File API requires a configure anyway
self.configure(extra_cmake_options)
+ # Continue with the file API If supported
+ if self.cmake_api is CMakeAPI.FILE:
+ # Parse the result
+ self.fileapi.load_reply()
+
+ # Load the buildsystem file list
+ cmake_files = self.fileapi.get_cmake_sources()
+ self.bs_files = [x.file for x in cmake_files if not x.is_cmake and not x.is_temp]
+ self.bs_files = [os.path.relpath(x, self.env.get_source_dir()) for x in self.bs_files]
+ self.bs_files = list(set(self.bs_files))
+
+ # Load the codemodel configurations
+ self.codemodel_configs = self.fileapi.get_cmake_configurations()
+ return
+
with self.client.connect():
generator = backend_generator_map[self.backend_name]
self.client.do_handshake(self.src_dir, self.build_dir, generator, 1)
@@ -573,10 +601,10 @@ class CMakeInterpreter:
self.bs_files = [x.file for x in bs_reply.build_files if not x.is_cmake and not x.is_temp]
self.bs_files = [os.path.relpath(os.path.join(src_dir, x), self.env.get_source_dir()) for x in self.bs_files]
self.bs_files = list(set(self.bs_files))
- self.codemodel = cm_reply
+ self.codemodel_configs = cm_reply.configs
def analyse(self) -> None:
- if self.codemodel is None:
+ if self.codemodel_configs is None:
raise CMakeException('CMakeInterpreter was not initialized')
# Clear analyser data
@@ -590,7 +618,7 @@ class CMakeInterpreter:
self.trace.parse(self.raw_trace)
# Find all targets
- for i in self.codemodel.configs:
+ for i in self.codemodel_configs:
for j in i.projects:
if not self.project_name:
self.project_name = j.name
@@ -598,6 +626,21 @@ class CMakeInterpreter:
if k.type not in skip_targets:
self.targets += [ConverterTarget(k, self.env)]
+ # Add interface targets from trace, if not already present.
+ # This step is required because interface targets were removed from
+ # the CMake file API output.
+ api_target_name_list = [x.name for x in self.targets]
+ for i in self.trace.targets.values():
+ if i.type != 'INTERFACE' or i.name in api_target_name_list:
+ continue
+ dummy = CMakeTarget({
+ 'name': i.name,
+ 'type': 'INTERFACE_LIBRARY',
+ 'sourceDirectory': self.src_dir,
+ 'buildDirectory': self.build_dir,
+ })
+ self.targets += [ConverterTarget(dummy, self.env)]
+
for i in self.trace.custom_targets:
self.custom_targets += [ConverterCustomTarget(i)]