Skip to content

Commit

Permalink
modules/rust: Allow explicitly setting the language to bind
Browse files Browse the repository at this point in the history
This may be of particular use when a header is .h but should be treated
as a C++ header instead of a C header.
  • Loading branch information
dcbaker committed Feb 23, 2024
1 parent 8ac4346 commit 05d49c6
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 6 deletions.
3 changes: 2 additions & 1 deletion docs/markdown/Rust-module.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ short-description: Rust language integration module
authors:
- name: Dylan Baker
email: dylan@pnwbakers.com
years: [2020, 2021, 2022]
years: [2020, 2021, 2022, 2024]
...

# Rust module
Expand Down Expand Up @@ -62,6 +62,7 @@ It takes the following keyword arguments
- `c_args`: a list of string arguments to pass to clang untouched
- `args`: a list of string arguments to pass to `bindgen` untouched.
- `dependencies`: a list of `Dependency` objects to pass to the underlying clang call (*since 1.0.0*)
- `language`: A literal string value of `c` or `cpp`. When set this will force bindgen to treat a source as the given language. Defaults to checking based on the input file extension. *(since 1.4.0)*

```meson
rust = import('unstable-rust')
Expand Down
5 changes: 5 additions & 0 deletions docs/markdown/snippets/rust-bindgen-language.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
## Overriding bindgen language setting

Even though Meson will now tell bindgen to do the right thing in most cases,
there may still be cases where Meson does not have the intended behavior,
specifically with headers with a `.h` suffix, but are C++ headers.
21 changes: 16 additions & 5 deletions mesonbuild/modules/rust.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@
from ..build import (BothLibraries, BuildTarget, CustomTargetIndex, Executable, ExtractedObjects, GeneratedList,
CustomTarget, InvalidArguments, Jar, StructuredSources, SharedLibrary)
from ..compilers.compilers import are_asserts_disabled, lang_suffixes
from ..interpreter.type_checking import DEPENDENCIES_KW, LINK_WITH_KW, SHARED_LIB_KWS, TEST_KWS, OUTPUT_KW, INCLUDE_DIRECTORIES, SOURCES_VARARGS
from ..interpreter.type_checking import (
DEPENDENCIES_KW, LINK_WITH_KW, SHARED_LIB_KWS, TEST_KWS, OUTPUT_KW,
INCLUDE_DIRECTORIES, SOURCES_VARARGS, NoneType, in_set_validator
)
from ..interpreterbase import ContainerTypeInfo, InterpreterException, KwargInfo, typed_kwargs, typed_pos_args, noPosargs, permittedKwargs
from ..mesonlib import File

Expand All @@ -27,7 +30,7 @@
from ..programs import ExternalProgram, OverrideProgram
from ..interpreter.type_checking import SourcesVarargsType

from typing_extensions import TypedDict
from typing_extensions import TypedDict, Literal

class FuncTest(_kwargs.BaseTest):

Expand All @@ -44,6 +47,7 @@ class FuncBindgen(TypedDict):
input: T.List[SourceInputs]
output: str
dependencies: T.List[T.Union[Dependency, ExternalLibrary]]
language: T.Optional[Literal['c', 'cpp']]


class RustModule(ExtensionModule):
Expand Down Expand Up @@ -187,6 +191,7 @@ def test(self, state: ModuleState, args: T.Tuple[str, BuildTarget], kwargs: Func
listify=True,
required=True,
),
KwargInfo('language', (str, NoneType), since='1.4.0', validator=in_set_validator({'c', 'cpp'})),
INCLUDE_DIRECTORIES.evolve(since_values={ContainerTypeInfo(list, str): '1.0.0'}),
OUTPUT_KW,
DEPENDENCIES_KW.evolve(since='1.0.0'),
Expand Down Expand Up @@ -243,7 +248,15 @@ def bindgen(self, state: ModuleState, args: T.List, kwargs: FuncBindgen) -> Modu

# bindgen assumes that C++ headers will be called .hpp. We want to
# ensure that anything Meson considers a C++ header is treated as one.
language = 'cpp' if os.path.splitext(name)[1][1:] in lang_suffixes['cpp'] else 'c'
language = kwargs['language']
if language is None:
ext = os.path.splitext(name)[1][1:]
if ext in lang_suffixes['cpp']:
language = 'cpp'
elif ext == 'h':
language = 'c'
else:
raise InterpreterException(f'Unknown file type extension for: {name}')

# We only want include directories and defines, other things may not be valid
cargs = state.get_option('args', state.subproject, lang=language)
Expand All @@ -252,8 +265,6 @@ def bindgen(self, state: ModuleState, args: T.List, kwargs: FuncBindgen) -> Modu
if a.startswith(('-I', '/I', '-D', '/D', '-U', '/U')):
clang_args.append(a)

# bindgen assumes that C++ headers will be called .hpp. We want to
# ensure that anything Meson considers a C++ header is treated as one.
if language == 'cpp':
clang_args.extend(['-x', 'c++'])

Expand Down
19 changes: 19 additions & 0 deletions test cases/rust/12 bindgen/cpp/meson.build
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# SPDX-license-identifer: Apache-2.0
# Copyright © 2021-2023 Intel Corporation

fs = import('fs')

cpp_header = fs.copyfile('../src/header.hpp', 'cpp_header.h')

cpp_bind_override = rust.bindgen(
input : cpp_header,
output : 'generated-cpp.rs',
language : 'cpp',
)

cpp_exe2 = executable(
'cpp_exe2',
structured_sources(['../src/cpp.rs', cpp_bind_override]),
link_with : cpp_lib,
)
test('cpp-forced', cpp_exe2)

0 comments on commit 05d49c6

Please sign in to comment.