// Copyright (c) 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "gn/functions.h"

#include "gn/config_values_generator.h"
#include "gn/err.h"
#include "gn/parse_tree.h"
#include "gn/scope.h"
#include "gn/target_generator.h"
#include "gn/template.h"
#include "gn/value.h"
#include "gn/variables.h"

#define DEPENDENT_CONFIG_VARS \
  "  Dependent configs: all_dependent_configs, public_configs\n"
#define DEPS_VARS "  Deps: data_deps, deps, public_deps\n"
#define GENERAL_TARGET_VARS                                                \
  "  General: check_includes, configs, data, friend, inputs, metadata,\n"  \
  "           output_name, output_extension, public, sources, testonly,\n" \
  "           visibility\n"
#define RUST_VARS \
  "  Rust variables: aliased_deps, crate_root, crate_name\n"
#define RUST_SHARED_VARS                                                 \
  "  Rust variables: aliased_deps, crate_root, crate_name, crate_type\n"

namespace functions {

namespace {

Value ExecuteGenericTarget(const char* target_type,
                           Scope* scope,
                           const FunctionCallNode* function,
                           const std::vector<Value>& args,
                           BlockNode* block,
                           Err* err) {
  NonNestableBlock non_nestable(scope, function, "target");
  if (!non_nestable.Enter(err))
    return Value();

  if (!EnsureNotProcessingImport(function, scope, err) ||
      !EnsureNotProcessingBuildConfig(function, scope, err))
    return Value();
  Scope block_scope(scope);
  if (!FillTargetBlockScope(scope, function, target_type, block, args,
                            &block_scope, err))
    return Value();

  block->Execute(&block_scope, err);
  if (err->has_error())
    return Value();

  TargetGenerator::GenerateTarget(&block_scope, function, args, target_type,
                                  err);
  if (err->has_error())
    return Value();

  block_scope.CheckForUnusedVars(err);
  return Value();
}

}  // namespace

// action ----------------------------------------------------------------------

// Common help paragraph on script runtime execution directories.
#define SCRIPT_EXECUTION_CONTEXT                                              \
  "\n"                                                                        \
  "  The script will be executed with the given arguments with the current\n" \
  "  directory being that of the root build directory. If you pass files\n"   \
  "  to your script, see \"gn help rebase_path\" for how to convert\n"        \
  "  file names to be relative to the build directory (file names in the\n"   \
  "  sources, outputs, and inputs will be all treated as relative to the\n"   \
  "  current build file and converted as needed automatically).\n"            \
  "\n"                                                                        \
  "  GN sets Ninja's flag 'restat = 1` for all action commands. This means\n" \
  "  that Ninja will check the timestamp of the output after the action\n"    \
  "  completes. If output timestamp is unchanged, the step will be treated\n" \
  "  as if it never needed to be rebuilt, potentially eliminating some\n"     \
  "  downstream steps for incremental builds. Scripts can improve build\n"    \
  "  performance by taking care not to change the timstamp of the output\n"   \
  "  file(s) if the contents have not changed.\n"

// Common help paragraph on script output directories.
#define SCRIPT_EXECUTION_OUTPUTS                                           \
  "\n"                                                                     \
  "  All output files must be inside the output directory of the build.\n" \
  "  You would generally use |$target_out_dir| or |$target_gen_dir| to\n"  \
  "  reference the output or generated intermediate file directories,\n"   \
  "  respectively.\n"

#define ACTION_DEPS                                                           \
  "\n"                                                                        \
  "  The \"deps\" and \"public_deps\" for an action will always be\n"         \
  "  completed before any part of the action is run so it can depend on\n"    \
  "  the output of previous steps. The \"data_deps\" will be built if the\n"  \
  "  action is built, but may not have completed before all steps of the\n"   \
  "  action are started. This can give additional parallelism in the build\n" \
  "  for runtime-only dependencies.\n"

// Common help paragraph on targets that can use different languages.
#define LANGUAGE_HELP                                                     \
  "\n"                                                                    \
  "  The tools and commands used to create this target type will be\n"    \
  "  determined by the source files in its sources. Targets containing\n" \
  "  multiple compiler-incompatible languages are not allowed (e.g. a\n"  \
  "  target containing both C and C++ sources is acceptable, but a\n"     \
  "  target containing C and Rust sources is not).\n"

const char kAction[] = "action";
const char kAction_HelpShort[] =
    "action: Declare a target that runs a script a single time.";
const char kAction_Help[] =
    R"(action: Declare a target that runs a script a single time.

