diff --git a/BUILDING.md b/BUILDING.md index 2cb15c812acf3b..48b2c83c57c354 100644 --- a/BUILDING.md +++ b/BUILDING.md @@ -10,58 +10,63 @@ file a new issue. ## Table of contents -* [Supported platforms](#supported-platforms) - * [Input](#input) - * [Strategy](#strategy) - * [Platform list](#platform-list) - * [Supported toolchains](#supported-toolchains) - * [Official binary platforms and toolchains](#official-binary-platforms-and-toolchains) - * [OpenSSL asm support](#openssl-asm-support) - * [Previous versions of this document](#previous-versions-of-this-document) -* [Building Node.js on supported platforms](#building-nodejs-on-supported-platforms) - * [Prerequisites](#prerequisites) - * [Unix and macOS](#unix-and-macos) - * [Unix prerequisites](#unix-prerequisites) - * [macOS prerequisites](#macos-prerequisites) - * [Building Node.js](#building-nodejs-1) - * [Installing Node.js](#installing-nodejs) - * [Running Tests](#running-tests) - * [Running Coverage](#running-coverage) - * [Building the documentation](#building-the-documentation) - * [Building a debug build](#building-a-debug-build) - * [Building an ASan build](#building-an-asan-build) - * [Speeding up frequent rebuilds when developing](#speeding-up-frequent-rebuilds-when-developing) - * [ccache](#ccache) - * [Loading JS files from disk instead of embedding](#loading-js-files-from-disk-instead-of-embedding) - * [Troubleshooting Unix and macOS builds](#troubleshooting-unix-and-macos-builds) - * [Windows](#windows) - * [Windows Prerequisites](#windows-prerequisites) - * [Option 1: Manual install](#option-1-manual-install) - * [Option 2: Automated install with WinGet](#option-2-automated-install-with-winget) - * [Building Node.js](#building-nodejs-2) - * [Using ccache](#using-ccache) - * [Android](#android) -* [`Intl` (ECMA-402) support](#intl-ecma-402-support) - * [Build with full ICU support (all locales supported by ICU)](#build-with-full-icu-support-all-locales-supported-by-icu) - * [Unix/macOS](#unixmacos) - * [Windows](#windows-1) - * [Trimmed: `small-icu` (English only) support](#trimmed-small-icu-english-only-support) - * [Unix/macOS](#unixmacos-1) - * [Windows](#windows-2) - * [Building without Intl support](#building-without-intl-support) - * [Unix/macOS](#unixmacos-2) - * [Windows](#windows-3) - * [Use existing installed ICU (Unix/macOS only)](#use-existing-installed-icu-unixmacos-only) - * [Build with a specific ICU](#build-with-a-specific-icu) - * [Unix/macOS](#unixmacos-3) - * [Windows](#windows-4) -* [Configuring OpenSSL config appname](#configure-openssl-appname) -* [Building Node.js with FIPS-compliant OpenSSL](#building-nodejs-with-fips-compliant-openssl) -* [Building Node.js with Temporal support](#building-nodejs-with-temporal-support) -* [Building Node.js with external core modules](#building-nodejs-with-external-core-modules) - * [Unix/macOS](#unixmacos-4) - * [Windows](#windows-5) -* [Note for downstream distributors of Node.js](#note-for-downstream-distributors-of-nodejs) +* [Building Node.js](#building-nodejs) + * [Table of contents](#table-of-contents) + * [Supported platforms](#supported-platforms) + * [Input](#input) + * [Strategy](#strategy) + * [Platform list](#platform-list) + * [Supported toolchains](#supported-toolchains) + * [Official binary platforms and toolchains](#official-binary-platforms-and-toolchains) + * [OpenSSL asm support](#openssl-asm-support) + * [Previous versions of this document](#previous-versions-of-this-document) + * [Building Node.js on supported platforms](#building-nodejs-on-supported-platforms) + * [Prerequisites](#prerequisites) + * [Unix and macOS](#unix-and-macos) + * [Unix prerequisites](#unix-prerequisites) + * [macOS prerequisites](#macos-prerequisites) + * [Nix integration](#nix-integration) + * [Building Node.js](#building-nodejs-1) + * [Installing Node.js](#installing-nodejs) + * [Running tests](#running-tests) + * [Running coverage](#running-coverage) + * [Building the documentation](#building-the-documentation) + * [Building a debug build](#building-a-debug-build) + * [Building an ASan build](#building-an-asan-build) + * [Speeding up frequent rebuilds when developing](#speeding-up-frequent-rebuilds-when-developing) + * [ccache](#ccache) + * [Loading JS files from disk instead of embedding](#loading-js-files-from-disk-instead-of-embedding) + * [Troubleshooting Unix and macOS builds](#troubleshooting-unix-and-macos-builds) + * [Windows](#windows) + * [Tips](#tips) + * [Windows Prerequisites](#windows-prerequisites) + * [Option 1: Manual install](#option-1-manual-install) + * [Option 2: Automated install with WinGet](#option-2-automated-install-with-winget) + * [Building Node.js](#building-nodejs-2) + * [Using ccache:](#using-ccache) + * [Android](#android) + * [`Intl` (ECMA-402) support](#intl-ecma-402-support) + * [Build with full ICU support (all locales supported by ICU)](#build-with-full-icu-support-all-locales-supported-by-icu) + * [Unix/macOS](#unixmacos) + * [Windows](#windows-1) + * [Trimmed: `small-icu` (English only) support](#trimmed-small-icu-english-only-support) + * [Unix/macOS](#unixmacos-1) + * [Windows](#windows-2) + * [Building without Intl support](#building-without-intl-support) + * [Unix/macOS](#unixmacos-2) + * [Windows](#windows-3) + * [Use existing installed ICU (Unix/macOS only)](#use-existing-installed-icu-unixmacos-only) + * [Build with a specific ICU](#build-with-a-specific-icu) + * [Unix/macOS](#unixmacos-3) + * [Windows](#windows-4) + * [Configure OpenSSL appname](#configure-openssl-appname) + * [Building Node.js with FIPS-compliant OpenSSL](#building-nodejs-with-fips-compliant-openssl) + * [Building Node.js with Temporal support](#building-nodejs-with-temporal-support) + * [Building Node.js with external core modules](#building-nodejs-with-external-core-modules) + * [Unix/macOS](#unixmacos-4) + * [Windows](#windows-5) + * [Building to use shared dependencies at runtime](#building-to-use-shared-dependencies-at-runtime) + * [Note for downstream distributors of Node.js](#note-for-downstream-distributors-of-nodejs) ## Supported platforms @@ -123,6 +128,7 @@ platforms. This is true regardless of entries in the table below. | SmartOS | x64 | >= 18 | Tier 2 | | | AIX | ppc64be >=power9 | >= 7.2 TL04 | Tier 2 | | | FreeBSD | x64 | >= 13.2 | Experimental | | +| Android | arm64 | >= 7.0 | Experimental | | | OpenHarmony | arm64 | >= 5.0 | Experimental | | @@ -914,6 +920,23 @@ make -j4 The Android SDK version should be at least 24 (Android 7.0) and the target architecture supports \[arm, arm64/aarch64, x86, x86\_64]. +The static Node.js archive is generated at `out/Release/obj.target/libnode.a`. +This archive is a thin archive by default. It references object files in the +build directory and may still require the other static dependency archives under +`out/Release/obj.target/` when embedding Node.js elsewhere. To produce one +standalone archive for distribution, merge the target static archives with the +NDK `llvm-ar`. + +To reduce the Android build size, disable optional features in the `./configure` +call made by `android_configure.py`. Common options include: + +```bash +--without-ssl +--without-node-snapshot +--without-intl +--without-inspector +``` + ## `Intl` (ECMA-402) support [Intl](doc/api/intl.md) support is diff --git a/android-configure b/android-configure index b2628f95e8e4f4..d79f9a18012fc2 100755 --- a/android-configure +++ b/android-configure @@ -4,13 +4,11 @@ # Note that the mix of single and double quotes is intentional, # as is the fact that the ] goes on a new line. _=[ 'exec' '/bin/sh' '-c' ''' -command -v python3.14 >/dev/null && exec python3.14 "$0" "$@" -command -v python3.13 >/dev/null && exec python3.13 "$0" "$@" -command -v python3.12 >/dev/null && exec python3.12 "$0" "$@" -command -v python3.11 >/dev/null && exec python3.11 "$0" "$@" -command -v python3.10 >/dev/null && exec python3.10 "$0" "$@" -command -v python3 >/dev/null && exec python3 "$0" "$@" -exec python "$0" "$@" +for python in python3.14 python3.13 python3.12 python3.11 python3.10 python3 python; do + command -v "$python" >/dev/null 2>&1 && exec "$python" "$0" "$@" +done +echo "No Python interpreter found." >&2 +exit 1 ''' "$0" "$@" ] del _ diff --git a/android_configure.py b/android_configure.py index 5cea0393f48a76..a4506779f26373 100644 --- a/android_configure.py +++ b/android_configure.py @@ -1,3 +1,4 @@ +import subprocess import platform import sys import os @@ -7,7 +8,12 @@ def patch_android(): print("- Patches List -") print("[1] [deps/v8/src/trap-handler/trap-handler.h] related to https://github.com/nodejs/node/issues/36287") if platform.system() == "Linux": - os.system('patch -f ./deps/v8/src/trap-handler/trap-handler.h < ./android-patches/trap-handler.h.patch') + with open("./android-patches/trap-handler.h.patch", "rb") as patch_file: + subprocess.run( + ["patch", "-f", "./deps/v8/src/trap-handler/trap-handler.h"], + stdin=patch_file, + check=True, + ) print("\033[92mInfo: \033[0m" + "Tried to patch.") if platform.system() != "Linux" and platform.system() != "Darwin": @@ -55,7 +61,7 @@ def patch_android(): print("\033[92mInfo: \033[0m" + "Configuring for " + DEST_CPU + "...") if platform.system() == "Darwin": - host_os = "darwin" + host_os = "mac" toolchain_path = android_ndk_path + "/toolchains/llvm/prebuilt/darwin-x86_64" elif platform.system() == "Linux": @@ -65,6 +71,18 @@ def patch_android(): os.environ['PATH'] += os.pathsep + toolchain_path + "/bin" os.environ['CC'] = toolchain_path + "/bin/" + TOOLCHAIN_PREFIX + android_sdk_version + "-" + "clang" os.environ['CXX'] = toolchain_path + "/bin/" + TOOLCHAIN_PREFIX + android_sdk_version + "-" + "clang++" +os.environ.setdefault('CC_target', os.environ['CC']) +os.environ.setdefault('CXX_target', os.environ['CXX']) +os.environ.setdefault('CC_host', 'cc') +os.environ.setdefault('CXX_host', 'c++') + +# macOS /usr/bin/ar cannot consume the @file-list syntax emitted by GYP for +# large archives. llvm-ar can archive both host Mach-O objects and Android +# target objects. +llvm_ar = toolchain_path + "/bin/llvm-ar" +os.environ.setdefault('AR', llvm_ar) +os.environ.setdefault('AR_host', llvm_ar) +os.environ.setdefault('AR_target', llvm_ar) GYP_DEFINES = "target_arch=" + arch GYP_DEFINES += " v8_target_arch=" + arch @@ -74,4 +92,12 @@ def patch_android(): os.environ['GYP_DEFINES'] = GYP_DEFINES if os.path.exists("./configure"): - os.system("./configure --dest-cpu=" + DEST_CPU + " --dest-os=android --openssl-no-asm --cross-compiling") + subprocess.run([ + "./configure", + "--dest-cpu=" + DEST_CPU, + "--dest-os=android", + "--openssl-no-asm", + "--cross-compiling", + "--enable-static", + "--v8-disable-temporal-support", + ], check=True) diff --git a/deps/uv/uv.gyp b/deps/uv/uv.gyp index 540445f1f3249b..dc6465203b84d0 100644 --- a/deps/uv/uv.gyp +++ b/deps/uv/uv.gyp @@ -406,6 +406,31 @@ 'src/unix/os390-syscalls.c' ] }], + ], + 'target_conditions': [ + [ '_toolset=="host" and host_os=="mac" and OS=="android"', { + 'defines': [ + '_DARWIN_USE_64_BIT_INODE=1', + '_DARWIN_UNLIMITED_SELECT=1', + ], + 'sources': [ + '<@(uv_sources_apple)', + '<@(uv_sources_bsd_common)', + 'src/unix/proctitle.c', + ], + 'sources!': [ + '<@(uv_sources_android)', + '<@(uv_sources_linux)', + ], + }], + [ '_toolset=="host" and host_os=="linux" and OS=="android"', { + 'sources': [ + '<@(uv_sources_linux)', + ], + 'sources!': [ + '<@(uv_sources_android)', + ], + }], ] }, ] diff --git a/deps/zlib/zlib.gyp b/deps/zlib/zlib.gyp index 12449e7b0294c9..b49e0bc247d5b2 100644 --- a/deps/zlib/zlib.gyp +++ b/deps/zlib/zlib.gyp @@ -201,6 +201,29 @@ 'USE_FILE32API' ], }], + ['OS=="android"', { + 'actions': [ + { + 'action_name': 'copy_android_cpufeatures', + 'inputs': [ + '<(android_ndk_path)/sources/android/cpufeatures/cpu-features.c', + ], + 'outputs': [ + '<(SHARED_INTERMEDIATE_DIR)/android_cpufeatures.c', + ], + 'action': [ + '<(python)', + '-c', + 'import os, shutil, sys; os.makedirs(os.path.dirname(sys.argv[2]), exist_ok=True); shutil.copyfile(sys.argv[1], sys.argv[2])', + '<@(_inputs)', + '<@(_outputs)', + ], + }, + ], + 'sources': [ + '<(SHARED_INTERMEDIATE_DIR)/android_cpufeatures.c', + ], + }], # Incorporate optimizations where possible. ['(target_arch in "ia32 x64" and OS!="ios") or arm_fpu=="neon"', { 'dependencies': [ 'zlib_data_chunk_simd' ], diff --git a/tools/gyp/pylib/gyp/generator/make.py b/tools/gyp/pylib/gyp/generator/make.py index 16b6f4e80b119a..66e6d5e6140bff 100644 --- a/tools/gyp/pylib/gyp/generator/make.py +++ b/tools/gyp/pylib/gyp/generator/make.py @@ -272,6 +272,21 @@ def CalculateGeneratorInputInfo(params): cmd_solink_module_host = $(LINK.$(TOOLSET)) -shared $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -Wl,-soname=$(@F) -o $@ $(filter-out FORCE_DO_CMD, $^) $(LIBS) """ # noqa: E501 +LINK_COMMANDS_ANDROID_DARWIN_HOST = LINK_COMMANDS_ANDROID.replace( + "$(AR.$(TOOLSET)) crsT $(1) @$(1).$(OBJ_FILE_LIST)", + 'if [ "$(TOOLSET)" = "host" ]; then \\\n' + " $(AR.$(TOOLSET)) crs $(1) @$(1).$(OBJ_FILE_LIST); \\\n" + " else \\\n" + " $(AR.$(TOOLSET)) crsT $(1) @$(1).$(OBJ_FILE_LIST); \\\n" + " fi", +).replace( + "cmd_link_host = $(LINK.$(TOOLSET)) $(GYP_LDFLAGS) " + "$(LDFLAGS.$(TOOLSET)) -o $@ -Wl,--start-group $(LD_INPUTS) " + "-Wl,--end-group $(LIBS)", + "cmd_link_host = $(LINK.$(TOOLSET)) $(GYP_LDFLAGS) " + "$(LDFLAGS.$(TOOLSET)) -o $@ $(LD_INPUTS) $(LIBS)", +) + LINK_COMMANDS_AIX = """\ quiet_cmd_alink = AR($(TOOLSET)) $@ @@ -2518,7 +2533,10 @@ def CalculateMakefilePath(build_file, base_name): } ) elif flavor == "android": - header_params.update({"link_commands": LINK_COMMANDS_ANDROID}) + link_commands = LINK_COMMANDS_ANDROID + if sys.platform == "darwin": + link_commands = LINK_COMMANDS_ANDROID_DARWIN_HOST + header_params.update({"link_commands": link_commands}) elif flavor == "zos": copy_archive_arguments = "-fPR" CC_target = GetEnvironFallback(("CC_target", "CC"), "njsc") diff --git a/tools/v8_gypfiles/abseil.gyp b/tools/v8_gypfiles/abseil.gyp index fdc2fae1ab4d75..d091f1d1648b8c 100644 --- a/tools/v8_gypfiles/abseil.gyp +++ b/tools/v8_gypfiles/abseil.gyp @@ -15,6 +15,13 @@ 'xcode_settings': { 'OTHER_LDFLAGS': ['-framework CoreFoundation'], }, + 'conditions': [ + [ '_toolset=="host" and host_os=="mac" and OS=="android"', { + 'libraries': [ + '-framework CoreFoundation', + ], + }], + ], }, 'include_dirs': [ '<(ABSEIL_ROOT)', diff --git a/tools/v8_gypfiles/v8.gyp b/tools/v8_gypfiles/v8.gyp index 945aa0aa501df1..4ee7d824ba2d70 100644 --- a/tools/v8_gypfiles/v8.gyp +++ b/tools/v8_gypfiles/v8.gyp @@ -1191,7 +1191,7 @@ 'conditions': [ ['v8_enable_webassembly==1', { 'conditions': [ - ['((_toolset=="host" and host_arch=="arm64" or _toolset=="target" and target_arch=="arm64") and (OS in "linux mac ios openharmony")) or ((_toolset=="host" and host_arch=="x64" or _toolset=="target" and target_arch=="x64") and (OS in "linux mac openharmony"))', { + ['((_toolset=="host" and host_arch=="arm64" or _toolset=="target" and target_arch=="arm64") and (OS in "linux mac ios openharmony")) or ((_toolset=="host" and host_arch=="x64" or _toolset=="target" and target_arch=="x64") and (OS in "linux mac openharmony")) or (_toolset=="host" and OS=="android" and host_arch=="arm64" and host_os in "linux mac ios openharmony") or (_toolset=="host" and OS=="android" and host_arch=="x64" and host_os in "linux mac openharmony")', { 'sources': [ '<(V8_ROOT)/src/trap-handler/handler-inside-posix.cc', '<(V8_ROOT)/src/trap-handler/handler-outside-posix.cc', @@ -1478,35 +1478,26 @@ }], ], }], - ['is_android', { + ['is_android and _toolset=="target"', { 'sources': [ '<(V8_ROOT)/src/base/platform/platform-posix.cc', '<(V8_ROOT)/src/base/platform/platform-posix.h', '<(V8_ROOT)/src/base/platform/platform-posix-time.cc', '<(V8_ROOT)/src/base/platform/platform-posix-time.h', + '<(V8_ROOT)/src/base/debug/stack_trace_android.cc', + '<(V8_ROOT)/src/base/platform/platform-linux.cc', + ], + }], + ['is_android and _toolset=="host" and host_os=="linux"', { + 'sources': [ + '<(V8_ROOT)/src/base/debug/stack_trace_posix.cc', + '<(V8_ROOT)/src/base/platform/platform-linux.cc', ], 'link_settings': { - 'target_conditions': [ - ['_toolset=="host" and host_os=="linux"', { - 'libraries': [ - '-ldl' - ], - }], + 'libraries': [ + '-ldl' ], }, - 'target_conditions': [ - ['_toolset=="host"', { - 'sources': [ - '<(V8_ROOT)/src/base/debug/stack_trace_posix.cc', - '<(V8_ROOT)/src/base/platform/platform-linux.cc', - ], - }, { - 'sources': [ - '<(V8_ROOT)/src/base/debug/stack_trace_android.cc', - '<(V8_ROOT)/src/base/platform/platform-linux.cc', - ], - }], - ], }], ['is_fuchsia', { 'sources': [