Skip to content

Commit

Permalink
pw_build: Add pw_rust_bindgen
Browse files Browse the repository at this point in the history
Bug: 365470545

Implement pw_rust_bindgen. A simple test case for generating C bindings
is added.

Change-Id: I7332bc78ef8a1af790ff6de2d8205f2447c2817c
Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/234671
Lint: Lint 🤖 <[email protected]>
Docs-Not-Needed: Jiacheng Lu <[email protected]>
Presubmit-Verified: CQ Bot Account <[email protected]>
Commit-Queue: Jiacheng Lu <[email protected]>
Reviewed-by: Erik Gilling <[email protected]>
  • Loading branch information
Jason0214 authored and CQ Bot Account committed Sep 26, 2024
1 parent 819dd2c commit 1f2a0fe
Show file tree
Hide file tree
Showing 10 changed files with 268 additions and 0 deletions.
1 change: 1 addition & 0 deletions BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -512,6 +512,7 @@ group("host_tools") {

if (pw_rust_ENABLE_EXPERIMENTAL_BUILD) {
deps += [ "$dir_pw_rust/examples/basic_executable:basic_executable($dir_pigweed/targets/host:host_clang_debug)" ]
deps += [ "$dir_pw_rust/examples/bindgen:test_add($dir_pigweed/targets/host:host_clang_debug)" ]
}
}