  This target type allows you to run a script a single time to produce one or
  more output files. If you want to run a script once for each of a set of
  input files, see "gn help action_foreach".

Inputs

  In an action the "sources" and "inputs" are treated the same: they're both
  input dependencies on script execution with no special handling. If you want
  to pass the sources to your script, you must do so explicitly by including
  them in the "args". Note also that this means there is no special handling of
  paths since GN doesn't know which of the args are paths and not. You will
  want to use rebase_path() to convert paths to be relative to the
  root_build_dir.

  You can dynamically write input dependencies (for incremental rebuilds if an
  input file changes) by writing a depfile when the script is run (see "gn help
  depfile"). This is more flexible than "inputs".

  If the command line length is very long, you can use response files to pass
  args to your script. See "gn help response_file_contents".

  It is recommended you put inputs to your script in the "sources" variable,
  and stuff like other Python files required to run your script in the "inputs"
  variable.
)"

    ACTION_DEPS

    R"(
Outputs

  You should specify files created by your script by specifying them in the
  "outputs".
)"

    SCRIPT_EXECUTION_CONTEXT

    R"(
File name handling
)"

    SCRIPT_EXECUTION_OUTPUTS

    R"(
Variables

  args, data, data_deps, depfile, deps, inputs, metadata, outputs*, pool,
  response_file_contents, script*, sources
  * = required

Example

  action("run_this_guy_once") {
    script = "doprocessing.py"
    sources = [ "my_configuration.txt" ]
    outputs = [ "$target_gen_dir/insightful_output.txt" ]

    # Our script imports this Python file so we want to rebuild if it changes.
    inputs = [ "helper_library.py" ]

    # Note that we have to manually pass the sources to our script if the
    # script needs them as inputs.
    args = [ "--out", rebase_path(target_gen_dir, root_build_dir) ] +
           rebase_path(sources, root_build_dir)
  }
)";

Value RunAction(Scope* scope,
                const FunctionCallNode* function,
                const std::vector<Value>& args,
                BlockNode* block,
                Err* err) {
  return ExecuteGenericTarget(functions::kAction, scope, function, args, block,
                              err);
}

// action_foreach --------------------------------------------------------------

const char kActionForEach[] = "action_foreach";
const char kActionForEach_HelpShort[] =
    "action_foreach: Declare a target that runs a script over a set of files.";
const char kActionForEach_Help[] =
    R"(action_foreach: Declare a target that runs a script over a set of files.

  This target type allows you to run a script once-per-file over a set of
  sources. If you want to run a script once that takes many files as input, see
  "gn help action".

Inputs

  The script will be run once per file in the "sources" variable. The "outputs"
  variable should specify one or more files with a source expansion pattern in
  it (see "gn help source_expansion"). The output file(s) for each script
  invocation should be unique. Normally you use "{{source_name_part}}" in each
  output file.

  If your script takes additional data as input, such as a shared configuration
  file or a Python module it uses, those files should be listed in the "inputs"
  variable. These files are treated as dependencies of each script invocation.

  If the command line length is very long, you can use response files to pass
  args to your script. See "gn help response_file_contents".

  You can dynamically write input dependencies (for incremental rebuilds if an
  input file changes) by writing a depfile when the script is run (see "gn help
  depfile"). This is more flexible than "inputs".
)" ACTION_DEPS
    R"(
Outputs
)" SCRIPT_EXECUTION_CONTEXT
    R"(
File name handling
)" SCRIPT_EXECUTION_OUTPUTS
    R"(
Variables

  args, data, data_deps, depfile, deps, inputs, metadata, outputs*, pool,
  response_file_contents, script*, sources*
  * = required

