modules/rust: Add support for dependencies in bindgen

This is needed for cases where we need external C headers, which are
passed to clang.
pull/11024/head
Dylan Baker 2 years ago
parent 24b0024065
commit d49e6bc038
  1. 3
      docs/markdown/Rust-module.md
  2. 5
      docs/markdown/snippets/rust_bindgen_deps.md
  3. 19
      mesonbuild/modules/rust.py
  4. 5
      test cases/rust/12 bindgen/dependencies/clib2.c
  5. 8
      test cases/rust/12 bindgen/dependencies/external_dep.h
  6. 6
      test cases/rust/12 bindgen/dependencies/internal_dep.h
  7. 16
      test cases/rust/12 bindgen/dependencies/internal_main.rs
  8. 43
      test cases/rust/12 bindgen/dependencies/meson.build
  9. 3
      test cases/rust/12 bindgen/meson.build

@ -35,7 +35,7 @@ that automatically.
Additional, test only dependencies may be passed via the dependencies
argument.
### bindgen(*, input: string | BuildTarget | [](string | BuildTarget), output: string, include_directories: [](include_directories | string), c_args: []string, args: []string)
### bindgen(*, input: string | BuildTarget | [](string | BuildTarget), output: string, include_directories: [](include_directories | string), c_args: []string, args: []string, dependencies: []Dependency)
This function wraps bindgen to simplify creating rust bindings around C
libraries. This has two advantages over hand-rolling ones own with a
@ -54,6 +54,7 @@ It takes the following keyword arguments
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
- 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*)
```meson
rust = import('unstable-rust')

@ -0,0 +1,5 @@
## rust.bindgen accepts a dependency argument
The `bindgen` method of the `rust` module now accepts a dependencies argument.
Any include paths in these dependencies will be passed to the underlying call to
`clang`, and the call to `bindgen` will correctly depend on any generatd sources.

@ -45,6 +45,7 @@ if T.TYPE_CHECKING:
include_directories: T.List[IncludeDirs]
input: T.List[SourceInputs]
output: str
dependencies: T.List[T.Union[Dependency, ExternalLibrary]]
class RustModule(ExtensionModule):
@ -173,6 +174,7 @@ class RustModule(ExtensionModule):
),
INCLUDE_DIRECTORIES.evolve(feature_validator=include_dir_string_new),
OUTPUT_KW,
DEPENDENCIES_KW.evolve(since='1.0.0'),
)
def bindgen(self, state: ModuleState, args: T.List, kwargs: FuncBindgen) -> ModuleReturnValue:
"""Wrapper around bindgen to simplify it's use.
@ -191,12 +193,23 @@ class RustModule(ExtensionModule):
else:
depends.append(d)
inc_strs: T.List[str] = []
clang_args: T.List[str] = []
for i in state.process_include_dirs(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(
clang_args.extend([f'-I{x}' for x in i.to_string_list(
state.environment.get_source_dir(), state.environment.get_build_dir())])
for de in kwargs['dependencies']:
for i in de.get_include_dirs():
clang_args.extend([f'-I{x}' for x in i.to_string_list(
state.environment.get_source_dir(), state.environment.get_build_dir())])
clang_args.extend(de.get_all_compile_args())
for s in de.get_sources():
if isinstance(s, File):
depend_files.append(s)
elif isinstance(s, CustomTarget):
depends.append(s)
if self._bindgen_bin is None:
self._bindgen_bin = state.find_program('bindgen')
@ -213,7 +226,7 @@ class RustModule(ExtensionModule):
'@INPUT@', '--output',
os.path.join(state.environment.build_dir, '@OUTPUT@')
] + \
kwargs['args'] + ['--'] + kwargs['c_args'] + inc_strs + \
kwargs['args'] + ['--'] + kwargs['c_args'] + clang_args + \
['-MD', '-MQ', '@INPUT@', '-MF', '@DEPFILE@']
target = CustomTarget(

@ -0,0 +1,5 @@
#include "internal_dep.h"
int64_t add64(const int64_t first, const int64_t second) {
return first + second;
}

@ -0,0 +1,8 @@
/* SPDX-License-Identifer: Apache-2.0 */
/* Copyright © 2022 Intel Corporation */
#include <zlib.h>
struct External {
z_stream * stream;
};

@ -0,0 +1,6 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright © 2022 Intel Corporation
#include "gen.h"
int64_t add64(const int64_t, const int64_t);

@ -0,0 +1,16 @@
// SPDX-license-identifer: Apache-2.0
// Copyright © 2021 Intel Corporation
#![allow(non_upper_case_globals)]
#![allow(non_camel_case_types)]
#![allow(non_snake_case)]
include!("internal_dep.rs");
use std::convert::TryInto;
fn main() {
unsafe {
std::process::exit(add64(0, 0).try_into().unwrap_or(5));
};
}

@ -0,0 +1,43 @@
# SPDX-License-Identifier: Apache-2.0
# Copyright © 2022 Intel Corporation
dep_zlib = dependency('zlib', required : false, disabler : true)
external_dep_rs = rust.bindgen(
input : 'external_dep.h',
output : 'external_dep.rs',
dependencies : dep_zlib
)
external_dep = static_library(
'external_dep',
[external_dep_rs],
dependencies : dep_zlib.partial_dependency(links : true),
)
rust.test('external dep', external_dep)
int_dep = declare_dependency(
sources : [gen_h, gen2_h],
include_directories : include_directories('..'),
)
internal_dep_rs = rust.bindgen(
input : 'internal_dep.h',
output : 'internal_dep.rs',
dependencies : int_dep,
)
c_lib2 = static_library(
'clib2',
'clib2.c',
dependencies : int_dep,
)
rust_bin_int_dep = executable(
'rust_bin_int_dep',
structured_sources(['internal_main.rs', internal_dep_rs]),
link_with : [c_lib, c_lib2],
)
test('generated header dependency', rust_bin_int_dep)

@ -1,5 +1,5 @@
# SPDX-license-identifer: Apache-2.0
# Copyright © 2021 Intel Corporation
# Copyright © 2021-2022 Intel Corporation
project('rustmod bindgen', ['c', 'rust'], meson_version : '>= 0.63')
@ -80,3 +80,4 @@ rust_bin2 = executable(
test('generated header', rust_bin2)
subdir('sub')
subdir('dependencies')

Loading…
Cancel
Save