1# Copyright 2019 Google LLC. 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# import("//gn/skia.gni") 6 7declare_args() { 8 using_fuchsia_sdk = true 9 10 # Fuchsia SDK install dir. 11 fuchsia_sdk_path = "//fuchsia/sdk/$host_os" 12 13 # Clang install dir. 14 fuchsia_toolchain_path = "//fuchsia/toolchain/$host_os" 15 16 # Path to GN-generated GN targets derived from parsing json file at 17 # |fuchsia_sdk_manifest_path|. The parsing logic can be found in sdk.gni. 18 fuchsia_sdk_root = "//build/fuchsia" 19} 20 21declare_args() { 22 fuchsia_sdk_manifest_path = "${fuchsia_sdk_path}/meta/manifest.json" 23} 24 25template("_fuchsia_sysroot") { 26 assert(defined(invoker.meta), "The meta.json file path must be specified.") 27 assert(target_cpu == "x64" || target_cpu == "arm64", 28 "We currently only support 'x64' and 'arm64' targets for fuchsia.") 29 30 meta_json = read_file(invoker.meta, "json") 31 32 assert(meta_json.type == "sysroot") 33 34 meta_json_versions = meta_json.versions 35 if (target_cpu == "x64") { 36 defs = meta_json_versions.x64 37 } else { 38 defs = meta_json_versions.arm64 39 } 40 41 _libs = [] 42 _lib_dirs = [] 43 _include_dirs = [] 44 45 foreach(link_lib, defs.link_libs) { 46 if (link_lib != "arch/${target_cpu}/sysroot/lib/Scrt1.o") { 47 _libs += [ rebase_path("$fuchsia_sdk_path/$link_lib") ] 48 } 49 } 50 51 defs_include_dir = defs.include_dir 52 _include_dirs += [ rebase_path("$fuchsia_sdk_path/$defs_include_dir") ] 53 54 config_name = "config_$target_name" 55 config(config_name) { 56 lib_dirs = _lib_dirs 57 libs = _libs 58 include_dirs = _include_dirs 59 } 60 61 group(target_name) { 62 public_configs = [ ":$config_name" ] 63 } 64} 65 66template("_fuchsia_fidl_library") { 67 assert(defined(invoker.meta), "The meta.json file path must be specified.") 68 assert(target_cpu == "x64" || target_cpu == "arm64", 69 "We currently only support 'x64' and 'arm64' targets for fuchsia.") 70 71 meta_json = read_file(invoker.meta, "json") 72 73 assert(meta_json.type == "fidl_library") 74 75 _deps = [ "../pkg:fidl_cpp" ] 76 77 library_name = string_replace(meta_json.name, "fuchsia.", "") 78 library_name_json = "$library_name.json" 79 80 foreach(dep, meta_json.deps) { 81 _deps += [ ":$dep" ] 82 } 83 84 config_name = "config_$target_name" 85 config(config_name) { 86 include_dirs = [ target_gen_dir ] 87 } 88 89 fidl_gen_target_name = "fidlgen_$target_name" 90 action(fidl_gen_target_name) { 91 script = "//build/fuchsia/fidl_gen_cpp" 92 93 library_name_slashes = string_replace(library_name, ".", "/") 94 95 inputs = [ 96 invoker.meta, 97 ] 98 99 outputs = [ 100 "$target_gen_dir/fuchsia/$library_name_slashes/c/fidl.h", 101 "$target_gen_dir/fuchsia/$library_name_slashes/c/tables.c", 102 "$target_gen_dir/fuchsia/$library_name_slashes/cpp/fidl.h", 103 "$target_gen_dir/fuchsia/$library_name_slashes/cpp/fidl.cc", 104 ] 105 106 args = [ 107 "--fidlc-bin", 108 rebase_path("$fuchsia_sdk_path/tools/fidlc"), 109 "--fidlgen-bin", 110 rebase_path("$fuchsia_sdk_path/tools/fidlgen"), 111 "--sdk-base", 112 rebase_path("$fuchsia_sdk_path"), 113 "--root", 114 rebase_path(invoker.meta), 115 "--json", 116 rebase_path("$target_gen_dir/$library_name_json"), 117 "--include-base", 118 rebase_path("$target_gen_dir"), 119 "--output-base-cc", 120 rebase_path("$target_gen_dir/fuchsia/$library_name_slashes/cpp/fidl"), 121 "--output-c-header", 122 rebase_path("$target_gen_dir/fuchsia/$library_name_slashes/c/fidl.h"), 123 "--output-c-tables", 124 rebase_path( 125 "$target_gen_dir/fuchsia/$library_name_slashes/c/tables.c"), 126 ] 127 } 128 129 source_set(target_name) { 130 public_configs = [ ":$config_name" ] 131 132 sources = get_target_outputs(":$fidl_gen_target_name") 133 134 deps = [ 135 ":$fidl_gen_target_name", 136 ] 137 138 public_deps = _deps 139 } 140} 141 142# 143# Produce a cc source library from invoker's json file. 144# Primary output is the source_set. 145# 146template("_fuchsia_cc_source_library") { 147 assert(defined(invoker.meta), "The meta.json file path must be specified.") 148 149 meta_json = read_file(invoker.meta, "json") 150 151 assert(meta_json.type == "cc_source_library") 152 153 _output_name = meta_json.name 154 _include_dirs = [] 155 _public_headers = [] 156 _sources = [] 157 _deps = [] 158 159 meta_json_include_dir = meta_json.include_dir 160 _include_dirs += [ rebase_path("$fuchsia_sdk_path/$meta_json_include_dir") ] 161 162 foreach(header, meta_json.headers) { 163 rebased_header = [] 164 rebased_header = [ rebase_path("$fuchsia_sdk_path/$header") ] 165 _public_headers += rebased_header 166 _sources += rebased_header 167 } 168 169 foreach(source, meta_json.sources) { 170 _sources += [ "$fuchsia_sdk_path/$source" ] 171 } 172 173 config_name = "config_$target_name" 174 config(config_name) { 175 include_dirs = _include_dirs 176 } 177 178 foreach(dep, meta_json.deps) { 179 _deps += [ "../pkg:$dep" ] 180 } 181 182 foreach(dep, meta_json.fidl_deps) { 183 _deps += [ "../fidl:$dep" ] 184 } 185 186 source_set(target_name) { 187 output_name = _output_name 188 public = _public_headers 189 sources = _sources 190 public_configs = [ ":$config_name" ] 191 public_deps = _deps 192 } 193} 194 195template("_fuchsia_cc_prebuilt_library") { 196 assert(defined(invoker.meta), "The meta.json file path must be specified.") 197 meta_json = read_file(invoker.meta, "json") 198 199 _include_dirs = [] 200 _deps = [] 201 _libs = [] 202 203 meta_json_include_dir = meta_json.include_dir 204 _include_dirs += [ "$fuchsia_sdk_path/$meta_json_include_dir" ] 205 206 foreach(dep, meta_json.deps) { 207 _deps += [ ":$dep" ] 208 } 209 210 meta_json_binaries = meta_json.binaries 211 if (target_cpu == "x64") { 212 meta_json_binaries_arch = meta_json_binaries.x64 213 } else { 214 meta_json_binaries_arch = meta_json_binaries.arm64 215 } 216 prebuilt_lib = meta_json_binaries_arch.link 217 _libs = [ "$fuchsia_sdk_path/$prebuilt_lib" ] 218 219 config_name = "config_$target_name" 220 config(config_name) { 221 include_dirs = _include_dirs 222 libs = _libs 223 } 224 225 group(target_name) { 226 public_configs = [ ":$config_name" ] 227 public_deps = _deps 228 } 229} 230 231# 232# Read SDK manifest json file and produce gn build targets for all 233# "enabled_parts" as specified by the template invoker. 234# 235# Fuchsia SDK manifest is primarily a "parts" array. 236# 237template("fuchsia_sdk") { 238 assert(defined(invoker.meta), "The meta.json file path must be specified.") 239 assert(defined(invoker.enabled_parts), 240 "A list containing the parts of the SDK to generate targets for.") 241 242 meta_json = read_file(invoker.meta, "json") 243 244 foreach(part, meta_json.parts) { 245 part_meta_json = { 246 } 247 248 part_meta = part.meta 249 part_meta_rebased = "$fuchsia_sdk_path/$part_meta" 250 251 part_meta_json = read_file(part_meta_rebased, "json") 252 subtarget_name = part_meta_json.name 253 254 foreach(enabled_part, invoker.enabled_parts) { 255 if (part.type == "cc_source_library") { 256 if (part.type == enabled_part) { 257 _fuchsia_cc_source_library(subtarget_name) { 258 meta = part_meta_rebased 259 } 260 } 261 } else if (part.type == "sysroot") { 262 if (part.type == enabled_part) { 263 _fuchsia_sysroot(subtarget_name) { 264 meta = part_meta_rebased 265 } 266 } 267 } else if (part.type == "fidl_library") { 268 if (part.type == enabled_part) { 269 _fuchsia_fidl_library(subtarget_name) { 270 meta = part_meta_rebased 271 } 272 } 273 } else if (part.type == "cc_prebuilt_library") { 274 if (part.type == enabled_part) { 275 _fuchsia_cc_prebuilt_library(subtarget_name) { 276 meta = part_meta_rebased 277 } 278 } 279 } 280 } 281 } 282 283 group(target_name) { 284 } 285} 286 287# 288# Create package in 'gen' directory. 289# 290template("fuchsia_package") { 291 assert(defined(invoker.name), "The name of the package must be specified.") 292 assert(defined(invoker.version), "The package version must be specified.") 293 294 pkg_dir = target_gen_dir 295 pkg_name = invoker.name 296 pkg_version = invoker.version 297 pkg_manifest = invoker.pkg_manifest 298 299 pkg_id_path = "${pkg_dir}/meta/package" 300 gen_far_target_name = "gen_far_${target_name}" 301 pkg_archive = "${pkg_dir}/${pkg_name}-${pkg_version}.far" 302 303 action(gen_far_target_name) { 304 script = "//build/fuchsia/gen_package" 305 306 pm_binary = rebase_path("$fuchsia_sdk_path/tools/pm") 307 308 inputs = [ 309 pm_binary, 310 ] 311 312 outputs = [ 313 pkg_id_path, 314 pkg_archive, 315 ] 316 317 args = [ 318 "--pm-bin", 319 pm_binary, 320 "--pkg-dir", 321 rebase_path(pkg_dir), 322 "--pkg-name", 323 pkg_name, 324 "--pkg-version", 325 "$pkg_version", 326 "--pkg-manifest", 327 rebase_path(pkg_manifest), 328 ] 329 330 if (defined(invoker.deps)) { 331 deps = invoker.deps 332 } 333 if (defined(invoker.testonly)) { 334 testonly = invoker.testonly 335 } 336 } 337 338 copy(target_name) { 339 if (defined(invoker.testonly)) { 340 testonly = invoker.testonly 341 } 342 343 sources = [ 344 pkg_archive, 345 ] 346 347 output_name = "${root_out_dir}/far/${pkg_name}.far" 348 outputs = [ 349 output_name, 350 ] 351 352 deps = [ 353 ":$gen_far_target_name", 354 ] 355 } 356} 357 358# 359# Places repo in output ('obj') directory. 360# 361template("fuchsia_repo") { 362 assert(defined(invoker.archives), 363 "The list of archives to publish must be specified.") 364 assert(defined(invoker.repo), "The location of the repo should be specified.") 365 366 action(target_name) { 367 if (defined(invoker.testonly)) { 368 testonly = invoker.testonly 369 } 370 script = "//build/fuchsia/gen_repo" 371 372 pm_binary = rebase_path("$fuchsia_sdk_path/tools/pm") 373 repo_directory = invoker.repo 374 375 inputs = [ 376 pm_binary, 377 ] 378 379 archive_flags = [] 380 381 foreach(archive, invoker.archives) { 382 assert(get_path_info(archive, "extension") == "far", 383 "Archive '$archive' does not have the .far extension.") 384 inputs += [ archive ] 385 archive_flags += [ 386 "--archive", 387 rebase_path(archive), 388 ] 389 } 390 391 outputs = [ 392 repo_directory, 393 ] 394 395 args = [ 396 "--pm-bin", 397 pm_binary, 398 "--repo-dir", 399 rebase_path(repo_directory), 400 ] + archive_flags 401 402 if (defined(invoker.deps)) { 403 deps = invoker.deps 404 } 405 } 406} 407