Example

  # Runs the script over each IDL file. The IDL script will generate both a .cc
  # and a .h file for each input.
  action_foreach("my_idl") {
    script = "idl_processor.py"
    sources = [ "foo.idl", "bar.idl" ]

    # Our script reads this file each time, so we need to list it as a
    # dependency so we can rebuild if it changes.
    inputs = [ "my_configuration.txt" ]

    # Transformation from source file name to output file names.
    outputs = [ "$target_gen_dir/{{source_name_part}}.h",
                "$target_gen_dir/{{source_name_part}}.cc" ]

    # Note that since "args" is opaque to GN, if you specify paths here, you
    # will need to convert it to be relative to the build directory using
    # rebase_path().
    args = [
      "{{source}}",
      "-o",
      rebase_path(relative_target_gen_dir, root_build_dir) +
        "/{{source_name_part}}.h" ]
  }
)";

Value RunActionForEach(Scope* scope,
                       const FunctionCallNode* function,
                       const std::vector<Value>& args,
                       BlockNode* block,
                       Err* err) {
  return ExecuteGenericTarget(functions::kActionForEach, scope, function, args,
                              block, err);
}

// bundle_data -----------------------------------------------------------------

const char kBundleData[] = "bundle_data";
const char kBundleData_HelpShort[] =
    "bundle_data: [iOS/macOS] Declare a target without output.";
const char kBundleData_Help[] =
    R"(bundle_data: [iOS/macOS] Declare a target without output.

  This target type allows to declare data that is required at runtime. It is
  used to inform "create_bundle" targets of the files to copy into generated
  bundle, see "gn help create_bundle" for help.

  The target must define a list of files as "sources" and a single "outputs".
  If there are multiple files, source expansions must be used to express the
  output. The output must reference a file inside of {{bundle_root_dir}}.

  This target can be used on all platforms though it is designed only to
  generate iOS/macOS bundle. In cross-platform projects, it is advised to put it
  behind iOS/macOS conditionals.

  See "gn help create_bundle" for more information.

Variables

  sources*, outputs*, deps, data_deps, metadata, public_deps, visibility
  * = required

Examples

  bundle_data("icudata") {
    sources = [ "sources/data/in/icudtl.dat" ]
    outputs = [ "{{bundle_resources_dir}}/{{source_file_part}}" ]
  }

  bundle_data("base_unittests_bundle_data]") {
    sources = [ "test/data" ]
    outputs = [
      "{{bundle_resources_dir}}/{{source_root_relative_dir}}/" +
          "{{source_file_part}}"
    ]
  }

  bundle_data("material_typography_bundle_data") {
    sources = [
      "src/MaterialTypography.bundle/Roboto-Bold.ttf",
      "src/MaterialTypography.bundle/Roboto-Italic.ttf",
      "src/MaterialTypography.bundle/Roboto-Regular.ttf",
      "src/MaterialTypography.bundle/Roboto-Thin.ttf",
    ]
    outputs = [
      "{{bundle_resources_dir}}/MaterialTypography.bundle/"
          "{{source_file_part}}"
    ]
  }
)";

Value RunBundleData(Scope* scope,
                    const FunctionCallNode* function,
                    const std::vector<Value>& args,
                    BlockNode* block,
                    Err* err) {
  return ExecuteGenericTarget(functions::kBundleData, scope, function, args,
                              block, err);
}

// create_bundle ---------------------------------------------------------------

const char kCreateBundle[] = "create_bundle";
const char kCreateBundle_HelpShort[] =
    "create_bundle: [iOS/macOS] Build an iOS or macOS bundle.";
const char kCreateBundle_Help[] =
    R"(create_bundle: [ios/macOS] Build an iOS or macOS bundle.

  This target generates an iOS or macOS bundle (which is a directory with a
  well-know structure). This target does not define any sources, instead they
  are computed from all "bundle_data" target this one depends on transitively
  (the recursion stops at "create_bundle" targets).

  The "bundle_*_dir" are be used for the expansion of {{bundle_*_dir}} rules in
  "bundle_data" outputs. The properties are optional but must be defined if any
  of the "bundle_data" target use them.

  This target can be used on all platforms though it is designed only to
  generate iOS or macOS bundle. In cross-platform projects, it is advised to put
  it behind iOS/macOS conditionals.

  If a create_bundle is specified as a data_deps for another target, the bundle
  is considered a leaf, and its public and private dependencies will not
  contribute to any data or data_deps. Required runtime dependencies should be
  placed in the bundle. A create_bundle can declare its own explicit data and
  data_deps, however.

