meson/rust: wrap `bindgen`s `wrap-static-fns` functionality

This way the `rust.bindgen` can generate a second output being a C file,
which contains wrapper functions for static inline ones.

This output file can then be compiled via C targets.
pull/12181/head
Karol Herbst 1 year ago committed by Dylan Baker
parent 11f2e07071
commit d44185026d
  1. 3
      docs/markdown/Rust-module.md
  2. 35
      mesonbuild/modules/rust.py

@ -57,6 +57,9 @@ It takes the following keyword arguments
- `input`: a list of Files, Strings, or CustomTargets. The first element is - `input`: a list of Files, Strings, or CustomTargets. The first element is
the header bindgen will parse, additional elements are dependencies. the header bindgen will parse, additional elements are dependencies.
- `output`: the name of the output rust file - `output`: the name of the output rust file
- `output_inline_wrapper`: the name of the optional output c file containing
wrappers for static inline function. This requires `bindgen-0.65` or
newer (*since 1.3.0*).
- `include_directories`: A list of `include_directories` or `string` objects, - `include_directories`: A list of `include_directories` or `string` objects,
these are passed to clang as `-I` arguments *(string since 1.0.0)* these are passed to clang as `-I` arguments *(string since 1.0.0)*
- `c_args`: a list of string arguments to pass to clang untouched - `c_args`: a list of string arguments to pass to clang untouched

