aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKarol Herbst <git@karolherbst.de>2023-09-17 12:12:13 +0200
committerDylan Baker <dylan@pnwbakers.com>2024-02-24 09:11:00 -0800
commitd44185026d7cdd83dad8f2da9cb8534c97293ec1 (patch)
tree99de50211f32273b9c855112a2dcd7c643a5b407
parent11f2e07071d062f31a69de531faa0a5d68b1f5bc (diff)
downloadmeson-d44185026d7cdd83dad8f2da9cb8534c97293ec1.zip
meson-d44185026d7cdd83dad8f2da9cb8534c97293ec1.tar.gz
meson-d44185026d7cdd83dad8f2da9cb8534c97293ec1.tar.bz2
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.
-rw-r--r--docs/markdown/Rust-module.md3
-rw-r--r--mesonbuild/modules/rust.py35
2 files changed, 32 insertions, 6 deletions
diff --git a/docs/markdown/Rust-module.md b/docs/markdown/Rust-module.md
index 11966ca..ee095e9 100644
--- a/docs/markdown/Rust-module.md
+++ b/docs/markdown/Rust-module.md
@@ -57,6 +57,9 @@ It takes the following keyword arguments
- `input`: a list of Files, Strings, or CustomTargets. The first element is
the header bindgen will parse, additional elements are dependencies.
- `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,
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
diff --git a/mesonbuild/modules/rust.py b/mesonbuild/modules/rust.py
index fb85280..73ac032 100644
--- a/mesonbuild/modules/rust.py
+++ b/mesonbuild/modules/rust.py
@@ -9,7 +9,7 @@ import typing as T
from mesonbuild.interpreterbase.decorators import FeatureNew
from . import ExtensionModule, ModuleReturnValue, ModuleInfo
-from .. import mlog
+from .. import mesonlib, mlog
from ..build import (BothLibraries, BuildTarget, CustomTargetIndex, Executable, ExtractedObjects, GeneratedList,
CustomTarget, InvalidArguments, Jar, StructuredSources, SharedLibrary)
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 ..mesonlib import File
+from ..programs import ExternalProgram
if T.TYPE_CHECKING:
from . import ModuleState
@@ -27,7 +28,7 @@ if T.TYPE_CHECKING:
from ..interpreter import Interpreter
from ..interpreter import kwargs as _kwargs
from ..interpreter.interpreter import SourceInputs, SourceOutputs
- from ..programs import ExternalProgram, OverrideProgram
+ from ..programs import OverrideProgram
from ..interpreter.type_checking import SourcesVarargsType
from typing_extensions import TypedDict, Literal
@@ -46,6 +47,7 @@ if T.TYPE_CHECKING:
include_directories: T.List[IncludeDirs]
input: T.List[SourceInputs]
output: str
+ output_inline_wrapper: str
dependencies: T.List[T.Union[Dependency, ExternalLibrary]]
language: T.Optional[Literal['c', 'cpp']]
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'),
INCLUDE_DIRECTORIES.evolve(since_values={ContainerTypeInfo(list, str): '1.0.0'}),
OUTPUT_KW,
+ KwargInfo(
+ 'output_inline_wrapper',
+ str,
+ default='',
+ since='1.3.0',
+ ),
DEPENDENCIES_KW.evolve(since='1.0.0'),
)
def bindgen(self, state: ModuleState, args: T.List, kwargs: FuncBindgen) -> ModuleReturnValue:
@@ -287,12 +295,27 @@ class RustModule(ExtensionModule):
if std != 'none':
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() + \
[
'@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@']
target = CustomTarget(
@@ -302,7 +325,7 @@ class RustModule(ExtensionModule):
state.environment,
cmd,
[header],
- [kwargs['output']],
+ outputs,
depfile='@PLAINNAME@.d',
extra_depends=depends,
depend_files=depend_files,
@@ -310,7 +333,7 @@ class RustModule(ExtensionModule):
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()
# because it could be setting required default values.