Code signing

  Some bundle needs to be code signed as part of the build (on iOS all
  application needs to be code signed to run on a device). The code signature
  can be configured via the code_signing_script variable.

  If set, code_signing_script is the path of a script that invoked after all
  files have been moved into the bundle. The script must not change any file in
  the bundle, but may add new files.

  If code_signing_script is defined, then code_signing_outputs must also be
  defined and non-empty to inform when the script needs to be re-run. The
  code_signing_args will be passed as is to the script (so path have to be
  rebased) and additional inputs may be listed with the variable
  code_signing_sources.

Variables

  bundle_root_dir, bundle_contents_dir, bundle_resources_dir,
  bundle_executable_dir, bundle_deps_filter, deps, data_deps, public_deps,
  visibility, product_type, code_signing_args, code_signing_script,
  code_signing_sources, code_signing_outputs, xcode_extra_attributes,
  xcode_test_application_name, partial_info_plist, metadata

Example

  # Defines a template to create an application. On most platform, this is just
  # an alias for an "executable" target, but on iOS/macOS, it builds an
  # application bundle.
  template("app") {
    if (!is_ios && !is_mac) {
      executable(target_name) {
        forward_variables_from(invoker, "*")
      }
    } else {
      app_name = target_name
      gen_path = target_gen_dir

      action("${app_name}_generate_info_plist") {
        script = [ "//build/ios/ios_gen_plist.py" ]
        sources = [ "templates/Info.plist" ]
        outputs = [ "$gen_path/Info.plist" ]
        args = rebase_path(sources, root_build_dir) +
               rebase_path(outputs, root_build_dir)
      }

      bundle_data("${app_name}_bundle_info_plist") {
        public_deps = [ ":${app_name}_generate_info_plist" ]
        sources = [ "$gen_path/Info.plist" ]
        outputs = [ "{{bundle_contents_dir}}/Info.plist" ]
      }

      executable("${app_name}_generate_executable") {
        forward_variables_from(invoker, "*", [
                                               "output_name",
                                               "visibility",
                                             ])
        output_name =
            rebase_path("$gen_path/$app_name", root_build_dir)
      }

      code_signing =
          defined(invoker.code_signing) && invoker.code_signing

      if (!is_ios || !code_signing) {
        bundle_data("${app_name}_bundle_executable") {
          public_deps = [ ":${app_name}_generate_executable" ]
          sources = [ "$gen_path/$app_name" ]
          outputs = [ "{{bundle_executable_dir}}/$app_name" ]
        }
      }

      create_bundle("$app_name.app") {
        product_type = "com.apple.product-type.application"

        if (is_ios) {
          bundle_root_dir = "$root_build_dir/$target_name"
          bundle_contents_dir = bundle_root_dir
          bundle_resources_dir = bundle_contents_dir
          bundle_executable_dir = bundle_contents_dir

          xcode_extra_attributes = {
            ONLY_ACTIVE_ARCH = "YES"
            DEBUG_INFORMATION_FORMAT = "dwarf"
          }
        } else {
          bundle_root_dir = "$root_build_dir/$target_name"
          bundle_contents_dir  = "$bundle_root_dir/Contents"
          bundle_resources_dir = "$bundle_contents_dir/Resources"
          bundle_executable_dir = "$bundle_contents_dir/MacOS"
        }
        deps = [ ":${app_name}_bundle_info_plist" ]
        if (is_ios && code_signing) {
          deps += [ ":${app_name}_generate_executable" ]
          code_signing_script = "//build/config/ios/codesign.py"
          code_signing_sources = [
            invoker.entitlements_path,
            "$target_gen_dir/$app_name",
          ]
          code_signing_outputs = [
            "$bundle_root_dir/$app_name",
            "$bundle_root_dir/_CodeSignature/CodeResources",
            "$bundle_root_dir/embedded.mobileprovision",
            "$target_gen_dir/$app_name.xcent",
          ]
          code_signing_args = [
            "-i=" + ios_code_signing_identity,
            "-b=" + rebase_path(
                "$target_gen_dir/$app_name", root_build_dir),
            "-e=" + rebase_path(
                invoker.entitlements_path, root_build_dir),
            "-e=" + rebase_path(
                "$target_gen_dir/$app_name.xcent", root_build_dir),
            rebase_path(bundle_root_dir, root_build_dir),
          ]
        } else {
          deps += [ ":${app_name}_bundle_executable" ]
        }
      }
    }
  }
)";

