diff options
author | Faraaz Sareshwala <faraazs@gmail.com> | 2023-03-20 20:35:33 +0000 |
---|---|---|
committer | CQ Bot Account <pigweed-scoped@luci-project-accounts.iam.gserviceaccount.com> | 2023-03-20 20:35:33 +0000 |
commit | 2ccdca35626325202cfaaa160792444e951a5137 (patch) | |
tree | fe23f1ee66a70f24ff57ba7177bb8bf0a19adeec | |
parent | b1c96f03cd4b6c1f74c35b4ff1ddb4fa0cf5b5e7 (diff) | |
download | pigweed-2ccdca35626325202cfaaa160792444e951a5137.tar.gz |
pw_build: Add support for building rust executables and linked libraries
Change-Id: Icdd6418cf8f0713d3f93346af5a74ca43a1f2ad1
Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/129586
Commit-Queue: Faraaz Sareshwala <fsareshwala@google.com>
Reviewed-by: Alexei Frolov <frolv@google.com>
Reviewed-by: Erik Gilling <konkers@google.com>
-rw-r--r-- | pw_build/BUILD.gn | 12 | ||||
-rw-r--r-- | pw_build/cc_executable.gni | 15 | ||||
-rw-r--r-- | pw_build/cc_library.gni | 10 | ||||
-rw-r--r-- | pw_build/gn_internal/build_target.gni | 24 | ||||
-rw-r--r-- | pw_build/rust_executable.gni | 56 | ||||
-rw-r--r-- | pw_build/rust_library.gni | 65 | ||||
-rw-r--r-- | pw_build/target_types.gni | 2 | ||||
-rw-r--r-- | pw_rust/examples/host_executable/BUILD.gn | 31 | ||||
-rw-r--r-- | pw_rust/examples/host_executable/a/lib.rs | 22 | ||||
-rw-r--r-- | pw_rust/examples/host_executable/b/lib.rs | 20 | ||||
-rw-r--r-- | pw_rust/examples/host_executable/c/lib.rs | 19 | ||||
-rw-r--r-- | pw_rust/examples/host_executable/main.rs | 27 | ||||
-rw-r--r-- | pw_rust/examples/host_executable/other.rs | 18 |
13 files changed, 293 insertions, 28 deletions
diff --git a/pw_build/BUILD.gn b/pw_build/BUILD.gn index 51e0fcc3f..25f53433a 100644 --- a/pw_build/BUILD.gn +++ b/pw_build/BUILD.gn @@ -88,6 +88,18 @@ config("reduced_size") { } } +config("rust_edition_2015") { + rustflags = [ "--edition=2015" ] +} + +config("rust_edition_2018") { + rustflags = [ "--edition=2018" ] +} + +config("rust_edition_2021") { + rustflags = [ "--edition=2021" ] +} + config("strict_warnings") { cflags = [ "-Wall", diff --git a/pw_build/cc_executable.gni b/pw_build/cc_executable.gni index 230b127ee..fe10da498 100644 --- a/pw_build/cc_executable.gni +++ b/pw_build/cc_executable.gni @@ -24,21 +24,6 @@ import("$dir_pw_build/gn_internal/build_target.gni") # templates may need to create pw_source_set targets internally, and can't # import target_types.gni because it creates a circular import path. -declare_args() { - # The name of the GN target type used to build Pigweed executables. - # - # If this is a custom template, the .gni file containing the template must - # be imported at the top of the target configuration file to make it globally - # available. - pw_build_EXECUTABLE_TARGET_TYPE = "executable" - - # The path to the .gni file that defines pw_build_EXECUTABLE_TARGET_TYPE. - # - # If pw_build_EXECUTABLE_TARGET_TYPE is not the default of `executable`, this - # .gni file is imported to provide the template definition. - pw_build_EXECUTABLE_TARGET_TYPE_FILE = "" -} - # This template wraps a configurable target type specified by the current # toolchain to be used for all pw_executable targets. This allows projects to # stamp out unique build logic for each pw_executable target, such as generating diff --git a/pw_build/cc_library.gni b/pw_build/cc_library.gni index 81465c580..02fe625a9 100644 --- a/pw_build/cc_library.gni +++ b/pw_build/cc_library.gni @@ -23,16 +23,6 @@ import("$dir_pw_build/gn_internal/build_target.gni") # templates may need to create pw_source_set targets internally, and can't # import target_types.gni because it creates a circular import path. -declare_args() { - # Additional build targets to add as dependencies for pw_executable, - # pw_static_library, and pw_shared_library targets. The - # $dir_pw_build:link_deps target pulls in these libraries. - # - # pw_build_LINK_DEPS can be used to break circular dependencies for low-level - # libraries such as pw_assert. - pw_build_LINK_DEPS = [] -} - # These templates are wrappers for GN's built-in source_set, static_library, # and shared_library targets. # diff --git a/pw_build/gn_internal/build_target.gni b/pw_build/gn_internal/build_target.gni index dbdd149ec..149c87eac 100644 --- a/pw_build/gn_internal/build_target.gni +++ b/pw_build/gn_internal/build_target.gni @@ -14,6 +14,29 @@ import("//build_overrides/pigweed.gni") +declare_args() { + # Additional build targets to add as dependencies for pw_executable, + # pw_static_library, and pw_shared_library targets. The + # $dir_pw_build:link_deps target pulls in these libraries. + # + # pw_build_LINK_DEPS can be used to break circular dependencies for low-level + # libraries such as pw_assert. + pw_build_LINK_DEPS = [] + + # The name of the GN target type used to build Pigweed executables. + # + # If this is a custom template, the .gni file containing the template must + # be imported at the top of the target configuration file to make it globally + # available. + pw_build_EXECUTABLE_TARGET_TYPE = "executable" + + # The path to the .gni file that defines pw_build_EXECUTABLE_TARGET_TYPE. + # + # If pw_build_EXECUTABLE_TARGET_TYPE is not the default of `executable`, this + # .gni file is imported to provide the template definition. + pw_build_EXECUTABLE_TARGET_TYPE_FILE = "" +} + # This template is the underlying implementation that defines what makes # pw_source_set, pw_executable, pw_shared_library, and pw_static_library unique. # For more information, see the documentation at @@ -61,6 +84,7 @@ template("pw_internal_build_target") { _builtin_target_types = [ "executable", + "rust_library", "shared_library", "source_set", "static_library", diff --git a/pw_build/rust_executable.gni b/pw_build/rust_executable.gni new file mode 100644 index 000000000..cc564b65d --- /dev/null +++ b/pw_build/rust_executable.gni @@ -0,0 +1,56 @@ +# Copyright 2023 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_executable targets. This allows projects +# to stamp out unique build logic for each pw_rust_executable target. +# This wrapper is analogous to pw_executable with additions to support rust +# specific parameters such as rust edition and cargo config features. +# +# Default configs, default visibility, and link deps are applied to the target +# before forwarding to the underlying type as specified by +# pw_build_EXECUTABLE_TARGET_TYPE. +# +# For more information on the features provided by this template, see the full +# docs at https://pigweed.dev/pw_build/?highlight=pw_rust_executable. +template("pw_rust_executable") { + pw_internal_build_target(target_name) { + forward_variables_from(invoker, "*") + + _edition = "2021" + if (defined(invoker.edition)) { + _edition = invoker.edition + } + assert(_edition == "2015" || _edition == "2018" || _edition == "2021", + "edition ${_edition} is not supported") + + if (defined(invoker.configs)) { + configs = invoker.configs + } else { + configs = [] + } + configs += [ "$dir_pw_build:rust_edition_${_edition}" ] + + underlying_target_type = pw_build_EXECUTABLE_TARGET_TYPE + target_type_file = pw_build_EXECUTABLE_TARGET_TYPE_FILE + output_dir = "${target_out_dir}/bin" + add_global_link_deps = true + } +} diff --git a/pw_build/rust_library.gni b/pw_build/rust_library.gni new file mode 100644 index 000000000..370f47d53 --- /dev/null +++ b/pw_build/rust_library.gni @@ -0,0 +1,65 @@ +# Copyright 2023 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_library targets. A wrapper for GN's +# built-in rust_library target, it is analogous to pw_static_library with +# additions to support rust specific parameters such as rust edition and cargo +# config features. +# +# For more information on the features provided by this template, see the full +# docs at https://pigweed.dev/pw_build/?highlight=pw_rust_library +template("pw_rust_library") { + pw_internal_build_target(target_name) { + forward_variables_from(invoker, "*") + + crate_name = target_name + if (defined(name)) { + crate_name = name + } + + _edition = "2021" + if (defined(edition)) { + _edition = edition + } + assert(_edition == "2015" || _edition == "2018" || _edition == "2021", + "edition ${_edition} is not supported") + + if (!defined(configs)) { + configs = [] + } + configs += [ "$dir_pw_build:rust_edition_${_edition}" ] + + if (!defined(rustflags)) { + rustflags = [] + } + if (defined(features)) { + foreach(i, features) { + rustflags += [ "--cfg=feature=\"${i}\"" ] + } + } + + underlying_target_type = "rust_library" + crate_name = string_replace(crate_name, "-", "_") + output_name = crate_name + output_dir = "${target_out_dir}/lib" + add_global_link_deps = true + } +} diff --git a/pw_build/target_types.gni b/pw_build/target_types.gni index afb03809d..3803c7194 100644 --- a/pw_build/target_types.gni +++ b/pw_build/target_types.gni @@ -16,3 +16,5 @@ import("//build_overrides/pigweed.gni") import("$dir_pw_build/cc_executable.gni") import("$dir_pw_build/cc_library.gni") +import("$dir_pw_build/rust_executable.gni") +import("$dir_pw_build/rust_library.gni") diff --git a/pw_rust/examples/host_executable/BUILD.gn b/pw_rust/examples/host_executable/BUILD.gn index 99013eccd..fca1f74e1 100644 --- a/pw_rust/examples/host_executable/BUILD.gn +++ b/pw_rust/examples/host_executable/BUILD.gn @@ -16,6 +16,33 @@ import("//build_overrides/pigweed.gni") import("$dir_pw_build/target_types.gni") -pw_executable("hello") { - sources = [ "main.rs" ] +pw_rust_executable("hello") { + sources = [ + "main.rs", + "other.rs", + ] + + deps = [ + ":a", + ":c", + ] +} + +# The dep chain hello->a->b will exercise the functionality of both direct and +# transitive deps for A +pw_rust_library("a") { + crate_root = "a/lib.rs" + sources = [ "a/lib.rs" ] + deps = [ ":b" ] +} + +pw_rust_library("b") { + crate_root = "b/lib.rs" + sources = [ "b/lib.rs" ] + deps = [ ":c" ] +} + +pw_rust_library("c") { + crate_root = "c/lib.rs" + sources = [ "c/lib.rs" ] } diff --git a/pw_rust/examples/host_executable/a/lib.rs b/pw_rust/examples/host_executable/a/lib.rs new file mode 100644 index 000000000..e49ddb40a --- /dev/null +++ b/pw_rust/examples/host_executable/a/lib.rs @@ -0,0 +1,22 @@ +// Copyright 2023 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. + +#![warn(clippy::all)] + +use b::RequiredB; + +#[derive(Copy, Clone, Default)] +pub struct RequiredA { + pub required_b: RequiredB, +} diff --git a/pw_rust/examples/host_executable/b/lib.rs b/pw_rust/examples/host_executable/b/lib.rs new file mode 100644 index 000000000..6e32a1425 --- /dev/null +++ b/pw_rust/examples/host_executable/b/lib.rs @@ -0,0 +1,20 @@ +// Copyright 2023 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. + +#![warn(clippy::all)] + +#[derive(Copy, Clone, Debug, Default)] +pub struct RequiredB { + pub value: i32, +} diff --git a/pw_rust/examples/host_executable/c/lib.rs b/pw_rust/examples/host_executable/c/lib.rs new file mode 100644 index 000000000..3c2cbff78 --- /dev/null +++ b/pw_rust/examples/host_executable/c/lib.rs @@ -0,0 +1,19 @@ +// Copyright 2023 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. + +#![warn(clippy::all)] + +pub fn value() -> i32 { + 1 +} diff --git a/pw_rust/examples/host_executable/main.rs b/pw_rust/examples/host_executable/main.rs index b78a75216..79d72df70 100644 --- a/pw_rust/examples/host_executable/main.rs +++ b/pw_rust/examples/host_executable/main.rs @@ -1,4 +1,4 @@ -// Copyright 2022 The Pigweed Authors +// Copyright 2023 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 @@ -12,6 +12,31 @@ // License for the specific language governing permissions and limitations under // the License. +#![warn(clippy::all)] + +mod other; + fn main() { println!("Hello, Pigweed!"); + + // ensure we can run code from other modules in the main crate + println!("{}", other::foo()); + + // ensure we can run code from dependent libraries + println!("{}", a::RequiredA::default().required_b.value); + println!("{}", c::value()); +} + +#[cfg(test)] +mod tests { + #[test] + fn test_simple() { + let x = 3.14; + assert!(x > 0.0); + } + + #[test] + fn test_other_module() { + assert!(a::RequiredA::default().required_b.value == 0); + } } diff --git a/pw_rust/examples/host_executable/other.rs b/pw_rust/examples/host_executable/other.rs new file mode 100644 index 000000000..fd571096f --- /dev/null +++ b/pw_rust/examples/host_executable/other.rs @@ -0,0 +1,18 @@ +// Copyright 2023 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. + +#[allow(unused)] +pub fn foo() -> i32 { + return 42; +} |