# Copyright 2019 Google LLC. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. # import("//gn/skia.gni") declare_args() { using_fuchsia_sdk = true # Fuchsia SDK install dir. fuchsia_sdk_path = "//fuchsia/sdk/$host_os" # Clang install dir. fuchsia_toolchain_path = "//fuchsia/toolchain/$host_os" # Path to GN-generated GN targets derived from parsing json file at # |fuchsia_sdk_manifest_path|. The parsing logic can be found in sdk.gni. fuchsia_sdk_root = "//build/fuchsia" } declare_args() { fuchsia_sdk_manifest_path = "${fuchsia_sdk_path}/meta/manifest.json" } template("_fuchsia_sysroot") { assert(defined(invoker.meta), "The meta.json file path must be specified.") assert(target_cpu == "x64" || target_cpu == "arm64", "We currently only support 'x64' and 'arm64' targets for fuchsia.") meta_json = read_file(invoker.meta, "json") assert(meta_json.type == "sysroot") meta_json_versions = meta_json.versions if (target_cpu == "x64") { defs = meta_json_versions.x64 } else { defs = meta_json_versions.arm64 } _libs = [] _lib_dirs = [] _include_dirs = [] foreach(link_lib, defs.link_libs) { if (link_lib != "arch/${target_cpu}/sysroot/lib/Scrt1.o") { _libs += [ rebase_path("$fuchsia_sdk_path/$link_lib") ] } } defs_include_dir = defs.include_dir _include_dirs += [ rebase_path("$fuchsia_sdk_path/$defs_include_dir") ] config_name = "config_$target_name" config(config_name) { lib_dirs = _lib_dirs libs = _libs include_dirs = _include_dirs } group(target_name) { public_configs = [ ":$config_name" ] } } template("_fuchsia_fidl_library") { assert(defined(invoker.meta), "The meta.json file path must be specified.") assert(target_cpu == "x64" || target_cpu == "arm64", "We currently only support 'x64' and 'arm64' targets for fuchsia.") meta_json = read_file(invoker.meta, "json") assert(meta_json.type == "fidl_library") _deps = [ "../pkg:fidl_cpp" ] library_name = string_replace(meta_json.name, "fuchsia.", "") library_name_json = "$library_name.json" foreach(dep, meta_json.deps) { _deps += [ ":$dep" ] } config_name = "config_$target_name" config(config_name) { include_dirs = [ target_gen_dir ] } fidl_gen_target_name = "fidlgen_$target_name" action(fidl_gen_target_name) { script = "//build/fuchsia/fidl_gen_cpp" library_name_slashes = string_replace(library_name, ".", "/") inputs = [ invoker.meta ] outputs = [ "$target_gen_dir/fuchsia/$library_name_slashes/c/tables.c", "$target_gen_dir/fuchsia/$library_name_slashes/cpp/fidl.h", "$target_gen_dir/fuchsia/$library_name_slashes/cpp/fidl.cc", ] args = [ "--fidlc-bin", rebase_path("$fuchsia_sdk_path/tools/fidlc"), "--fidlgen-bin", rebase_path("$fuchsia_sdk_path/tools/fidlgen"), "--sdk-base", rebase_path("$fuchsia_sdk_path"), "--root", rebase_path(invoker.meta), "--json", rebase_path("$target_gen_dir/$library_name_json"), "--include-base", rebase_path("$target_gen_dir"), "--output-base-cc", rebase_path("$target_gen_dir/fuchsia/$library_name_slashes/cpp/fidl"), "--output-c-tables", rebase_path("$target_gen_dir/fuchsia/$library_name_slashes/c/tables.c"), ] } source_set(target_name) { public_configs = [ ":$config_name" ] sources = get_target_outputs(":$fidl_gen_target_name") deps = [ ":$fidl_gen_target_name" ] public_deps = _deps } } # # Produce a cc source library from invoker's json file. # Primary output is the source_set. # template("_fuchsia_cc_source_library") { assert(defined(invoker.meta), "The meta.json file path must be specified.") meta_json = read_file(invoker.meta, "json") assert(meta_json.type == "cc_source_library") _output_name = meta_json.name _include_dirs = [] _public_headers = [] _sources = [] _deps = [] meta_json_include_dir = meta_json.include_dir _include_dirs += [ rebase_path("$fuchsia_sdk_path/$meta_json_include_dir") ] foreach(header, meta_json.headers) { rebased_header = [] rebased_header = [ rebase_path("$fuchsia_sdk_path/$header") ] _public_headers += rebased_header _sources += rebased_header } foreach(source, meta_json.sources) { _sources += [ "$fuchsia_sdk_path/$source" ] } config_name = "config_$target_name" config(config_name) { include_dirs = _include_dirs } foreach(dep, meta_json.deps) { _deps += [ "../pkg:$dep" ] } foreach(dep, meta_json.fidl_deps) { _deps += [ "../fidl:$dep" ] } source_set(target_name) { output_name = _output_name public = _public_headers sources = _sources public_configs = [ ":$config_name" ] public_deps = _deps } } template("_fuchsia_cc_prebuilt_library") { assert(defined(invoker.meta), "The meta.json file path must be specified.") meta_json = read_file(invoker.meta, "json") _include_dirs = [] _deps = [] _libs = [] meta_json_include_dir = meta_json.include_dir _include_dirs += [ "$fuchsia_sdk_path/$meta_json_include_dir" ] foreach(dep, meta_json.deps) { _deps += [ ":$dep" ] } meta_json_binaries = meta_json.binaries if (target_cpu == "x64") { meta_json_binaries_arch = meta_json_binaries.x64 } else { meta_json_binaries_arch = meta_json_binaries.arm64 } prebuilt_lib = meta_json_binaries_arch.link _libs = [ "$fuchsia_sdk_path/$prebuilt_lib" ] config_name = "config_$target_name" config(config_name) { include_dirs = _include_dirs libs = _libs } group(target_name) { public_configs = [ ":$config_name" ] public_deps = _deps } } # # Read SDK manifest json file and produce gn build targets for all # "enabled_parts" as specified by the template invoker. # # Fuchsia SDK manifest is primarily a "parts" array. # template("fuchsia_sdk") { assert(defined(invoker.meta), "The meta.json file path must be specified.") assert(defined(invoker.enabled_parts), "A list containing the parts of the SDK to generate targets for.") meta_json = read_file(invoker.meta, "json") foreach(part, meta_json.parts) { part_meta_json = { } part_meta = part.meta part_meta_rebased = "$fuchsia_sdk_path/$part_meta" part_meta_json = read_file(part_meta_rebased, "json") subtarget_name = part_meta_json.name foreach(enabled_part, invoker.enabled_parts) { if (part.type == "cc_source_library") { if (part.type == enabled_part) { _fuchsia_cc_source_library(subtarget_name) { meta = part_meta_rebased } } } else if (part.type == "sysroot") { if (part.type == enabled_part) { _fuchsia_sysroot(subtarget_name) { meta = part_meta_rebased } } } else if (part.type == "fidl_library") { if (part.type == enabled_part) { _fuchsia_fidl_library(subtarget_name) { meta = part_meta_rebased } } } else if (part.type == "cc_prebuilt_library") { if (part.type == enabled_part) { _fuchsia_cc_prebuilt_library(subtarget_name) { meta = part_meta_rebased } } } } } group(target_name) { } } # # Create package in 'gen' directory. # template("fuchsia_package") { assert(defined(invoker.name), "The name of the package must be specified.") assert(defined(invoker.version), "The package version must be specified.") pkg_dir = target_gen_dir pkg_name = invoker.name pkg_version = invoker.version pkg_manifest = invoker.pkg_manifest pkg_id_path = "${pkg_dir}/meta/package" gen_far_target_name = "gen_far_${target_name}" pkg_archive = "${pkg_dir}/${pkg_name}-${pkg_version}.far" action(gen_far_target_name) { script = "//build/fuchsia/gen_package" pm_binary = rebase_path("$fuchsia_sdk_path/tools/pm") inputs = [ pm_binary ] outputs = [ pkg_id_path, pkg_archive, ] args = [ "--pm-bin", pm_binary, "--pkg-dir", rebase_path(pkg_dir), "--pkg-name", pkg_name, "--pkg-version", "$pkg_version", "--pkg-manifest", rebase_path(pkg_manifest), ] if (defined(invoker.deps)) { deps = invoker.deps } if (defined(invoker.testonly)) { testonly = invoker.testonly } } copy(target_name) { if (defined(invoker.testonly)) { testonly = invoker.testonly } sources = [ pkg_archive ] output_name = "${root_out_dir}/far/${pkg_name}.far" outputs = [ output_name ] deps = [ ":$gen_far_target_name" ] } } # # Places repo in output ('obj') directory. # template("fuchsia_repo") { assert(defined(invoker.archives), "The list of archives to publish must be specified.") assert(defined(invoker.repo), "The location of the repo should be specified.") action(target_name) { if (defined(invoker.testonly)) { testonly = invoker.testonly } script = "//build/fuchsia/gen_repo" pm_binary = rebase_path("$fuchsia_sdk_path/tools/pm") repo_directory = invoker.repo inputs = [ pm_binary ] archive_flags = [] foreach(archive, invoker.archives) { assert(get_path_info(archive, "extension") == "far", "Archive '$archive' does not have the .far extension.") inputs += [ archive ] archive_flags += [ "--archive", rebase_path(archive), ] } outputs = [ repo_directory ] args = [ "--pm-bin", pm_binary, "--repo-dir", rebase_path(repo_directory), ] + archive_flags if (defined(invoker.deps)) { deps = invoker.deps } } }