Value RunCreateBundle(Scope* scope,
                      const FunctionCallNode* function,
                      const std::vector<Value>& args,
                      BlockNode* block,
                      Err* err) {
  return ExecuteGenericTarget(functions::kCreateBundle, scope, function, args,
                              block, err);
}

// copy ------------------------------------------------------------------------

const char kCopy[] = "copy";
const char kCopy_HelpShort[] = "copy: Declare a target that copies files.";
const char kCopy_Help[] =
    R"(copy: Declare a target that copies files.

File name handling

  All output files must be inside the output directory of the build. You would
  generally use |$target_out_dir| or |$target_gen_dir| to reference the output
  or generated intermediate file directories, respectively.

  Both "sources" and "outputs" must be specified. Sources can include as many
  files as you want, but there can only be one item in the outputs list (plural
  is used for the name for consistency with other target types).

  If there is more than one source file, your output name should specify a
  mapping from each source file to an output file name using source expansion
  (see "gn help source_expansion"). The placeholders will look like
  "{{source_name_part}}", for example.

Examples

  # Write a rule that copies a checked-in DLL to the output directory.
  copy("mydll") {
    sources = [ "mydll.dll" ]
    outputs = [ "$target_out_dir/mydll.dll" ]
  }

  # Write a rule to copy several files to the target generated files directory.
  copy("myfiles") {
    sources = [ "data1.dat", "data2.dat", "data3.dat" ]

    # Use source expansion to generate output files with the corresponding file
    # names in the gen dir. This will just copy each file.
    outputs = [ "$target_gen_dir/{{source_file_part}}" ]
  }
)";

Value RunCopy(const FunctionCallNode* function,
              const std::vector<Value>& args,
              Scope* scope,
              Err* err) {
  if (!EnsureNotProcessingImport(function, scope, err) ||
      !EnsureNotProcessingBuildConfig(function, scope, err))
    return Value();
  TargetGenerator::GenerateTarget(scope, function, args, functions::kCopy, err);
  return Value();
}

// executable ------------------------------------------------------------------

const char kExecutable[] = "executable";
const char kExecutable_HelpShort[] =
    "executable: Declare an executable target.";
const char kExecutable_Help[] =
    R"(executable: Declare an executable target.

Language and compilation
)" LANGUAGE_HELP
    R"(

Variables

)" CONFIG_VALUES_VARS_HELP DEPS_VARS DEPENDENT_CONFIG_VARS GENERAL_TARGET_VARS
        RUST_VARS;

Value RunExecutable(Scope* scope,
                    const FunctionCallNode* function,
                    const std::vector<Value>& args,
                    BlockNode* block,
                    Err* err) {
  return ExecuteGenericTarget(functions::kExecutable, scope, function, args,
                              block, err);
}

// group -----------------------------------------------------------------------

const char kGroup[] = "group";
const char kGroup_HelpShort[] = "group: Declare a named group of targets.";
const char kGroup_Help[] =
    R"(group: Declare a named group of targets.

  This target type allows you to create meta-targets that just collect a set of
  dependencies into one named target. Groups can additionally specify configs
  that apply to their dependents.

Variables

)" DEPS_VARS DEPENDENT_CONFIG_VARS

    R"(
Example

  group("all") {
    deps = [
      "//project:runner",
      "//project:unit_tests",
    ]
  }
)";

Value RunGroup(Scope* scope,
               const FunctionCallNode* function,
               const std::vector<Value>& args,
               BlockNode* block,
               Err* err) {
  return ExecuteGenericTarget(functions::kGroup, scope, function, args, block,
                              err);
}

// loadable_module -------------------------------------------------------------

const char kLoadableModule[] = "loadable_module";
const char kLoadableModule_HelpShort[] =
    "loadable_module: Declare a loadable module target.";
