|  | # Copyright 2021 The Fuchsia Authors. All rights reserved. | 
|  | # Use of this source code is governed by a BSD-style license that can be | 
|  | # found in the LICENSE file. | 
|  |  | 
|  | # Copies a directory preserving its structure. | 
|  | # | 
|  | # NOTE: Don't use this tempalte if GN's built-in `copy` can be used instead, see | 
|  | # example below, also `gn help copy`. Usually the reason to use this template is | 
|  | # the content of the directory cannot be determined in BUILD.gn. Because of | 
|  | # this, it is impossible for this template to guarantee incremental correctness. | 
|  | # For example, changes to files in a directory may not cause its mtime to | 
|  | # change, so the build system won't rerun this action when building | 
|  | # incrementally. The `inputs` parameter is required to mitigate this problem, | 
|  | # but it provides no guarantees. See more details in https://fxbug.dev/73250. | 
|  | # | 
|  | # Example: | 
|  | # | 
|  | # ``` | 
|  | # copy_tree("my_copy") { | 
|  | #   src_dir = "path/to/src/dir" | 
|  | #   dest_dir = "path/to/dest/dir" | 
|  | #   inputs = [ | 
|  | #     "version/of/src/dir", | 
|  | #   ] | 
|  | #   ignore_patterns = [ | 
|  | #     "*not_useful*", | 
|  | #     "*.to_ignore", | 
|  | #   ] | 
|  | # } | 
|  | # ``` | 
|  | # | 
|  | # Use `copy` if content of dir can be determined in BUILD.gn: | 
|  | # | 
|  | # ``` | 
|  | # copy("my_copy") { | 
|  | #   sources = [ | 
|  | #     "path/to/src/dir/file1", | 
|  | #     "path/to/src/dir/file2", | 
|  | #     "path/to/src/dir/file3", | 
|  | #   ] | 
|  | #   outputs = [ "path/to/dest/dir/{{source_file_part}}" ] | 
|  | # } | 
|  | # ``` | 
|  | # | 
|  | # Parameters | 
|  | # | 
|  | #   src_dir (required) | 
|  | #     Path to the directory to copy. | 
|  | #     Type: path | 
|  | # | 
|  | #   dest_dir (required) | 
|  | #     Path to copy the directory to. | 
|  | #     Type: path | 
|  | # | 
|  | #   inputs (optional) | 
|  | #     A list of files that changes when the content of the directory changes, so | 
|  | #     in incremental builds a rerun of this action can be correctly triggered. | 
|  | #     Type: list(path) | 
|  | #     Default: empty | 
|  | # | 
|  | #   ignore_patterns (optional) | 
|  | #     Glob-style patterns to ignore when copying. | 
|  | #     Type: list(string) | 
|  | #     Default: empty | 
|  | # | 
|  | #   deps | 
|  | #   testonly | 
|  | #   visibility | 
|  | template("copy_tree") { | 
|  | action(target_name) { | 
|  | # Not all inputs and outputs are listed by this action, so it is not | 
|  | # hermetic. This is usually the very reason a user would want this template | 
|  | # instead of, GN's built-in copy tool. | 
|  | hermetic_deps = false | 
|  |  | 
|  | forward_variables_from(invoker, | 
|  | [ | 
|  | "deps", | 
|  | "dest_dir", | 
|  | "ignore_patterns", | 
|  | "inputs", | 
|  | "src_dir", | 
|  | "testonly", | 
|  | "visibility", | 
|  | ]) | 
|  |  | 
|  | assert(defined(src_dir), "src_dir must be defined for ${target_name}") | 
|  | assert(defined(dest_dir), "dest_dir must be defined for ${target_name}") | 
|  |  | 
|  | if (defined(inputs)) { | 
|  | inputs += [ src_dir ] | 
|  | } else { | 
|  | inputs = [ src_dir ] | 
|  | } | 
|  |  | 
|  | script = "//build/copy_tree.py" | 
|  |  | 
|  | stamp_file = "${dest_dir}.stamp" | 
|  | args = [ | 
|  | rebase_path(src_dir, root_build_dir), | 
|  | rebase_path(dest_dir, root_build_dir), | 
|  | rebase_path(stamp_file, root_build_dir), | 
|  | ] | 
|  | if (defined(ignore_patterns)) { | 
|  | args += [ "--ignore_patterns" ] + ignore_patterns | 
|  | } | 
|  |  | 
|  | outputs = [ | 
|  | dest_dir, | 
|  | stamp_file, | 
|  | ] | 
|  | } | 
|  | } |