aboutsummaryrefslogtreecommitdiff
path: root/ports/v8
diff options
context:
space:
mode:
Diffstat (limited to 'ports/v8')
-rw-r--r--ports/v8/3f8dc4b.patch155
-rw-r--r--ports/v8/CONTROL6
-rw-r--r--ports/v8/build.patch179
-rw-r--r--ports/v8/icu.gn71
-rw-r--r--ports/v8/portfile.cmake186
-rw-r--r--ports/v8/v8.patch89
-rw-r--r--ports/v8/v8.pc.in11
-rw-r--r--ports/v8/v8_libbase.pc.in10
-rw-r--r--ports/v8/v8_libplatform.pc.in10
-rw-r--r--ports/v8/v8_monolith.pc.in11
-rw-r--r--ports/v8/zlib.gn21
11 files changed, 749 insertions, 0 deletions
diff --git a/ports/v8/3f8dc4b.patch b/ports/v8/3f8dc4b.patch
new file mode 100644
index 000000000..6360a1d34
--- /dev/null
+++ b/ports/v8/3f8dc4b.patch
@@ -0,0 +1,155 @@
+diff --git a/src/objects/js-number-format.cc b/src/objects/js-number-format.cc
+index ad831c5..bcd4403 100644
+--- a/src/objects/js-number-format.cc
++++ b/src/objects/js-number-format.cc
+@@ -1241,44 +1241,33 @@
+ }
+
+ namespace {
+-Maybe<icu::UnicodeString> IcuFormatNumber(
++Maybe<bool> IcuFormatNumber(
+ Isolate* isolate,
+ const icu::number::LocalizedNumberFormatter& number_format,
+- Handle<Object> numeric_obj, icu::FieldPositionIterator* fp_iter) {
++ Handle<Object> numeric_obj, icu::number::FormattedNumber* formatted) {
+ // If it is BigInt, handle it differently.
+ UErrorCode status = U_ZERO_ERROR;
+- icu::number::FormattedNumber formatted;
+ if (numeric_obj->IsBigInt()) {
+ Handle<BigInt> big_int = Handle<BigInt>::cast(numeric_obj);
+ Handle<String> big_int_string;
+ ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, big_int_string,
+ BigInt::ToString(isolate, big_int),
+- Nothing<icu::UnicodeString>());
+- formatted = number_format.formatDecimal(
++ Nothing<bool>());
++ *formatted = number_format.formatDecimal(
+ {big_int_string->ToCString().get(), big_int_string->length()}, status);
+ } else {
+ double number = numeric_obj->IsNaN()
+ ? std::numeric_limits<double>::quiet_NaN()
+ : numeric_obj->Number();
+- formatted = number_format.formatDouble(number, status);
++ *formatted = number_format.formatDouble(number, status);
+ }
+ if (U_FAILURE(status)) {
+ // This happen because of icu data trimming trim out "unit".
+ // See https://bugs.chromium.org/p/v8/issues/detail?id=8641
+- THROW_NEW_ERROR_RETURN_VALUE(isolate,
+- NewTypeError(MessageTemplate::kIcuError),
+- Nothing<icu::UnicodeString>());
++ THROW_NEW_ERROR_RETURN_VALUE(
++ isolate, NewTypeError(MessageTemplate::kIcuError), Nothing<bool>());
+ }
+- if (fp_iter) {
+- formatted.getAllFieldPositions(*fp_iter, status);
+- }
+- icu::UnicodeString result = formatted.toString(status);
+- if (U_FAILURE(status)) {
+- THROW_NEW_ERROR_RETURN_VALUE(isolate,
+- NewTypeError(MessageTemplate::kIcuError),
+- Nothing<icu::UnicodeString>());
+- }
+- return Just(result);
++ return Just(true);
+ }
+
+ } // namespace
+@@ -1289,10 +1278,16 @@
+ Handle<Object> numeric_obj) {
+ DCHECK(numeric_obj->IsNumeric());
+
+- Maybe<icu::UnicodeString> maybe_format =
+- IcuFormatNumber(isolate, number_format, numeric_obj, nullptr);
++ icu::number::FormattedNumber formatted;
++ Maybe<bool> maybe_format =
++ IcuFormatNumber(isolate, number_format, numeric_obj, &formatted);
+ MAYBE_RETURN(maybe_format, Handle<String>());
+- return Intl::ToString(isolate, maybe_format.FromJust());
++ UErrorCode status = U_ZERO_ERROR;
++ icu::UnicodeString result = formatted.toString(status);
++ if (U_FAILURE(status)) {
++ THROW_NEW_ERROR(isolate, NewTypeError(MessageTemplate::kIcuError), String);
++ }
++ return Intl::ToString(isolate, result);
+ }
+
+ namespace {
+@@ -1405,12 +1400,18 @@
+ }
+
+ namespace {
+-Maybe<int> ConstructParts(Isolate* isolate, const icu::UnicodeString& formatted,
+- icu::FieldPositionIterator* fp_iter,
++Maybe<int> ConstructParts(Isolate* isolate,
++ icu::number::FormattedNumber* formatted,
+ Handle<JSArray> result, int start_index,
+ Handle<Object> numeric_obj, bool style_is_unit) {
++ UErrorCode status = U_ZERO_ERROR;
++ icu::UnicodeString formatted_text = formatted->toString(status);
++ if (U_FAILURE(status)) {
++ THROW_NEW_ERROR_RETURN_VALUE(
++ isolate, NewTypeError(MessageTemplate::kIcuError), Nothing<int>());
++ }
+ DCHECK(numeric_obj->IsNumeric());
+- int32_t length = formatted.length();
++ int32_t length = formatted_text.length();
+ int index = start_index;
+ if (length == 0) return Just(index);
+
+@@ -1419,13 +1420,14 @@
+ // other region covers some part of the formatted string. It's possible
+ // there's another field with exactly the same begin and end as this backdrop,
+ // in which case the backdrop's field_id of -1 will give it lower priority.
+- regions.push_back(NumberFormatSpan(-1, 0, formatted.length()));
++ regions.push_back(NumberFormatSpan(-1, 0, formatted_text.length()));
+
+ {
+- icu::FieldPosition fp;
+- while (fp_iter->next(fp)) {
+- regions.push_back(NumberFormatSpan(fp.getField(), fp.getBeginIndex(),
+- fp.getEndIndex()));
++ icu::ConstrainedFieldPosition cfp;
++ cfp.constrainCategory(UFIELD_CATEGORY_NUMBER);
++ while (formatted->nextPosition(cfp, status)) {
++ regions.push_back(
++ NumberFormatSpan(cfp.getField(), cfp.getStart(), cfp.getLimit()));
+ }
+ }
+
+@@ -1447,7 +1449,7 @@
+ Handle<String> substring;
+ ASSIGN_RETURN_ON_EXCEPTION_VALUE(
+ isolate, substring,
+- Intl::ToString(isolate, formatted, part.begin_pos, part.end_pos),
++ Intl::ToString(isolate, formatted_text, part.begin_pos, part.end_pos),
+ Nothing<int>());
+ Intl::AddElement(isolate, result, index, field_type_string, substring);
+ ++index;
+@@ -1467,20 +1469,19 @@
+ number_format->icu_number_formatter().raw();
+ CHECK_NOT_NULL(fmt);
+
+- icu::FieldPositionIterator fp_iter;
+- Maybe<icu::UnicodeString> maybe_format =
+- IcuFormatNumber(isolate, *fmt, numeric_obj, &fp_iter);
++ icu::number::FormattedNumber formatted;
++ Maybe<bool> maybe_format =
++ IcuFormatNumber(isolate, *fmt, numeric_obj, &formatted);
+ MAYBE_RETURN(maybe_format, Handle<JSArray>());
+-
+ UErrorCode status = U_ZERO_ERROR;
++
+ bool style_is_unit =
+ Style::UNIT == StyleFromSkeleton(fmt->toSkeleton(status));
+ CHECK(U_SUCCESS(status));
+
+ Handle<JSArray> result = factory->NewJSArray(0);
+- Maybe<int> maybe_format_to_parts =
+- ConstructParts(isolate, maybe_format.FromJust(), &fp_iter, result, 0,
+- numeric_obj, style_is_unit);
++ Maybe<int> maybe_format_to_parts = ConstructParts(
++ isolate, &formatted, result, 0, numeric_obj, style_is_unit);
+ MAYBE_RETURN(maybe_format_to_parts, Handle<JSArray>());
+
+ return result;
diff --git a/ports/v8/CONTROL b/ports/v8/CONTROL
new file mode 100644
index 000000000..604821739
--- /dev/null
+++ b/ports/v8/CONTROL
@@ -0,0 +1,6 @@
+Source: v8
+Version: 8.3.110.13
+Homepage: https://v8.dev
+Description: Google Chrome's JavaScript engine
+Build-Depends: icu, zlib, glib (linux), pthread (linux)
+Supports: !(arm|arm64|uwp|osx)
diff --git a/ports/v8/build.patch b/ports/v8/build.patch
new file mode 100644
index 000000000..7394c6591
--- /dev/null
+++ b/ports/v8/build.patch
@@ -0,0 +1,179 @@
+diff --git a/config/compiler/BUILD.gn b/config/compiler/BUILD.gn
+index 5a0984f54..4f301517b 100644
+--- a/config/compiler/BUILD.gn
++++ b/config/compiler/BUILD.gn
+@@ -1473,6 +1473,8 @@ config("default_warnings") {
+ # Disables.
+ "-Wno-missing-field-initializers", # "struct foo f = {0};"
+ "-Wno-unused-parameter", # Unused function parameters.
++ "-Wno-invalid-offsetof", # Use of "conditionally-supported" offsetof in c++17
++ "-Wno-range-loop-construct",
+ ]
+ }
+
+@@ -1887,11 +1889,21 @@ config("no_incompatible_pointer_warnings") {
+ # Shared settings for both "optimize" and "optimize_max" configs.
+ # IMPORTANT: On Windows "/O1" and "/O2" must go before the common flags.
+ if (is_win) {
+- common_optimize_on_cflags = [
++ common_optimize_on_cflags = []
++ if(is_clang) {
++ common_optimize_on_cflags += [
+ "/Ob2", # Both explicit and auto inlining.
++ ]
++ } else {
++ common_optimize_on_cflags += [
++ "/Ob3", # Both explicit and auto inlining.
++ ]
++ }
++ common_optimize_on_cflags += [
+ "/Oy-", # Disable omitting frame pointers, must be after /O2.
+ "/Zc:inline", # Remove unreferenced COMDAT (faster links).
+ ]
++
+ if (!is_asan) {
+ common_optimize_on_cflags += [
+ # Put data in separate COMDATs. This allows the linker
+diff --git a/config/linux/pkg-config.py b/config/linux/pkg-config.py
+index 5adf70cc3..1438c365b 100644
+--- a/config/linux/pkg-config.py
++++ b/config/linux/pkg-config.py
+@@ -41,7 +41,11 @@ from optparse import OptionParser
+ # Additionally, you can specify the option --atleast-version. This will skip
+ # the normal outputting of a dictionary and instead print true or false,
+ # depending on the return value of pkg-config for the given package.
+-
++#
++# --pkg_config_libdir=<path> allows direct override
++# of the PKG_CONFIG_LIBDIR environment library.
++#
++# --full-path-libs causes lib names to include their full path.
+
+ def SetConfigPath(options):
+ """Set the PKG_CONFIG_LIBDIR environment variable.
+@@ -105,11 +109,29 @@ def RewritePath(path, strip_prefix, sysroot):
+ return path
+
+
++flag_regex = re.compile("(-.)(.+)")
++
++def FlagReplace(matchobj):
++ if matchobj.group(1) == '-I':
++ return matchobj.group(1) + subprocess.check_output([u'cygpath',u'-w',matchobj.group(2)]).strip().decode("utf-8")
++ if matchobj.group(1) == '-L':
++ return matchobj.group(1) + subprocess.check_output([u'cygpath',u'-w',matchobj.group(2)]).strip().decode("utf-8")
++ if matchobj.group(1) == '-l':
++ return matchobj.group(1) + matchobj.group(2) + '.lib'
++ return matchobj.group(0)
++
++def ConvertGCCToMSVC(flags):
++ """Rewrites GCC flags into MSVC flags."""
++ if 'win32' not in sys.platform:
++ return flags
++ return [ flag_regex.sub(FlagReplace,flag) for flag in flags]
++
++
+ def main():
+ # If this is run on non-Linux platforms, just return nothing and indicate
+ # success. This allows us to "kind of emulate" a Linux build from other
+ # platforms.
+- if "linux" not in sys.platform:
++ if "linux" not in sys.platform and 'win32' not in sys.platform:
+ print("[[],[],[],[],[]]")
+ return 0
+
+@@ -122,12 +144,15 @@ def main():
+ parser.add_option('-a', action='store', dest='arch', type='string')
+ parser.add_option('--system_libdir', action='store', dest='system_libdir',
+ type='string', default='lib')
++ parser.add_option('--pkg_config_libdir', action='store', dest='pkg_config_libdir',
++ type='string')
+ parser.add_option('--atleast-version', action='store',
+ dest='atleast_version', type='string')
+ parser.add_option('--libdir', action='store_true', dest='libdir')
+ parser.add_option('--dridriverdir', action='store_true', dest='dridriverdir')
+ parser.add_option('--version-as-components', action='store_true',
+ dest='version_as_components')
++ parser.add_option('--full-path-libs', action='store_true', dest='full_path_libs')
+ (options, args) = parser.parse_args()
+
+ # Make a list of regular expressions to strip out.
+@@ -144,6 +169,10 @@ def main():
+ else:
+ prefix = ''
+
++ # Override PKG_CONFIG_LIBDIR
++ if options.pkg_config_libdir:
++ os.environ['PKG_CONFIG_LIBDIR'] = options.pkg_config_libdir
++
+ if options.atleast_version:
+ # When asking for the return value, just run pkg-config and print the return
+ # value, no need to do other work.
+@@ -203,7 +232,7 @@ def main():
+ # For now just split on spaces to get the args out. This will break if
+ # pkgconfig returns quoted things with spaces in them, but that doesn't seem
+ # to happen in practice.
+- all_flags = flag_string.strip().split(' ')
++ all_flags = ConvertGCCToMSVC(flag_string.strip().split(' '))
+
+
+ sysroot = options.sysroot
+@@ -220,7 +249,10 @@ def main():
+ continue;
+
+ if flag[:2] == '-l':
+- libs.append(RewritePath(flag[2:], prefix, sysroot))
++ library = RewritePath(flag[2:], prefix, sysroot)
++ # Skip math library on MSVC
++ if library != 'm.lib':
++ libs.append(library)
+ elif flag[:2] == '-L':
+ lib_dirs.append(RewritePath(flag[2:], prefix, sysroot))
+ elif flag[:2] == '-I':
+@@ -237,6 +269,14 @@ def main():
+ else:
+ cflags.append(flag)
+
++ if options.full_path_libs:
++ full_path_libs = []
++ for lib_dir in lib_dirs:
++ for lib in libs:
++ if os.path.isfile(lib_dir+"/"+lib):
++ full_path_libs.append(lib_dir+"/"+lib)
++ libs = full_path_libs
++
+ # Output a GN array, the first one is the cflags, the second are the libs. The
+ # JSON formatter prints GN compatible lists when everything is a list of
+ # strings.
+diff --git a/config/linux/pkg_config.gni b/config/linux/pkg_config.gni
+index 428e44ac0..a0d2175ee 100644
+--- a/config/linux/pkg_config.gni
++++ b/config/linux/pkg_config.gni
+@@ -45,6 +45,9 @@ declare_args() {
+ # in similar fashion by setting the `system_libdir` variable in the build's
+ # args.gn file to 'lib' or 'lib64' as appropriate for the target architecture.
+ system_libdir = "lib"
++
++ # Allow directly overriding the PKG_CONFIG_LIBDIR enviroment variable
++ pkg_config_libdir = ""
+ }
+
+ pkg_config_script = "//build/config/linux/pkg-config.py"
+@@ -87,6 +90,17 @@ if (host_pkg_config != "") {
+ host_pkg_config_args = pkg_config_args
+ }
+
++if (pkg_config_libdir != "") {
++ pkg_config_args += [
++ "--pkg_config_libdir",
++ pkg_config_libdir,
++ ]
++ host_pkg_config_args += [
++ "--pkg_config_libdir",
++ pkg_config_libdir,
++ ]
++}
++
+ template("pkg_config") {
+ assert(defined(invoker.packages),
+ "Variable |packages| must be defined to be a list in pkg_config.")
diff --git a/ports/v8/icu.gn b/ports/v8/icu.gn
new file mode 100644
index 000000000..60dc6b8b7
--- /dev/null
+++ b/ports/v8/icu.gn
@@ -0,0 +1,71 @@
+import("//build/config/linux/pkg_config.gni")
+
+declare_args() {
+ # Tells icu to load an external data file rather than rely on the icudata
+ # being linked directly into the binary.
+ icu_use_data_file = true
+ # If true, compile icu into a standalone static library. Currently this is
+ # only useful on Chrome OS.
+ icu_disable_thin_archive = false
+}
+
+pkg_config("system_icui18n") {
+ packages = [ "icu-i18n" ]
+ if (is_win) {
+ extra_args = ["--full-path-libs"] # Workaround the WinSDK having an older version of ICU
+ }
+}
+
+pkg_config("system_icuuc") {
+ packages = [ "icu-uc" ]
+ if (is_win) {
+ extra_args = ["--full-path-libs"] # Workaround the WinSDK having an older version of ICU
+ }
+}
+
+group("icu") {
+ public_deps = [
+ ":icui18n",
+ ":icuuc",
+ ]
+}
+
+config("icu_config") {
+ defines = [
+ "USING_SYSTEM_ICU=1",
+ ]
+ if(is_win){
+ if(!is_component_build) {
+ ldflags = ["/ignore:4099"] # needed on CI builds
+ }
+ defines += [ "UCHAR_TYPE=wchar_t" ]
+ }
+ else{
+ defines += [ "UCHAR_TYPE=uint16_t" ]
+ }
+ if (icu_use_data_file) {
+ defines += [ "ICU_UTIL_DATA_IMPL=ICU_UTIL_DATA_FILE" ]
+ } else {
+ defines += [ "ICU_UTIL_DATA_IMPL=ICU_UTIL_DATA_STATIC" ]
+ }
+}
+
+source_set("icui18n") {
+ public_configs = [
+ ":icu_config",
+ ":system_icui18n"
+ ]
+}
+
+source_set("icuuc") {
+ public_configs = [
+ ":icu_config",
+ ":system_icuuc"
+ ]
+}
+
+source_set("icudata") {
+ public_configs = [
+ ":icu_config",
+ ]
+}
diff --git a/ports/v8/portfile.cmake b/ports/v8/portfile.cmake
new file mode 100644
index 000000000..e2bb45da9
--- /dev/null
+++ b/ports/v8/portfile.cmake
@@ -0,0 +1,186 @@
+
+set(pkgver "8.3.110.13")
+
+set(ENV{DEPOT_TOOLS_WIN_TOOLCHAIN} 0)
+
+get_filename_component(GIT_PATH ${GIT} DIRECTORY)
+vcpkg_find_acquire_program(PYTHON2)
+get_filename_component(PYTHON2_PATH ${PYTHON2} DIRECTORY)
+vcpkg_find_acquire_program(GN)
+get_filename_component(GN_PATH ${GN} DIRECTORY)
+vcpkg_find_acquire_program(NINJA)
+get_filename_component(NINJA_PATH ${NINJA} DIRECTORY)
+
+vcpkg_add_to_path(PREPEND "${CURRENT_INSTALLED_DIR}/bin")
+vcpkg_add_to_path(PREPEND "${CURRENT_INSTALLED_DIR}/debug/bin")
+vcpkg_add_to_path(PREPEND "${GIT_PATH}")
+vcpkg_add_to_path(PREPEND "${PYTHON2_PATH}")
+vcpkg_add_to_path(PREPEND "${GN_PATH}")
+vcpkg_add_to_path(PREPEND "${NINJA_PATH}")
+if(WIN32)
+ vcpkg_acquire_msys(MSYS_ROOT PACKAGES pkg-config)
+ vcpkg_add_to_path("${MSYS_ROOT}/usr/bin")
+endif()
+
+set(VCPKG_KEEP_ENV_VARS PATH;DEPOT_TOOLS_WIN_TOOLCHAIN)
+
+function(v8_fetch)
+ set(oneValueArgs DESTINATION URL REF SOURCE)
+ set(multipleValuesArgs PATCHES)
+ cmake_parse_arguments(V8 "" "${oneValueArgs}" "${multipleValuesArgs}" ${ARGN})
+
+ if(NOT DEFINED V8_DESTINATION)
+ message(FATAL_ERROR "DESTINATION must be specified.")
+ endif()
+
+ if(NOT DEFINED V8_URL)
+ message(FATAL_ERROR "The git url must be specified")
+ endif()
+
+ if(NOT DEFINED V8_REF)
+ message(FATAL_ERROR "The git ref must be specified.")
+ endif()
+
+ if(EXISTS ${V8_SOURCE}/${V8_DESTINATION})
+ vcpkg_execute_required_process(
+ COMMAND ${GIT} reset --hard
+ WORKING_DIRECTORY ${V8_SOURCE}/${V8_DESTINATION}
+ LOGNAME build-${TARGET_TRIPLET})
+ else()
+ vcpkg_execute_required_process(
+ COMMAND ${GIT} clone --depth 1 ${V8_URL} ${V8_DESTINATION}
+ WORKING_DIRECTORY ${V8_SOURCE}
+ LOGNAME build-${TARGET_TRIPLET})
+ vcpkg_execute_required_process(
+ COMMAND ${GIT} fetch --depth 1 origin ${V8_REF}
+ WORKING_DIRECTORY ${V8_SOURCE}/${V8_DESTINATION}
+ LOGNAME build-${TARGET_TRIPLET})
+ vcpkg_execute_required_process(
+ COMMAND ${GIT} checkout FETCH_HEAD
+ WORKING_DIRECTORY ${V8_SOURCE}/${V8_DESTINATION}
+ LOGNAME build-${TARGET_TRIPLET})
+ endif()
+ foreach(PATCH ${V8_PATCHES})
+ vcpkg_execute_required_process(
+ COMMAND ${GIT} apply ${PATCH}
+ WORKING_DIRECTORY ${V8_SOURCE}/${V8_DESTINATION}
+ LOGNAME build-${TARGET_TRIPLET})
+ endforeach()
+endfunction()
+
+vcpkg_from_git(
+ OUT_SOURCE_PATH SOURCE_PATH
+ URL https://chromium.googlesource.com/v8/v8.git
+ REF 90904eb48b16b32f7edbf1f8a92ece561d05e738
+ PATCHES ${CURRENT_PORT_DIR}/v8.patch ${CURRENT_PORT_DIR}/3f8dc4b.patch
+)
+
+message(STATUS "Fetching submodules")
+v8_fetch(
+ DESTINATION build
+ URL https://chromium.googlesource.com/chromium/src/build.git
+ REF 26e9d485d01d6e0eb9dadd21df767a63494c8fea
+ SOURCE ${SOURCE_PATH}
+ PATCHES ${CURRENT_PORT_DIR}/build.patch)
+v8_fetch(
+ DESTINATION third_party/zlib
+ URL https://chromium.googlesource.com/chromium/src/third_party/zlib.git
+ REF 156be8c52f80cde343088b4a69a80579101b6e67
+ SOURCE ${SOURCE_PATH})
+v8_fetch(
+ DESTINATION base/trace_event/common
+ URL https://chromium.googlesource.com/chromium/src/base/trace_event/common.git
+ REF dab187b372fc17e51f5b9fad8201813d0aed5129
+ SOURCE ${SOURCE_PATH})
+v8_fetch(
+ DESTINATION third_party/googletest/src
+ URL https://chromium.googlesource.com/external/github.com/google/googletest.git
+ REF 10b1902d893ea8cc43c69541d70868f91af3646b
+ SOURCE ${SOURCE_PATH})
+v8_fetch(
+ DESTINATION third_party/jinja2
+ URL https://chromium.googlesource.com/chromium/src/third_party/jinja2.git
+ REF b41863e42637544c2941b574c7877d3e1f663e25
+ SOURCE ${SOURCE_PATH})
+v8_fetch(
+ DESTINATION third_party/markupsafe
+ URL https://chromium.googlesource.com/chromium/src/third_party/markupsafe.git
+ REF 8f45f5cfa0009d2a70589bcda0349b8cb2b72783
+ SOURCE ${SOURCE_PATH})
+
+vcpkg_execute_required_process(
+ COMMAND ${PYTHON2} build/util/lastchange.py -o build/util/LASTCHANGE
+ WORKING_DIRECTORY ${SOURCE_PATH}
+ LOGNAME build-${TARGET_TRIPLET}
+)
+
+file(MAKE_DIRECTORY "${SOURCE_PATH}/third_party/icu")
+configure_file(${CURRENT_PORT_DIR}/zlib.gn ${SOURCE_PATH}/third_party/zlib/BUILD.gn COPYONLY)
+configure_file(${CURRENT_PORT_DIR}/icu.gn ${SOURCE_PATH}/third_party/icu/BUILD.gn COPYONLY)
+
+if(UNIX)
+ set(UNIX_CURRENT_INSTALLED_DIR ${CURRENT_INSTALLED_DIR})
+ set(LIBS "-ldl -lpthread")
+ set(REQUIRES ", gmodule-2.0, gobject-2.0, gthread-2.0")
+elseif(WIN32)
+ execute_process(COMMAND cygpath "${CURRENT_INSTALLED_DIR}" OUTPUT_VARIABLE UNIX_CURRENT_INSTALLED_DIR)
+ string(STRIP ${UNIX_CURRENT_INSTALLED_DIR} UNIX_CURRENT_INSTALLED_DIR)
+ set(LIBS "-lWinmm -lDbgHelp")
+endif()
+
+if(VCPKG_LIBRARY_LINKAGE STREQUAL dynamic)
+ set(is_component_build true)
+ set(v8_monolithic false)
+ set(v8_use_external_startup_data true)
+ set(targets :v8_libbase :v8_libplatform :v8)
+else()
+ set(is_component_build false)
+ set(v8_monolithic true)
+ set(v8_use_external_startup_data false)
+ set(targets :v8_monolith)
+endif()
+
+message(STATUS "Generating v8 build files. Please wait...")
+
+vcpkg_configure_gn(
+ SOURCE_PATH ${SOURCE_PATH}
+ OPTIONS "is_component_build=${is_component_build} target_cpu=\"${VCPKG_TARGET_ARCHITECTURE}\" v8_monolithic=${v8_monolithic} v8_use_external_startup_data=${v8_use_external_startup_data} use_sysroot=false is_clang=false use_custom_libcxx=false v8_enable_verify_heap=false icu_use_data_file=false"
+ OPTIONS_DEBUG "is_debug=true enable_iterator_debugging=true pkg_config_libdir=\"${UNIX_CURRENT_INSTALLED_DIR}/debug/lib/pkgconfig\""
+ OPTIONS_RELEASE "is_debug=false enable_iterator_debugging=false pkg_config_libdir=\"${UNIX_CURRENT_INSTALLED_DIR}/lib/pkgconfig\""
+)
+
+message(STATUS "Building v8. Please wait...")
+
+vcpkg_install_gn(
+ SOURCE_PATH ${SOURCE_PATH}
+ TARGETS ${targets}
+)
+
+set(CFLAGS "-DV8_COMPRESS_POINTERS")
+if(VCPKG_TARGET_ARCHITECTURE STREQUAL "x64")
+ set(CFLAGS "${CFLAGS} -DV8_31BIT_SMIS_ON_64BIT_ARCH")
+endif()
+file(INSTALL ${SOURCE_PATH}/include DESTINATION ${CURRENT_PACKAGES_DIR}/include FILES_MATCHING PATTERN "*.h")
+if(VCPKG_LIBRARY_LINKAGE STREQUAL dynamic)
+ set(PREFIX ${CURRENT_PACKAGES_DIR})
+ configure_file(${CURRENT_PORT_DIR}/v8.pc.in ${CURRENT_PACKAGES_DIR}/lib/pkgconfig/v8.pc @ONLY)
+ configure_file(${CURRENT_PORT_DIR}/v8_libbase.pc.in ${CURRENT_PACKAGES_DIR}/lib/pkgconfig/v8_libbase.pc @ONLY)
+ configure_file(${CURRENT_PORT_DIR}/v8_libplatform.pc.in ${CURRENT_PACKAGES_DIR}/lib/pkgconfig/v8_libplatform.pc @ONLY)
+ set(PREFIX ${CURRENT_PACKAGES_DIR}/debug)
+ configure_file(${CURRENT_PORT_DIR}/v8.pc.in ${CURRENT_PACKAGES_DIR}/debug/lib/pkgconfig/v8.pc @ONLY)
+ configure_file(${CURRENT_PORT_DIR}/v8_libbase.pc.in ${CURRENT_PACKAGES_DIR}/debug/lib/pkgconfig/v8_libbase.pc @ONLY)
+ configure_file(${CURRENT_PORT_DIR}/v8_libplatform.pc.in ${CURRENT_PACKAGES_DIR}/debug/lib/pkgconfig/v8_libplatform.pc @ONLY)
+else()
+ set(PREFIX ${CURRENT_PACKAGES_DIR})
+ configure_file(${CURRENT_PORT_DIR}/v8_monolith.pc.in ${CURRENT_PACKAGES_DIR}/lib/pkgconfig/v8_monolith.pc @ONLY)
+ set(PREFIX ${CURRENT_PACKAGES_DIR}/debug)
+ configure_file(${CURRENT_PORT_DIR}/v8_monolith.pc.in ${CURRENT_PACKAGES_DIR}/debug/lib/pkgconfig/v8_monolith.pc @ONLY)
+endif()
+
+vcpkg_copy_pdbs()
+
+# v8 libraries are listed as SYSTEM_LIBRARIES because the pc files reference each other.
+vcpkg_fixup_pkgconfig(SYSTEM_LIBRARIES m dl pthread Winmm DbgHelp v8_libbase v8_libplatform v8)
+
+# Handle copyright
+file(INSTALL ${SOURCE_PATH}/LICENSE DESTINATION ${CURRENT_PACKAGES_DIR}/share/${PORT} RENAME copyright)
diff --git a/ports/v8/v8.patch b/ports/v8/v8.patch
new file mode 100644
index 000000000..8a58a50b9
--- /dev/null
+++ b/ports/v8/v8.patch
@@ -0,0 +1,89 @@
+diff --git a/src/compiler/node-cache.h b/src/compiler/node-cache.h
+index 935e5778e3..d5dae22512 100644
+--- a/src/compiler/node-cache.h
++++ b/src/compiler/node-cache.h
+@@ -29,7 +29,7 @@ class Node;
+ // nodes such as constants, parameters, etc.
+ template <typename Key, typename Hash = base::hash<Key>,
+ typename Pred = std::equal_to<Key> >
+-class EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE) NodeCache final {
++class V8_EXPORT_PRIVATE NodeCache final {
+ public:
+ explicit NodeCache(Zone* zone) : map_(zone) {}
+ ~NodeCache() = default;
+diff --git a/src/objects/feedback-vector.cc b/src/objects/feedback-vector.cc
+index 929b312f22..7beff3395d 100644
+--- a/src/objects/feedback-vector.cc
++++ b/src/objects/feedback-vector.cc
+@@ -114,9 +114,9 @@ Handle<FeedbackMetadata> FeedbackMetadata::New(LocalIsolate* isolate,
+ return metadata;
+ }
+
+-template Handle<FeedbackMetadata> FeedbackMetadata::New(
++template V8_EXPORT Handle<FeedbackMetadata> FeedbackMetadata::New(
+ Isolate* isolate, const FeedbackVectorSpec* spec);
+-template Handle<FeedbackMetadata> FeedbackMetadata::New(
++template V8_EXPORT Handle<FeedbackMetadata> FeedbackMetadata::New(
+ OffThreadIsolate* isolate, const FeedbackVectorSpec* spec);
+
+ bool FeedbackMetadata::SpecDiffersFrom(
+diff --git a/src/objects/ordered-hash-table.h b/src/objects/ordered-hash-table.h
+index b587960432..e80b5757e4 100644
+--- a/src/objects/ordered-hash-table.h
++++ b/src/objects/ordered-hash-table.h
+@@ -7,7 +7,11 @@
+
+ #include "src/base/export-template.h"
+ #include "src/common/globals.h"
++#if defined(_M_IX86) && defined(_MSC_VER)
++#include "src/objects/fixed-array-inl.h"
++#else
+ #include "src/objects/fixed-array.h"
++#endif
+ #include "src/objects/js-objects.h"
+ #include "src/objects/smi.h"
+ #include "src/roots/roots.h"
+diff --git a/src/snapshot/serializer-common.cc b/src/snapshot/serializer-common.cc
+index 9218d4eaa9..7b226de2f9 100644
+--- a/src/snapshot/serializer-common.cc
++++ b/src/snapshot/serializer-common.cc
+@@ -8,7 +8,7 @@
+ #include "src/objects/foreign-inl.h"
+ #include "src/objects/objects-inl.h"
+ #include "src/objects/slots.h"
+-#include "third_party/zlib/zlib.h"
++#include "zlib.h"
+
+ namespace v8 {
+ namespace internal {
+diff --git a/test/cctest/BUILD.gn b/test/cctest/BUILD.gn
+index 89fe36f65b..588950228b 100644
+--- a/test/cctest/BUILD.gn
++++ b/test/cctest/BUILD.gn
+@@ -421,6 +421,9 @@ v8_source_set("cctest_sources") {
+ # C4309: 'static_cast': truncation of constant value
+ cflags += [ "/wd4309" ]
+
++ # Buffer overrun warning... intended?
++ cflags += [ "/wd4789" ]
++
+ # MSVS wants this for gay-{precision,shortest}.cc.
+ cflags += [ "/bigobj" ]
+
+diff --git a/tools/v8windbg/BUILD.gn b/tools/v8windbg/BUILD.gn
+index 10d06a127f..a269b81136 100644
+--- a/tools/v8windbg/BUILD.gn
++++ b/tools/v8windbg/BUILD.gn
+@@ -8,6 +8,12 @@ config("v8windbg_config") {
+ # Required for successful compilation of SDK header file DbgModel.h.
+ cflags_cc = [ "/Zc:twoPhase-" ]
+
++ if(is_win && !is_clang){
++ # Avoid "The contents of <optional> are available only with C++17 or later."
++ # warning from MSVC
++ cflags_cc += [ "/std:c++latest" ]
++ }
++
+ include_dirs = [ "../.." ]
+ }
+
diff --git a/ports/v8/v8.pc.in b/ports/v8/v8.pc.in
new file mode 100644
index 000000000..5f5721725
--- /dev/null
+++ b/ports/v8/v8.pc.in
@@ -0,0 +1,11 @@
+prefix=@PREFIX@
+exec_prefix=${prefix}
+libdir=${prefix}/lib
+includedir=${prefix}/include
+
+Name: v8
+Description: V8 JavaScript Engine
+Version: @pkgver@
+Requires: zlib, icu-uc, icu-i18n, v8_libbase = @pkgver@
+Libs: -L${libdir} -lv8
+Cflags: -I${includedir} @CFLAGS@
diff --git a/ports/v8/v8_libbase.pc.in b/ports/v8/v8_libbase.pc.in
new file mode 100644
index 000000000..ad472abf9
--- /dev/null
+++ b/ports/v8/v8_libbase.pc.in
@@ -0,0 +1,10 @@
+prefix=@PREFIX@
+exec_prefix=${prefix}
+libdir=${prefix}/lib
+includedir=${prefix}/include
+
+Name: v8
+Description: V8 JavaScript Engine - Base library
+Version: @pkgver@
+Libs: -L${libdir} -lv8_libbase
+Cflags: -I${includedir} @CFLAGS@
diff --git a/ports/v8/v8_libplatform.pc.in b/ports/v8/v8_libplatform.pc.in
new file mode 100644
index 000000000..19c54ba79
--- /dev/null
+++ b/ports/v8/v8_libplatform.pc.in
@@ -0,0 +1,10 @@
+prefix=@PREFIX@
+exec_prefix=${prefix}
+libdir=${prefix}/lib
+includedir=${prefix}/include
+
+Name: v8
+Description: V8 JavaScript Engine - Platform library
+Version: @pkgver@
+Libs: -L${libdir} -lv8_libplatform
+Cflags: -I${includedir} @CFLAGS@
diff --git a/ports/v8/v8_monolith.pc.in b/ports/v8/v8_monolith.pc.in
new file mode 100644
index 000000000..b23c661e8
--- /dev/null
+++ b/ports/v8/v8_monolith.pc.in
@@ -0,0 +1,11 @@
+prefix=@PREFIX@
+exec_prefix=${prefix}
+libdir=${prefix}/lib
+includedir=${prefix}/include
+
+Name: v8
+Description: V8 JavaScript Engine
+Version: @pkgver@
+Requires: zlib, icu-uc, icu-i18n @REQUIRES@
+Libs: -L${libdir} -lv8_monolith @LIBS@
+Cflags: -I${includedir} @CFLAGS@
diff --git a/ports/v8/zlib.gn b/ports/v8/zlib.gn
new file mode 100644
index 000000000..570d0e22a
--- /dev/null
+++ b/ports/v8/zlib.gn
@@ -0,0 +1,21 @@
+import("//build/config/linux/pkg_config.gni")
+
+pkg_config("system_zlib") {
+ packages = [ "zlib" ]
+ defines = [ "USE_SYSTEM_ZLIB=1" ]
+}
+
+config("zlib_config") {
+ if(is_win && !is_component_build) {
+ ldflags = ["/ignore:4099"] # needed on VCPKG CI builds
+ }
+ configs = [
+ ":system_zlib",
+ ]
+}
+
+source_set("zlib") {
+ public_configs = [
+ ":system_zlib",
+ ]
+}