diff --git a/mesonbuild/cmake/client.py b/mesonbuild/cmake/client.py index 219acaeeb..b98bf463e 100644 --- a/mesonbuild/cmake/client.py +++ b/mesonbuild/cmake/client.py @@ -232,14 +232,14 @@ class CMakeClient: if not cmake_exe.found(): raise CMakeException('Unable to find CMake') - mlog.log('Starting CMake server with CMake', mlog.bold(' '.join(cmake_exe.get_command())), 'version', mlog.cyan(cmake_vers)) + mlog.debug('Starting CMake server with CMake', mlog.bold(' '.join(cmake_exe.get_command())), 'version', mlog.cyan(cmake_vers)) self.proc = Popen(cmake_exe.get_command() + ['-E', 'server', '--experimental', '--debug'], stdin=PIPE, stdout=PIPE) def shutdown(self) -> None: if self.proc is None: return - mlog.log('Shutting down the CMake server') + mlog.debug('Shutting down the CMake server') # Close the pipes to exit self.proc.stdin.close() diff --git a/mesonbuild/cmake/interpreter.py b/mesonbuild/cmake/interpreter.py index 03fceca55..e12c15ac1 100644 --- a/mesonbuild/cmake/interpreter.py +++ b/mesonbuild/cmake/interpreter.py @@ -21,6 +21,8 @@ from .. import mlog from ..build import Build from ..environment import Environment from ..backend.backends import Backend +from ..dependencies.base import CMakeDependency, ExternalProgram +from subprocess import Popen, PIPE, STDOUT import os CMAKE_BACKEND_GENERATOR_MAP = { @@ -31,6 +33,16 @@ CMAKE_BACKEND_GENERATOR_MAP = { 'vs2017': 'Visual Studio 15 2017', } +CMAKE_LANGUAGE_MAP = { + 'c': 'C', + 'cpp': 'CXX', + 'cuda': 'CUDA', + 'cs': 'CSharp', + 'java': 'Java', + 'fortran': 'Fortran', + 'swift': 'Swift', +} + class CMakeInterpreter: def __init__(self, build: Build, src_dir: str, build_dir: str, env: Environment, backend: Backend): assert(hasattr(backend, 'name')) @@ -42,7 +54,54 @@ class CMakeInterpreter: self.client = CMakeClient(self.env) os.makedirs(self.build_dir, exist_ok=True) + def configure(self) -> None: + # Find CMake + cmake_exe, cmake_vers, _ = CMakeDependency.find_cmake_binary(self.env) + if cmake_exe is None or cmake_exe is False: + raise CMakeException('Unable to find CMake') + assert(isinstance(cmake_exe, ExternalProgram)) + if not cmake_exe.found(): + raise CMakeException('Unable to find CMake') + + generator = CMAKE_BACKEND_GENERATOR_MAP[self.backend_name] + cmake_args = cmake_exe.get_command() + + # Map meson compiler to CMake variables + for lang, comp in self.build.compilers.items(): + if lang not in CMAKE_LANGUAGE_MAP: + continue + cmake_lang = CMAKE_LANGUAGE_MAP[lang] + exelist = comp.get_exelist() + if len(exelist) == 1: + cmake_args += ['-DCMAKE_{}_COMPILER={}'.format(cmake_lang, exelist[0])] + elif len(exelist) == 2: + cmake_args += ['-DCMAKE_{}_COMPILER_LAUNCHER={}'.format(cmake_lang, exelist[0]), + '-DCMAKE_{}_COMPILER={}'.format(cmake_lang, exelist[1])] + cmake_args += ['-G', generator] + + # Run CMake + mlog.log('Configuring the build directory with', mlog.bold('CMake'), 'version', mlog.cyan(cmake_vers)) + with mlog.nested(): + mlog.log(mlog.bold('Running:'), ' '.join(cmake_args)) + proc = Popen(cmake_args + [self.src_dir], stdout=PIPE, stderr=STDOUT, cwd=self.build_dir) + + # Print CMake log in realtime + while True: + line = proc.stdout.readline() + if not line: + break + mlog.log(line.decode('utf-8').strip('\n')) + + # Wait for CMake to finish + proc.communicate() + + h = mlog.green('SUCCEEDED') if proc.returncode == 0 else mlog.red('FAILED') + mlog.log('CMake configuration', h) + if proc.returncode != 0: + raise CMakeException('Failed to configure the CMake subproject') + def run(self) -> None: + self.configure() with self.client.connect(): generator = CMAKE_BACKEND_GENERATOR_MAP[self.backend_name] self.client.do_handshake(self.src_dir, self.build_dir, generator, 1)