|
|
|
@ -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) |
|
|
|
|