# 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 raw heap snapshots containing internals. Used for debugging memory
  # on platform and embedder level.
  v8_enable_raw_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
  # On Mac hosts, 32-bit builds targeting Windows can't use snapshots, see
  # https://crbug.com/794838
  v8_use_snapshot = !(is_win && host_os != "win" && target_cpu == "x64") &&
                    !(is_win && host_os == "mac" && target_cpu == "x86")

  # 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

  # Use Perfetto (https://perfetto.dev) as the default TracingController. Not
  # currently implemented.
  v8_use_perfetto = 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 + "/include/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",
]

if (is_debug && !v8_optimized_debug) {
  v8_remove_configs += [ "//build/config/compiler:default_optimization" ]
  v8_add_configs += [ "//build/config/compiler:no_optimize" ]
} else {
  v8_remove_configs += [ "//build/config/compiler:default_optimization" ]

  # TODO(crbug.com/621335) Rework this so that we don't have the confusion
  # between "optimize_speed" and "optimize_max".
  if (((is_posix && !is_android) || is_fuchsia) && !using_sanitizer) {
    v8_add_configs += [ "//build/config/compiler:optimize_speed" ]
  } else {
    v8_add_configs += [ "//build/config/compiler:optimize_max" ]
  }
}

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
  }
}
