# Copyright 2016 the V8 project 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/jumbo.gni")
import("//build/config/sanitizers/sanitizers.gni")
import("//build/config/v8_target_cpu.gni")
import("//build/split_static_library.gni")

declare_args() {
  # Set flags for tracking code coverage. Uses gcov with gcc and sanitizer
  # coverage with clang.
  v8_code_coverage = false

  # Includes files needed for correctness fuzzing.
  v8_correctness_fuzzer = false

  # Adds additional compile target for building multiple architectures at once.
  v8_multi_arch_build = false

  # Indicate if valgrind was fetched as a custom deps to make it available on
  # swarming.
  v8_has_valgrind = false

  # Indicate if gcmole was fetched as a hook to make it available on swarming.
  v8_gcmole = false

  # Turns on compiler optimizations in V8 in Debug build.
  v8_optimized_debug = true

  # Support for backtrace_symbols on linux.
  v8_enable_backtrace = ""

  # Enables full heap snapshots containing internals. Used for debugging memory
  # on platform and embedder level.
  v8_enable_full_heap_snapshots = false

  # Enable the snapshot feature, for fast context creation.
  # https://v8.dev/blog/custom-startup-snapshots
  # TODO(thakis): Make snapshots work in 64-bit win/cross builds,
  # https://803591
  v8_use_snapshot = !(is_win && host_os != "win" && target_cpu == "x64")

  # Enable several snapshots side-by-side (e.g. default and for trusted code).
  v8_use_multi_snapshots = false

  # Use external files for startup data blobs:
  # the JS builtins sources and the start snapshot.
  v8_use_external_startup_data = ""

  # Enable ECMAScript Internationalization API. Enabling this feature will
  # add a dependency on the ICU library.
  v8_enable_i18n_support = true

  # Use static libraries instead of source_sets.
  v8_static_library = false

  # Enable monolithic static library for embedders.
  v8_monolithic = false

  # Expose symbols for dynamic linking.
  v8_expose_symbols = false
}

if (v8_use_external_startup_data == "") {
  # If not specified as a gn arg, use external startup data by default if
  # a snapshot is used and if we're not on ios.
  v8_use_external_startup_data = v8_use_snapshot && !is_ios
}

if (v8_use_multi_snapshots) {
  # Silently disable multi snapshots if they're incompatible with the current
  # build configuration. This allows us to set v8_use_multi_snapshots=true on
  # all bots, and e.g. no-snapshot bots will automatically do the right thing.
  v8_use_multi_snapshots =
      v8_use_external_startup_data && !build_with_chromium && !use_jumbo_build
}

if (v8_enable_backtrace == "") {
  v8_enable_backtrace = is_debug && !v8_optimized_debug
}

# Points to // in v8 stand-alone or to //v8/ in chromium. We need absolute
# paths for all configs in templates as they are shared in different
# subdirectories.
v8_path_prefix = get_path_info("../", "abspath")

v8_inspector_js_protocol = v8_path_prefix + "/src/inspector/js_protocol.pdl"

###############################################################################
# Templates
#

# Common configs to remove or add in all v8 targets.
v8_remove_configs = []
v8_add_configs = [
  v8_path_prefix + ":features",
  v8_path_prefix + ":toolchain",
]

v8_remove_configs += [ "//build/config/compiler:default_optimization" ]
v8_add_configs += [ v8_path_prefix + ":default_optimization" ]

if (v8_code_coverage && !is_clang) {
  v8_add_configs += [
    v8_path_prefix + ":v8_gcov_coverage_cflags",
    v8_path_prefix + ":v8_gcov_coverage_ldflags",
  ]
}

if ((is_posix || is_fuchsia) &&
    (v8_enable_backtrace || v8_monolithic || v8_expose_symbols)) {
  v8_remove_configs += [ "//build/config/gcc:symbol_visibility_hidden" ]
  v8_add_configs += [ "//build/config/gcc:symbol_visibility_default" ]
}

# On MIPS gcc_target_rpath and ldso_path might be needed for all builds.
if (target_cpu == "mipsel" || target_cpu == "mips64el" ||
    target_cpu == "mips" || target_cpu == "mips64") {
  v8_add_configs += [ "//build/config/gcc:rpath_for_built_shared_libraries" ]
}

if (!build_with_chromium && is_clang) {
  v8_remove_configs += [ "//build/config/clang:find_bad_constructs" ]
}

# All templates should be kept in sync.
template("v8_source_set") {
  if (defined(invoker.split_count) && invoker.split_count > 1 &&
      defined(v8_static_library) && v8_static_library && is_win) {
    link_target_type = "jumbo_split_static_library"
  } else if (defined(v8_static_library) && v8_static_library) {
    link_target_type = "jumbo_static_library"
  } else {
    link_target_type = "jumbo_source_set"
  }
  target(link_target_type, target_name) {
    forward_variables_from(invoker,
                           "*",
                           [
                             "configs",
                             "remove_configs",
                           ])
    configs -= v8_remove_configs
    configs += v8_add_configs
    if (defined(invoker.remove_configs)) {
      configs -= invoker.remove_configs
    }
    configs += invoker.configs
  }
}

template("v8_header_set") {
  jumbo_source_set(target_name) {
    forward_variables_from(invoker, "*", [ "configs" ])
    configs -= v8_remove_configs
    configs += v8_add_configs
    configs += invoker.configs
  }
}

template("v8_executable") {
  executable(target_name) {
    forward_variables_from(invoker,
                           "*",
                           [
                             "configs",
                             "remove_configs",
                           ])
    configs -= v8_remove_configs
    configs += v8_add_configs
    if (defined(invoker.remove_configs)) {
      configs -= invoker.remove_configs
    }
    configs += invoker.configs
    if (is_linux) {
      # For enabling ASLR.
      ldflags = [ "-pie" ]
    }
    if (defined(testonly) && testonly && v8_code_coverage) {
      # Only add code coverage cflags for non-test files for performance
      # reasons.
      if (is_clang) {
        configs -= [ "//build/config/sanitizers:default_sanitizer_flags" ]
        configs +=
            [ "//build/config/sanitizers:default_sanitizer_flags_but_coverage" ]
      } else {
        configs -= [ v8_path_prefix + ":v8_gcov_coverage_cflags" ]
      }
    }
    deps += [ v8_path_prefix + ":v8_dump_build_config" ]
  }
}

template("v8_component") {
  component(target_name) {
    forward_variables_from(invoker, "*", [ "configs" ])
    configs -= v8_remove_configs
    configs += v8_add_configs
    configs += invoker.configs
  }
}

template("v8_static_library") {
  static_library(target_name) {
    complete_static_lib = true
    forward_variables_from(invoker, "*", [ "configs" ])
    configs -= v8_remove_configs
    configs -= [ "//build/config/compiler:thin_archive" ]
    configs += v8_add_configs
    configs += invoker.configs
  }
}