@ -9,7 +9,7 @@ import typing as T
from mesonbuild.interpreterbase.decorators import FeatureNew from mesonbuild.interpreterbase.decorators import FeatureNew
from . import ExtensionModule, ModuleReturnValue, ModuleInfo from . import ExtensionModule, ModuleReturnValue, ModuleInfo
from .. import mlog from .. import mesonlib, mlog
from ..build import (BothLibraries, BuildTarget, CustomTargetIndex, Executable, ExtractedObjects, GeneratedList, from ..build import (BothLibraries, BuildTarget, CustomTargetIndex, Executable, ExtractedObjects, GeneratedList,
CustomTarget, InvalidArguments, Jar, StructuredSources, SharedLibrary) CustomTarget, InvalidArguments, Jar, StructuredSources, SharedLibrary)
from ..compilers.compilers import are_asserts_disabled, lang_suffixes from ..compilers.compilers import are_asserts_disabled, lang_suffixes
@ -19,6 +19,7 @@ from ..interpreter.type_checking import (
) )
from ..interpreterbase import ContainerTypeInfo, InterpreterException, KwargInfo, typed_kwargs, typed_pos_args, noPosargs, permittedKwargs from ..interpreterbase import ContainerTypeInfo, InterpreterException, KwargInfo, typed_kwargs, typed_pos_args, noPosargs, permittedKwargs
from ..mesonlib import File from ..mesonlib import File
from ..programs import ExternalProgram
if T.TYPE_CHECKING: if T.TYPE_CHECKING:
from . import ModuleState from . import ModuleState
@ -27,7 +28,7 @@ if T.TYPE_CHECKING:
from ..interpreter import Interpreter from ..interpreter import Interpreter
from ..interpreter import kwargs as _kwargs from ..interpreter import kwargs as _kwargs
from ..interpreter.interpreter import SourceInputs, SourceOutputs from ..interpreter.interpreter import SourceInputs, SourceOutputs
from ..programs import ExternalProgram, OverrideProgram from ..programs import OverrideProgram
from ..interpreter.type_checking import SourcesVarargsType from ..interpreter.type_checking import SourcesVarargsType
from typing_extensions import TypedDict, Literal from typing_extensions import TypedDict, Literal
@ -46,6 +47,7 @@ if T.TYPE_CHECKING:
include_directories: T.List[IncludeDirs] include_directories: T.List[IncludeDirs]
input: T.List[SourceInputs] input: T.List[SourceInputs]
output: str output: str
output_inline_wrapper: str
dependencies: T.List[T.Union[Dependency, ExternalLibrary]] dependencies: T.List[T.Union[Dependency, ExternalLibrary]]
language: T.Optional[Literal['c', 'cpp']] language: T.Optional[Literal['c', 'cpp']]
bindgen_version: T.List[str] bindgen_version: T.List[str]
@ -196,6 +198,12 @@ class RustModule(ExtensionModule):
KwargInfo('bindgen_version', ContainerTypeInfo(list, str), default=[], listify=True, since='1.4.0'), KwargInfo('bindgen_version', ContainerTypeInfo(list, str), default=[], listify=True, since='1.4.0'),
INCLUDE_DIRECTORIES.evolve(since_values={ContainerTypeInfo(list, str): '1.0.0'}), INCLUDE_DIRECTORIES.evolve(since_values={ContainerTypeInfo(list, str): '1.0.0'}),
OUTPUT_KW, OUTPUT_KW,
KwargInfo(
'output_inline_wrapper',
str,
default='',
since='1.3.0',
),
DEPENDENCIES_KW.evolve(since='1.0.0'), DEPENDENCIES_KW.evolve(since='1.0.0'),
) )
def bindgen(self, state: ModuleState, args: T.List, kwargs: FuncBindgen) -> ModuleReturnValue: def bindgen(self, state: ModuleState, args: T.List, kwargs: FuncBindgen) -> ModuleReturnValue:
@ -287,12 +295,27 @@ class RustModule(ExtensionModule):
if std != 'none': if std != 'none':
clang_args.append(f'-std={std}') clang_args.append(f'-std={std}')
inline_wrapper_args: T.List[str] = []
outputs = [kwargs['output']]
if kwargs['output_inline_wrapper']:
# Todo drop this isinstance once Executable supports version_compare
if isinstance(self._bindgen_bin, ExternalProgram):
if mesonlib.version_compare(self._bindgen_bin.get_version(), '< 0.65'):
raise InterpreterException('\'output_inline_wrapper\' parameter of rust.bindgen requires bindgen-0.65 or newer')
outputs.append(kwargs['output_inline_wrapper'])
inline_wrapper_args = [
'--experimental', '--wrap-static-fns',
'--wrap-static-fns-path', os.path.join(state.environment.build_dir, '@OUTPUT1@')
]
cmd = self._bindgen_bin.get_command() + \ cmd = self._bindgen_bin.get_command() + \
[ [
'@INPUT@', '--output', '@INPUT@', '--output',
os.path.join(state.environment.build_dir, '@OUTPUT@') os.path.join(state.environment.build_dir, '@OUTPUT0@')
] + \ ] + \
kwargs['args'] + ['--'] + kwargs['c_args'] + clang_args + \ kwargs['args'] + inline_wrapper_args + ['--'] + \
kwargs['c_args'] + clang_args + \
['-MD', '-MQ', '@INPUT@', '-MF', '@DEPFILE@'] ['-MD', '-MQ', '@INPUT@', '-MF', '@DEPFILE@']
target = CustomTarget( target = CustomTarget(
@ -302,7 +325,7 @@ class RustModule(ExtensionModule):
state.environment, state.environment,
cmd, cmd,
[header], [header],
[kwargs['output']], outputs,
depfile='@PLAINNAME@.d', depfile='@PLAINNAME@.d',
extra_depends=depends, extra_depends=depends,
depend_files=depend_files, depend_files=depend_files,
@ -310,7 +333,7 @@ class RustModule(ExtensionModule):
description='Generating bindings for Rust {}', description='Generating bindings for Rust {}',
) )
return ModuleReturnValue([target], [target]) return ModuleReturnValue(target, [target])
# Allow a limited set of kwargs, but still use the full set of typed_kwargs() # Allow a limited set of kwargs, but still use the full set of typed_kwargs()
# because it could be setting required default values. # because it could be setting required default values.

Loading…
Cancel
Save