| # Copyright 2020 The Meson development team |
| |
| # Licensed under the Apache License, Version 2.0 (the "License"); |
| # you may not use this file except in compliance with the License. |
| # You may obtain a copy of the License at |
| |
| # http://www.apache.org/licenses/LICENSE-2.0 |
| |
| # Unless required by applicable law or agreed to in writing, software |
| # distributed under the License is distributed on an "AS IS" BASIS, |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| # See the License for the specific language governing permissions and |
| # limitations under the License. |
| |
| """Entrypoint script for backend agnostic compile.""" |
| |
| import os |
| import pathlib |
| import shutil |
| import sys |
| import typing as T |
| |
| from . import mlog |
| from . import mesonlib |
| from .mesonlib import MesonException |
| |
| if T.TYPE_CHECKING: |
| import argparse |
| |
| |
| def add_arguments(parser: 'argparse.ArgumentParser') -> None: |
| """Add compile specific arguments.""" |
| parser.add_argument( |
| '-j', '--jobs', |
| action='store', |
| default=0, |
| type=int, |
| help='The number of worker jobs to run (if supported). If the value is less than 1 the build program will guess.' |
| ) |
| parser.add_argument( |
| '-l', '--load-average', |
| action='store', |
| default=0, |
| type=int, |
| help='The system load average to try to maintain (if supported)' |
| ) |
| parser.add_argument( |
| '--clean', |
| action='store_true', |
| help='Clean the build directory.' |
| ) |
| parser.add_argument( |
| '-C', |
| action='store', |
| dest='builddir', |
| type=pathlib.Path, |
| default='.', |
| help='The directory containing build files to be built.' |
| ) |
| |
| |
| def run(options: 'argparse.Namespace') -> int: |
| bdir = options.builddir # type: pathlib.Path |
| if not bdir.exists(): |
| raise MesonException('Path to builddir {} does not exist!'.format(str(bdir.resolve()))) |
| if not bdir.is_dir(): |
| raise MesonException('builddir path should be a directory.') |
| |
| cmd = [] # type: T.List[str] |
| runner = None # type T.Optional[str] |
| slns = list(bdir.glob('*.sln')) |
| |
| if (bdir / 'build.ninja').exists(): |
| runner = os.environ.get('NINJA') |
| if not runner: |
| if shutil.which('ninja'): |
| runner = 'ninja' |
| elif shutil.which('samu'): |
| runner = 'samu' |
| |
| if runner is None: |
| raise MesonException('Cannot find either ninja or samu.') |
| |
| cmd = [runner, '-C', bdir.as_posix()] |
| |
| # If the value is set to < 1 then don't set anything, which let's |
| # ninja/samu decide what to do. |
| if options.jobs > 0: |
| cmd.extend(['-j', str(options.jobs)]) |
| if options.load_average > 0: |
| cmd.extend(['-l', str(options.load_average)]) |
| if options.clean: |
| cmd.append('clean') |
| |
| # TODO: with python 3.8 this could be `elif slns := bdir.glob('*.sln'):` |
| elif slns: |
| assert len(slns) == 1, 'More than one solution in a project?' |
| |
| sln = slns[0] |
| cmd = ['msbuild', str(sln.resolve())] |
| |
| # In msbuild `-m` with no number means "detect cpus", the default is `-m1` |
| if options.jobs > 0: |
| cmd.append('-m{}'.format(options.jobs)) |
| else: |
| cmd.append('-m') |
| |
| if options.load_average: |
| mlog.warning('Msbuild does not have a load-average switch, ignoring.') |
| if options.clean: |
| cmd.extend(['/t:Clean']) |
| |
| # TODO: xcode? |
| else: |
| raise MesonException( |
| 'Could not find any runner or backend for directory {}'.format(bdir.resolve().as_posix())) |
| |
| mlog.log('Found runner:', runner) |
| |
| p, *_ = mesonlib.Popen_safe(cmd, stdout=sys.stdout.buffer, stderr=sys.stderr.buffer) |
| |
| return p.returncode |