xref: /aosp_15_r20/external/pigweed/pw_tokenizer/database.gni (revision 61c4878ac05f98d0ceed94b57d316916de578985)
1# Copyright 2020 The Pigweed Authors
2#
3# Licensed under the Apache License, Version 2.0 (the "License"); you may not
4# use this file except in compliance with the License. You may obtain a copy of
5# the License at
6#
7#     https://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12# License for the specific language governing permissions and limitations under
13# the License.
14
15import("//build_overrides/pigweed.gni")
16
17import("$dir_pw_build/python_action.gni")
18
19# Updates a tokenized string database in the source tree with artifacts from one
20# or more targets. Other database files may also be used.
21#
22# The database file must exist. A CSV or binary database can be created with the
23# pw/pw_tokenizer/database.py tool. An empty CSV database file can be also
24# created as a starting point.
25#
26# Args:
27#   database: if updating a database, path to an existing database in the source
28#       tree; optional if creating a database, but may provide an output
29#       directory path to override the default of
30#       "$target_gen_dir/$target_name.[csv/binary]"
31#   create: if specified, create a database instead of updating one; 'create'
32#       must be set to one of the supported database types: "csv" or "binary"
33#   targets: GN targets (executables or libraries) from which to add tokens;
34#       these targets are added to deps
35#   optional_targets: GN targets from which to add tokens, if the output files
36#       already exist; these targets are NOT added to 'deps'
37#   optional_paths: Paths or globs to files in the output directory from which
38#       to add tokens. For example, "$root_build_dir/**/*.elf" finds all ELF
39#       files in the output directory; this does NOT add anything to 'deps': add
40#       targets to 'deps' or 'targets' if they must be built first
41#   input_databases: paths to other database files from which to add tokens
42#   deps: GN targets to build prior to generating the database; artifacts from
43#       these targets are NOT implicitly used for database generation
44#   domain: if provided, extract strings from tokenization domains matching this
45#       regular expression
46#
47template("pw_tokenizer_database") {
48  assert(defined(invoker.database) || defined(invoker.create),
49         "pw_tokenizer_database requires a 'database' variable, unless " +
50             "'create' is specified")
51
52  if (defined(invoker.create)) {
53    assert(invoker.create == "csv" || invoker.create == "binary",
54           "If provided, 'create' must be \"csv\" or \"binary\"")
55    _create = invoker.create
56  } else {
57    _create = ""
58  }
59
60  if (defined(invoker.database)) {
61    _database = invoker.database
62  } else {
63    _database = "$target_gen_dir/$target_name.${invoker.create}"
64  }
65  if (defined(invoker.targets)) {
66    _targets = invoker.targets
67  } else {
68    _targets = []
69  }
70
71  if (defined(invoker.optional_targets)) {
72    _optional_targets = invoker.optional_targets
73  } else {
74    _optional_targets = []
75  }
76
77  if (defined(invoker.input_databases)) {
78    _input_databases = invoker.input_databases
79  } else {
80    _input_databases = []
81  }
82
83  if (defined(invoker.domain)) {
84    _domain = "#" + invoker.domain
85  } else {
86    _domain = ""
87  }
88
89  if (_targets == [] && _optional_targets == []) {
90    # If no targets were specified, the domain will not be used, which is OK.
91    not_needed([ "_domain" ])
92  }
93
94  pw_python_action(target_name) {
95    script = "$dir_pw_tokenizer/py/pw_tokenizer/database.py"
96
97    inputs = _input_databases
98
99    if (_create == "") {
100      # Restrict parallelism for updating this database file to one thread. This
101      # makes it safe to update it from multiple toolchains.
102      pool = "$dir_pw_tokenizer/pool:database($default_toolchain)"
103      args = [ "add" ]
104      if (defined(invoker.commit)) {
105        args += [
106          "--discard-temporary",
107          invoker.commit,
108        ]
109      }
110      inputs += [ _database ]
111      stamp = true
112    } else {
113      args = [
114        "create",
115        "--force",
116        "--type",
117        _create,
118      ]
119      outputs = [ _database ]
120    }
121
122    args += [
123      "--database",
124      rebase_path(_database, root_build_dir),
125    ]
126    args += rebase_path(_input_databases, root_build_dir)
127
128    foreach(target, _targets) {
129      args += [ "<TARGET_FILE($target)>$_domain" ]
130    }
131
132    # For optional targets, the build outputs may not exist, since they aren't
133    # added to deps. Use TARGET_FILE_IF_EXISTS to handle this.
134    foreach(target, _optional_targets) {
135      args += [ "<TARGET_FILE_IF_EXISTS($target)>$_domain" ]
136    }
137
138    if (defined(invoker.optional_paths)) {
139      _paths = rebase_path(invoker.optional_paths, root_build_dir)
140      assert(filter_include(_paths, [ "../*" ]) == [],
141             "Paths in 'optional_paths' must be in the out directory. Use " +
142                 "'input_databases' for files in the source tree.")
143      args += _paths
144    }
145
146    deps = _targets
147
148    if (defined(invoker.deps)) {
149      deps += invoker.deps
150    }
151  }
152}
153