| # Copyright 2019 The Fuchsia Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| import("//build/config/fuchsia/zircon.gni") |
| import("//build/cpp/verify_pragma_once.gni") |
| import("//build/sdk/sdk_atom.gni") |
| |
| # Define a library in //zircon/public/lib/$target_name/BUILD.gn. |
| # |
| # zircon_library() is invoked by files copied from template.gn based on |
| # "$zircon_root_build_dir/legacy-$target_cpu.json" entries generated by |
| # Zircon library() targets with $sdk set. They provide the deps API for |
| # Fuchsia targets to depend on Zircon libraries, which are either used as |
| # binaries previously built by Zircon, or built in Fuchsia from source. |
| # |
| # Parameters |
| # |
| # deps, public_deps |
| # Optional: Dependencies for the target. $deps is only relevant for |
| # source libraries. $public_deps reflects header dependencies. |
| # Type: list(label matching "//zircon/public/lib/*") |
| # |
| # dir |
| # Required: Source-absolute path to library's source directory in //zircon. |
| # Type: dir |
| # |
| # sources |
| # Optional: If present, publish library as source with these files. |
| # Type: list(file) |
| # |
| # libs |
| # Optional: If present, publish library as prebuilt with these files. |
| # Type: list(path relative to $zircon_root_build_dir) |
| # |
| # include_dirs |
| # Required: The directory prefix where $headers are found. |
| # Type: singleton list(path relative to $zircon_root_build_dir) |
| # |
| # headers |
| # Required: List of header files to copy into the SDK. |
| # Type: list(path relative to ${include_dirs[0]}) |
| # |
| # Either $sources or $libs must be present. |
| # |
| template("zircon_library") { |
| library = target_name |
| |
| include = rebase_path(invoker.include_dirs, ".", zircon_root_build_dir) |
| assert(include == [ include[0] ]) |
| library_headers = rebase_path(invoker.headers, ".", include[0]) |
| |
| # Zircon targets depend explicitly on $zx/system/ulib/zircon, but in |
| # legacy Fuchsia GN there is no //zircon/public/lib/zircon and instead |
| # it's available implicitly in the sysroot via `libs = [ "zircon" ]`. |
| library_deps = [] |
| library_public_deps = [] |
| library_libs = [] |
| if (defined(invoker.deps)) { |
| library_deps = invoker.deps |
| } |
| if (defined(invoker.public_deps)) { |
| library_public_deps = invoker.public_deps |
| } |
| if (library_deps + [ "//zircon/public/lib/zircon" ] - |
| [ "//zircon/public/lib/zircon" ] != library_deps) { |
| library_deps -= [ "//zircon/public/lib/zircon" ] |
| library_libs += [ "zircon" ] |
| } |
| if (library_public_deps + [ "//zircon/public/lib/zircon" ] - |
| [ "//zircon/public/lib/zircon" ] != library_public_deps) { |
| library_public_deps -= [ "//zircon/public/lib/zircon" ] |
| library_libs += [ "zircon" ] |
| } |
| |
| # A library() always an include/ directory dependents must use. |
| # A prebuilt library() (`sdk != "source"`) has a library they must link in. |
| config("$library.config") { |
| include_dirs = include |
| if (is_fuchsia) { |
| libs = library_libs |
| } else { |
| not_needed([ "library_libs" ]) |
| } |
| if (defined(invoker.libs) && invoker.libs != []) { |
| assert(is_fuchsia, "Prebuilt $library used for host") |
| libs += rebase_path(invoker.libs, ".", zircon_root_build_dir) |
| } |
| } |
| |
| if (defined(invoker.libs)) { |
| # A prebuilt binary (either static .a or shared .so, doesn't matter) |
| # has nothing to do but bring in the config() for its `libs`. |
| type = "group" |
| } else { |
| # A source library is always built for static linking only. |
| # The invoker (i.e. the JSON) specifies `sources`. |
| type = "static_library" |
| } |
| |
| target(type, library) { |
| forward_variables_from(invoker, |
| "*", |
| [ |
| "debug", |
| "deps", |
| "dir", |
| "headers", |
| "include_dirs", |
| "install", |
| "lib_dirs", |
| "dist_dir", |
| "libs", |
| "public_deps", |
| "source_dir", |
| ]) |
| public_configs = [ ":$library.config" ] |
| deps = library_deps |
| public_deps = library_public_deps |
| if (!is_fuchsia) { |
| public_deps += [ "//zircon/system/public" ] |
| } |
| |
| if (defined(invoker.libs)) { |
| # Rust targets use -L... -lfoo instead of explicit files. So they |
| # need to collect the -L list via metadata, and directories on that |
| # list needs to hold exact names libfoo.so or libfoo.a for -lfoo. |
| metadata = { |
| zircon_lib_dirs = [] |
| foreach(file, invoker.libs) { |
| if (get_path_info(file, "extension") == "so" || |
| get_path_info(file, "extension") == "a") { |
| zircon_lib_dirs += [ rebase_path(get_path_info(file, "dir"), |
| "", |
| zircon_root_build_dir) ] |
| } else { |
| file = rebase_path(file, "", zircon_root_build_dir) |
| write_file("$target_gen_dir/lib$library.so", [ "INPUT($file)" ]) |
| zircon_lib_dirs += [ rebase_path(target_gen_dir) ] |
| } |
| } |
| if (defined(invoker.lib_dirs)) { |
| zircon_lib_dirs += |
| rebase_path(invoker.lib_dirs, "", zircon_root_build_dir) |
| } |
| } |
| } |
| } |
| |
| verify_pragma_once("$library-cpp_pragma") { |
| headers = library_headers |
| } |
| |
| is_shared = false |
| if (invoker.install != []) { |
| _debug = invoker.debug |
| installed_binaries = { |
| if (_debug != []) { |
| assert(_debug == [ _debug[0] ]) |
| debug = rebase_path(_debug[0], "", zircon_root_build_dir) |
| } |
| foreach(file, invoker.install) { |
| if (get_path_info(file.dest, "dir") == "dist") { |
| dist = "arch/$target_cpu/${file.dest}" |
| } else if (get_path_info(file.dest, "dir") == "lib") { |
| link = "arch/$target_cpu/${file.dest}" |
| } |
| } |
| } |
| is_shared = get_path_info(installed_binaries.link, "extension") == "so" |
| } |
| |
| _sdk_deps = [] |
| if (!is_shared && defined(invoker.deps)) { |
| _sdk_deps += invoker.deps |
| } |
| if (defined(invoker.public_deps)) { |
| _sdk_deps += invoker.public_deps |
| } |
| |
| # De-duplicate. |
| sdk_deps = [] |
| foreach(label, _sdk_deps) { |
| sdk_deps += [ label ] |
| sdk_deps -= [ label ] |
| sdk_deps += [ label ] |
| } |
| |
| _lib_deps = [] |
| _fidl_deps = [] |
| _banjo_deps = [] |
| foreach(label, sdk_deps) { |
| if (get_path_info(get_path_info(label, "dir"), "name") == "fidl") { |
| _fidl_deps += [ get_path_info(get_label_info(label, "dir"), "name") ] |
| } else if (get_path_info(get_path_info(label, "dir"), "name") == "banjo") { |
| _banjo_deps += [ get_path_info(get_label_info(label, "dir"), "name") ] |
| } else { |
| _lib_deps += [ get_path_info(get_label_info(label, "dir"), "name") ] |
| } |
| } |
| |
| # Zircon targets depend explicitly on $zx/system/ulib/zircon, but in |
| # legacy Fuchsia GN there is no //zircon/public/lib/zircon and instead |
| # it's available implicitly in the sysroot via `libs = [ "zircon" ]`. |
| # zircon-internal is a header-only library used by some static libraries. |
| _lib_deps += [ |
| "zircon", |
| "zircon-internal", |
| ] |
| _lib_deps -= [ |
| "zircon", |
| "zircon-internal", |
| ] |
| |
| pkg = "pkg/$library" |
| sdk_metadata = { |
| name = library |
| root = pkg |
| if (defined(invoker.sources)) { |
| type = "cc_source_library" |
| } else { |
| type = "cc_prebuilt_library" |
| } |
| |
| include_dir = "$pkg/include" |
| headers = rebase_path(invoker.headers, "//", "//$pkg/include") |
| if (defined(invoker.sources)) { |
| sources = rebase_path(rebase_path(invoker.sources, invoker.source_dir), |
| "//", |
| "//$pkg") |
| } |
| |
| deps = _lib_deps |
| if (invoker.install == []) { |
| banjo_deps = _banjo_deps |
| fidl_deps = _fidl_deps |
| } else { |
| not_needed([ |
| "_banjo_deps", |
| "_fidl_deps", |
| ]) |
| if (is_shared) { |
| format = "shared" |
| } else if (get_path_info(installed_binaries.link, "extension") == "a") { |
| format = "static" |
| } |
| binaries = { |
| if (target_cpu == "arm64") { |
| arm64 = installed_binaries |
| } else if (target_cpu == "x64") { |
| x64 = installed_binaries |
| } |
| } |
| } |
| |
| if (!defined(invoker.sources)) { |
| dist_dir = pkg |
| } |
| } |
| |
| sdk_atom("${library}_sdk") { |
| id = "sdk://pkg/$library" |
| category = "partner" |
| |
| meta = { |
| dest = "$pkg/meta.json" |
| schema = sdk_metadata.type |
| if (invoker.debug == []) { |
| value = sdk_metadata |
| } else { |
| source = "$target_out_dir/$library.meta.out.json" |
| } |
| } |
| |
| non_sdk_deps = [ ":$library-cpp_pragma" ] |
| if (invoker.debug != []) { |
| non_sdk_deps += [ ":$library-meta" ] |
| file_list = "$target_out_dir/$library.debug.manifest" |
| } |
| |
| files = [] |
| |
| foreach(file, library_headers) { |
| files += [ |
| { |
| source = file |
| dest = "$pkg/include/" + rebase_path(file, include[0]) |
| }, |
| ] |
| } |
| |
| if (defined(invoker.sources)) { |
| foreach(file, invoker.sources) { |
| files += [ |
| { |
| source = file |
| dest = "$pkg/" + rebase_path(file, invoker.source_dir) |
| }, |
| ] |
| } |
| } |
| |
| foreach(file, invoker.install) { |
| files += [ |
| { |
| source = rebase_path(file.source, "", zircon_root_build_dir) |
| dest = "arch/$target_cpu/${file.dest}" |
| }, |
| ] |
| } |
| } |
| |
| if (invoker.debug != []) { |
| write_file("$target_gen_dir/$library.meta.in.json", sdk_metadata, "json") |
| action("$library-meta") { |
| visibility = [ ":*" ] |
| script = "//build/zircon/sdk_build_id.py" |
| sources = [ |
| "$target_gen_dir/$library.meta.in.json", |
| ] |
| outputs = [ |
| "$target_out_dir/$library.meta.out.json", |
| "$target_out_dir/$library.debug.manifest", |
| ] |
| args = [ |
| "--input=" + rebase_path(sources[0], root_build_dir), |
| "--output=" + rebase_path(outputs[0], root_build_dir), |
| "--manifest=" + rebase_path(outputs[1], root_build_dir), |
| "--location=/binaries/$target_cpu/debug", |
| ] |
| } |
| } |
| } |