diff options
author | Daniel Mensinger <daniel@mensinger-ka.de> | 2019-02-22 17:18:31 +0100 |
---|---|---|
committer | Daniel Mensinger <daniel@mensinger-ka.de> | 2019-06-06 18:27:01 +0200 |
commit | 5089eb356b2cc1d68fdc8b06946e2676dd48d576 (patch) | |
tree | d8cad8c7dbed53e175f693daa05be86e37e83d49 /mesonbuild/cmake/client.py | |
parent | 2039cb708bddc1bd8f3b936485e57278e4578a3d (diff) | |
download | meson-5089eb356b2cc1d68fdc8b06946e2676dd48d576.zip meson-5089eb356b2cc1d68fdc8b06946e2676dd48d576.tar.gz meson-5089eb356b2cc1d68fdc8b06946e2676dd48d576.tar.bz2 |
cmake: extract the codemodel
Diffstat (limited to 'mesonbuild/cmake/client.py')
-rw-r--r-- | mesonbuild/cmake/client.py | 171 |
1 files changed, 163 insertions, 8 deletions
diff --git a/mesonbuild/cmake/client.py b/mesonbuild/cmake/client.py index 037a3b7..ae572f9 100644 --- a/mesonbuild/cmake/client.py +++ b/mesonbuild/cmake/client.py @@ -39,7 +39,9 @@ CMAKE_MESSAGE_TYPES = { CMAKE_REPLY_TYPES = { 'handshake': [], 'configure': [], - 'cmakeInputs': ['buildFiles', 'cmakeRootDirectory', 'sourceDirectory'] + 'compute': [], + 'cmakeInputs': ['buildFiles', 'cmakeRootDirectory', 'sourceDirectory'], + 'codemodel': ['configurations'] } # Base CMake server message classes @@ -151,10 +153,18 @@ class RequestConfigure(RequestBase): res['cacheArguments'] = self.args return res +class RequestCompute(RequestBase): + def __init__(self): + super().__init__('compute') + class RequestCMakeInputs(RequestBase): def __init__(self): super().__init__('cmakeInputs') +class RequestCodeModel(RequestBase): + def __init__(self): + super().__init__('codemodel') + # Reply classes class ReplyHandShake(ReplyBase): @@ -165,6 +175,10 @@ class ReplyConfigure(ReplyBase): def __init__(self, cookie: str): super().__init__(cookie, 'configure') +class ReplyCompute(ReplyBase): + def __init__(self, cookie: str): + super().__init__(cookie, 'compute') + class CMakeBuildFile: def __init__(self, file: str, is_cmake: bool, is_temp: bool): self.file = file @@ -189,6 +203,150 @@ class ReplyCMakeInputs(ReplyBase): for i in self.build_files: mlog.log(str(i)) +def _flags_to_list(raw: str) -> List[str]: + res = [] + curr = '' + escape = False + in_string = False + for i in raw: + if escape: + curr += i + escape = False + elif i == '\\': + escape = True + elif i == '"' or i == "'": + in_string = not in_string + elif i == ' ' or i == '\n': + if in_string: + curr += i + else: + res += [curr] + curr = '' + else: + curr += i + res += [curr] + res = list(filter(lambda x: len(x) > 0, res)) + return res + +class CMakeFileGroup: + def __init__(self, data: dict): + self.defines = data.get('defines', '') + self.flags = _flags_to_list(data.get('compileFlags', '')) + self.includes = data.get('includePath', []) + self.is_generated = data.get('isGenerated', False) + self.language = data.get('language', 'C') + self.sources = data.get('sources', []) + + # Fix the include directories + tmp = [] + for i in self.includes: + if isinstance(i, dict) and 'path' in i: + tmp += [i['path']] + elif isinstance(i, str): + tmp += [i] + self.includes = tmp + + def log(self) -> None: + mlog.log('flags =', mlog.bold(', '.join(self.flags))) + mlog.log('defines =', mlog.bold(', '.join(self.defines))) + mlog.log('includes =', mlog.bold(', '.join(self.includes))) + mlog.log('is_generated =', mlog.bold('true' if self.is_generated else 'false')) + mlog.log('language =', mlog.bold(self.language)) + mlog.log('sources:') + for i in self.sources: + with mlog.nested(): + mlog.log(i) + +class CMakeTarget: + def __init__(self, data: dict): + self.artifacts = data.get('artifacts', []) + self.src_dir = data.get('sourceDirectory', '') + self.build_dir = data.get('buildDirectory', '') + self.name = data.get('name', '') + self.full_name = data.get('fullName', '') + self.install = data.get('hasInstallRule', False) + self.install_paths = list(set(data.get('installPaths', []))) + self.link_lang = data.get('linkerLanguage', '') + self.link_libraries = _flags_to_list(data.get('linkLibraries', '')) + self.link_flags = _flags_to_list(data.get('linkFlags', '')) + self.link_lang_flags = _flags_to_list(data.get('linkLanguageFlags', '')) + self.link_path = data.get('linkPath', '') + self.type = data.get('type', 'EXECUTABLE') + self.is_generator_provided = data.get('isGeneratorProvided', False) + self.files = [] + + for i in data.get('fileGroups', []): + self.files += [CMakeFileGroup(i)] + + def log(self) -> None: + mlog.log('artifacts =', mlog.bold(', '.join(self.artifacts))) + mlog.log('src_dir =', mlog.bold(self.src_dir)) + mlog.log('build_dir =', mlog.bold(self.build_dir)) + mlog.log('name =', mlog.bold(self.name)) + mlog.log('full_name =', mlog.bold(self.full_name)) + mlog.log('install =', mlog.bold('true' if self.install else 'false')) + mlog.log('install_paths =', mlog.bold(', '.join(self.install_paths))) + mlog.log('link_lang =', mlog.bold(self.link_lang)) + mlog.log('link_libraries =', mlog.bold(', '.join(self.link_libraries))) + mlog.log('link_flags =', mlog.bold(', '.join(self.link_flags))) + mlog.log('link_lang_flags =', mlog.bold(', '.join(self.link_lang_flags))) + mlog.log('link_path =', mlog.bold(self.link_path)) + mlog.log('type =', mlog.bold(self.type)) + mlog.log('is_generator_provided =', mlog.bold('true' if self.is_generator_provided else 'false')) + for idx, i in enumerate(self.files): + mlog.log('Files {}:'.format(idx)) + with mlog.nested(): + i.log() + +class CMakeProject: + def __init__(self, data: dict): + self.src_dir = data.get('sourceDirectory', '') + self.build_dir = data.get('buildDirectory', '') + self.name = data.get('name', '') + self.targets = [] + + for i in data.get('targets', []): + self.targets += [CMakeTarget(i)] + + def log(self) -> None: + mlog.log('src_dir =', mlog.bold(self.src_dir)) + mlog.log('build_dir =', mlog.bold(self.build_dir)) + mlog.log('name =', mlog.bold(self.name)) + for idx, i in enumerate(self.targets): + mlog.log('Target {}:'.format(idx)) + with mlog.nested(): + i.log() + +class CMakeConfiguration: + def __init__(self, data: dict): + self.name = data.get('name', '') + self.projects = [] + for i in data.get('projects', []): + self.projects += [CMakeProject(i)] + + def log(self) -> None: + mlog.log('name =', mlog.bold(self.name)) + for idx, i in enumerate(self.projects): + mlog.log('Project {}:'.format(idx)) + with mlog.nested(): + i.log() + +class ReplyCodeModel(ReplyBase): + def __init__(self, data: dict): + super().__init__(data['cookie'], 'codemodel') + self.configs = [] + for i in data['configurations']: + self.configs += [CMakeConfiguration(i)] + + def log(self) -> None: + mlog.log('CMake code mode:') + for idx, i in enumerate(self.configs): + mlog.log('Configuration {}:'.format(idx)) + with mlog.nested(): + i.log() + +# Main client class + class CMakeClient: def __init__(self, env: Environment): self.env = env @@ -205,7 +363,9 @@ class CMakeClient: self.reply_map = { 'handshake': lambda data: ReplyHandShake(data['cookie']), 'configure': lambda data: ReplyConfigure(data['cookie']), + 'compute': lambda data: ReplyCompute(data['cookie']), 'cmakeInputs': self.resolve_reply_cmakeInputs, + 'codemodel': lambda data: ReplyCodeModel(data), } def readMessageRaw(self) -> dict: @@ -260,7 +420,7 @@ class CMakeClient: def query_checked(self, request: RequestBase, message: str) -> ReplyBase: reply = self.query(request) h = mlog.green('SUCCEEDED') if reply.type == 'reply' else mlog.red('FAILED') - mlog.log(message, h) + mlog.log(message + ':', h) if reply.type != 'reply': reply.log() raise CMakeException('CMake server query failed') @@ -273,12 +433,7 @@ class CMakeClient: raise CMakeException('Recieved an unexpected message from the CMake server') request = RequestHandShake(src_dir, build_dir, generator, vers_major, vers_minor) - reply = self.query(request) - if not isinstance(reply, ReplyHandShake): - reply.log() - mlog.log('CMake server handshake', mlog.red('FAILED')) - raise CMakeException('Failed to perform the handshake with the CMake server') - mlog.log('CMake server handshake', mlog.green('SUCCEEDED')) + self.query_checked(request, 'CMake server handshake') def resolve_type_reply(self, data: dict) -> ReplyBase: reply_type = data['inReplyTo'] |