Expand Down
3 changes: 3 additions & 0 deletions pw_build/exec.gni
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ import("python_action.gni")
#
# args: Optional list of arguments to the program.
#
# depfile: Optional depfile of the underlying target.
#
# deps: Dependencies for this target.
#
# public_deps: Public dependencies for this target. In addition to outputs from
Expand Down Expand Up @@ -138,6 +140,7 @@ template("pw_exec") {

forward_variables_from(invoker,
[
"depfile",
"deps",
"inputs",
"pool",
Expand Down
54 changes: 54 additions & 0 deletions pw_build/rust_bindgen.gni
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# Copyright 2024 The Pigweed Authors
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
# use this file except in compliance with the License. You may obtain a copy of
# the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations under
# the License.

import("//build_overrides/pigweed.gni")

import("$dir_pw_build/gn_internal/build_target.gni")

# Note: In general, prefer to import target_types.gni rather than this file.
#
# This template wraps a configurable target type specified by the current
# toolchain to be used for all pw_rust_bindgen targets. It wraps a creation of
# an action target `rust_bindgen_action.gni`.
#
# Args:
# deps: Dependencies for this target.
#
# public_deps: Public dependencies for this target. In addition to outputs from
# this target, outputs generated by public dependencies can be used as inputs
# from targets that depend on this one. This is not the case for private
# deps.
#
# visibility: GN visibility to apply to the underlying target.
#
# header: C header file for generating bindings.
#
# outputs: Output path of the generated rust bindings source file.
#
# flags: Additional flags passed to bindgen executable.
#
# For more information on the features provided by this template, see the full
# docs at https://pigweed.dev/pw_build/?highlight=pw_rust_bindgen

_action_gni_path = get_path_info("rust_bindgen_action.gni", "abspath")

template("pw_rust_bindgen") {
pw_internal_build_target(target_name) {
forward_variables_from(invoker, "*")

target_type_file = _action_gni_path
underlying_target_type = "rust_bindgen_action"
add_global_link_deps = false
}
}
65 changes: 65 additions & 0 deletions pw_build/rust_bindgen_action.gni
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# Copyright 2024 The Pigweed Authors
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
# use this file except in compliance with the License. You may obtain a copy of
# the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations under
# the License.
import("//build_overrides/pigweed.gni")
import("//build_overrides/pigweed_environment.gni")
import("$dir_pw_build/exec.gni")

_bindgen_exe_path =
rebase_path(pw_env_setup_CIPD_PIGWEED + "/rust_bindgen/bindgen")

# Bindgen is not part of GN tools, so use pw_exec to run it.
template("rust_bindgen_action") {
pw_exec(target_name) {
forward_variables_from(invoker,
[
"deps",
"public_deps",
"visibility",
])
not_needed(invoker, "*")

output_gen_rs = "$target_gen_dir/${target_name}.rs"

program = _bindgen_exe_path
header = rebase_path(invoker.header, root_build_dir)

outputs = [ output_gen_rs ]
depfile = "$target_out_dir/${target_name}.d"
args = [
"--depfile",
rebase_path(depfile, root_build_dir),
"--output",
rebase_path(output_gen_rs, root_build_dir),
]

args += [
# Do not search for system default include paths.
"--no-include-path-detection",
]
if (defined(invoker.flags)) {
foreach(flag, invoker.flags) {
args += [ flag ]
}
}

args += [
header,
"--",
"{{defines}}",
"{{include_dirs}}",
"{{cflags}}",
"{{cflags_c}}",
]
}
}
1 change: 1 addition & 0 deletions pw_build/target_types.gni
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import("//build_overrides/pigweed.gni")

import("$dir_pw_build/cc_executable.gni")
import("$dir_pw_build/cc_library.gni")
import("$dir_pw_build/rust_bindgen.gni")
import("$dir_pw_build/rust_executable.gni")
import("$dir_pw_build/rust_library.gni")
import("$dir_pw_build/rust_proc_macro.gni")
Expand Down
23 changes: 23 additions & 0 deletions pw_rust/examples/bindgen/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Copyright 2024 The Pigweed Authors
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
# use this file except in compliance with the License. You may obtain a copy of
# the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations under
# the License.
package(default_visibility = ["//:__subpackages__"])

# Not used. Defined to workaround "source_is_in_bazel_build" linter.
filegroup(
name = "c_add",
srcs = [
"add.cc",
"add.h",
],
)
43 changes: 43 additions & 0 deletions pw_rust/examples/bindgen/BUILD.gn
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Copyright 2024 The Pigweed Authors
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
# use this file except in compliance with the License. You may obtain a copy of
# the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations under
# the License.

import("//build_overrides/pigweed.gni")

import("$dir_pw_build/target_types.gni")

pw_source_set("c_add") {
public = [ "add.h" ]
sources = [ "add.cc" ]
public_deps = [ "$dir_pw_preprocessor" ]
}

pw_rust_bindgen("c_add_bindgen") {
header = "add.h"
flags = [
"--use-core",
"--allowlist-item",
"add",
]
deps = [ "$dir_pw_preprocessor" ]
}

pw_rust_test("test_add") {
bindgen_output = get_target_outputs(":c_add_bindgen")
rustenv = [ "BINDGEN_RS_FILE=" + rebase_path(bindgen_output[0]) ]
sources = [ "src/lib.rs" ]
deps = [
":c_add",
":c_add_bindgen",
]
}
21 changes: 21 additions & 0 deletions pw_rust/examples/bindgen/add.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Copyright 2024 The Pigweed Authors
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy of
// the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations under
// the License.

#include "add.h"

#include <stdint.h>

#include "pw_preprocessor/util.h"

PW_EXTERN_C int32_t add(int32_t a, int32_t b) { return a + b; }
20 changes: 20 additions & 0 deletions pw_rust/examples/bindgen/add.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Copyright 2024 The Pigweed Authors
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy of
// the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations under
// the License.

#pragma once
#include <stdint.h>

#include "pw_preprocessor/util.h"

PW_EXTERN_C int32_t add(int32_t a, int32_t b);
37 changes: 37 additions & 0 deletions pw_rust/examples/bindgen/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// Copyright 2024 The Pigweed Authors
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy of
// the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations under
// the License.

#![no_std]

include!(env!("BINDGEN_RS_FILE"));

fn extern_c_add(a: i32, b: i32) -> i32 {
return unsafe { add(a, b) };
}

#[cfg(test)]
mod tests {
use crate::extern_c_add;

fn rust_add(a: i32, b: i32) -> i32 {
return a + b;
}

#[test]
fn test_extern_add_works() {
let a = -3;
let b = 1;
assert!(extern_c_add(a, b) == rust_add(a, b));
}
}

0 comments on commit 1f2a0fe

Please sign in to comment.