const char kLoadableModule_Help[] =
    R"(loadable_module: Declare a loadable module target.

  This target type allows you to create an object file that is (and can only
  be) loaded and unloaded at runtime.

  A loadable module will be specified on the linker line for targets listing
  the loadable module in its "deps". If you don't want this (if you don't need
  to dynamically load the library at runtime), then you should use a
  "shared_library" target type instead.

Language and compilation
)" LANGUAGE_HELP
    R"(

Variables

)" CONFIG_VALUES_VARS_HELP DEPS_VARS DEPENDENT_CONFIG_VARS GENERAL_TARGET_VARS
        RUST_SHARED_VARS;

Value RunLoadableModule(Scope* scope,
                        const FunctionCallNode* function,
                        const std::vector<Value>& args,
                        BlockNode* block,
                        Err* err) {
  return ExecuteGenericTarget(functions::kLoadableModule, scope, function, args,
                              block, err);
}

// rust_library ----------------------------------------------------------------

const char kRustLibrary[] = "rust_library";
const char kRustLibrary_HelpShort[] =
    "rust_library: Declare a Rust library target.";
const char kRustLibrary_Help[] =
    R"(rust_library: Declare a Rust library target.

  A Rust library is an archive containing additional rust-c provided metadata.
  These are the files produced by the rustc compiler with the `.rlib`
  extension, and are the intermediate step for most Rust-based binaries.

Language and compilation
)" LANGUAGE_HELP
    R"(

Variables

)" CONFIG_VALUES_VARS_HELP DEPS_VARS DEPENDENT_CONFIG_VARS GENERAL_TARGET_VARS
        RUST_VARS;
Value RunRustLibrary(Scope* scope,
                     const FunctionCallNode* function,
                     const std::vector<Value>& args,
                     BlockNode* block,
                     Err* err) {
  return ExecuteGenericTarget(functions::kRustLibrary, scope, function, args,
                              block, err);
}

// rust_proc_macro ----------------------------------------------------------------

const char kRustProcMacro[] = "rust_proc_macro";
const char kRustProcMacro_HelpShort[] =
    "rust_proc_macro: Declare a Rust procedural macro target.";
const char kRustProcMacro_Help[] =
    R"(rust_proc_macro: Declare a Rust procedural macro target.

  A Rust procedural macro allows creating syntax extensions as execution of a
  function. They are compiled as dynamic libraries and used by the compiler at
  runtime.

  Their use is the same as of other Rust libraries, but their build has some
  additional restrictions in terms of supported flags.

Language and compilation
)" LANGUAGE_HELP
    R"(

Variables

)" CONFIG_VALUES_VARS_HELP DEPS_VARS DEPENDENT_CONFIG_VARS GENERAL_TARGET_VARS
        RUST_VARS;
Value RunRustProcMacro(Scope* scope,
                   const FunctionCallNode* function,
                   const std::vector<Value>& args,
                   BlockNode* block,
                   Err* err) {
  return ExecuteGenericTarget(functions::kRustProcMacro, scope, function, args,
                              block, err);
}

// shared_library --------------------------------------------------------------

const char kSharedLibrary[] = "shared_library";
const char kSharedLibrary_HelpShort[] =
    "shared_library: Declare a shared library target.";
const char kSharedLibrary_Help[] =
    R"(shared_library: Declare a shared library target.

  A shared library will be specified on the linker line for targets listing the
  shared library in its "deps". If you don't want this (say you dynamically
  load the library at runtime), then you should depend on the shared library
  via "data_deps" or, on Darwin platforms, use a "loadable_module" target type
  instead.

Language and compilation
)" LANGUAGE_HELP
    R"(

Variables

)" CONFIG_VALUES_VARS_HELP DEPS_VARS DEPENDENT_CONFIG_VARS GENERAL_TARGET_VARS
        RUST_SHARED_VARS;

Value RunSharedLibrary(Scope* scope,
                       const FunctionCallNode* function,
                       const std::vector<Value>& args,
                       BlockNode* block,
                       Err* err) {
  return ExecuteGenericTarget(functions::kSharedLibrary, scope, function, args,
                              block, err);
}

