mesonbuild: Add mcompile command

This is tested working with both msbuild and ninja/samu. Since our xcode
support is pretty much broken I didn't bother.

Fixes #6670
pull/6735/head
Dylan Baker 5 years ago committed by Xavier Claessens
parent a46f0a6202
commit 1210a67f66
  1. 2
      .github/workflows/lint_mypy.yml
  2. 21
      docs/markdown/snippets/meson_compile_command.md
  3. 123
      mesonbuild/mcompile.py
  4. 4
      mesonbuild/mesonmain.py
  5. 15
      run_unittests.py

@ -30,4 +30,4 @@ jobs:
with:
python-version: '3.x'
- run: python -m pip install mypy
- run: mypy --follow-imports=skip mesonbuild/interpreterbase.py mesonbuild/mtest.py mesonbuild/minit.py mesonbuild/mintro.py mesonbuild/mparser.py mesonbuild/msetup.py mesonbuild/ast mesonbuild/wrap tools/ mesonbuild/modules/fs.py mesonbuild/dependencies/boost.py mesonbuild/dependencies/mpi.py mesonbuild/dependencies/hdf5.py mesonbuild/compilers/mixins/intel.py mesonbuild/mlog.py
- run: mypy --follow-imports=skip mesonbuild/interpreterbase.py mesonbuild/mtest.py mesonbuild/minit.py mesonbuild/mintro.py mesonbuild/mparser.py mesonbuild/msetup.py mesonbuild/ast mesonbuild/wrap tools/ mesonbuild/modules/fs.py mesonbuild/dependencies/boost.py mesonbuild/dependencies/mpi.py mesonbuild/dependencies/hdf5.py mesonbuild/compilers/mixins/intel.py mesonbuild/mlog.py mesonbuild/mcompile.py

@ -0,0 +1,21 @@
## Backend agnostic compile command
A new `meson compile` command has been added to support backend agnostic
compilation. It accepts two arguments, `-j` and `-l`, which are used if
possible (`-l` does nothing with msbuild). A `-j` or `-l` value < 1 lets the
backend decide how many threads to use. For msbuild this means `-m`, for
ninja it means passing no arguments.
```console
meson builddir --backend vs
meson compile -C builddir -j0 # this is the same as `msbuild builddir/my.sln -m`
```
```console
meson builddir
meson compile -C builddir -j3 # this is the same as `ninja -C builddir -j3`
```
Additionally `meson compile` provides a `--clean` switch to clean the project.
A complete list of arguments is always documented via `meson compile --help`

@ -0,0 +1,123 @@
# 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,
required=True,
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

@ -22,7 +22,7 @@ import shutil
from . import mesonlib
from . import mlog
from . import mconf, mdist, minit, minstall, mintro, msetup, mtest, rewriter, msubprojects, munstable_coredata
from . import mconf, mdist, minit, minstall, mintro, msetup, mtest, rewriter, msubprojects, munstable_coredata, mcompile
from .mesonlib import MesonException
from .environment import detect_msys2_arch
from .wrap import wraptool
@ -62,6 +62,8 @@ class CommandLineParser:
help_msg='Print help of a subcommand')
self.add_command('rewrite', lambda parser: rewriter.add_arguments(parser, self.formatter), rewriter.run,
help_msg='Modify the project definition')
self.add_command('compile', mcompile.add_arguments, mcompile.run,
help_msg='Build the project')
# Hidden commands
self.add_command('runpython', self.add_runpython_arguments, self.run_runpython_command,

@ -4412,6 +4412,21 @@ recommended as it is not supported on some platforms''')
else:
self.assertEqual(expected_lines, out_lines)
def test_meson_compile(self):
"""Test the meson compile command."""
prog = 'trivialprog'
if is_windows():
prog = '{}.exe'.format(prog)
testdir = os.path.join(self.common_test_dir, '1 trivial')
self.init(testdir)
self._run([*self.meson_command, 'compile', '-C', self.builddir])
# If compile worked then we should get a program
self.assertPathExists(os.path.join(self.builddir, prog))
self._run([*self.meson_command, 'compile', '-C', self.builddir, '--clean'])
self.assertPathDoesNotExist(os.path.join(self.builddir, prog))
class FailureTests(BasePlatformTests):
'''

Loading…
Cancel
Save