1 # Copyright 2014 The Chromium Authors. All rights reserved. 2 # Use of this source code is governed by a BSD-style license that can be 3 # found in the LICENSE file. 4 5 # Defines a static library corresponding to the output of schema compiler tools 6 # over a set of extensions API schemas (IDL or JSON format.) The library target 7 # has implicit hard dependencies on all schema files listed by the invoker and 8 # is itself a hard dependency. 9 # 10 # Invocations of this template may use the following variables: 11 # 12 # sources [required] A list of schema files to be compiled. 13 # 14 # root_namespace [required] 15 # A Python string substituion pattern used to generate the C++ 16 # namespace for each API. Use %(namespace)s to replace with the API 17 # namespace, like "toplevel::%(namespace)s_api". 18 # 19 # schema_include_rules [optional] 20 # A list of paths to include when searching for referenced objects, 21 # with the namespace separated by a :. 22 # Example: 23 # [ '/foo/bar:Foo::Bar::%(namespace)s' ] 24 # 25 # schemas [optional, default = false] 26 # Boolean indicating if the schema files should be generated. 27 # 28 # bundle [optional, default = false] 29 # Boolean indicating if the schema bundle files should be generated. 30 # 31 # bundle_registration [optional, default = false] 32 # Boolean indicating if the API registration bundle files should be generated. 33 # 34 # bundle_name [required if bundle or bundle_registrations]: 35 # A string to prepend to generated bundle class names, so that multiple 36 # bundle rules can be used without conflicting. Only used with one of 37 # the cpp-bundle generators. 38 # 39 # impl_dir [required if bundle_registration = true, otherwise unused] 40 # The path containing C++ implementations of API functions. This path is 41 # used as the root path when looking for {schema}/{schema}_api.h headers 42 # when generating API registration bundles. Such headers, if found, are 43 # automatically included by the generated code. 44 # 45 # uncompiled_sources [optional, only used when bundle = true or 46 # bundle_registration = true] 47 # A list of schema files which should not be compiled, but which should still 48 # be processed for API bundle generation. 49 # 50 # configs [optional] 51 # Extra configs to apply to the compile step. 52 # 53 # deps [optional] 54 # If any deps are specified they will be inherited by the static library 55 # target. 56 # 57 # generate_static_library [optional, defaults to false] 58 # Produces a static library instead of a source_set. 59 # 60 # The generated library target also inherits the visibility and output_name 61 # of its invoker. 62 63 template("json_schema_api") { 64 assert(defined(invoker.sources), 65 "\"sources\" must be defined for the $target_name template.") 66 assert(defined(invoker.root_namespace), 67 "\"root_namespace\" must be defined for the $target_name template.") 68 69 schemas = defined(invoker.schemas) && invoker.schemas 70 bundle = defined(invoker.bundle) && invoker.bundle 71 bundle_registration = 72 defined(invoker.bundle_registration) && invoker.bundle_registration 73 74 schema_include_rules = "" 75 if (defined(invoker.schema_include_rules)) { 76 schema_include_rules = invoker.schema_include_rules 77 } 78 79 # Keep a copy of the target_name here since it will be trampled 80 # in nested targets. 81 target_visibility = [ ":$target_name" ] 82 83 generated_config_name = target_name + "_generated_config" 84 config(generated_config_name) { 85 include_dirs = [ root_gen_dir ] 86 visibility = target_visibility 87 } 88 89 root_namespace = invoker.root_namespace 90 91 compiler_root = "//tools/json_schema_compiler" 92 compiler_script = "$compiler_root/compiler.py" 93 compiler_sources = [ 94 "$compiler_root/cc_generator.py", 95 "$compiler_root/code.py", 96 "$compiler_root/compiler.py", 97 "$compiler_root/cpp_bundle_generator.py", 98 "$compiler_root/cpp_generator.py", 99 "$compiler_root/cpp_type_generator.py", 100 "$compiler_root/cpp_util.py", 101 "$compiler_root/h_generator.py", 102 "$compiler_root/idl_schema.py", 103 "$compiler_root/model.py", 104 "$compiler_root/util_cc_helper.py", 105 ] 106 107 if (schemas) { 108 schema_generator_name = target_name + "_schema_generator" 109 action_foreach(schema_generator_name) { 110 script = compiler_script 111 sources = invoker.sources 112 inputs = compiler_sources 113 outputs = [ 114 "$target_gen_dir/{{source_name_part}}.cc", 115 "$target_gen_dir/{{source_name_part}}.h", 116 ] 117 args = [ 118 "{{source}}", 119 "--root=" + rebase_path("//", root_build_dir), 120 "--destdir=" + rebase_path(root_gen_dir, root_build_dir), 121 "--namespace=$root_namespace", 122 "--generator=cpp", 123 "--include-rules=$schema_include_rules", 124 ] 125 126 if (defined(invoker.visibility)) { 127 # If visibility is restricted, add our own target to it. 128 visibility = invoker.visibility + target_visibility 129 } 130 } 131 } 132 133 if (bundle) { 134 assert(defined(invoker.bundle_name), 135 "\"bundle_name\" must be defined for bundles") 136 137 uncompiled_sources = [] 138 if (defined(invoker.uncompiled_sources)) { 139 uncompiled_sources = invoker.uncompiled_sources 140 } 141 142 bundle_generator_schema_name = target_name + "_bundle_generator_schema" 143 action(bundle_generator_schema_name) { 144 script = compiler_script 145 inputs = compiler_sources + invoker.sources + uncompiled_sources 146 outputs = [ 147 "$target_gen_dir/generated_schemas.cc", 148 "$target_gen_dir/generated_schemas.h", 149 ] 150 args = [ 151 "--root=" + rebase_path("//", root_build_dir), 152 "--destdir=" + rebase_path(root_gen_dir, root_build_dir), 153 "--namespace=$root_namespace", 154 "--bundle-name=" + invoker.bundle_name, 155 "--generator=cpp-bundle-schema", 156 "--include-rules=$schema_include_rules", 157 ] + rebase_path(invoker.sources, root_build_dir) + 158 rebase_path(uncompiled_sources, root_build_dir) 159 } 160 } 161 162 if (bundle_registration) { 163 assert(defined(invoker.bundle_name), 164 "\"bundle_name\" must be defined for bundle registrations") 165 166 uncompiled_sources = [] 167 if (defined(invoker.uncompiled_sources)) { 168 uncompiled_sources = invoker.uncompiled_sources 169 } 170 171 assert(defined(invoker.impl_dir), 172 "\"impl_dir\" must be defined for the $target_name template.") 173 174 # Child directory inside the generated file tree. 175 gen_child_dir = rebase_path(invoker.impl_dir, "//") 176 177 bundle_generator_registration_name = 178 target_name + "_bundle_generator_registration" 179 action(bundle_generator_registration_name) { 180 script = compiler_script 181 inputs = compiler_sources + invoker.sources + uncompiled_sources 182 outputs = [ 183 "$root_gen_dir/$gen_child_dir/generated_api_registration.cc", 184 "$root_gen_dir/$gen_child_dir/generated_api_registration.h", 185 ] 186 args = [ 187 "--root=" + rebase_path("//", root_build_dir), 188 "--destdir=" + rebase_path(root_gen_dir, root_build_dir), 189 "--namespace=$root_namespace", 190 "--bundle-name=" + invoker.bundle_name, 191 "--generator=cpp-bundle-registration", 192 "--impl-dir=$gen_child_dir", 193 "--include-rules=$schema_include_rules", 194 ] + rebase_path(invoker.sources, root_build_dir) + 195 rebase_path(uncompiled_sources, root_build_dir) 196 } 197 } 198 199 # Compute the contents of the library/source set. 200 lib_sources = invoker.sources 201 lib_deps = [] 202 lib_public_deps = [] 203 lib_extra_configs = [] 204 if (defined(invoker.configs)) { 205 lib_extra_configs += invoker.configs 206 } 207 208 if (schemas) { 209 lib_sources += get_target_outputs(":$schema_generator_name") 210 lib_public_deps += [ ":$schema_generator_name" ] 211 lib_deps += [ "//tools/json_schema_compiler:generated_api_util" ] 212 lib_extra_configs += [ "//build/config/compiler:no_size_t_to_int_warning" ] 213 } 214 215 if (bundle) { 216 lib_sources += get_target_outputs(":$bundle_generator_schema_name") 217 lib_deps += [ ":$bundle_generator_schema_name" ] 218 } 219 220 if (bundle_registration) { 221 lib_sources += get_target_outputs(":$bundle_generator_registration_name") 222 lib_deps += [ ":$bundle_generator_registration_name" ] 223 } 224 225 if (defined(invoker.deps)) { 226 lib_deps += invoker.deps 227 } 228 229 # Generate either a static library or a source set. 230 if (defined(invoker.generate_static_library) && 231 invoker.generate_static_library) { 232 static_library(target_name) { 233 sources = lib_sources 234 deps = lib_deps 235 public_deps = lib_public_deps 236 configs += lib_extra_configs 237 public_configs = [ ":$generated_config_name" ] 238 239 if (defined(invoker.visibility)) { 240 visibility = invoker.visibility 241 } 242 if (defined(invoker.output_name)) { 243 output_name = invoker.output_name 244 } 245 } 246 } else { 247 source_set(target_name) { 248 sources = lib_sources 249 deps = lib_deps 250 public_deps = lib_public_deps 251 configs += lib_extra_configs 252 public_configs = [ ":$generated_config_name" ] 253 254 if (defined(invoker.visibility)) { 255 visibility = invoker.visibility 256 } 257 if (defined(invoker.output_name)) { 258 output_name = invoker.output_name 259 } 260 } 261 } 262 } 263