summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/markdown/snippets/rust-bindgen-cpp.md6
-rw-r--r--mesonbuild/modules/rust.py25
-rw-r--r--test cases/rust/12 bindgen/meson.build16
-rw-r--r--test cases/rust/12 bindgen/src/cpp.rs19
-rw-r--r--test cases/rust/12 bindgen/src/header.hpp9
-rw-r--r--test cases/rust/12 bindgen/src/impl.cpp7
6 files changed, 73 insertions, 9 deletions
diff --git a/docs/markdown/snippets/rust-bindgen-cpp.md b/docs/markdown/snippets/rust-bindgen-cpp.md
new file mode 100644
index 000000000..e12e0f966
--- /dev/null
+++ b/docs/markdown/snippets/rust-bindgen-cpp.md
@@ -0,0 +1,6 @@
+## Bindgen will now use Meson's hueristic for what is a C++ header
+
+Bindgen natively assumes that a file with the extension `.cpp` is a C++ header,
+but that everything else is a C header. Meson has a whole list of extensions it
+considers to be C++, and now will automatically look for those extensions and
+set bindgen to treat those as C++
diff --git a/mesonbuild/modules/rust.py b/mesonbuild/modules/rust.py
index 96e1e6f16..caa1be296 100644
--- a/mesonbuild/modules/rust.py
+++ b/mesonbuild/modules/rust.py
@@ -12,7 +12,7 @@ from . import ExtensionModule, ModuleReturnValue, ModuleInfo
from .. import mlog
from ..build import (BothLibraries, BuildTarget, CustomTargetIndex, Executable, ExtractedObjects, GeneratedList,
CustomTarget, InvalidArguments, Jar, StructuredSources, SharedLibrary)
-from ..compilers.compilers import are_asserts_disabled
+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 ..interpreterbase import ContainerTypeInfo, InterpreterException, KwargInfo, typed_kwargs, typed_pos_args, noPosargs, permittedKwargs
from ..mesonlib import File
@@ -230,13 +230,6 @@ class RustModule(ExtensionModule):
elif isinstance(s, CustomTarget):
depends.append(s)
- # We only want include directories and defines, other things may not be valid
- cargs = state.get_option('args', state.subproject, lang='c')
- assert isinstance(cargs, list), 'for mypy'
- for a in itertools.chain(state.global_args.get('c', []), state.project_args.get('c', []), cargs):
- if a.startswith(('-I', '/I', '-D', '/D', '-U', '/U')):
- clang_args.append(a)
-
if self._bindgen_bin is None:
self._bindgen_bin = state.find_program('bindgen')
@@ -248,6 +241,22 @@ class RustModule(ExtensionModule):
else:
name = header.get_outputs()[0]
+ # 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'
+
+ # We only want include directories and defines, other things may not be valid
+ cargs = state.get_option('args', state.subproject, lang=language)
+ assert isinstance(cargs, list), 'for mypy'
+ for a in itertools.chain(state.global_args.get(language, []), state.project_args.get(language, []), cargs):
+ 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++'])
+
cmd = self._bindgen_bin.get_command() + \
[
'@INPUT@', '--output',
diff --git a/test cases/rust/12 bindgen/meson.build b/test cases/rust/12 bindgen/meson.build
index e36e9e2d1..840a8afab 100644
--- a/test cases/rust/12 bindgen/meson.build
+++ b/test cases/rust/12 bindgen/meson.build
@@ -1,7 +1,7 @@
# SPDX-license-identifer: Apache-2.0
# Copyright © 2021-2022 Intel Corporation
-project('rustmod bindgen', ['c', 'rust'], meson_version : '>= 0.63')
+project('rustmod bindgen', ['c', 'cpp', 'rust'], meson_version : '>= 0.63')
prog_bindgen = find_program('bindgen', required : false)
if not prog_bindgen.found()
@@ -107,3 +107,17 @@ gp_exe = executable(
)
test('global and project arguments', gp_exe)
+
+cpp_lib = static_library('cpplib', 'src/impl.cpp')
+
+cpp_bind = rust.bindgen(
+ input : 'src/header.hpp',
+ output : 'generated-cpp.rs',
+)
+
+cpp_exe = executable(
+ 'cpp_exe',
+ structured_sources(['src/cpp.rs', cpp_bind]),
+ link_with : cpp_lib,
+)
+test('cpp', cpp_exe)
diff --git a/test cases/rust/12 bindgen/src/cpp.rs b/test cases/rust/12 bindgen/src/cpp.rs
new file mode 100644
index 000000000..51a594cc4
--- /dev/null
+++ b/test cases/rust/12 bindgen/src/cpp.rs
@@ -0,0 +1,19 @@
+// SPDX-license-identifer: Apache-2.0
+// Copyright © 2023 Intel Corporation
+
+#![allow(non_upper_case_globals)]
+#![allow(non_camel_case_types)]
+#![allow(non_snake_case)]
+
+include!("generated-cpp.rs");
+
+fn main() {
+ let mut instance = std::mem::MaybeUninit::<MyClass>::uninit();
+ let val: i32;
+ unsafe {
+ MyClass_MyClass(instance.as_mut_ptr());
+ val = instance.assume_init_mut().method();
+ }
+ let success = val == 7;
+ std::process::exit(!success as i32);
+}
diff --git a/test cases/rust/12 bindgen/src/header.hpp b/test cases/rust/12 bindgen/src/header.hpp
new file mode 100644
index 000000000..3f01c5f7d
--- /dev/null
+++ b/test cases/rust/12 bindgen/src/header.hpp
@@ -0,0 +1,9 @@
+#pragma once
+
+class MyClass {
+ public:
+ MyClass();
+ int method() const;
+ private:
+ int val;
+};
diff --git a/test cases/rust/12 bindgen/src/impl.cpp b/test cases/rust/12 bindgen/src/impl.cpp
new file mode 100644
index 000000000..39c8f2ebe
--- /dev/null
+++ b/test cases/rust/12 bindgen/src/impl.cpp
@@ -0,0 +1,7 @@
+#include "header.hpp"
+
+MyClass::MyClass() : val{7} {};
+
+int MyClass::method() const {
+ return val;
+}