// source_set ------------------------------------------------------------------

const char kSourceSet[] = "source_set";
const char kSourceSet_HelpShort[] = "source_set: Declare a source set target.";
const char kSourceSet_Help[] =
    R"(source_set: Declare a source set target.

  Only C-language source sets are supported at the moment.

C-language source_sets

  A source set is a collection of sources that get compiled, but are not linked
  to produce any kind of library. Instead, the resulting object files are
  implicitly added to the linker line of all targets that depend on the source
  set.

  In most cases, a source set will behave like a static library, except no
  actual library file will be produced. This will make the build go a little
  faster by skipping creation of a large static library, while maintaining the
  organizational benefits of focused build targets.

  The main difference between a source set and a static library is around
  handling of exported symbols. Most linkers assume declaring a function
  exported means exported from the static library. The linker can then do dead
  code elimination to delete code not reachable from exported functions.

  A source set will not do this code elimination since there is no link step.
  This allows you to link many source sets into a shared library and have the
  "exported symbol" notation indicate "export from the final shared library and
  not from the intermediate targets." There is no way to express this concept
  when linking multiple static libraries into a shared library.

Variables

)" CONFIG_VALUES_VARS_HELP DEPS_VARS DEPENDENT_CONFIG_VARS GENERAL_TARGET_VARS;

Value RunSourceSet(Scope* scope,
                   const FunctionCallNode* function,
                   const std::vector<Value>& args,
                   BlockNode* block,
                   Err* err) {
  return ExecuteGenericTarget(functions::kSourceSet, scope, function, args,
                              block, err);
}

// static_library --------------------------------------------------------------

const char kStaticLibrary[] = "static_library";
const char kStaticLibrary_HelpShort[] =
    "static_library: Declare a static library target.";
const char kStaticLibrary_Help[] =
    R"(static_library: Declare a static library target.

  Make a ".a" / ".lib" file.

  If you only need the static library for intermediate results in the build,
  you should consider a source_set instead since it will skip the (potentially
  slow) step of creating the intermediate library file.

Variables

  complete_static_lib
)" CONFIG_VALUES_VARS_HELP DEPS_VARS DEPENDENT_CONFIG_VARS GENERAL_TARGET_VARS
        RUST_VARS LANGUAGE_HELP;

Value RunStaticLibrary(Scope* scope,
                       const FunctionCallNode* function,
                       const std::vector<Value>& args,
                       BlockNode* block,
                       Err* err) {
  return ExecuteGenericTarget(functions::kStaticLibrary, scope, function, args,
                              block, err);
}

// target ---------------------------------------------------------------------

const char kTarget[] = "target";
const char kTarget_HelpShort[] =
    "target: Declare an target with the given programmatic type.";
