Skip to content

Temporal does not compile with shared ICU or no ICU #62676

Closed

Description

@richardlau

When Node.js is configured with --with-intl=none (or --without-intl) or --with-intl=system-icu the build fails when Temporal is enabled.

e.g.

20:51:03   ccache clang++-19 -o /home/iojs/build/workspace/node-test-commit-linux-containered/out/Release/obj.target/v8_base_without_compiler/deps/v8/src/objects/js-temporal-zoneinfo64.o ../deps/v8/src/objects/js-temporal-zoneinfo64.cc '-D_GLIBCXX_USE_CXX11_ABI=1' '-D_FILE_OFFSET_BITS=64' '-DNODE_OPENSSL_CONF_NAME=nodejs_conf' '-DICU_NO_USER_DATA_OVERRIDE' '-DV8_GYP_BUILD' '-DV8_TYPED_ARRAY_MAX_SIZE_IN_HEAP=64' '-DBUILDING_V8_SHARED' '-DBUILDING_V8_PLATFORM_SHARED' '-D__STDC_FORMAT_MACROS' '-DOPENSSL_NO_PINSHARED' '-DOPENSSL_THREADS' '-DV8_TARGET_ARCH_X64' '-DV8_HAVE_TARGET_OS' '-DV8_TARGET_OS_LINUX' '-DV8_EMBEDDER_STRING="-node.17"' '-DENABLE_DISASSEMBLER' '-DV8_PROMISE_INTERNAL_FIELD_COUNT=1' '-DENABLE_GDB_JIT_INTERFACE' '-DV8_ENABLE_PRIVATE_MAPPING_FORK_OPTIMIZATION' '-DV8_SHORT_BUILTIN_CALLS' '-DOBJECT_PRINT' '-DV8_INTL_SUPPORT' '-DV8_TEMPORAL_SUPPORT' '-DV8_ATOMIC_OBJECT_FIELD_WRITES' '-DV8_ENABLE_LAZY_SOURCE_POSITIONS' '-DV8_USE_SIPHASH' '-DV8_ENABLE_SEEDED_ARRAY_INDEX_HASH' '-DNDEBUG' '-DV8_WIN64_UNWINDING_INFO' '-DV8_ENABLE_REGEXP_INTERPRETER_THREADED_DISPATCH' '-DV8_USE_ZLIB' '-DV8_ENABLE_LEAPTIERING' '-DV8_ENABLE_SPARKPLUG' '-DV8_ENABLE_MAGLEV' '-DV8_ENABLE_TURBOFAN' '-DV8_ENABLE_WEBASSEMBLY' '-DV8_ENABLE_JAVASCRIPT_PROMISE_HOOKS' '-DV8_ENABLE_CONTINUATION_PRESERVED_EMBEDDER_DATA' '-DV8_ALLOCATION_FOLDING' '-DV8_ALLOCATION_SITE_TRACKING' '-DV8_ADVANCED_BIGINT_ALGORITHMS' '-DV8_ENABLE_WASM_SIMD256_REVEC' '-DICU_UTIL_DATA_IMPL=ICU_UTIL_DATA_STATIC' -I../deps/v8 -I../deps/v8/include -I/opt/icu-73.2/include -I/home/iojs/build/workspace/node-test-commit-linux-containered/out/Release/obj/gen/inspector-generated-output-root -I../deps/v8/third_party/inspector_protocol -I/home/iojs/build/workspace/node-test-commit-linux-containered/out/Release/obj/gen -I/home/iojs/build/workspace/node-test-commit-linux-containered/out/Release/obj/gen/inspector-generated-output-root/include -I/home/iojs/build/workspace/node-test-commit-linux-containered/out/Release/obj/gen/generate-bytecode-output-root -I../deps/v8/third_party/zlib -I../deps/v8/third_party/zlib/google -I../deps/v8/third_party/fp16/src/include -I../deps/v8/third_party/highway/src -I../deps/v8/third_party/simdutf -I../deps/v8/third_party/abseil-cpp -I../deps/crates/vendor/temporal_capi/bindings/cpp  -fvisibility=hidden -fvisibility-inlines-hidden -pthread -Wno-unused-parameter -m64 -O3 -fno-omit-frame-pointer -fdata-sections -ffunction-sections -O3 -fno-rtti -fno-exceptions -fno-strict-aliasing -std=gnu++20 -Wno-invalid-offsetof -Wno-nullability-completeness -MMD -MF /home/iojs/build/workspace/node-test-commit-linux-containered/out/Release/.deps//home/iojs/build/workspace/node-test-commit-linux-containered/out/Release/obj.target/v8_base_without_compiler/deps/v8/src/objects/js-temporal-zoneinfo64.o.d.raw   -c
20:51:05 ../deps/v8/src/objects/js-temporal-zoneinfo64.cc:14:10: fatal error: 'udatamem.h' file not found
20:51:05    14 | #include "udatamem.h"
20:51:05       |          ^~~~~~~~~~~~
20:51:05 1 error generated.
20:51:05 make[2]: *** [tools/v8_gypfiles/v8_base_without_compiler.target.mk:1138: /home/iojs/build/workspace/node-test-commit-linux-containered/out/Release/obj.target/v8_base_without_compiler/deps/v8/src/objects/js-temporal-zoneinfo64.o] Error 1
23:19:59 /usr/bin/ld: /home/iojs/build/workspace/node-test-commit-linux-containered/out/Release/obj.target/v8_base_without_compiler/deps/v8/src/objects/js-temporal-zoneinfo64.o: in function `v8::internal::ZoneInfo64Provider::ZoneInfo64Provider()':
23:19:59 js-temporal-zoneinfo64.cc:(.text._ZN2v88internal18ZoneInfo64ProviderC2Ev+0x13): undefined reference to `zoneinfo64_static_data_len'
23:19:59 /usr/bin/ld: js-temporal-zoneinfo64.cc:(.text._ZN2v88internal18ZoneInfo64ProviderC2Ev+0x1d): undefined reference to `zoneinfo64_static_data'
23:20:00 clang++-19: error: linker command failed with exit code 1 (use -v to see invocation)
23:20:00 make[2]: *** [tools/v8_gypfiles/mksnapshot.target.mk:222: /home/iojs/build/workspace/node-test-commit-linux-containered/out/Release/mksnapshot] Error 1
23:20:00 rm a50936564b94c8a1c04b713ccd861b094c973ce83a2131b86111777ecadc0a82.intermediate 

The first issue (with --with-intl=system-icu) stems from V8 using a private header file from ICU. In #62508, this is being worked around by temporarily patching V8 with https://github.com/nodejs/node/pull/62508/files#diff-89a9a4423f9b83142d44bfb376f2c56ffff396ee1ef98c4930a61d5ed9732c7f. Unfortunately applying that in #61806 breaks parallel/test-temporal-with-zoneinfo in the default (no --with-intl=... specified) case.

e.g. https://github.com/nodejs/node/actions/runs/24165429332/job/70525857573?pr=61806#step:9:6040

=== release test-temporal-with-zoneinfo ===
Path: parallel/test-temporal-with-zoneinfo
Error: --- stderr ---
/home/runner/work/node/node/node/test/parallel/test-temporal-with-zoneinfo.js:19
assert.strictEqual(pdt.toString(), '1969-07-20T20:17:00Z');
                       ^

Error: Temporal error: Internal error: Failed to load timezone info.
    at Instant.toString (<anonymous>)
    at Object.<anonymous> (/home/runner/work/node/node/node/test/parallel/test-temporal-with-zoneinfo.js:19:24)
    at Module._compile (node:internal/modules/cjs/loader:1829:14)
    at Object..js (node:internal/modules/cjs/loader:1969:10)
    at Module.load (node:internal/modules/cjs/loader:1552:32)
    at Module._load (node:internal/modules/cjs/loader:1354:12)
    at wrapModuleLoad (node:internal/modules/cjs/loader:255:19)
    at Module.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:154:5)
    at node:internal/main/run_main_module:33:47

Node.js v26.0.0-pre
Command: out/Release/node --harmony-temporal /home/runner/work/node/node/node/test/parallel/test-temporal-with-zoneinfo.js

===
=== 1 tests failed
===

Failed tests:
out/Release/node --harmony-temporal /home/runner/work/node/node/node/test/parallel/test-temporal-with-zoneinfo.js

Also ideally we don't want to be carrying patches on top of V8 as much as possible, so would prefer something patched upstream in V8 if possible.

Refs: #61806 (comment)

Activity

  1. aduh95 commented on Aug 9, 2026

    @aduh95
    Contributor

    Still relevant

  2. removed
    staleIssues and PRs marked stale due to inactivity and scheduled for automatic closure.
    on Aug 10, 2026
  3. added
    never-staleIssues and PRs exempt from automated stale handling.
    icuIssues and PRs related to the ICU dependency.
    on Aug 11, 2026
  4. srl295 commented on Aug 21, 2026

    @srl295
    Member

    Hi!

    Follow-up with the ICU upstream tracking link:

    I actually didn't see the proposal go to that list.

    My current read of the long-term direction is:

    1. V8/Chromium should be able to keep the current no-duplicate-data design when ICU already ships zoneinfo64.res.
    2. Node and other external/system-ICU embedders should not need ICU private headers such as udatamem.h to build a public Node release.
    3. ICU should expose a stable public data-item view/export API that can return the raw ICU data item plus exact length for cases like temporal_rs that intentionally need the raw .res bytes.

    Until that ICU API exists, the practical V8-side short-term fix seems to be an explicit V8 build option for the Temporal zoneinfo64 provider: default to the ICU-backed path for Chromium/bundled ICU builds, and let embedders that cannot use private ICU headers disable that path and use baked zoneinfo64 data instead. That is better than silently dropping Temporal from Node builds, and cleaner than relying on __has_include to guess packaging policy.

    I think a simpler patch can be made without using private headers, working on that.

  5. aduh95 commented on Aug 21, 2026

    @aduh95
    Contributor

    I can confirm srl295/v8@8ffc0b8 looks quite promising, thanks!

    ICU Builds test-temporal-with-zoneinfo
    No ICU (--without-intl) ❌ N/A
    Shared (--with=intl=system-icu) ✅ ✅
    Small ICU (--with-intl=small-icu) ✅ ✅
    Full ICU (default) ✅ ✅
    No ICU build error
    Undefined symbols for architecture arm64:
      "_zoneinfo64_static_data", referenced from:
          v8::internal::ZoneInfo64Provider::ZoneInfo64Provider() in libv8_base_without_compiler.a(v8_base_without_compiler.js-temporal-zoneinfo64.o)
          v8::internal::ZoneInfo64Provider::ZoneInfo64Provider() in libv8_base_without_compiler.a(v8_base_without_compiler.js-temporal-zoneinfo64.o)
      "_zoneinfo64_static_data_len", referenced from:
          v8::internal::ZoneInfo64Provider::ZoneInfo64Provider() in libv8_base_without_compiler.a(v8_base_without_compiler.js-temporal-zoneinfo64.o)
          v8::internal::ZoneInfo64Provider::ZoneInfo64Provider() in libv8_base_without_compiler.a(v8_base_without_compiler.js-temporal-zoneinfo64.o)
    

    The following diff fixes the compilation (and test-temporal-with-zoneinfo still passes):

    diff --git a/deps/v8/src/objects/js-temporal-zoneinfo64.cc b/deps/v8/src/objects/js-temporal-zoneinfo64.cc
    index 8b461a29023..f8ff5a698fc 100644
    --- a/deps/v8/src/objects/js-temporal-zoneinfo64.cc
    +++ b/deps/v8/src/objects/js-temporal-zoneinfo64.cc
    @@ -30,8 +30,8 @@ struct UDataMemoryShadow {
     #else
     // Defined in builtins-temporal-zoneinfo64-data.cc, generated by
     // include-file-as-bytes.py
    -extern "C" uint32_t zoneinfo64_static_data[];
    -extern "C" size_t zoneinfo64_static_data_len;
    +static uint32_t zoneinfo64_static_data[] = {};
    +static size_t zoneinfo64_static_data_len = 0;
     #endif
     
     namespace v8::internal {
  6. srl295 commented on Aug 21, 2026

    @srl295
    Member

    I assume no icu isn't a regression.

  7. added a commit that references this issue on Aug 21, 2026
  8. srl295 commented on Aug 21, 2026

    @srl295
    Member

    @aduh95 i dug into this a little more. (and please chime in on the v8 above ^ )

    The no-icu failure you got seems to also be where v8_enable_temporal_support is falsy. If it was true, then the data items should have been baked in. I'm going to restore the code, but with an ifdef.

  9. srl295 commented on Aug 24, 2026

    @srl295
    Member

    CC @nodejs/i18n-api

  10. added
    i18n-apiIssues and PRs related to Node.js internationalization support.
    on Aug 24, 2026
  11. aduh95 commented on Aug 24, 2026

    @aduh95
    Contributor

    The defined(V8_TEMPORAL_SUPPORT) in srl295/v8@9e43c2a are almost certainly a red herring, the deps/v8/src/objects/js-temporal-zoneinfo64.cc file should be included only if temporal support is enabled, so it's only adding non-reachable code AFAICT.

    FWIW if I manually run python deps/v8/tools/include-file-as-bytes.py deps/crates/vendor/zoneinfo64-v0_3/src/data/zoneinfo64.res deps/v8/src/objects/builtins-temporal-zoneinfo64-data.cc zoneinfo64_static_data, add a #include "builtins-temporal-zoneinfo64-data.cc" in deps/v8/src/objects/js-temporal-zoneinfo64.cc, I'm able to compile with --without-intl. FWIW here's the build rule for that file:

    node/deps/v8/BUILD.gn

    Lines 3563 to 3578 in 46a7dbd

    if (v8_enable_temporal_support) {
    # In cases where we aren't using ICU4C (e.g. v8_enable_i18n_support=false),
    # we "bake" in a zoneinfo64.res binary for Temporal
    action("make_temporal_zoneinfo_cpp") {
    script = "tools/include-file-as-bytes.py"
    inputs = [ get_label_info("//third_party/icu/", "dir") +
    "/tzres/zoneinfo64.res" ]
    outputs =
    [ "$target_gen_dir/src/builtins/builtins-temporal-zoneinfo64-data.cc" ]
    args = [
    rebase_path(inputs[0], root_build_dir),
    rebase_path(outputs[0], root_build_dir),
    "zoneinfo64_static_data",
    ]
    }
    }

    I couldn't find it in Node.js GYP files. So the issue I reported above is more likely Node.js-specific than indicating an issue with srl295/v8@8ffc0b8. I'm happy to chime in on the V8 CL, but I'm afraid I'd likely be off-topic.

  12. srl295 commented on Aug 24, 2026

    @srl295
    Member

    The defined(V8_TEMPORAL_SUPPORT) in srl295/v8@9e43c2a are almost certainly a red herring, the deps/v8/src/objects/js-temporal-zoneinfo64.cc file should be included only if temporal support is enabled, so it's only adding non-reachable code AFAICT.

    OK.

    FWIW if I manually run python deps/v8/tools/include-file-as-bytes.py deps/crates/vendor/zoneinfo64-v0_3/src/data/zoneinfo64.res deps/v8/src/objects/builtins-temporal-zoneinfo64-data.cc zoneinfo64_static_data, add a #include "builtins-temporal-zoneinfo64-data.cc" in deps/v8/src/objects/js-temporal-zoneinfo64.cc, I'm able to compile with --without-intl. FWIW here's the build rule for that file:

    node/deps/v8/BUILD.gn

    Lines 3563 to 3578 in 46a7dbd

    if (v8_enable_temporal_support) {
    # In cases where we aren't using ICU4C (e.g. v8_enable_i18n_support=false),
    # we "bake" in a zoneinfo64.res binary for Temporal
    action("make_temporal_zoneinfo_cpp") {
    script = "tools/include-file-as-bytes.py"
    inputs = [ get_label_info("//third_party/icu/", "dir") +
    "/tzres/zoneinfo64.res" ]
    outputs =
    [ "$target_gen_dir/src/builtins/builtins-temporal-zoneinfo64-data.cc" ]
    args = [
    rebase_path(inputs[0], root_build_dir),
    rebase_path(outputs[0], root_build_dir),
    "zoneinfo64_static_data",
    ]
    }
    }

    Ah, so that needs to be ported to node.. thanks

    I couldn't find it in Node.js GYP files. So the issue I reported above is more likely Node.js-specific than indicating an issue with srl295/v8@8ffc0b8. I'm happy to chime in on the V8 CL, but I'm afraid I'd likely be off-topic.

  13. self-assigned this
    on Sep 11, 2026
  14. srl295 commented on Sep 17, 2026

    @srl295
    Member

    I have a fix in #65992 that floats a v8 patch.

  15. added a commit that references this issue on Sep 23, 2026
  16. added a commit that references this issue on Oct 4, 2026
  17. added a commit that references this issue on Oct 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

i18n-apiIssues and PRs related to Node.js internationalization support.icuIssues and PRs related to the ICU dependency.never-staleIssues and PRs exempt from automated stale handling.v8 engineIssues and PRs related to the V8 dependency.

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions