v8 147.3.0

Rust bindings to V8
Documentation
# Copyright 2025 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import("//build/config/apple/apple_sdk.gni")
import("//build/config/c++/modules.gni")
import("//build/config/clang/clang.gni")
import("//build/config/compiler/compiler.gni")
import("//build/config/sysroot.gni")
if (use_xcode_symlinks) {
  import("//build/config/apple/mobile_config.gni")
}
if (is_win) {
  import("//build/toolchain/win/win_toolchain_data.gni")
}

configs_to_add = [
  "//buildtools/third_party/libc++:extra_flags",
  "//buildtools/third_party/libc++:stdver",
  "//build/config/compiler:no_chromium_code",
]

configs_to_remove = [
  "//build/config/compiler:chromium_code",
  "//build/config/coverage:default_coverage",
]

if (use_clang_modules) {
  template("clang_module") {
    source_set(target_name) {
      forward_variables_from(invoker, "*", [ "modulemap" ])
      use_libcxx_modules = false
      sources = [ invoker.modulemap ]
      module_name = target_name
      if (!defined(public_deps)) {
        public_deps = []
      }

      if (!defined(public_configs)) {
        public_configs = []
      }

      public_configs += [ "//build/config/compiler:libcxx_module" ]

      # Implicit module maps won't work on apple because we're currently
      # missing some dependencies.
      if (use_autogenerated_modules) {
        # Explicitly DO NOT use public configs here. If we have two framework
        # modules foo and bar, and only foo is transitively depended on by
        # libcxx:
        # * When building the module for libcxx, we want both -fmodule-map-file
        #   for both foo and bar, to ensure that if libcxx did depend on bar, we
        #   would throw an error.
        # * We may choose not to build bar because it's so rarely used that it
        #   won't increase performance to precompile it
        # * If we provide -fmodule-map-file=bar but choose not to build bar,
        #   then any target that did depend on bar would fail to compile.
        configs += [ "//buildtools/third_party/libc++:all_modulemap_configs" ]
      } else {
        if (use_xcode_symlinks) {
          # The `copy_sysroot_modulemaps` action depends on SDK paths that differ
          # between macOS and iOS, so it must be built with the correct toolchain
          # for the target OS.
          toolchain = "//build/toolchain/mac:clang_$target_cpu"
          if (is_ios || target_environment == "catalyst") {
            toolchain = "//build/toolchain/ios:ios_clang_$target_cpu"
          } else if (target_os == "ios" && is_mac) {
            toolchain = "//build/toolchain/mac:clang_$host_cpu"
          }
          public_deps += [ "//buildtools/third_party/libc++:copy_sysroot_modulemaps($toolchain)" ]
        }

        # By always including all module maps, we can get it to error out if
        # we attempt to include something not in your dependencies.
        # Otherwise, it would silently add it to your own AST.
        public_configs += [
          "//buildtools/third_party/libc++:builtin_modulemap",
          "//buildtools/third_party/libc++:libcxx_modulemap",
          "//buildtools/third_party/libc++:sysroot_modulemaps",
        ]
      }

      # Header files in modules need to be built with chromium_code config as
      # some warnings are not triggered if we use no_chromium_code config for
      # modules compiles.
      configs -= configs_to_remove - [ "//build/config/compiler:chromium_code" ]

      # The module needs to use the same version of -std that is used by the
      # libraries depending on it. Otherwise we get a module config mismatch.
      configs += configs_to_add - [
                   "//build/config/compiler:no_chromium_code",
                   "//buildtools/third_party/libc++:stdver",
                 ]

      # Any complex target-specific logic needs to go in here.
      # The modularize tool supports simple attributes, but not conditional
      # logic.
      if (target_name == "std_stdatomic_h" && use_cxx23) {
        # In cxx23, stdatomic.h uses libcxx's stdatomic rather than the
        # builtin.
        if (!is_win) {
          public_deps -= [ ":_Builtin_stdatomic" ]
        }
        public_deps += [ ":std" ]
      }
    }
  }

  template("builtin_module") {
    # This is a template to build modules that reside in clang builtin's module file.
    clang_module(target_name) {
      forward_variables_from(invoker, "*")
      modulemap = "${clang_base_path}/lib/clang/${clang_version}/include/module.modulemap"
      if (use_autogenerated_modules) {
        public_configs = [ "//buildtools/third_party/libc++:builtin_modulemap" ]
      }
    }
  }

  template("libcxx_module") {
    # This is a template to build modules that reside in libc++'s module file.
    clang_module(target_name) {
      forward_variables_from(invoker, "*")
      modulemap = "${root_build_dir}/gen/third_party/libc++/src/include/module.modulemap"
      deps = [
        "//buildtools/third_party/libc++:custom_headers",
        "//buildtools/third_party/libc++:libcxx_headers",
      ]
      if (use_autogenerated_modules) {
        public_configs = [ "//buildtools/third_party/libc++:libcxx_modulemap" ]
      }
    }
  }

  if (use_autogenerated_modules) {
    template("sysroot_module") {
      clang_module(target_name) {
        forward_variables_from(invoker, "*")
        modulemap = "${target_gen_dir}/module.modulemap"
        public_configs = [ ":sysroot_modulemap" ]
      }
    }
  } else if (is_apple) {
    template("DarwinBasic_module") {
      clang_module(target_name) {
        forward_variables_from(invoker, "*")
        modulemap = "$sdk_path/usr/include/DarwinBasic.modulemap"
      }
    }
    template("DarwinFoundation1_module") {
      clang_module(target_name) {
        forward_variables_from(invoker, "*")
        modulemap = "$sdk_path/usr/include/DarwinFoundation1.modulemap"
      }
    }
    template("DarwinFoundation2_module") {
      clang_module(target_name) {
        forward_variables_from(invoker, "*")
        modulemap = "$sdk_path/usr/include/DarwinFoundation2.modulemap"
      }
    }
    template("DarwinFoundation3_module") {
      clang_module(target_name) {
        forward_variables_from(invoker, "*")
        modulemap = "$sdk_path/usr/include/DarwinFoundation3.modulemap"
      }
    }
  } else {
    template("sysroot_module") {
      clang_module(target_name) {
        forward_variables_from(invoker, "*")
        modulemap = sysroot_modulemap
        deps = [
          ":custom_headers",
          ":libcxx_headers",
        ]
      }
    }
  }
}

template("modulemap_config") {
  config(target_name) {
    path = rebase_path(invoker.source, root_build_dir)
    cflags_cc = [ "-fmodule-map-file=${path}" ]
    swiftflags = [ "-Xcc=-fmodule-map-file=${path}" ]
  }
}

template("sysroot_modulemap") {
  content = read_file(invoker.source, "string")
  if (is_win) {
    if (current_cpu == "x64") {
      win_toolchain_data = win_toolchain_data_x64
    } else if (current_cpu == "x86") {
      win_toolchain_data = win_toolchain_data_x86
    } else if (current_cpu == "arm64") {
      win_toolchain_data = win_toolchain_data_arm64
    } else {
      assert(false,
             "Unsuppported windows CPU, add it to win_toolchain_data.gni")
    }

    # This must be relative to the directory the modulemap is contained within.
    content = string_replace(content,
                             "\$msvc",
                             rebase_path(win_toolchain_data.msvc_dir,
                                         target_gen_dir,
                                         root_build_dir))
    content = string_replace(content,
                             "\$windows_kits",
                             rebase_path(win_toolchain_data.windows_kits_dir,
                                         target_gen_dir,
                                         root_build_dir))
  } else {
    include_dir = "${sysroot}/usr/include"
    if (is_fuchsia) {
      include_dir = "${sysroot}/include"
    }

    # This must be relative to the directory the modulemap is contained within.
    content =
        string_replace(content,
                       "\$sysroot",
                       rebase_path(include_dir, target_gen_dir, root_build_dir))
  }
  write_file(invoker.out, content)

  modulemap_config(target_name) {
    source = invoker.out
  }
}

template("apple_sysroot_modulemap") {
  modulemap = "${sysroot_include_dir}/${invoker.sysroot_path}"
  modulemap_config(target_name) {
    source = modulemap
  }

  # sysroot_modulemaps can be inside the build directory. This no-op action
  # declares the modulemap files as outputs to satisfy GN's dependency
  # tracking when other targets use them as inputs.
  rel = string_split(rebase_path(modulemap, root_build_dir), "/")
  if (rel[0] == "..") {
    # It's not in the output directory so we can't declare it as an output file.
    group(target_name + "_file") {
    }
  } else {
    action(target_name + "_file") {
      script = "//build/noop.py"
      outputs = [ modulemap ]
    }
  }
}

template("apple_sysroot_module") {
  clang_module(target_name) {
    forward_variables_from(invoker,
                           "*",
                           [
                             "modulemap",
                             "modulemap_path",
                           ])
    modulemap = "${sysroot_include_dir}/${invoker.modulemap_path}"
    public_configs = [ invoker.modulemap ]
    if (!defined(public_deps)) {
      public_deps = []
    }

    # The no-op action above depends on SDK paths that differ between macOS and
    # iOS, so it must be built with the correct toolchain
    # for the target OS.
    if (use_xcode_symlinks) {
      toolchain = "//build/toolchain/mac:clang_$target_cpu"
      if (is_ios || target_environment == "catalyst") {
        toolchain = "//build/toolchain/ios:ios_clang_$target_cpu"
      } else if (target_os == "ios" && is_mac) {
        toolchain = "//build/toolchain/mac:clang_$host_cpu"
      }
      public_deps += [ "${invoker.modulemap}_file(${toolchain})" ]
    }
  }
}

template("framework_modulemap") {
  modulemap_config(target_name) {
    source =
        "${frameworks_dir}/${invoker.name}.framework/Modules/module.modulemap"
  }
}

template("framework_module") {
  clang_module(target_name) {
    forward_variables_from(invoker, "*", [ "framework" ])

    # :foo_modulemap -> ${frameworks_dir}/foo.framework/Modules/module.modulemap
    modulemap = string_replace(
            string_replace(invoker.modulemap, ":", "${frameworks_dir}/"),
            "_modulemap",
            ".framework/Modules/module.modulemap")
    public_configs = [ invoker.modulemap ]

    cflags = [
      # Some frameworks don't have proper umbrellas.
      "-Wno-incomplete-umbrella",
    ]
  }
}