From 32af45d241d7682a7807e76b5693078f273abdba Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Sat, 11 Nov 2023 18:51:05 +0900 Subject: [PATCH] build: add GN build files MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR-URL: https://github.com/nodejs/node/pull/47637 Reviewed-By: Michaƫl Zasso Reviewed-By: James M Snell Reviewed-By: Yagiz Nizipli --- BUILD.gn | 14 ++ deps/ada/BUILD.gn | 14 ++ deps/ada/unofficial.gni | 29 +++ deps/base64/BUILD.gn | 14 ++ deps/base64/unofficial.gni | 141 +++++++++++++ deps/brotli/BUILD.gn | 14 ++ deps/brotli/unofficial.gni | 45 +++++ deps/cares/BUILD.gn | 14 ++ deps/cares/unofficial.gni | 81 ++++++++ deps/googletest/BUILD.gn | 14 ++ deps/googletest/unofficial.gni | 41 ++++ deps/histogram/BUILD.gn | 14 ++ deps/histogram/unofficial.gni | 38 ++++ deps/llhttp/BUILD.gn | 14 ++ deps/llhttp/unofficial.gni | 34 ++++ deps/nghttp2/BUILD.gn | 14 ++ deps/nghttp2/unofficial.gni | 45 +++++ deps/ngtcp2/BUILD.gn | 14 ++ deps/ngtcp2/unofficial.gni | 74 +++++++ deps/openssl/BUILD.gn | 14 ++ deps/openssl/unofficial.gni | 151 ++++++++++++++ deps/postject/BUILD.gn | 14 ++ deps/postject/unofficial.gni | 21 ++ deps/simdutf/BUILD.gn | 14 ++ deps/simdutf/unofficial.gni | 37 ++++ deps/uv/BUILD.gn | 14 ++ deps/uv/unofficial.gni | 110 +++++++++++ deps/uvwasi/BUILD.gn | 14 ++ deps/uvwasi/unofficial.gni | 38 ++++ node.gni | 67 +++++++ src/inspector/BUILD.gn | 14 ++ src/inspector/unofficial.gni | 81 ++++++++ tools/generate_config_gypi.py | 75 +++++++ tools/gypi_to_gn.py | 219 ++++++++++++++++++++ tools/search_files.py | 20 ++ unofficial.gni | 352 +++++++++++++++++++++++++++++++++ 36 files changed, 1923 insertions(+) create mode 100644 BUILD.gn create mode 100644 deps/ada/BUILD.gn create mode 100644 deps/ada/unofficial.gni create mode 100644 deps/base64/BUILD.gn create mode 100644 deps/base64/unofficial.gni create mode 100644 deps/brotli/BUILD.gn create mode 100644 deps/brotli/unofficial.gni create mode 100644 deps/cares/BUILD.gn create mode 100644 deps/cares/unofficial.gni create mode 100644 deps/googletest/BUILD.gn create mode 100644 deps/googletest/unofficial.gni create mode 100644 deps/histogram/BUILD.gn create mode 100644 deps/histogram/unofficial.gni create mode 100644 deps/llhttp/BUILD.gn create mode 100644 deps/llhttp/unofficial.gni create mode 100644 deps/nghttp2/BUILD.gn create mode 100644 deps/nghttp2/unofficial.gni create mode 100644 deps/ngtcp2/BUILD.gn create mode 100644 deps/ngtcp2/unofficial.gni create mode 100644 deps/openssl/BUILD.gn create mode 100644 deps/openssl/unofficial.gni create mode 100644 deps/postject/BUILD.gn create mode 100644 deps/postject/unofficial.gni create mode 100644 deps/simdutf/BUILD.gn create mode 100644 deps/simdutf/unofficial.gni create mode 100644 deps/uv/BUILD.gn create mode 100644 deps/uv/unofficial.gni create mode 100644 deps/uvwasi/BUILD.gn create mode 100644 deps/uvwasi/unofficial.gni create mode 100644 node.gni create mode 100644 src/inspector/BUILD.gn create mode 100644 src/inspector/unofficial.gni create mode 100755 tools/generate_config_gypi.py create mode 100755 tools/gypi_to_gn.py create mode 100755 tools/search_files.py create mode 100644 unofficial.gni diff --git a/BUILD.gn b/BUILD.gn new file mode 100644 index 00000000000..1ed186b597e --- /dev/null +++ b/BUILD.gn @@ -0,0 +1,14 @@ +############################################################################## +# # +# DO NOT EDIT THIS FILE! # +# # +############################################################################## + +# This file is used by GN for building, which is NOT the build system used for +# building official binaries. +# Please modify the gyp files if you are making changes to build system. + +import("unofficial.gni") + +node_gn_build("node") { +} diff --git a/deps/ada/BUILD.gn b/deps/ada/BUILD.gn new file mode 100644 index 00000000000..e92ac3a3bea --- /dev/null +++ b/deps/ada/BUILD.gn @@ -0,0 +1,14 @@ +############################################################################## +# # +# DO NOT EDIT THIS FILE! # +# # +############################################################################## + +# This file is used by GN for building, which is NOT the build system used for +# building official binaries. +# Please modify the gyp files if you are making changes to build system. + +import("unofficial.gni") + +ada_gn_build("ada") { +} diff --git a/deps/ada/unofficial.gni b/deps/ada/unofficial.gni new file mode 100644 index 00000000000..d3d14193c5a --- /dev/null +++ b/deps/ada/unofficial.gni @@ -0,0 +1,29 @@ +# Copyright 2023 Microsoft Inc. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +# This file is used by GN for building, which is NOT the build system used for +# building official binaries. +# Please edit the gyp files if you are making changes to build system. + +import("../../node.gni") +import("$node_v8_path/gni/v8.gni") + +# The actual configurations are put inside a template in unofficial.gni to +# prevent accidental edits from contributors. +template("ada_gn_build") { + config("ada_config") { + include_dirs = [ "." ] + } + + gypi_values = exec_script("../../tools/gypi_to_gn.py", + [ rebase_path("ada.gyp") ], + "scope", + [ "ada.gyp" ]) + + source_set(target_name) { + forward_variables_from(invoker, "*") + public_configs = [ ":ada_config" ] + sources = gypi_values.ada_sources + } +} diff --git a/deps/base64/BUILD.gn b/deps/base64/BUILD.gn new file mode 100644 index 00000000000..172dd960910 --- /dev/null +++ b/deps/base64/BUILD.gn @@ -0,0 +1,14 @@ +############################################################################## +# # +# DO NOT EDIT THIS FILE! # +# # +############################################################################## + +# This file is used by GN for building, which is NOT the build system used for +# building official binaries. +# Please modify the gyp files if you are making changes to build system. + +import("unofficial.gni") + +base64_gn_build("base64") { +} diff --git a/deps/base64/unofficial.gni b/deps/base64/unofficial.gni new file mode 100644 index 00000000000..8138d88798e --- /dev/null +++ b/deps/base64/unofficial.gni @@ -0,0 +1,141 @@ +# Copyright (c) 2013-2022 GitHub Inc. +# Copyright 2022 the V8 project authors. All rights reserved. +# Copyright 2023 Microsoft Inc. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +# This file is used by GN for building, which is NOT the build system used for +# building official binaries. +# Please edit the gyp files if you are making changes to build system. + +# The actual configurations are put inside a template in unofficial.gni to +# prevent accidental edits from contributors. +template("base64_gn_build") { + config("base64_external_config") { + include_dirs = [ "base64/include" ] + if (!is_component_build) { + defines = [ "BASE64_STATIC_DEFINE" ] + } + } + + config("base64_internal_config") { + include_dirs = [ "base64/lib" ] + if (is_component_build) { + defines = [ "BASE64_EXPORTS" ] + } else { + defines = [] + } + if (target_cpu == "x86" || target_cpu == "x64") { + defines += [ + "HAVE_SSSE3=1", + "HAVE_SSE41=1", + "HAVE_SSE42=1", + "HAVE_AVX=1", + "HAVE_AVX2=1", + ] + } + if (target_cpu == "arm") { + defines += [ "HAVE_NEON32=1" ] + } + if (target_cpu == "arm64") { + defines += [ "HAVE_NEON64=1" ] + } + if (is_clang || !is_win) { + cflags_c = [ + "-Wno-implicit-fallthrough", + "-Wno-shadow", + "-Wno-unused-but-set-variable", + ] + } + } + + gypi_values = exec_script("../../tools/gypi_to_gn.py", + [ rebase_path("base64.gyp") ], + "scope", + [ "base64.gyp" ]) + + component(target_name) { + forward_variables_from(invoker, "*") + configs += [ ":base64_internal_config" ] + public_configs = [ ":base64_external_config" ] + sources = gypi_values.base64_sources_common + deps = [ + ":base64_ssse3", + ":base64_sse41", + ":base64_sse42", + ":base64_avx", + ":base64_avx2", + ":base64_neon32", + ":base64_neon64", + ] + } + + source_set("base64_ssse3") { + configs += [ ":base64_internal_config" ] + sources = [ "base64/lib/arch/ssse3/codec.c" ] + if (target_cpu == "x86" || target_cpu == "x64") { + if (is_clang || !is_win) { + cflags_c = [ "-mssse3" ] + } + } + } + + source_set("base64_sse41") { + configs += [ ":base64_internal_config" ] + sources = [ "base64/lib/arch/sse41/codec.c" ] + if (target_cpu == "x86" || target_cpu == "x64") { + if (is_clang || !is_win) { + cflags_c = [ "-msse4.1" ] + } + } + } + + source_set("base64_sse42") { + configs += [ ":base64_internal_config" ] + sources = [ "base64/lib/arch/sse42/codec.c" ] + if (target_cpu == "x86" || target_cpu == "x64") { + if (is_clang || !is_win) { + cflags_c = [ "-msse4.2" ] + } + } + } + + source_set("base64_avx") { + configs += [ ":base64_internal_config" ] + sources = [ "base64/lib/arch/avx/codec.c" ] + if (target_cpu == "x86" || target_cpu == "x64") { + if (is_clang || !is_win) { + cflags_c = [ "-mavx" ] + } else if (is_win) { + cflags_c = [ "/arch:AVX" ] + } + } + } + source_set("base64_avx2") { + configs += [ ":base64_internal_config" ] + sources = [ "base64/lib/arch/avx2/codec.c" ] + if (target_cpu == "x86" || target_cpu == "x64") { + if (is_clang || !is_win) { + cflags_c = [ "-mavx2" ] + } else if (is_win) { + cflags_c = [ "/arch:AVX2" ] + } + } + } + + source_set("base64_neon32") { + configs += [ ":base64_internal_config" ] + sources = [ "base64/lib/arch/neon32/codec.c" ] + if (target_cpu == "arm") { + if (is_clang || !is_win) { + cflags_c = [ "-mfpu=neon" ] + } + } + } + + source_set("base64_neon64") { + configs += [ ":base64_internal_config" ] + sources = [ "base64/lib/arch/neon64/codec.c" ] + # NEON is required in arm64, so no -mfpu flag is needed + } +} diff --git a/deps/brotli/BUILD.gn b/deps/brotli/BUILD.gn new file mode 100644 index 00000000000..8bdf8ce74d9 --- /dev/null +++ b/deps/brotli/BUILD.gn @@ -0,0 +1,14 @@ +############################################################################## +# # +# DO NOT EDIT THIS FILE! # +# # +############################################################################## + +# This file is used by GN for building, which is NOT the build system used for +# building official binaries. +# Please modify the gyp files if you are making changes to build system. + +import("unofficial.gni") + +brotli_gn_build("brotli") { +} diff --git a/deps/brotli/unofficial.gni b/deps/brotli/unofficial.gni new file mode 100644 index 00000000000..ce1df0d14cc --- /dev/null +++ b/deps/brotli/unofficial.gni @@ -0,0 +1,45 @@ +# Copyright 2014 The Chromium Authors. All rights reserved. +# Copyright 2019 the V8 project authors. All rights reserved. +# Copyright 2023 Microsoft Inc. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +# This file is used by GN for building, which is NOT the build system used for +# building official binaries. +# Please edit the gyp files if you are making changes to build system. + +# The actual configurations are put inside a template in unofficial.gni to +# prevent accidental edits from contributors. +template("brotli_gn_build") { + config("brotli_config") { + include_dirs = [ "c/include" ] + } + + gypi_values = exec_script("../../tools/gypi_to_gn.py", + [ rebase_path("brotli.gyp") ], + "scope", + [ "brotli.gyp" ]) + + source_set(target_name) { + forward_variables_from(invoker, "*") + public_configs = [ ":brotli_config" ] + sources = gypi_values.brotli_sources + if (is_linux) { + defines = [ "OS_LINUX" ] + } else if (is_mac) { + defines = [ "OS_MACOSX" ] + } else if (target_os == "freebsd") { + defines = [ "OS_FREEBSD" ] + } + if (!is_win) { + libs = [ "m" ] + } + if (is_clang || !is_win) { + cflags_c = [ + "-Wno-implicit-fallthrough", + "-Wno-unreachable-code", + "-Wno-unreachable-code-return", + ] + } + } +} diff --git a/deps/cares/BUILD.gn b/deps/cares/BUILD.gn new file mode 100644 index 00000000000..ac19ac73ed1 --- /dev/null +++ b/deps/cares/BUILD.gn @@ -0,0 +1,14 @@ +############################################################################## +# # +# DO NOT EDIT THIS FILE! # +# # +############################################################################## + +# This file is used by GN for building, which is NOT the build system used for +# building official binaries. +# Please modify the gyp files if you are making changes to build system. + +import("unofficial.gni") + +cares_gn_build("cares") { +} diff --git a/deps/cares/unofficial.gni b/deps/cares/unofficial.gni new file mode 100644 index 00000000000..07e2ed65b36 --- /dev/null +++ b/deps/cares/unofficial.gni @@ -0,0 +1,81 @@ +# Copyright (c) 2013-2019 GitHub Inc. +# Copyright 2019 the V8 project authors. All rights reserved. +# Copyright 2023 Microsoft Inc. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +# This file is used by GN for building, which is NOT the build system used for +# building official binaries. +# Please edit the gyp files if you are making changes to build system. + +# The actual configurations are put inside a template in unofficial.gni to +# prevent accidental edits from contributors. +template("cares_gn_build") { + config("cares_config") { + include_dirs = [ "include" ] + if (!is_component_build) { + defines = [ "CARES_STATICLIB" ] + } + } + + gypi_values = exec_script("../../tools/gypi_to_gn.py", + [ rebase_path("cares.gyp") ], + "scope", + [ "cares.gyp" ]) + + component(target_name) { + forward_variables_from(invoker, "*") + public_configs = [ ":cares_config" ] + if (is_component_build) { + defines = [ "CARES_BUILDING_LIBRARY" ] + } else { + defines = [] + } + if (is_win) { + defines += [ "CARES_PULL_WS2TCPIP_H=1" ] + } + if (is_posix) { + defines += [ + "_DARWIN_USE_64_BIT_INODE=1", + "_LARGEFILE_SOURCE", + "_FILE_OFFSET_BITS=64", + "_GNU_SOURCE", + "HAVE_CONFIG_H", + ] + } + + include_dirs = [ "src/lib" ] + if (is_win) { + include_dirs += [ "config/win32" ] + } else if (is_linux) { + include_dirs += [ "config/linux" ] + } else if (is_mac) { + include_dirs += [ "config/darwin" ] + } + + if (is_win) { + libs = [ + "ws2_32.lib", + "iphlpapi.lib", + ] + } + + sources = gypi_values.cares_sources_common + if (is_win) { + sources += gypi_values.cares_sources_win + } + if (is_linux) { + sources += [ "config/linux/ares_config.h" ] + } + if (is_mac) { + sources += [ "config/darwin/ares_config.h" ] + } + + if (is_clang || !is_win) { + cflags_c = [ + "-Wno-implicit-fallthrough", + "-Wno-unreachable-code", + ] + } + } +} diff --git a/deps/googletest/BUILD.gn b/deps/googletest/BUILD.gn new file mode 100644 index 00000000000..de13f3f653b --- /dev/null +++ b/deps/googletest/BUILD.gn @@ -0,0 +1,14 @@ +############################################################################## +# # +# DO NOT EDIT THIS FILE! # +# # +############################################################################## + +# This file is used by GN for building, which is NOT the build system used for +# building official binaries. +# Please modify the gyp files if you are making changes to build system. + +import("unofficial.gni") + +googletest_gn_build("googletest") { +} diff --git a/deps/googletest/unofficial.gni b/deps/googletest/unofficial.gni new file mode 100644 index 00000000000..e262d1bc182 --- /dev/null +++ b/deps/googletest/unofficial.gni @@ -0,0 +1,41 @@ +# Copyright 2021 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. + +# This file is used by GN for building, which is NOT the build system used for +# building official binaries. +# Please edit the gyp files if you are making changes to build system. + +# The actual configurations are put inside a template in unofficial.gni to +# prevent accidental edits from contributors. +template("googletest_gn_build") { + config("googletest_config") { + include_dirs = [ "include" ] + } + + gypi_values = exec_script("../../tools/gypi_to_gn.py", + [ rebase_path("googletest.gyp") ], + "scope", + [ "googletest.gyp" ]) + + source_set(target_name) { + forward_variables_from(invoker, "*") + testonly = true + include_dirs = [ + "include", + ".", + ] + defines = [ + "GTEST_HAS_POSIX_RE=0", + "GTEST_LANG_CXX11=1", + ] + sources = gypi_values.googletest_sources + } + + source_set("gtest_main") { + testonly = true + deps = [ ":googletest" ] + sources = [ "src/gtest_main.cc" ] + public_configs = [ ":googletest_config" ] + } +} diff --git a/deps/histogram/BUILD.gn b/deps/histogram/BUILD.gn new file mode 100644 index 00000000000..e2f3ee37137 --- /dev/null +++ b/deps/histogram/BUILD.gn @@ -0,0 +1,14 @@ +############################################################################## +# # +# DO NOT EDIT THIS FILE! # +# # +############################################################################## + +# This file is used by GN for building, which is NOT the build system used for +# building official binaries. +# Please modify the gyp files if you are making changes to build system. + +import("unofficial.gni") + +histogram_gn_build("histogram") { +} diff --git a/deps/histogram/unofficial.gni b/deps/histogram/unofficial.gni new file mode 100644 index 00000000000..eedb6204909 --- /dev/null +++ b/deps/histogram/unofficial.gni @@ -0,0 +1,38 @@ +# Copyright (c) 2013-2019 GitHub Inc. +# Copyright 2019 the V8 project authors. All rights reserved. +# Copyright 2023 Microsoft Inc. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +# This file is used by GN for building, which is NOT the build system used for +# building official binaries. +# Please edit the gyp files if you are making changes to build system. + +# The actual configurations are put inside a template in unofficial.gni to +# prevent accidental edits from contributors. +template("histogram_gn_build") { + config("histogram_config") { + include_dirs = [ "include" ] + } + + gypi_values = exec_script("../../tools/gypi_to_gn.py", + [ rebase_path("histogram.gyp") ], + "scope", + [ "histogram.gyp" ]) + + source_set(target_name) { + forward_variables_from(invoker, "*") + public_configs = [ ":histogram_config" ] + sources = gypi_values.histogram_sources + if (is_clang || !is_win) { + cflags_c = [ + "-Wno-atomic-alignment", + "-Wno-incompatible-pointer-types", + "-Wno-unused-function", + ] + } + if (is_linux) { + libs = [ "atomic" ] + } + } +} diff --git a/deps/llhttp/BUILD.gn b/deps/llhttp/BUILD.gn new file mode 100644 index 00000000000..64a2a4799d5 --- /dev/null +++ b/deps/llhttp/BUILD.gn @@ -0,0 +1,14 @@ +############################################################################## +# # +# DO NOT EDIT THIS FILE! # +# # +############################################################################## + +# This file is used by GN for building, which is NOT the build system used for +# building official binaries. +# Please modify the gyp files if you are making changes to build system. + +import("unofficial.gni") + +llhttp_gn_build("llhttp") { +} diff --git a/deps/llhttp/unofficial.gni b/deps/llhttp/unofficial.gni new file mode 100644 index 00000000000..80e360d4726 --- /dev/null +++ b/deps/llhttp/unofficial.gni @@ -0,0 +1,34 @@ +# Copyright (c) 2013-2019 GitHub Inc. +# Copyright 2019 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. + +# This file is used by GN for building, which is NOT the build system used for +# building official binaries. +# Please edit the gyp files if you are making changes to build system. + +# The actual configurations are put inside a template in unofficial.gni to +# prevent accidental edits from contributors. +template("llhttp_gn_build") { + config("llhttp_config") { + include_dirs = [ "include" ] + } + + gypi_values = exec_script("../../tools/gypi_to_gn.py", + [ rebase_path("llhttp.gyp") ], + "scope", + [ "llhttp.gyp" ]) + + source_set(target_name) { + forward_variables_from(invoker, "*") + public_configs = [ ":llhttp_config" ] + include_dirs = [ "include" ] + sources = gypi_values.llhttp_sources + if (is_clang || !is_win) { + cflags_c = [ + "-Wno-implicit-fallthrough", + "-Wno-unreachable-code", + ] + } + } +} diff --git a/deps/nghttp2/BUILD.gn b/deps/nghttp2/BUILD.gn new file mode 100644 index 00000000000..274352b0e24 --- /dev/null +++ b/deps/nghttp2/BUILD.gn @@ -0,0 +1,14 @@ +############################################################################## +# # +# DO NOT EDIT THIS FILE! # +# # +############################################################################## + +# This file is used by GN for building, which is NOT the build system used for +# building official binaries. +# Please modify the gyp files if you are making changes to build system. + +import("unofficial.gni") + +nghttp2_gn_build("nghttp2") { +} diff --git a/deps/nghttp2/unofficial.gni b/deps/nghttp2/unofficial.gni new file mode 100644 index 00000000000..0d84500a66f --- /dev/null +++ b/deps/nghttp2/unofficial.gni @@ -0,0 +1,45 @@ +# Copyright (c) 2013-2019 GitHub Inc. +# Copyright 2019 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. + +# This file is used by GN for building, which is NOT the build system used for +# building official binaries. +# Please edit the gyp files if you are making changes to build system. + +# The actual configurations are put inside a template in unofficial.gni to +# prevent accidental edits from contributors. +template("nghttp2_gn_build") { + config("nghttp2_config") { + include_dirs = [ "lib/includes" ] + if (!is_component_build) { + defines = [ "NGHTTP2_STATICLIB" ] + } + } + + gypi_values = exec_script("../../tools/gypi_to_gn.py", + [ rebase_path("nghttp2.gyp") ], + "scope", + [ "nghttp2.gyp" ]) + + component(target_name) { + forward_variables_from(invoker, "*") + + public_configs = [ ":nghttp2_config" ] + defines = [ + "_U_", + "HAVE_CONFIG_H" + ] + if (is_component_build) { + defines += [ "BUILDING_NGHTTP2" ] + } + + sources = gypi_values.nghttp2_sources + + if (is_clang || !is_win) { + cflags_c = [ + "-Wno-implicit-fallthrough", + ] + } + } +} diff --git a/deps/ngtcp2/BUILD.gn b/deps/ngtcp2/BUILD.gn new file mode 100644 index 00000000000..41df46fea41 --- /dev/null +++ b/deps/ngtcp2/BUILD.gn @@ -0,0 +1,14 @@ +############################################################################## +# # +# DO NOT EDIT THIS FILE! # +# # +############################################################################## + +# This file is used by GN for building, which is NOT the build system used for +# building official binaries. +# Please modify the gyp files if you are making changes to build system. + +import("unofficial.gni") + +ngtcp2_gn_build("ngtcp2") { +} diff --git a/deps/ngtcp2/unofficial.gni b/deps/ngtcp2/unofficial.gni new file mode 100644 index 00000000000..a304cf4aded --- /dev/null +++ b/deps/ngtcp2/unofficial.gni @@ -0,0 +1,74 @@ +# Copyright (c) 2013-2021 GitHub Inc. +# Copyright 2021 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. + +# This file is used by GN for building, which is NOT the build system used for +# building official binaries. +# Please edit the gyp files if you are making changes to build system. + +import("//node/node.gni") + +# The actual configurations are put inside a template in unofficial.gni to +# prevent accidental edits from contributors. +template("ngtcp2_gn_build") { + config("ngtcp2_config") { + include_dirs = [ + "nghttp3/lib/", + "nghttp3/lib/includes/", + "ngtcp2/crypto/includes/", + "ngtcp2/lib/includes/", + ] + defines = [ + "NGTCP2_STATICLIB", + "NGHTTP3_STATICLIB", + ] + } + + gypi_values = exec_script("../../tools/gypi_to_gn.py", + [ rebase_path("ngtcp2.gyp") ], + "scope", + [ "ngtcp2.gyp" ]) + + # FIXME(zcbenz): Some APIs of ngtcp2 are not marked as export, so can not turn + # into component. This should be fixed in upstream ngtcp2 + static_library(target_name) { + forward_variables_from(invoker, "*") + public_configs = [ ":ngtcp2_config" ] + + defines = [ "_U_" ] + if (is_win) { + defines += [ + "WIN32", + "_WINDOWS", + "HAVE_CONFIG_H", + ] + } + if (is_linux) { + defines += [ + "HAVE_ARPA_INET_H", + "HAVE_NETINET_IN_H", + ] + } + + include_dirs = [ + ".", + "ngtcp2/lib/", + "ngtcp2/crypto/", + "nghttp3/lib/" + ] + + sources = gypi_values.nghttp3_sources + gypi_values.ngtcp2_sources + if (node_use_openssl) { + sources += gypi_values.ngtcp2_sources_openssl + deps = [ "../openssl" ] + } + + if (is_clang || !is_win) { + cflags_c = [ + "-Wno-extra-semi", + "-Wno-implicit-fallthrough", + ] + } + } +} diff --git a/deps/openssl/BUILD.gn b/deps/openssl/BUILD.gn new file mode 100644 index 00000000000..7d2db10a84c --- /dev/null +++ b/deps/openssl/BUILD.gn @@ -0,0 +1,14 @@ +############################################################################## +# # +# DO NOT EDIT THIS FILE! # +# # +############################################################################## + +# This file is used by GN for building, which is NOT the build system used for +# building official binaries. +# Please modify the gyp files if you are making changes to build system. + +import("unofficial.gni") + +openssl_gn_build("openssl") { +} diff --git a/deps/openssl/unofficial.gni b/deps/openssl/unofficial.gni new file mode 100644 index 00000000000..9b94ccb275e --- /dev/null +++ b/deps/openssl/unofficial.gni @@ -0,0 +1,151 @@ +# Copyright 2019 the V8 project authors. All rights reserved. +# Copyright 2023 Microsoft Inc. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +# This file is used by GN for building, which is NOT the build system used for +# building official binaries. +# Please edit the gyp files if you are making changes to build system. + +declare_args() { + # Do not build optimized assembly for OpenSSL + # FIXME(zcbenz): asm code does not compile with clang. + openssl_no_asm = true +} + +# The actual configurations are put inside a template in unofficial.gni to +# prevent accidental edits from contributors. +template("openssl_gn_build") { + config("openssl_external_config") { + include_dirs = [ + "openssl/crypto/include", + "openssl/include", + ] + } + + config("openssl_internal_config") { + gypi_values = exec_script("../../tools/gypi_to_gn.py", + [ rebase_path("openssl.gypi") ], + "scope", + [ "openssl.gypi" ]) + + defines = [ + "MODULESDIR=\"deps/openssl/lib/openssl-modules\"", + "OPENSSL_API_COMPAT=0x10100001L", + "STATIC_LEGACY", + ] + gypi_values.openssl_default_defines_all + if (is_win) { + defines += [ + ## default of Win. See INSTALL in openssl repo. + "OPENSSLDIR=\"C:\\\Program\ Files\\\Common\ Files\\\SSL\"", + "ENGINESDIR=\"NUL\"", + "OPENSSL_SYS_WIN32", "WIN32_LEAN_AND_MEAN", "L_ENDIAN", + "_CRT_SECURE_NO_DEPRECATE", "UNICODE", "_UNICODE", + ] + } else if (is_mac) { + defines += [ + "OPENSSLDIR=\"/System/Library/OpenSSL/\"", + "ENGINESDIR=\"/dev/null\"", + ] + } else { + defines += [ + "OPENSSLDIR=\"/etc/ssl\"", + "ENGINESDIR=\"/dev/null\"", + "TERMIOS", + ] + } + + if (is_posix) { + asmflags = [ "-fPIC" ] + cflags = [ "-fPIC" ] + ldflags = [ "-fPIC" ] + } + if (is_clang || !is_win) { + cflags_c = [ + "-Wno-atomic-alignment", + "-Wno-constant-conversion", + "-Wno-implicit-fallthrough", + "-Wno-implicit-function-declaration", + "-Wno-sign-compare", + "-Wno-unknown-escape-sequence", + "-Wno-unreachable-code", + "-Wno-unreachable-code-break", + "-Wno-unreachable-code-return", + "-Wno-unused-function", + ] + } + if (is_win) { + libs = [ "crypt32.lib" ] + } else if (is_linux) { + libs = [ "atomic" ] + } + + common_gypi_values = exec_script("../../tools/gypi_to_gn.py", + [ rebase_path("openssl_common.gypi") ], + "scope", + [ "openssl_common.gypi" ]) + include_dirs = common_gypi_values.include_dirs + } + + static_library(target_name) { + forward_variables_from(invoker, "*") + + configs += [ ":openssl_internal_config" ] + public_configs = [ ":openssl_external_config" ] + + config_path_name = "" + if (is_win) { + if (target_cpu == "x86") { + config_path_name = "VC-WIN32" + } else if (target_cpu == "x64") { + config_path_name = "VC-WIN64A" + } else if (target_cpu == "arm64") { + config_path_name = "VC-WIN64-ARM" + } + } else if (is_linux) { + if (target_cpu == "x86") { + config_path_name = "linux-elf" + } else if (target_cpu == "x64") { + config_path_name = "linux-x86_64" + } else if (target_cpu == "arm") { + config_path_name = "linux-armv4" + } else if (target_cpu == "arm64") { + config_path_name = "linux-aarch64" + } + } else if (is_apple) { + if (target_cpu == "x86") { + config_path_name = "darwin-i386-cc" + } else if (target_cpu == "x64") { + config_path_name = "darwin64-x86_64-cc" + } else if (target_cpu == "arm64") { + config_path_name = "darwin64-arm64-cc" + } + } + assert(config_path_name != "", "Unsupported platform") + + # GN variables can not have - in name. + config_name = string_replace(config_path_name, "-", "_") + + if (openssl_no_asm) { + asm_name = "no-asm" + } else { + # TODO(zcbenz): Check gas_version and nasm_version. + asm_name = "asm_avx2" + } + if (is_win && target_cpu == "arm64") { + asm_name = "no-asm" + } + config_path = "config/archs/" + config_path_name + "/" + asm_name + + gypi_values = exec_script("../../tools/gypi_to_gn.py", + [ rebase_path(config_path + "/openssl.gypi"), ], + "scope", + [ config_path + "/openssl.gypi" ]) + + include_dirs = rebase_path(gypi_values.include_dirs, ".", config_path) + defines = gypi_values["openssl_defines_" + config_name] + sources = filter_exclude(gypi_values.openssl_sources + + gypi_values["openssl_sources_" + config_name], + [ "*.ld" ]) + } +} diff --git a/deps/postject/BUILD.gn b/deps/postject/BUILD.gn new file mode 100644 index 00000000000..895b5bfc5b3 --- /dev/null +++ b/deps/postject/BUILD.gn @@ -0,0 +1,14 @@ +############################################################################## +# # +# DO NOT EDIT THIS FILE! # +# # +############################################################################## + +# This file is used by GN for building, which is NOT the build system used for +# building official binaries. +# Please modify the gyp files if you are making changes to build system. + +import("unofficial.gni") + +postject_gn_build("postject") { +} diff --git a/deps/postject/unofficial.gni b/deps/postject/unofficial.gni new file mode 100644 index 00000000000..6a4d2ddb36e --- /dev/null +++ b/deps/postject/unofficial.gni @@ -0,0 +1,21 @@ +# Copyright 2023 Microsoft Inc. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +# This file is used by GN for building, which is NOT the build system used for +# building official binaries. +# Please edit the gyp files if you are making changes to build system. + +# The actual configurations are put inside a template in unofficial.gni to +# prevent accidental edits from contributors. +template("postject_gn_build") { + config("postject_config") { + include_dirs = [ "." ] + } + + source_set(target_name) { + forward_variables_from(invoker, "*") + public_configs = [ ":postject_config" ] + sources = [ "postject-api.h" ] + } +} diff --git a/deps/simdutf/BUILD.gn b/deps/simdutf/BUILD.gn new file mode 100644 index 00000000000..119d4945691 --- /dev/null +++ b/deps/simdutf/BUILD.gn @@ -0,0 +1,14 @@ +############################################################################## +# # +# DO NOT EDIT THIS FILE! # +# # +############################################################################## + +# This file is used by GN for building, which is NOT the build system used for +# building official binaries. +# Please modify the gyp files if you are making changes to build system. + +import("unofficial.gni") + +simdutf_gn_build("simdutf") { +} diff --git a/deps/simdutf/unofficial.gni b/deps/simdutf/unofficial.gni new file mode 100644 index 00000000000..d623de36312 --- /dev/null +++ b/deps/simdutf/unofficial.gni @@ -0,0 +1,37 @@ +# Copyright (c) 2013-2019 GitHub Inc. +# Copyright 2019 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. + +# This file is used by GN for building, which is NOT the build system used for +# building official binaries. +# Please edit the gyp files if you are making changes to build system. + +# The actual configurations are put inside a template in unofficial.gni to +# prevent accidental edits from contributors. +template("simdutf_gn_build") { + config("simdutf_config") { + include_dirs = [ "." ] + } + + gypi_values = exec_script("../../tools/gypi_to_gn.py", + [ rebase_path("simdutf.gyp") ], + "scope", + [ "simdutf.gyp" ]) + + source_set(target_name) { + forward_variables_from(invoker, "*") + public_configs = [ ":simdutf_config" ] + sources = gypi_values.simdutf_sources + if (is_clang || !is_win) { + cflags_cc = [ + "-Wno-#pragma-messages", + "-Wno-ambiguous-reversed-operator", + "-Wno-unreachable-code-break", + "-Wno-unused-const-variable", + "-Wno-unused-function", + "-Wno-c++98-compat-extra-semi", + ] + } + } +} diff --git a/deps/uv/BUILD.gn b/deps/uv/BUILD.gn new file mode 100644 index 00000000000..8e6ac27048b --- /dev/null +++ b/deps/uv/BUILD.gn @@ -0,0 +1,14 @@ +############################################################################## +# # +# DO NOT EDIT THIS FILE! # +# # +############################################################################## + +# This file is used by GN for building, which is NOT the build system used for +# building official binaries. +# Please modify the gyp files if you are making changes to build system. + +import("unofficial.gni") + +uv_gn_build("uv") { +} diff --git a/deps/uv/unofficial.gni b/deps/uv/unofficial.gni new file mode 100644 index 00000000000..64d6bcbc5c1 --- /dev/null +++ b/deps/uv/unofficial.gni @@ -0,0 +1,110 @@ +# Copyright (c) 2013-2019 GitHub Inc. +# Copyright 2019 the V8 project authors. All rights reserved. +# Copyright 2023 Microsoft Inc. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +# This file is used by GN for building, which is NOT the build system used for +# building official binaries. +# Please edit the gyp files if you are making changes to build system. + +# The actual configurations are put inside a template in unofficial.gni to +# prevent accidental edits from contributors. +template("uv_gn_build") { + config("uv_external_config") { + include_dirs = [ "include" ] + } + + config("uv_internal_config") { + include_dirs = [ + "include", + "src", + ] + + defines = [ "BUILDING_UV_SHARED" ] # always export symbols + if (is_posix) { + defines += [ + "_LARGEFILE_SOURCE", + "_FILE_OFFSET_BITS=64", + ] + } + if (is_linux) { + defines += [ + "_POSIX_C_SOURCE=200112", + "_GNU_SOURCE", + ] + } + if (is_apple) { + defines += [ + "_DARWIN_USE_64_BIT_INODE=1", + "_DARWIN_UNLIMITED_SELECT=1", + ] + } + if (is_clang || !is_win) { + cflags_c = [ + "-Wno-deprecated-declarations", + "-Wno-extra-semi", + "-Wno-implicit-fallthrough", + "-Wno-missing-braces", + "-Wno-string-conversion", + "-Wno-shadow", + "-Wno-unreachable-code", + "-Wno-unreachable-code-return", + "-Wno-unused-but-set-variable", + "-Wno-unused-function", + "-Wno-unused-result", + "-Wno-unused-variable", + ] + } + } + + gypi_values = exec_script("../../tools/gypi_to_gn.py", + [ rebase_path("uv.gyp") ], + "scope", + [ "uv.gyp" ]) + + component(target_name) { + forward_variables_from(invoker, "*") + + configs += [ ":uv_internal_config" ] + public_configs = [ ":uv_external_config" ] + + if (is_win) { + libs = [ + "advapi32.lib", + "iphlpapi.lib", + "psapi.lib", + "shell32.lib", + "user32.lib", + "userenv.lib", + "ws2_32.lib", + ] + } + if (is_posix) { + libs = [ "m" ] + ldflags = [ "-pthread" ] + } + if (is_linux) { + libs += [ + "dl", + "rt", + ] + } + + sources = gypi_values.uv_sources_common + if (is_win) { + sources += gypi_values.uv_sources_win + } + if (is_posix) { + sources += gypi_values.uv_sources_posix + + [ "src/unix/proctitle.c" ] + } + if (is_linux) { + sources += gypi_values.uv_sources_linux + } + if (is_apple) { + sources += gypi_values.uv_sources_apple + + gypi_values.uv_sources_bsd_common + } + } +} diff --git a/deps/uvwasi/BUILD.gn b/deps/uvwasi/BUILD.gn new file mode 100644 index 00000000000..4f8fb081df8 --- /dev/null +++ b/deps/uvwasi/BUILD.gn @@ -0,0 +1,14 @@ +############################################################################## +# # +# DO NOT EDIT THIS FILE! # +# # +############################################################################## + +# This file is used by GN for building, which is NOT the build system used for +# building official binaries. +# Please modify the gyp files if you are making changes to build system. + +import("unofficial.gni") + +uvwasi_gn_build("uvwasi") { +} diff --git a/deps/uvwasi/unofficial.gni b/deps/uvwasi/unofficial.gni new file mode 100644 index 00000000000..17f4c8e6eed --- /dev/null +++ b/deps/uvwasi/unofficial.gni @@ -0,0 +1,38 @@ +# Copyright (c) 2013-2019 GitHub Inc. +# Copyright 2019 the V8 project authors. All rights reserved. +# Copyright 2023 Microsoft Inc. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +# This file is used by GN for building, which is NOT the build system used for +# building official binaries. +# Please edit the gyp files if you are making changes to build system. + +# The actual configurations are put inside a template in unofficial.gni to +# prevent accidental edits from contributors. +template("uvwasi_gn_build") { + config("uvwasi_config") { + include_dirs = [ "include" ] + } + + gypi_values = exec_script("../../tools/gypi_to_gn.py", + [ rebase_path("uvwasi.gyp") ], + "scope", + [ "uvwasi.gyp" ]) + + source_set(target_name) { + forward_variables_from(invoker, "*") + + public_configs = [ ":uvwasi_config" ] + sources = gypi_values.uvwasi_sources + include_dirs = [ "src" ] + deps = [ "../uv" ] + + if (is_clang || !is_win) { + cflags_c = [ + "-Wno-extra-semi", + "-Wno-shadow", + ] + } + } +} diff --git a/node.gni b/node.gni new file mode 100644 index 00000000000..2be97a17a2f --- /dev/null +++ b/node.gni @@ -0,0 +1,67 @@ +# Copyright 2019 the V8 project authors. All rights reserved. +# Copyright 2023 Microsoft Inc. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +# This file is used by GN for building, which is NOT the build system used for +# building official binaries. +# Please take a look at node.gyp if you are making changes to build system. + +# Embedder options. +declare_args() { + # The location of Node.js in source code tree. + node_path = "//node" + + # The location of V8, use the one from node's deps by default. + node_v8_path = "$node_path/deps/v8" + + # The NODE_MODULE_VERSION defined in node_version.h. + node_module_version = exec_script("$node_path/tools/getmoduleversion.py", [], "value") + + # Support for external shareable builtins. + # TODO(zcbenz): This is currently copied from configure.py, we should share + # the list between configure.py and GN configurations. + node_builtin_shareable_builtins = [ + "deps/cjs-module-lexer/lexer.js", + "deps/cjs-module-lexer/dist/lexer.js", + "deps/undici/undici.js", + ] +} + +# Equivalent of gyp file's configurations. +declare_args() { + # Enable the V8 inspector protocol for use with node. + node_enable_inspector = true + + # Build node with SSL support. + # The variable is called "openssl" for parity with node's GYP build. + node_use_openssl = true + + # Use the specified path to system CA (PEM format) in addition to + # the BoringSSL supplied CA store or compiled-in Mozilla CA copy. + node_openssl_system_ca_path = "" + + # Initialize v8 platform during node.js startup. + node_use_v8_platform = true + + # Custom build tag. + node_tag = "" + + # V8 options to pass, see `node --v8-options` for examples. + node_v8_options = "" + + # Provide a custom URL prefix for the `process.release` properties + # `sourceUrl` and `headersUrl`. When compiling a release build, this will + # default to https://nodejs.org/download/release/'). + node_release_urlbase = "" + + # Use code cache to speed up startup. Disabled for cross compilation. + node_use_node_code_cache = host_os == target_os && host_cpu == target_cpu + + # Use snapshot to speed up startup. + # TODO(zcbenz): node_mksnapshot is not ready for cross-os compilation. + node_use_node_snapshot = host_os == target_os +} + +assert(!node_enable_inspector || node_use_openssl, + "node_enable_inspector requires node_use_openssl") diff --git a/src/inspector/BUILD.gn b/src/inspector/BUILD.gn new file mode 100644 index 00000000000..909fd14345f --- /dev/null +++ b/src/inspector/BUILD.gn @@ -0,0 +1,14 @@ +############################################################################## +# # +# DO NOT EDIT THIS FILE! # +# # +############################################################################## + +# This file is used by GN for building, which is NOT the build system used for +# building official binaries. +# Please modify the gyp files if you are making changes to build system. + +import("unofficial.gni") + +inspector_gn_build("inspector") { +} diff --git a/src/inspector/unofficial.gni b/src/inspector/unofficial.gni new file mode 100644 index 00000000000..b562109e94c --- /dev/null +++ b/src/inspector/unofficial.gni @@ -0,0 +1,81 @@ +# Copyright (c) 2013-2019 GitHub Inc. +# Copyright 2019 the V8 project authors. All rights reserved. +# Copyright 2023 Microsoft Inc. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import("../../node.gni") +import("$node_v8_path/gni/v8.gni") + +# The actual configurations are put inside a template in unofficial.gni to +# prevent accidental edits from contributors. +template("inspector_gn_build") { + group(target_name) { + forward_variables_from(invoker, "*") + deps = [ + ":node_protocol_generated_sources", + ":v8_inspector_compress_protocol_json", + ] + } + + node_gen_dir = get_label_info("../..", "target_gen_dir") + protocol_tool_path = "../../tools/inspector_protocol" + + gypi_values = exec_script( + "../../tools/gypi_to_gn.py", + [ rebase_path("node_inspector.gypi"), + "--replace=<(SHARED_INTERMEDIATE_DIR)=$node_gen_dir", + "--replace=<(protocol_tool_path)=$protocol_tool_path" ], + "scope", + [ "node_inspector.gypi" ]) + + action("node_protocol_generated_sources") { + script = "$protocol_tool_path/code_generator.py" + + deps = [ ":node_protocol_json" ] + + outputs = gypi_values.node_inspector_generated_sources + inputs = gypi_values.node_protocol_files + [ + "node_protocol_config.json", + "$node_gen_dir/src/node_protocol.json", + ] + + args = [ + "--jinja_dir", + # jinja is in third_party. + rebase_path("//third_party/", root_build_dir), + "--output_base", + rebase_path("$node_gen_dir/src", root_build_dir), + "--config", + rebase_path("node_protocol_config.json", root_build_dir), + ] + } + + action("v8_inspector_compress_protocol_json") { + script = "../../tools/compress_json.py" + deps = [ ":concatenate_protocols" ] + inputs = [ "$target_gen_dir/concatenated_protocol.json" ] + outputs = [ "$target_gen_dir/v8_inspector_protocol_json.h" ] + args = rebase_path(inputs + outputs, root_build_dir) + } + + action("concatenate_protocols") { + script = "$protocol_tool_path/concatenate_protocols.py" + deps = [ ":node_protocol_json" ] + inputs = [ + "$node_gen_dir/src/js_protocol.json", + "$node_gen_dir/src/node_protocol.json", + ] + outputs = [ + "$target_gen_dir/concatenated_protocol.json", + ] + args = rebase_path(inputs + outputs, root_build_dir) + } + + action_foreach("node_protocol_json") { + script = "$node_v8_path/third_party/inspector_protocol/convert_protocol_to_json.py" + sources = [ "node_protocol.pdl", v8_inspector_js_protocol ] + outputs = [ "$node_gen_dir/src/{{source_name_part}}.json" ] + args = [ "{{source}}" ] + rebase_path(outputs, root_build_dir) + } +} diff --git a/tools/generate_config_gypi.py b/tools/generate_config_gypi.py new file mode 100755 index 00000000000..26cc5f04201 --- /dev/null +++ b/tools/generate_config_gypi.py @@ -0,0 +1,75 @@ +#!/usr/bin/env python3 +# Copyright (c) 2013-2019 GitHub Inc. +# Copyright 2019 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. + +# This script reads the configurations of GN and outputs a config.gypi file that +# will be used to populate process.config.variables. + +import re +import os +import subprocess +import sys + +root_dir = os.path.dirname(os.path.dirname(__file__)) +sys.path.append(os.path.join(root_dir, 'node', 'tools')) +import getmoduleversion +import getnapibuildversion + +GN_RE = re.compile(r'(\w+)\s+=\s+(.*?)$', re.MULTILINE) + +def bool_string_to_number(v): + return 1 if v == 'true' else 0 + +def translate_config(config): + return { + 'target_defaults': { + 'default_configuration': + 'Debug' if config['is_debug'] == 'true' else 'Release', + }, + 'variables': { + 'asan': bool_string_to_number(config['is_asan']), + 'llvm_version': 13, + 'napi_build_version': config['napi_build_version'], + 'node_builtin_shareable_builtins': + eval(config['node_builtin_shareable_builtins']), + 'node_module_version': int(config['node_module_version']), + 'node_shared': bool_string_to_number(config['is_component_build']), + 'node_use_openssl': config['node_use_openssl'], + 'node_use_node_code_cache': config['node_use_node_code_cache'], + 'node_use_node_snapshot': config['node_use_node_snapshot'], + 'v8_enable_31bit_smis_on_64bit_arch': + bool_string_to_number(config['v8_enable_31bit_smis_on_64bit_arch']), + 'v8_enable_pointer_compression': + bool_string_to_number(config['v8_enable_pointer_compression']), + 'v8_enable_i18n_support': + bool_string_to_number(config['v8_enable_i18n_support']), + 'v8_enable_inspector': # this is actually a node misnomer + bool_string_to_number(config['node_enable_inspector']), + 'shlib_suffix': 'dylib' if sys.platform == 'darwin' else 'so', + } + } + +def main(gn_out_dir, output_file, depfile): + # Get GN config and parse into a dictionary. + if sys.platform == 'win32': + gn = 'gn.exe' + else: + gn = 'gn' + gnconfig = subprocess.check_output( + [gn, 'args', '--list', '--short', '-C', gn_out_dir]) + config = dict(re.findall(GN_RE, gnconfig.decode('utf-8'))) + config['node_module_version'] = getmoduleversion.get_version() + config['napi_build_version'] = getnapibuildversion.get_napi_version() + + # Write output. + with open(output_file, 'w') as f: + f.write(repr(translate_config(config))) + + # Write depfile. Force regenerating config.gypi when GN configs change. + with open(depfile, 'w') as f: + f.write('%s: %s '%(output_file, 'build.ninja')) + +if __name__ == '__main__': + main(sys.argv[1], sys.argv[2], sys.argv[3]) diff --git a/tools/gypi_to_gn.py b/tools/gypi_to_gn.py new file mode 100755 index 00000000000..47182d8017b --- /dev/null +++ b/tools/gypi_to_gn.py @@ -0,0 +1,219 @@ +#!/usr/bin/env python3 +# Copyright 2014 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. +# Deleted from Chromium in https://crrev.com/097f64c631. + +"""Converts a given gypi file to a python scope and writes the result to stdout. +USING THIS SCRIPT IN CHROMIUM +Forking Python to run this script in the middle of GN is slow, especially on +Windows, and it makes both the GYP and GN files harder to follow. You can't +use "git grep" to find files in the GN build any more, and tracking everything +in GYP down requires a level of indirection. Any calls will have to be removed +and cleaned up once the GYP-to-GN transition is complete. +As a result, we only use this script when the list of files is large and +frequently-changing. In these cases, having one canonical list outweights the +downsides. +As of this writing, the GN build is basically complete. It's likely that all +large and frequently changing targets where this is appropriate use this +mechanism already. And since we hope to turn down the GYP build soon, the time +horizon is also relatively short. As a result, it is likely that no additional +uses of this script should every be added to the build. During this later part +of the transition period, we should be focusing more and more on the absolute +readability of the GN build. +HOW TO USE +It is assumed that the file contains a toplevel dictionary, and this script +will return that dictionary as a GN "scope" (see example below). This script +does not know anything about GYP and it will not expand variables or execute +conditions. +It will strip conditions blocks. +A variables block at the top level will be flattened so that the variables +appear in the root dictionary. This way they can be returned to the GN code. +Say your_file.gypi looked like this: + { + 'sources': [ 'a.cc', 'b.cc' ], + 'defines': [ 'ENABLE_DOOM_MELON' ], + } +You would call it like this: + gypi_values = exec_script("//build/gypi_to_gn.py", + [ rebase_path("your_file.gypi") ], + "scope", + [ "your_file.gypi" ]) +Notes: + - The rebase_path call converts the gypi file from being relative to the + current build file to being system absolute for calling the script, which + will have a different current directory than this file. + - The "scope" parameter tells GN to interpret the result as a series of GN + variable assignments. + - The last file argument to exec_script tells GN that the given file is a + dependency of the build so Ninja can automatically re-run GN if the file + changes. +Read the values into a target like this: + component("mycomponent") { + sources = gypi_values.sources + defines = gypi_values.defines + } +Sometimes your .gypi file will include paths relative to a different +directory than the current .gn file. In this case, you can rebase them to +be relative to the current directory. + sources = rebase_path(gypi_values.sources, ".", + "//path/gypi/input/values/are/relative/to") +This script will tolerate a 'variables' in the toplevel dictionary or not. If +the toplevel dictionary just contains one item called 'variables', it will be +collapsed away and the result will be the contents of that dictinoary. Some +.gypi files are written with or without this, depending on how they expect to +be embedded into a .gyp file. +This script also has the ability to replace certain substrings in the input. +Generally this is used to emulate GYP variable expansion. If you passed the +argument "--replace=<(foo)=bar" then all instances of "<(foo)" in strings in +the input will be replaced with "bar": + gypi_values = exec_script("//build/gypi_to_gn.py", + [ rebase_path("your_file.gypi"), + "--replace=<(foo)=bar"], + "scope", + [ "your_file.gypi" ]) +""" + +from __future__ import absolute_import +from __future__ import print_function +from optparse import OptionParser +import os +import sys + + +# Look for standalone GN distribution. +def FindGNPath(): + for i in os.environ['PATH'].split(os.pathsep): + if i.rstrip(os.sep).endswith('gn'): + return i + return None + + +try: + # May already be in the import path. + import gn_helpers +except ImportError: + # Add src/build to import path. + src_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), + os.pardir, os.pardir)) + sys.path.append(os.path.join(src_dir, 'build')) + if FindGNPath(): + sys.path.append(os.path.join(FindGNPath(), 'build')) + import gn_helpers + + +def LoadPythonDictionary(path): + file_string = open(path).read() + try: + file_data = eval(file_string, {'__builtins__': None}, None) + except SyntaxError as e: + e.filename = path + raise + except Exception as e: + raise Exception("Unexpected error while reading %s: %s" % (path, str(e))) + + assert isinstance(file_data, dict), "%s does not eval to a dictionary" % path + + # Flatten any variables to the top level. + if 'variables' in file_data: + file_data.update(file_data['variables']) + del file_data['variables'] + + # Strip all elements that this script can't process. + elements_to_strip = [ + 'conditions', + 'direct_dependent_settings', + 'target_conditions', + 'target_defaults', + 'targets', + 'includes', + 'actions', + ] + for element in elements_to_strip: + if element in file_data: + del file_data[element] + + return file_data + + +def ReplaceSubstrings(values, search_for, replace_with): + """Recursively replaces substrings in a value. + Replaces all substrings of the "search_for" with "repace_with" for all + strings occurring in "values". This is done by recursively iterating into + lists as well as the keys and values of dictionaries.""" + if isinstance(values, str): + return values.replace(search_for, replace_with) + + if isinstance(values, list): + result = [] + for v in values: + # Remove the item from list for complete match. + if v == search_for and replace_with == '': + continue + result.append(ReplaceSubstrings(v, search_for, replace_with)) + return result + + if isinstance(values, dict): + # For dictionaries, do the search for both the key and values. + result = {} + for key, value in values.items(): + new_key = ReplaceSubstrings(key, search_for, replace_with) + new_value = ReplaceSubstrings(value, search_for, replace_with) + result[new_key] = new_value + return result + + # Assume everything else is unchanged. + return values + + +def DeduplicateLists(values): + """Recursively remove duplicate values in lists.""" + if isinstance(values, list): + return sorted(list(set(values))) + + if isinstance(values, dict): + for key in values: + values[key] = DeduplicateLists(values[key]) + return values + + +def main(): + parser = OptionParser() + parser.add_option("-r", "--replace", action="append", + help="Replaces substrings. If passed a=b, replaces all substrs a with b.") + (options, args) = parser.parse_args() + + if len(args) != 1: + raise Exception("Need one argument which is the .gypi file to read.") + + data = LoadPythonDictionary(args[0]) + if options.replace: + # Do replacements for all specified patterns. + for replace in options.replace: + split = replace.split('=') + # Allow "foo=" to replace with nothing. + if len(split) == 1: + split.append('') + assert len(split) == 2, "Replacement must be of the form 'key=value'." + data = ReplaceSubstrings(data, split[0], split[1]) + + gn_dict = {} + for key in data: + gn_key = key.replace('-', '_') + # Sometimes .gypi files use the GYP syntax with percents at the end of the + # variable name (to indicate not to overwrite a previously-defined value): + # 'foo%': 'bar', + # Convert these to regular variables. + if len(key) > 1 and key[len(key) - 1] == '%': + gn_dict[gn_key[:-1]] = data[key] + else: + gn_dict[gn_key] = data[key] + + print(gn_helpers.ToGNString(DeduplicateLists(gn_dict))) + +if __name__ == '__main__': + try: + main() + except Exception as e: + print(str(e)) + sys.exit(1) diff --git a/tools/search_files.py b/tools/search_files.py new file mode 100755 index 00000000000..65d0e1be42f --- /dev/null +++ b/tools/search_files.py @@ -0,0 +1,20 @@ +#!/usr/bin/env python3 +# Copyright 2008 the V8 project authors. +# Copyright 2023 Microsoft Inc. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import os +import sys + +from utils import SearchFiles + + +if __name__ == '__main__': + try: + files = SearchFiles(*sys.argv[2:]) + files = [ os.path.relpath(x, sys.argv[1]) for x in files ] + print('\n'.join(files)) + except Exception as e: + print(str(e)) + sys.exit(1) diff --git a/unofficial.gni b/unofficial.gni new file mode 100644 index 00000000000..29685d4ade5 --- /dev/null +++ b/unofficial.gni @@ -0,0 +1,352 @@ +# Copyright (c) 2013-2019 GitHub Inc. +# Copyright 2019 the V8 project authors. All rights reserved. +# Copyright 2023 Microsoft Inc. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +# This file is used by GN for building, which is NOT the build system used for +# building official binaries. +# Please take a look at node.gyp if you are making changes to build system. + +import("node.gni") +import("$node_v8_path/gni/snapshot_toolchain.gni") +import("$node_v8_path/gni/v8.gni") + +# The actual configurations are put inside a template in unofficial.gni to +# prevent accidental edits from contributors. +template("node_gn_build") { + config("node_features") { + defines = [] + if (is_component_build) { + defines += [ + "USING_UV_SHARED", + "USING_V8_SHARED", + ] + } + if (node_use_openssl) { + defines += [ "HAVE_OPENSSL=1" ] + } else { + defines += [ "HAVE_OPENSSL=0" ] + } + if (node_use_v8_platform) { + defines += [ "NODE_USE_V8_PLATFORM=1" ] + } else { + defines += [ "NODE_USE_V8_PLATFORM=0" ] + } + if (node_enable_inspector) { + defines += [ "HAVE_INSPECTOR=1" ] + } else { + defines += [ "HAVE_INSPECTOR=0" ] + } + if (node_use_node_code_cache) { + defines += [ "NODE_USE_NODE_CODE_CACHE=1"] + } + if (v8_enable_i18n_support) { + defines += [ "NODE_HAVE_I18N_SUPPORT=1" ] + } else { + defines += [ "NODE_HAVE_I18N_SUPPORT=0" ] + } + } + + config("node_external_config") { + include_dirs = [ + target_gen_dir, + "src", + ] + defines = [ + "NODE_WANT_INTERNALS=1", + "NODE_EMBEDDER_MODULE_VERSION=$node_module_version", + ] + configs = [ + ":node_features", + "$node_v8_path:external_config", + ] + } + + config("node_internal_config") { + visibility = [ + ":*", + "src/inspector:*", + ] + configs = [ ":node_external_config" ] + libs = [] + cflags = [ "-Wno-microsoft-include" ] + cflags_cc = [ + "-Wno-deprecated-declarations", + "-Wno-extra-semi", + "-Wno-implicit-fallthrough", + "-Wno-macro-redefined", + "-Wno-return-type", + "-Wno-shadow", + "-Wno-sometimes-uninitialized", + "-Wno-string-plus-int", + "-Wno-string-conversion", + "-Wno-unreachable-code", + "-Wno-unreachable-code-break", + "-Wno-unreachable-code-return", + "-Wno-unused-label", + "-Wno-unused-private-field", + "-Wno-unused-variable", + "-Wno-unused-function", + ] + + if (target_cpu == "x86") { + node_arch = "ia32" + } else { + node_arch = target_cpu + } + if (target_os == "win") { + node_platform = "win32" + } else if (target_os == "mac") { + node_platform = "darwin" + } else { + node_platform = target_os + } + defines = [ + "NODE_ARCH=\"$node_arch\"", + "NODE_PLATFORM=\"$node_platform\"", + "NODE_REPORT" + ] + + if (is_win) { + defines += [ + "NOMINMAX", + "_UNICODE=1", + ] + } else { + defines += [ "__POSIX__" ] + } + if (node_tag != "") { + defines += [ "NODE_TAG=\"$node_tag\"" ] + } + if (node_v8_options != "") { + defines += [ "NODE_V8_OPTIONS=\"$node_v8_options\"" ] + } + if (node_release_urlbase != "") { + defines += [ "NODE_RELEASE_URLBASE=\"$node_release_urlbase\"" ] + } + if (node_use_openssl) { + defines += [ + "NODE_OPENSSL_SYSTEM_CERT_PATH=\"$node_openssl_system_ca_path\"", + ] + } + } + + gypi_values = exec_script("./tools/gypi_to_gn.py", + [ rebase_path("node.gyp"), + "--replace=<@(node_builtin_shareable_builtins)=" ], + "scope", + [ "node.gyp" ]) + + source_set("libnode") { + configs += [ ":node_internal_config" ] + public_configs = [ + ":node_external_config", + "deps/googletest:googletest_config", + ] + public_deps = [ + "deps/ada", + "deps/uv", + "deps/base64", + "$node_v8_path", + ] + deps = [ + ":run_node_js2c", + "deps/brotli", + "deps/cares", + "deps/histogram", + "deps/llhttp", + "deps/nghttp2", + "deps/ngtcp2", + "deps/postject", + "deps/simdutf", + "deps/uvwasi", + "//third_party/zlib", + "$node_v8_path:v8_libplatform", + ] + + sources = [ + "$target_gen_dir/node_javascript.cc", + ] + gypi_values.node_sources + + if (is_win) { + libs = [ "psapi.lib" ] + } + if (is_mac) { + frameworks = [ "CoreFoundation.framework" ] + } + + if (v8_enable_i18n_support) { + deps += [ "//third_party/icu" ] + } + if (node_use_openssl) { + public_deps += [ "deps/openssl" ] + sources += gypi_values.node_crypto_sources + } + if (node_enable_inspector) { + deps += [ + "src/inspector:node_protocol_generated_sources", + "src/inspector:v8_inspector_compress_protocol_json", + ] + include_dirs = [ + "$target_gen_dir/src", + "$target_gen_dir/src/inspector", + ] + node_inspector = exec_script( + "./tools/gypi_to_gn.py", + [ rebase_path("src/inspector/node_inspector.gypi"), + "--replace=<(SHARED_INTERMEDIATE_DIR)=$target_gen_dir" ], + "scope", + [ "src/inspector/node_inspector.gypi" ]) + sources += node_inspector.node_inspector_sources + + node_inspector.node_inspector_generated_sources + } + } + + executable(target_name) { + forward_variables_from(invoker, "*") + + sources = [ "src/node_main.cc" ] + deps = [ ":libnode" ] + if (node_use_node_snapshot) { + sources += [ "$target_gen_dir/node_snapshot.cc" ] + deps += [ ":run_node_mksnapshot" ] + if (is_clang || !is_win) { + cflags_cc = [ + "-Wno-c++11-narrowing", + "-Wno-shadow", + ] + } + } else { + sources += [ "src/node_snapshot_stub.cc" ] + } + output_name = "node" + } + + if (node_use_node_snapshot) { + if (current_toolchain == v8_snapshot_toolchain) { + executable("node_mksnapshot") { + configs += [ ":node_internal_config" ] + sources = [ + "src/node_snapshot_stub.cc", + "tools/snapshot/node_mksnapshot.cc", + ] + deps = [ ":libnode" ] + } + } + + action("run_node_mksnapshot") { + deps = [ ":node_mksnapshot($v8_snapshot_toolchain)" ] + script = "$node_v8_path/tools/run.py" + sources = [] + data = [] + + mksnapshot_dir = get_label_info(":node_mksnapshot($v8_snapshot_toolchain)", + "root_out_dir") + + outputs = [ "$target_gen_dir/node_snapshot.cc" ] + args = [ + "./" + rebase_path(mksnapshot_dir + "/node_mksnapshot", root_build_dir), + rebase_path("$target_gen_dir/node_snapshot.cc", root_build_dir), + ] + } + } + + action("generate_config_gypi") { + script = "tools/generate_config_gypi.py" + outputs = [ "$target_gen_dir/config.gypi" ] + depfile = "$target_gen_dir/$target_name.d" + script_args = [ "$root_build_dir" ] + script_args += outputs + script_args += [ depfile ] + args = rebase_path(script_args, root_build_dir) + } + + executable("node_js2c") { + deps = [ + "deps/simdutf", + "deps/uv", + ] + sources = [ + "tools/js2c.cc", + "tools/executable_wrapper.h", + ] + } + + action("run_node_js2c") { + script = "$node_v8_path/tools/run.py" + deps = [ + ":node_js2c($host_toolchain)", + ":generate_config_gypi", + ] + + node_deps_files = gypi_values.deps_files + node_builtin_shareable_builtins + node_library_files = exec_script("./tools/search_files.py", + [ rebase_path(".", root_build_dir), + rebase_path("lib", root_build_dir), + "js" ], + "list lines") + + inputs = node_library_files + + node_deps_files + + [ "$target_gen_dir/config.gypi" ] + outputs = [ "$target_gen_dir/node_javascript.cc" ] + + # Get the path to node_js2c executable of the host toolchain. + if (host_os == "win") { + host_executable_suffix = ".exe" + } else { + host_executable_suffix = "" + } + node_js2c_path = + get_label_info(":node_js2c($host_toolchain)", "root_out_dir") + "/" + + get_label_info(":node_js2c($host_toolchain)", "name") + + host_executable_suffix + + args = [ rebase_path(node_js2c_path), + rebase_path("$target_gen_dir/node_javascript.cc"), + "--root", rebase_path("."), + "lib", rebase_path("$target_gen_dir/config.gypi") ] + + node_deps_files + } + + executable("node_cctest") { + testonly = true + configs += [ ":node_internal_config" ] + + deps = [ + ":libnode", + "deps/googletest", + "deps/googletest:gtest_main", + "deps/simdutf", + ] + + sources = gypi_values.node_cctest_sources + if (node_use_openssl) { + sources += gypi_values.node_cctest_openssl_sources + } + if (node_enable_inspector) { + sources += gypi_values.node_cctest_inspector_sources + } + } + + executable("node_embedtest") { + output_name = "embedtest" + testonly = true + deps = [ ":libnode" ] + sources = [ + "src/node_snapshot_stub.cc", + "test/embedding/embedtest.cc", + ] + } + + executable("overlapped_checker") { + output_name = "overlapped-checker" + testonly = true + if (is_win) { + sources = [ "test/overlapped-checker/main_win.c" ] + } else { + sources = [ "test/overlapped-checker/main_unix.c" ] + } + } +}