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