pw_build: pw_mirror_tree target
The pw_mirror_tree target makes source files available in the output
directory. This can be used to efficiently add a prefix to a source
tree.
Change-Id: I9f5458e2b786ab8ca0132b6e85f4df57a1c267a5
Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/34980
Commit-Queue: Wyatt Hepler <hepler@google.com>
Pigweed-Auto-Submit: Wyatt Hepler <hepler@google.com>
Reviewed-by: Alexei Frolov <frolv@google.com>
diff --git a/pw_build/mirror_tree.gni b/pw_build/mirror_tree.gni
new file mode 100644
index 0000000..0551d58
--- /dev/null
+++ b/pw_build/mirror_tree.gni
@@ -0,0 +1,61 @@
+# Copyright 2021 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")
+
+# Mirrors a directory structure to the output directory.
+#
+# This is similar to a GN copy target, with some differences:
+#
+# - The outputs list is generated by the template based on the source_root and
+# directory arguments, rather than using source expansion.
+# - The source_root argument can be used to trim prefixes from source files.
+# - pw_mirror_tree uses hard links instead of copies for efficiency.
+#
+# Args:
+#
+# directory: Output directory for the files.
+# sources: List of files to mirror to the output directory.
+# source_root: Root path for sources; defaults to ".".
+#
+template("pw_mirror_tree") {
+ assert(defined(invoker.sources) && invoker.sources != [],
+ "At least one source file must be provided in 'sources'")
+ assert(defined(invoker.directory) && invoker.directory != "",
+ "The output path must be specified as 'directory'")
+
+ if (defined(invoker.source_root)) {
+ _root = invoker.source_root
+ } else {
+ _root = "."
+ }
+
+ action(target_name) {
+ script = "$dir_pw_build/py/pw_build/mirror_tree.py"
+
+ outputs = []
+ foreach(path, rebase_path(invoker.sources, _root)) {
+ outputs += [ "${invoker.directory}/$path" ]
+ }
+
+ args = [
+ "--source-root",
+ rebase_path(_root),
+ "--directory",
+ rebase_path(invoker.directory),
+ ] + rebase_path(invoker.sources)
+
+ forward_variables_from(invoker, "*", [ "script" ])
+ }
+}