• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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    # Restrict parallelism for updating this database file to one thread. This
98    # makes it safe to update it from multiple toolchains.
99    pool = "$dir_pw_tokenizer/pool:database($default_toolchain)"
100
101    inputs = _input_databases
102
103    if (_create == "") {
104      args = [ "add" ]
105      inputs += [ _database ]
106      stamp = true
107    } else {
108      args = [
109        "create",
110        "--force",
111        "--type",
112        _create,
113      ]
114      outputs = [ _database ]
115    }
116
117    args += [
118      "--database",
119      rebase_path(_database, root_build_dir),
120    ]
121    args += rebase_path(_input_databases, root_build_dir)
122
123    foreach(target, _targets) {
124      args += [ "<TARGET_FILE($target)>$_domain" ]
125    }
126
127    # For optional targets, the build outputs may not exist, since they aren't
128    # added to deps. Use TARGET_FILE_IF_EXISTS to handle this.
129    foreach(target, _optional_targets) {
130      args += [ "<TARGET_FILE_IF_EXISTS($target)>$_domain" ]
131    }
132
133    if (defined(invoker.optional_paths)) {
134      _paths = rebase_path(invoker.optional_paths, root_build_dir)
135      assert(filter_include(_paths, [ "../*" ]) == [],
136             "Paths in 'optional_paths' must be in the out directory. Use " +
137                 "'input_databases' for files in the source tree.")
138      args += _paths
139    }
140
141    deps = _targets
142
143    if (defined(invoker.deps)) {
144      deps += invoker.deps
145    }
146  }
147}
148