summaryrefslogtreecommitdiff
path: root/mesonbuild/modules/unstable_rust.py
diff options
context:
space:
mode:
authorDylan Baker <dylan@pnwbakers.com>2022-07-14 13:12:25 -0700
committerEli Schwartz <eschwartz93@gmail.com>2022-08-17 16:25:36 -0400
commita78992dd81b4bd1673e4815ff26acd694ff77f68 (patch)
tree80c6dfddc3a1c8cfa45903d23c3ff01b3862051a /mesonbuild/modules/unstable_rust.py
parentc32f83a829b6b10a0cbc191c1368b563d4582c28 (diff)
downloadmeson-a78992dd81b4bd1673e4815ff26acd694ff77f68.tar.gz
interpreter: move handling of module stability to interpreter
Thanks to `ModuleInfo`, all modules are just named `foo.py` instead of `unstable_foo.py`, which simplifies the import method a bit. This also allows for accurate FeatureNew/FeatureDeprecated use, as we know when the module was added and if/when it was stabilized.
Diffstat (limited to 'mesonbuild/modules/unstable_rust.py')
-rw-r--r--mesonbuild/modules/unstable_rust.py235
1 files changed, 0 insertions, 235 deletions
diff --git a/mesonbuild/modules/unstable_rust.py b/mesonbuild/modules/unstable_rust.py
deleted file mode 100644
index 792195e6d..000000000
--- a/mesonbuild/modules/unstable_rust.py
+++ /dev/null
@@ -1,235 +0,0 @@
-# Copyright © 2020 Intel Corporation
-
-# 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.
-
-import os
-import typing as T
-
-from . import ExtensionModule, ModuleReturnValue, ModuleInfo
-from .. import mlog
-from ..build import BothLibraries, BuildTarget, CustomTargetIndex, Executable, ExtractedObjects, GeneratedList, IncludeDirs, CustomTarget, StructuredSources
-from ..dependencies import Dependency, ExternalLibrary
-from ..interpreter.interpreter import TEST_KWARGS, OUTPUT_KW
-from ..interpreterbase import ContainerTypeInfo, InterpreterException, KwargInfo, typed_kwargs, typed_pos_args, noPosargs
-from ..mesonlib import File
-
-if T.TYPE_CHECKING:
- from . import ModuleState
- from ..interpreter import Interpreter
- from ..interpreter import kwargs as _kwargs
- from ..interpreter.interpreter import SourceInputs, SourceOutputs
- from ..programs import ExternalProgram
-
- from typing_extensions import TypedDict
-
- class FuncTest(_kwargs.BaseTest):
-
- dependencies: T.List[T.Union[Dependency, ExternalLibrary]]
- is_parallel: bool
-
- class FuncBindgen(TypedDict):
-
- args: T.List[str]
- c_args: T.List[str]
- include_directories: T.List[IncludeDirs]
- input: T.List[SourceInputs]
- output: str
-
-
-class RustModule(ExtensionModule):
-
- """A module that holds helper functions for rust."""
-
- INFO = ModuleInfo('rust', '0.57.0', unstable=True)
-
- def __init__(self, interpreter: 'Interpreter') -> None:
- super().__init__(interpreter)
- self._bindgen_bin: T.Optional['ExternalProgram'] = None
- self.methods.update({
- 'test': self.test,
- 'bindgen': self.bindgen,
- })
-
- @typed_pos_args('rust.test', str, BuildTarget)
- @typed_kwargs(
- 'rust.test',
- *TEST_KWARGS,
- KwargInfo('is_parallel', bool, default=False),
- KwargInfo(
- 'dependencies',
- ContainerTypeInfo(list, (Dependency, ExternalLibrary)),
- listify=True,
- default=[]),
- )
- def test(self, state: 'ModuleState', args: T.Tuple[str, BuildTarget], kwargs: 'FuncTest') -> ModuleReturnValue:
- """Generate a rust test target from a given rust target.
-
- Rust puts it's unitests inside it's main source files, unlike most
- languages that put them in external files. This means that normally
- you have to define two separate targets with basically the same
- arguments to get tests:
-
- ```meson
- rust_lib_sources = [...]
- rust_lib = static_library(
- 'rust_lib',
- rust_lib_sources,
- )
-
- rust_lib_test = executable(
- 'rust_lib_test',
- rust_lib_sources,
- rust_args : ['--test'],
- )
-
- test(
- 'rust_lib_test',
- rust_lib_test,
- protocol : 'rust',
- )
- ```
-
- This is all fine, but not very DRY. This method makes it much easier
- to define rust tests:
-
- ```meson
- rust = import('unstable-rust')
-
- rust_lib = static_library(
- 'rust_lib',
- [sources],
- )
-
- rust.test('rust_lib_test', rust_lib)
- ```
- """
- name = args[0]
- base_target: BuildTarget = args[1]
- if not base_target.uses_rust():
- raise InterpreterException('Second positional argument to rustmod.test() must be a rust based target')
- extra_args = kwargs['args']
-
- # Delete any arguments we don't want passed
- if '--test' in extra_args:
- mlog.warning('Do not add --test to rustmod.test arguments')
- extra_args.remove('--test')
- if '--format' in extra_args:
- mlog.warning('Do not add --format to rustmod.test arguments')
- i = extra_args.index('--format')
- # Also delete the argument to --format
- del extra_args[i + 1]
- del extra_args[i]
- for i, a in enumerate(extra_args):
- if isinstance(a, str) and a.startswith('--format='):
- del extra_args[i]
- break
-
- dependencies = [d for d in kwargs['dependencies']]
-
- # We need to cast here, as currently these don't have protocol in them, but test itself does.
- tkwargs = T.cast('_kwargs.FuncTest', kwargs.copy())
-
- tkwargs['args'] = extra_args + ['--test', '--format', 'pretty']
- tkwargs['protocol'] = 'rust'
-
- new_target_kwargs = base_target.kwargs.copy()
- # Don't mutate the shallow copied list, instead replace it with a new
- # one
- new_target_kwargs['rust_args'] = new_target_kwargs.get('rust_args', []) + ['--test']
- new_target_kwargs['install'] = False
- new_target_kwargs['dependencies'] = new_target_kwargs.get('dependencies', []) + dependencies
-
- new_target = Executable(
- name, base_target.subdir, state.subproject, base_target.for_machine,
- base_target.sources, base_target.structured_sources,
- base_target.objects, base_target.environment, base_target.compilers,
- new_target_kwargs
- )
-
- test = self.interpreter.make_test(
- self.interpreter.current_node, (name, new_target), tkwargs)
-
- return ModuleReturnValue(None, [new_target, test])
-
- @noPosargs
- @typed_kwargs(
- 'rust.bindgen',
- KwargInfo('c_args', ContainerTypeInfo(list, str), default=[], listify=True),
- KwargInfo('args', ContainerTypeInfo(list, str), default=[], listify=True),
- KwargInfo('include_directories', ContainerTypeInfo(list, IncludeDirs), default=[], listify=True),
- KwargInfo(
- 'input',
- ContainerTypeInfo(list, (File, GeneratedList, BuildTarget, BothLibraries, ExtractedObjects, CustomTargetIndex, CustomTarget, str), allow_empty=False),
- default=[],
- listify=True,
- required=True,
- ),
- OUTPUT_KW,
- )
- def bindgen(self, state: 'ModuleState', args: T.List, kwargs: 'FuncBindgen') -> ModuleReturnValue:
- """Wrapper around bindgen to simplify it's use.
-
- The main thing this simplifies is the use of `include_directory`
- objects, instead of having to pass a plethora of `-I` arguments.
- """
- header, *_deps = self.interpreter.source_strings_to_files(kwargs['input'])
-
- # Split File and Target dependencies to add pass to CustomTarget
- depends: T.List['SourceOutputs'] = []
- depend_files: T.List[File] = []
- for d in _deps:
- if isinstance(d, File):
- depend_files.append(d)
- else:
- depends.append(d)
-
- inc_strs: T.List[str] = []
- for i in kwargs['include_directories']:
- # bindgen always uses clang, so it's safe to hardcode -I here
- inc_strs.extend([f'-I{x}' for x in i.to_string_list(
- state.environment.get_source_dir(), state.environment.get_build_dir())])
-
- if self._bindgen_bin is None:
- self._bindgen_bin = state.find_program('bindgen')
-
- name: str
- if isinstance(header, File):
- name = header.fname
- elif isinstance(header, (BuildTarget, BothLibraries, ExtractedObjects, StructuredSources)):
- raise InterpreterException('bindgen source file must be a C header, not an object or build target')
- else:
- name = header.get_outputs()[0]
-
- target = CustomTarget(
- f'rustmod-bindgen-{name}'.replace('/', '_'),
- state.subdir,
- state.subproject,
- state.environment,
- self._bindgen_bin.get_command() + [
- '@INPUT@', '--output',
- os.path.join(state.environment.build_dir, '@OUTPUT@')] +
- kwargs['args'] + ['--'] + kwargs['c_args'] + inc_strs +
- ['-MD', '-MQ', '@INPUT@', '-MF', '@DEPFILE@'],
- [header],
- [kwargs['output']],
- depfile='@PLAINNAME@.d',
- extra_depends=depends,
- depend_files=depend_files,
- backend=state.backend,
- )
-
- return ModuleReturnValue([target], [target])
-
-
-def initialize(interp: 'Interpreter') -> RustModule:
- return RustModule(interp)