| # Copyright 2018 The ChromiumOS Authors |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| declare_args() { |
| # The OS build is running on. |
| OS = "" |
| |
| # Specifies pkg-config program to retrieve information about packages. |
| pkg_config = "" |
| |
| # The logical root directory for headers and libraries. |
| # Trailing slash should not be added (except root path). |
| sysroot = "" |
| |
| # The libdir of the target board. e.g. /usr/lib64 |
| libdir = "" |
| |
| # The path to the directory where build artifacts are located. |
| build_root = "" |
| |
| # The path to src/platform2. |
| platform2_root = "" |
| |
| # Libbase revision number read from BASE_VER variable or file. |
| libbase_ver = "" |
| |
| # Set true to allow C++ code to use exceptions. |
| enable_exceptions = false |
| |
| # Set true if clang is used for C compiler. |
| clang_cc = false |
| |
| # Set true if clang is used for C++ compiler. |
| clang_cxx = false |
| |
| # Additional flags for C compiler. |
| external_cflags = [] |
| |
| # Additional flags for C++ compiler. |
| external_cxxflags = [] |
| |
| # Additional flags for C and C++ preprocessor. |
| external_cppflags = [] |
| |
| # Additional flags for C and C++ linker. |
| external_ldflags = [] |
| |
| # Whether to link against libstdc++fs. Set this to true if the compiler |
| # version requires -lstdc++fs to use std::filesystem. Useful when compiling |
| # common-mk projects outside Chrome OS where there are many compiler |
| # variations. |
| link_stdcppfs = false |
| |
| # Set this to true if you want to activate the debug mode. |
| is_debug = false |
| |
| # Subdir in platform2 where the package is located. |
| # TODO(oka): This value is public because it is used in ap/ package for common |
| # targets to use different default flags based on the package to be built. |
| # This is hacky, so remove such usages and move this variable back to |
| # gn_root/BUILD.gn . |
| platform_subdir = "" |
| } |
| import("//common-mk/use.gni") |
| |
| assert(pkg_config != "", "pkg-config script path must be set") |
| assert(libbase_ver != -1, "libbase_ver must be set") |
| assert(libdir != "", "libdir must be set") |
| |
| if (target_os == "") { |
| target_os = host_os |
| } |
| if (target_cpu == "") { |
| target_cpu = host_cpu |
| } |
| if (current_cpu == "") { |
| current_cpu = target_cpu |
| } |
| if (current_os == "") { |
| current_os = target_os |
| } |
| |
| # Practically sysroot is used as a prefix of paths, e.g. |
| # "${sysroot}/usr/include". If sysroot is root (= "/"), it will be |
| # "//usr/include". However, in GN, paths starting with "//" represents the path |
| # to the GN root, rather than the file system root, which is unexpected. |
| # To support that case, replace sysroot with "/.", if sysroot is "/". |
| if (sysroot == "/") { |
| sysroot = "/." |
| } |
| |
| # All binary targets will get this list of configs by default. |
| _binary_target_configs = [ "//common-mk:compiler_defaults" ] |
| |
| if (!enable_exceptions) { |
| _binary_target_configs += [ "//common-mk:no_exceptions" ] |
| } |
| |
| if (!clang_cc) { |
| _binary_target_configs += [ "//common-mk:gcc_cflags_c" ] |
| } |
| if (!clang_cxx) { |
| _binary_target_configs += [ "//common-mk:gcc_cflags_cc" ] |
| } |
| |
| set_defaults("executable") { |
| configs = _binary_target_configs |
| configs += [ "//common-mk:pie" ] |
| } |
| |
| set_defaults("static_library") { |
| configs = _binary_target_configs |
| configs += [ |
| "//common-mk:pie", |
| "//common-mk:use_thin_archive", |
| ] |
| } |
| |
| set_defaults("shared_library") { |
| configs = _binary_target_configs |
| configs += [ "//common-mk:pic" ] |
| } |
| |
| set_defaults("source_set") { |
| configs = _binary_target_configs |
| } |
| |
| set_default_toolchain("//common-mk/toolchain") |
| |
| # In Chrome OS, pkg-config is commonly and widely used. |
| # It is not natively supported by GN. Instead, here a few special fields are |
| # injected to the executable, shared_library and static_library targets |
| # to support pkg-config. |
| # src_install and src_test settings are also written in the same way. |
| # |
| # install_path exports metadata for installing the file built by the target. |
| # For example, |
| # - executable("my_executable") # template invocation |
| # is expanded to: |
| # - executable("my_executable") # GN built-in function invocation |
| # - install_config("my_executable-install_config") |
| # In this case ":my_executable" is usually joined to the dependency chain from |
| # the root (":all") by the BUILD.gn that uses this template. However, the |
| # ":my_executable-install_config" is not. So we chain it by adding to deps. |
| # ":all" --> ":my_executable" -(add this dep)-> ":my_executable-install_config" |
| # |
| # Args: |
| # pkg_deps(optional): A list of package names to be depend. |
| # A corresponding config is created, and then injected to |configs|. |
| # public_pkg_deps(optional): Similart to pkg_deps, but injected to |
| # |public_configs| instead. |
| # all_dependent_pkg_deps(optional): Similar to pkg_deps, but injected to |
| # |all_dependent_configs|. |
| # run_test(optional): A boolean if this is a unittest program that should be |
| # automatically run. A corresponding metadata is injected to itself. |
| # test_config(optional): A scope of configs for tests. |
| # A corresponding metadata is injected to itself. |
| # install_path(optional): A path to install into. |
| # A corresponding group is created, and then injected to |deps|. |
| |
| import("//common-mk/install_config.gni") |
| import("//common-mk/pkg_config.gni") |
| |
| template("_generate_config_rule") { |
| if (defined(invoker.pkg_deps) && invoker.pkg_deps != []) { |
| _pkg_deps_name = "_${target_name}-pkg_deps-config" |
| pkg_config(_pkg_deps_name) { |
| pkg_deps = invoker.pkg_deps |
| } |
| } |
| if (defined(invoker.public_pkg_deps) && invoker.public_pkg_deps != []) { |
| _public_pkg_deps_name = "_${target_name}-public_pkg_deps-config" |
| pkg_config(_public_pkg_deps_name) { |
| pkg_deps = invoker.public_pkg_deps |
| } |
| } |
| if (defined(invoker.all_dependent_pkg_deps) && |
| invoker.all_dependent_pkg_deps != []) { |
| _all_dependent_pkg_deps_name = |
| "_${target_name}-all_dependent_pkg_deps-config" |
| pkg_config(_all_dependent_pkg_deps_name) { |
| pkg_deps = invoker.all_dependent_pkg_deps |
| } |
| } |
| |
| if (defined(invoker.install_path)) { |
| _install_config_name = "_${target_name}-install_config" |
| source_name = invoker.target_name |
| if (defined(invoker.output_name)) { |
| source_name = invoker.output_name |
| } |
| source_dir = invoker.root_build_dir |
| if (defined(invoker.output_dir)) { |
| source_dir = invoker.output_dir |
| } |
| install_config(_install_config_name) { |
| if (defined(invoker.target_type)) { |
| type = invoker.target_type |
| } |
| if (invoker.target_type == "shared_library") { |
| sources = [ "${source_dir}/lib/${source_name}.so" ] |
| } else if (invoker.target_type == "static_library") { |
| sources = [ "${source_dir}/${source_name}.a" ] |
| } else { |
| sources = [ "${source_dir}/${source_name}" ] |
| } |
| install_path = invoker.install_path |
| } |
| } |
| |
| target(invoker.target_type, target_name) { |
| forward_variables_from(invoker, |
| "*", |
| [ |
| "all_dependent_pkg_deps", |
| "install_path", |
| "metadata", |
| "pkg_deps", |
| "public_pkg_deps", |
| "run_test", |
| "target_type", |
| "test_config", |
| ]) |
| if (defined(_pkg_deps_name)) { |
| if (!defined(configs)) { |
| configs = [] |
| } |
| configs += [ ":${_pkg_deps_name}" ] |
| } |
| if (defined(_public_pkg_deps_name)) { |
| if (!defined(public_configs)) { |
| public_configs = [] |
| } |
| public_configs += [ ":${_public_pkg_deps_name}" ] |
| } |
| if (defined(_all_dependent_pkg_deps_name)) { |
| if (!defined(all_dependent_configs)) { |
| all_dependent_configs = [] |
| } |
| all_dependent_configs += [ ":${_all_dependent_pkg_deps_name}" ] |
| } |
| if (defined(_install_config_name)) { |
| # Add deps to have install_config rule joined to the dependency chain. |
| # The dependency direction is opposite to the real information flow, but |
| # it does not matter here because the installation is done in the |
| # src_install ebuild phase after all build is finished. |
| if (!defined(deps)) { |
| deps = [] |
| } |
| deps += [ ":${_install_config_name}" ] |
| } |
| _run_test = defined(invoker.run_test) && invoker.run_test |
| if (defined(invoker.metadata) || _run_test) { |
| metadata = { |
| if (defined(invoker.metadata)) { |
| forward_variables_from(invoker.metadata, "*") |
| } |
| if (_run_test) { |
| _run_test = [ true ] |
| if (defined(invoker.test_config)) { |
| _test_config = [ invoker.test_config ] |
| } |
| } |
| } |
| } |
| } |
| } |
| |
| # Add variables for exporting install configs of files generated by action targets. |
| # |
| # install_configs: |
| # Optional list of scopes that specify installation configuration. |
| # Each scope can contain these values: |
| # path: Install destination. |
| # files: Optional list of files to be installed. |
| # This should be a subset of outputs. |
| # When this is omitted, the enclosing install_configs can have only |
| # one item, and all the files in the outputs are installed. |
| # options: Optional string. Specifies the insopts. |
| template("action") { |
| if (defined(invoker.install_configs)) { |
| _installs = [] |
| _i = 0 |
| _all_files = false |
| foreach(c, invoker.install_configs) { |
| _install_config_name = "_${target_name}-${_i}-install_config" |
| install_config(_install_config_name) { |
| if (defined(c.files)) { |
| sources = c.files |
| } else { |
| sources = invoker.outputs |
| } |
| install_path = c.path |
| if (defined(c.options)) { |
| options = c.options |
| } |
| } |
| _installs += [ ":${_install_config_name}" ] |
| _i = _i + 1 |
| if (!defined(c.files)) { |
| _all_files = true |
| } |
| } |
| |
| # _i here is the length of invoker.intall_configs. |
| # Note that GN does not provide a function to get a list length. |
| assert( |
| _i == 1 || !_all_files, |
| "|install_configs| should have only one entry when |files| is omitted inside it.") |
| } |
| action(target_name) { |
| forward_variables_from(invoker, "*", [ "install_configs" ]) |
| if (defined(_installs)) { |
| # Add deps so that data export is added to the dependency chain. |
| # See the comments in _generate_config_rule. |
| if (!defined(deps)) { |
| deps = [] |
| } |
| deps += _installs |
| } |
| } |
| } |
| |
| template("executable") { |
| _generate_config_rule(target_name) { |
| forward_variables_from(invoker, "*") |
| target_type = "executable" |
| } |
| } |
| |
| template("shared_library") { |
| _generate_config_rule(target_name) { |
| forward_variables_from(invoker, "*") |
| target_type = "shared_library" |
| } |
| } |
| |
| template("static_library") { |
| _generate_config_rule(target_name) { |
| forward_variables_from(invoker, "*") |
| target_type = "static_library" |
| } |
| } |