const char kTarget_Help[] =
    R"(target: Declare an target with the given programmatic type.

  target(target_type_string, target_name_string) { ... }

  The target() function is a way to invoke a built-in target or template with a
  type determined at runtime. This is useful for cases where the type of a
  target might not be known statically.

  Only templates and built-in target functions are supported for the
  target_type_string parameter. Arbitrary functions, configs, and toolchains
  are not supported.

  The call:
    target("source_set", "doom_melon") {
  Is equivalent to:
    source_set("doom_melon") {

Example

  if (foo_build_as_shared) {
    my_type = "shared_library"
  } else {
    my_type = "source_set"
  }

  target(my_type, "foo") {
    ...
  }
)";
Value RunTarget(Scope* scope,
                const FunctionCallNode* function,
                const std::vector<Value>& args,
                BlockNode* block,
                Err* err) {
  if (args.size() != 2) {
    *err = Err(function, "Expected two arguments.", "Try \"gn help target\".");
    return Value();
  }

  // The first argument must be a string (the target type). Don't type-check
  // the second argument since the target-specific function will do that.
  if (!args[0].VerifyTypeIs(Value::STRING, err))
    return Value();
  const std::string& target_type = args[0].string_value();

  // The rest of the args are passed to the function.
  std::vector<Value> sub_args(args.begin() + 1, args.end());

  // Run a template if it is one.
  const Template* templ = scope->GetTemplate(target_type);
  if (templ)
    return templ->Invoke(scope, function, target_type, sub_args, block, err);

  // Otherwise, assume the target is a built-in target type.
  return ExecuteGenericTarget(target_type.c_str(), scope, function, sub_args,
                              block, err);
}

const char kGeneratedFile[] = "generated_file";
const char kGeneratedFile_HelpShort[] =
    "generated_file: Declare a generated_file target.";
const char kGeneratedFile_Help[] =
    R"(generated_file: Declare a generated_file target.

  Writes data value(s) to disk on resolution. This target type mirrors some
  functionality of the write_file() function, but also provides the ability to
  collect metadata from its dependencies on resolution rather than writing out
  at parse time.

  The `outputs` variable is required to be a list with a single element,
  specifying the intended location of the output file.

  The `output_conversion` variable specified the format to write the
  value. See `gn help output_conversion`.

  One of `contents` or `data_keys` must be specified; use of `data` will write
  the contents of that value to file, while use of `data_keys` will trigger a
  metadata collection walk based on the dependencies of the target and the
  optional values of the `rebase` and `walk_keys` variables. See
  `gn help metadata`.

  Collected metadata, if specified, will be returned in postorder of
  dependencies. See the example for details.

Example (metadata collection)

  Given the following targets defined in //base/BUILD.gn, where A depends on B
  and B depends on C and D:

    group("a") {
      metadata = {
        doom_melon = [ "enable" ]
        my_files = [ "foo.cpp" ]

        # Note: this is functionally equivalent to not defining `my_barrier`
        # at all in this target's metadata.
        my_barrier = [ "" ]
      }

      deps = [ ":b" ]
    }

    group("b") {
      metadata = {
        my_files = [ "bar.cpp" ]
        my_barrier = [ ":c" ]
      }

      deps = [ ":c", ":d" ]
    }

    group("c") {
      metadata = {
        doom_melon = [ "disable" ]
        my_files = [ "baz.cpp" ]
      }
    }

    group("d") {
      metadata = {
        my_files = [ "missing.cpp" ]
      }
    }

  If the following generated_file target is defined:

    generated_file("my_files_metadata") {
      outputs = [ "$root_build_dir/my_files.json" ]
      data_keys = [ "my_files" ]

      deps = [ "//base:a" ]
    }

  The following will be written to "$root_build_dir/my_files.json" (less the
  comments):
    [
      "baz.cpp",  // from //base:c via //base:b
      "missing.cpp"  // from //base:d via //base:b
      "bar.cpp",  // from //base:b via //base:a
      "foo.cpp",  // from //base:a
    ]

  Alternatively, as an example of using walk_keys, if the following
  generated_file target is defined:

  generated_file("my_files_metadata") {
    outputs = [ "$root_build_dir/my_files.json" ]
    data_keys = [ "my_files" ]
    walk_keys = [ "my_barrier" ]

    deps = [ "//base:a" ]
  }

  The following will be written to "$root_build_dir/my_files.json" (again less
  the comments):
    [
      "baz.cpp",  // from //base:c via //base:b
      "bar.cpp",  // from //base:b via //base:a
      "foo.cpp",  // from //base:a
    ]

  If `rebase` is used in the following generated_file target:

  generated_file("my_files_metadata") {
    outputs = [ "$root_build_dir/my_files.json" ]
    data_keys = [ "my_files" ]
    walk_keys = [ "my_barrier" ]
    rebase = root_build_dir

    deps = [ "//base:a" ]
  }

  The following will be written to "$root_build_dir/my_files.json" (again less
  the comments) (assuming root_build_dir = "//out"):
    [
      "../base/baz.cpp",  // from //base:c via //base:b
      "../base/bar.cpp",  // from //base:b via //base:a
      "../base/foo.cpp",  // from //base:a
    ]


Variables

  contents
  data_keys
  rebase
  walk_keys
  output_conversion
)" DEPS_VARS DEPENDENT_CONFIG_VARS;

Value RunGeneratedFile(Scope* scope,
                       const FunctionCallNode* function,
                       const std::vector<Value>& args,
                       BlockNode* block,
                       Err* err) {
  return ExecuteGenericTarget(functions::kGeneratedFile, scope, function, args,
                              block, err);
}

}  // namespace functions
