diff --git a/eng/testing/WasmRunnerTemplate.cmd b/eng/testing/WasmRunnerTemplate.cmd
index e2f0afa32f93ed..7949a295fa13ec 100644
--- a/eng/testing/WasmRunnerTemplate.cmd
+++ b/eng/testing/WasmRunnerTemplate.cmd
@@ -47,7 +47,11 @@ if /I [%XHARNESS_COMMAND%] == [test] (
)
if [%JS_ENGINE_ARGS%] == [] (
- set "JS_ENGINE_ARGS=--engine-arg^=--stack-trace-limit^=1000 --engine-arg^=--module"
+ set "JS_ENGINE_ARGS=--engine-arg^=--stack-trace-limit^=1000"
+
+ if [!JS_ENGINE!] == [--engine^=V8] (
+ set "JS_ENGINE_ARGS=!JS_ENGINE_ARGS! --engine-arg^=--module"
+ )
)
) else (
if /I [%SCENARIO%] == [WasmTestOnChrome] (
diff --git a/eng/testing/WasmRunnerTemplate.sh b/eng/testing/WasmRunnerTemplate.sh
index 111cd59e0acc2c..82424b9f6df043 100644
--- a/eng/testing/WasmRunnerTemplate.sh
+++ b/eng/testing/WasmRunnerTemplate.sh
@@ -36,16 +36,19 @@ if [[ -z "$XHARNESS_COMMAND" ]]; then
fi
if [[ "$XHARNESS_COMMAND" == "test" ]]; then
+ if [[ -z "$JS_ENGINE" ]]; then
+ JS_ENGINE="--engine=V8"
+ fi
if [[ -z "$MAIN_JS" ]]; then
MAIN_JS="--js-file=test-main.js"
fi
if [[ -z "$JS_ENGINE_ARGS" ]]; then
- JS_ENGINE_ARGS="--engine-arg=--stack-trace-limit=1000 --engine-arg=--module"
- fi
+ JS_ENGINE_ARGS="--engine-arg=--stack-trace-limit=1000"
- if [[ -z "$JS_ENGINE" ]]; then
- JS_ENGINE="--engine=V8"
+ if [[ "$JS_ENGINE" == "--engine=V8" ]] ; then
+ JS_ENGINE_ARGS="$JS_ENGINE_ARGS --engine-arg=--module"
+ fi
fi
else
if [[ "$SCENARIO" == "WasmTestOnChrome" || "$SCENARIO" == "wasmtestonchrome" ]]; then
diff --git a/src/installer/pkg/sfx/Microsoft.NETCore.App/Directory.Build.props b/src/installer/pkg/sfx/Microsoft.NETCore.App/Directory.Build.props
index 44625877c6561d..ae37c31acea679 100644
--- a/src/installer/pkg/sfx/Microsoft.NETCore.App/Directory.Build.props
+++ b/src/installer/pkg/sfx/Microsoft.NETCore.App/Directory.Build.props
@@ -82,6 +82,8 @@
+
+
@@ -220,7 +222,6 @@
-
diff --git a/src/mono/browser/browser.proj b/src/mono/browser/browser.proj
index b0a14f621b2b99..df869dc0546036 100644
--- a/src/mono/browser/browser.proj
+++ b/src/mono/browser/browser.proj
@@ -28,7 +28,6 @@
true
false
false
- false
emcc
$(ArtifactsObjDir)wasm
<_EmccDefaultsRspPath>$(NativeBinDir)src\emcc-default.rsp
@@ -46,7 +45,6 @@
-
@@ -81,74 +79,7 @@
-
-
-
- <_WasmTimezonesPath>$([MSBuild]::NormalizePath('$(PkgSystem_Runtime_TimeZoneData)', 'contentFiles', 'any', 'any', 'data'))
- <_WasmTimezonesBundleSourceFile>wasm-bundled-timezones.c
- <_WasmTimezonesBundleArchive>$(WasmObjDir)\wasm-bundled-timezones.a
- <_WasmTimezonesSourcesRsp>$(WasmObjDir)\wasm-bundled-timezones-sources.rsp
- <_WasmTimezonesArchiveRsp>$(WasmObjDir)\wasm-bundled-timezones-archive.rsp
-
-
- <_WasmTimezonesInternal Include="$(_WasmTimezonesPath)\**\*.*" WasmRole="Timezone"/>
-
-
- <_WasmTimezonesInternal Update="@(_WasmTimezonesInternal)">
- /usr/share/zoneinfo/$([MSBuild]::MakeRelative($(_WasmTimezonesPath), %(_WasmTimezonesInternal.Identity)).Replace('\','/'))
-
-
-
-
-
-
-
- <_WasmBundleTimezonesSources Include="$([MSBuild]::MakeRelative($(WasmObjDir), %(BundledWasmTimezones.DestinationFile)).Replace('\','/'))" />
- <_WasmBundleTimezonesSources Include="$(_WasmTimezonesBundleSourceFile)" />
-
-
-
-
-
-
-
-
-
-
-
-
- <_WasmArchivedTimezones Include="$(WasmObjDir)\wasm-bundled-timezones.a" />
-
-
-
-
- <_WasmBundleTimezonesToDelete Include="$(_WasmIntermediateOutputPath)*.o" />
- <_WasmBundleTimezonesToDelete Include="$(_WasmIntermediateOutputPath)*.c" />
- <_WasmBundleTimezonesToDelete Remove="$(WasmObjDir)\$(_WasmTimezonesBundleSourceFile)" />
- <_WasmBundleTimezonesToDelete Remove="%(BundledWasmTimezones.DestinationFile)" />
- <_WasmBundleTimezonesToDelete Remove="$(WasmObjDir)\%(WasmBundleTimezonesObjects)" />
-
-
-
@@ -374,7 +305,7 @@
+ DependsOnTargets="GenerateEmccPropsAndRspFiles;GenerateManagedToNative;InstallNpmPackages;BuildWithRollup">
@@ -519,7 +449,7 @@
DestinationFolder="$(MicrosoftNetCoreAppRuntimePackNativeDir)"
SkipUnchangedFiles="true" />
-
diff --git a/src/mono/browser/build/BrowserWasmApp.targets b/src/mono/browser/build/BrowserWasmApp.targets
index 9a0cedad72646c..4d3cac30ac8e95 100644
--- a/src/mono/browser/build/BrowserWasmApp.targets
+++ b/src/mono/browser/build/BrowserWasmApp.targets
@@ -328,10 +328,9 @@
<_EmccCFlags Include="-DENABLE_AOT=1" Condition="'$(_WasmShouldAOT)' == 'true'" />
<_EmccCFlags Include="-DDRIVER_GEN=1" Condition="'$(_WasmShouldAOT)' == 'true'" />
<_EmccCFlags Include="-DINVARIANT_GLOBALIZATION=1" Condition="'$(InvariantGlobalization)' == 'true'" />
- <_EmccCFlags Include="-DINVARIANT_TIMEZONE=1" Condition="'$(InvariantTimezone)' == 'true'" />
<_EmccCFlags Include="-DLINK_ICALLS=1" Condition="'$(WasmLinkIcalls)' == 'true'" />
<_EmccCFlags Include="-DENABLE_AOT_PROFILER=1" Condition="$(WasmProfilers.Contains('aot'))" />
- <_EmccCFlags Include="-DENABLE_DEVTOOLS_PROFILER=1" Condition="$(WasmProfilers.Contains('browser'))" />
+ <_EmccCFlags Include="-DENABLE_DEVTOOLS_PROFILER=1" Condition="$(WasmProfilers.Contains('browser'))" />
<_EmccCFlags Include="-DENABLE_LOG_PROFILER=1" Condition="$(WasmProfilers.Contains('log'))" />
<_EmccCFlags Include="-DENABLE_JS_INTEROP_BY_VALUE=1" Condition="'$(WasmEnableJsInteropByValue)' == 'true'" />
@@ -459,9 +458,10 @@
- <_MonoRuntimeComponentDontLink Include="wasm-bundled-timezones.a" Condition="'$(InvariantTimezone)' == 'true'"/>
<_MonoRuntimeComponentDontLink Include="libmono-component-diagnostics_tracing-static.a" Condition="'$(EnableDiagnostics)' != 'true'" />
<_MonoRuntimeComponentDontLink Include="libmono-component-diagnostics_tracing-stub-static.lib" Condition="'$(EnableDiagnostics)' == 'true'" />
+ <_MonoRuntimeComponentDontLink Include="libSystem.Native.TimeZoneData.Invariant.a" Condition="'$(InvariantTimezone)' != 'true'" />
+ <_MonoRuntimeComponentDontLink Include="libSystem.Native.TimeZoneData.a" Condition="'$(InvariantTimezone)' == 'true'" />
diff --git a/src/mono/browser/runtime/CMakeLists.txt b/src/mono/browser/runtime/CMakeLists.txt
index 78d5d6eeeea0e7..912383b513d871 100644
--- a/src/mono/browser/runtime/CMakeLists.txt
+++ b/src/mono/browser/runtime/CMakeLists.txt
@@ -26,8 +26,8 @@ target_link_libraries(dotnet.native
${MONO_ARTIFACTS_DIR}/libmono-icall-table.a
${MONO_ARTIFACTS_DIR}/libmono-wasm-eh-js.a
${MONO_ARTIFACTS_DIR}/libmono-wasm-${CONFIGURATION_INTERPSIMDTABLES_LIB}.a
- ${NATIVE_BIN_DIR}/wasm-bundled-timezones.a
${NATIVE_BIN_DIR}/libSystem.Native.a
+ ${NATIVE_BIN_DIR}/libSystem.Native.TimeZoneData.a
${NATIVE_BIN_DIR}/libSystem.Globalization.Native.a
${NATIVE_BIN_DIR}/libSystem.IO.Compression.Native.a
${NATIVE_BIN_DIR}/libz.a)
diff --git a/src/mono/browser/runtime/driver.c b/src/mono/browser/runtime/driver.c
index 4122d53f69c357..8306e961908cb6 100644
--- a/src/mono/browser/runtime/driver.c
+++ b/src/mono/browser/runtime/driver.c
@@ -44,9 +44,6 @@ int monoeg_g_setenv(const char *variable, const char *value, int overwrite);
char *mono_method_get_full_name (MonoMethod *method);
char *mono_method_full_name (MonoMethod *method, int32_t signature);
-#ifndef INVARIANT_TIMEZONE
-extern void mono_register_timezones_bundle (void);
-#endif /* INVARIANT_TIMEZONE */
extern void mono_wasm_set_entrypoint_breakpoint (const char* assembly_name, int method_token);
extern void mono_bundled_resources_add_assembly_resource (const char *id, const char *name, const uint8_t *data, uint32_t size, void (*free_func)(void *, void*), void *free_data);
@@ -193,12 +190,6 @@ mono_wasm_load_runtime (int debug_level, int propertyCount, const char **propert
monovm_initialize (propertyCount, propertyKeys, propertyValues);
-#ifndef INVARIANT_TIMEZONE
- char* invariant_timezone = monoeg_g_getenv ("DOTNET_SYSTEM_TIMEZONE_INVARIANT");
- if (strcmp(invariant_timezone, "true") != 0 && strcmp(invariant_timezone, "1") != 0)
- mono_register_timezones_bundle ();
-#endif /* INVARIANT_TIMEZONE */
-
root_domain = mono_wasm_load_runtime_common (debug_level, wasm_trace_logger, interp_opts);
bindings_initialize_internals();
diff --git a/src/mono/wasi/build/WasiApp.targets b/src/mono/wasi/build/WasiApp.targets
index f5301b87fe7085..6b6eb0a30dda8c 100644
--- a/src/mono/wasi/build/WasiApp.targets
+++ b/src/mono/wasi/build/WasiApp.targets
@@ -253,7 +253,6 @@
<_WasmCommonCFlags Condition="'$(_DriverGenCNeeded)' == 'true'" Include="-DDRIVER_GEN=1" />
<_WasmCommonCFlags Condition="'$(WasmSingleFileBundle)' == 'true'" Include="-DWASM_SINGLE_FILE=1" />
<_WasmCommonCFlags Condition="'$(InvariantGlobalization)' == 'true'" Include="-DINVARIANT_GLOBALIZATION=1" />
- <_WasmCommonCFlags Condition="'$(InvariantTimezone)' == 'true'" Include="-DINVARIANT_TIMEZONE=1" />
<_WasmCommonCFlags Condition="'$(WasmLinkIcalls)' == 'true'" Include="-DLINK_ICALLS=1" />
<_WasmCommonCFlags Condition="'$(_IsLibraryMode)' == 'true'" Include="-DWASM_LIBRARY_MODE=1" />
<_WasiClangCFlags Include="@(_WasmCommonCFlags)" />
@@ -365,9 +364,10 @@
- <_MonoRuntimeComponentDontLink Include="wasm-bundled-timezones.a" Condition="'$(InvariantTimezone)' == 'true'"/>
<_MonoRuntimeComponentDontLink Include="libmono-component-diagnostics_tracing-static.a" Condition="'$(EnableDiagnostics)' != 'true'" />
<_MonoRuntimeComponentDontLink Include="libmono-component-diagnostics_tracing-stub-static.lib" Condition="'$(EnableDiagnostics)' == 'true'" />
+ <_MonoRuntimeComponentDontLink Include="libSystem.Native.TimeZoneData.Invariant.a" Condition="'$(InvariantTimezone)' != 'true'" />
+ <_MonoRuntimeComponentDontLink Include="libSystem.Native.TimeZoneData.a" Condition="'$(InvariantTimezone)' == 'true'" />
diff --git a/src/mono/wasi/runtime/CMakeLists.txt b/src/mono/wasi/runtime/CMakeLists.txt
index c13a5c959f1fd4..9de09d87bbe7ea 100644
--- a/src/mono/wasi/runtime/CMakeLists.txt
+++ b/src/mono/wasi/runtime/CMakeLists.txt
@@ -26,8 +26,8 @@ target_link_libraries(dotnet
${MONO_ARTIFACTS_DIR}/libmonosgen-2.0.a
${MONO_ARTIFACTS_DIR}/libmono-icall-table.a
${MONO_ARTIFACTS_DIR}/libmono-wasm-${CONFIGURATION_INTERPSIMDTABLES_LIB}.a
- ${NATIVE_BIN_DIR}/wasm-bundled-timezones.a
${NATIVE_BIN_DIR}/libSystem.Native.a
+ ${NATIVE_BIN_DIR}/libSystem.Native.TimeZoneData.a
${NATIVE_BIN_DIR}/libSystem.Globalization.Native.a
${NATIVE_BIN_DIR}/libSystem.IO.Compression.Native.a
${NATIVE_BIN_DIR}/libz.a
diff --git a/src/mono/wasi/runtime/driver.c b/src/mono/wasi/runtime/driver.c
index 6278f5bb8d2478..5d0a72250e9067 100644
--- a/src/mono/wasi/runtime/driver.c
+++ b/src/mono/wasi/runtime/driver.c
@@ -41,9 +41,6 @@ int monoeg_g_setenv(const char *variable, const char *value, int overwrite);
int32_t monoeg_g_hasenv(const char *variable);
void mono_free (void*);
char *mono_method_get_full_name (MonoMethod *method);
-#ifndef INVARIANT_TIMEZONE
-extern void mono_register_timezones_bundle (void);
-#endif /* INVARIANT_TIMEZONE */
#ifdef WASM_SINGLE_FILE
extern void mono_register_assemblies_bundle (void);
extern void mono_register_runtimeconfig_bin (void);
@@ -265,11 +262,6 @@ mono_wasm_load_runtime (int debug_level)
load_runtimeconfig();
monovm_initialize (2, appctx_keys, appctx_values);
-#ifndef INVARIANT_TIMEZONE
- char* invariant_timezone = monoeg_g_getenv ("DOTNET_SYSTEM_TIMEZONE_INVARIANT");
- if (strcmp(invariant_timezone, "true") != 0 && strcmp(invariant_timezone, "1") != 0)
- mono_register_timezones_bundle ();
-#endif /* INVARIANT_TIMEZONE */
#ifdef WASM_SINGLE_FILE
mono_register_assemblies_bundle ();
#endif
diff --git a/src/mono/wasi/wasi.proj b/src/mono/wasi/wasi.proj
index 0dba67c01bca10..84f19c81439885 100644
--- a/src/mono/wasi/wasi.proj
+++ b/src/mono/wasi/wasi.proj
@@ -12,7 +12,6 @@
true
false
false
- false
$(ArtifactsObjDir)wasi
<_WasiDefaultsRspPath>$(NativeBinDir)src\wasi-default.rsp
<_WasiCompileRspPath>$(NativeBinDir)src\wasi-compile.rsp
@@ -29,7 +28,6 @@
-
@@ -65,60 +63,6 @@
-
-
-
- $(RuntimeBuildWasiSdkPath)bin/clang
- $(WasiClang).exe
- $(RuntimeBuildWasiSdkPath)bin/llvm-ar
- $(WasiLLVMAr).exe
-
- <_WasmTimezonesPath>$([MSBuild]::NormalizePath('$(PkgSystem_Runtime_TimeZoneData)', 'contentFiles', 'any', 'any', 'data'))
- <_WasmTimezonesBundleObjectFile>wasm-bundled-timezones.o
- <_WasmTimezonesBundleArchive>$(WasiObjDir)\wasm-bundled-timezones.a
- <_WasmTimezonesArchiveRsp>$(WasiObjDir)\wasm-bundled-timezones-archive.rsp
-
-
- <_WasmTimezonesInternal Include="$(_WasmTimezonesPath)\**\*.*" WasmRole="Timezone"/>
-
-
- <_WasmTimezonesInternal Update="@(_WasmTimezonesInternal)">
- /usr/share/zoneinfo/$([MSBuild]::MakeRelative($(_WasmTimezonesPath), %(_WasmTimezonesInternal.Identity)).Replace('\','/'))
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- <_WasmArchivedTimezones Include="$(_WasmTimezonesBundleArchive)" />
-
-
-
-
- <_WasmBundleTimezonesToDelete Include="$(_WasmIntermediateOutputPath)*.o" />
- <_WasmBundleTimezonesToDelete Remove="$(WasiObjDir)\$(_WasmTimezonesBundleObjectFile)" />
- <_WasmBundleTimezonesToDelete Remove="%(BundledWasiTimezones.DestinationFile)" />
-
-
-
-
@@ -190,7 +134,7 @@
+ DependsOnTargets="AcquireWasiSdk;GenerateWasiPropsAndRspFiles;GenerateManagedToNative">
@@ -284,7 +227,7 @@
DestinationFolder="$(MicrosoftNetCoreAppRuntimePackNativeDir)"
SkipUnchangedFiles="true" />
-
diff --git a/src/native/libs/System.Native/CMakeLists.txt b/src/native/libs/System.Native/CMakeLists.txt
index 78a0533148d4ca..c746d141d55838 100644
--- a/src/native/libs/System.Native/CMakeLists.txt
+++ b/src/native/libs/System.Native/CMakeLists.txt
@@ -151,3 +151,20 @@ install (TARGETS System.Native-Static DESTINATION ${STATIC_LIB_DESTINATION} COMP
if(CLR_CMAKE_HOST_ANDROID OR CLR_CMAKE_HOST_IOS OR CLR_CMAKE_HOST_TVOS OR CLR_CMAKE_HOST_MACCATALYST)
install (TARGETS System.Native-Static DESTINATION sharedFramework COMPONENT runtime)
endif()
+
+if (CLR_CMAKE_TARGET_ARCH_WASM AND DEFINED CMAKE_TZD_DIR)
+ cmake_path(CONVERT "${CMAKE_TZD_DIR}/" TO_CMAKE_PATH_LIST TZ_FILES_DIR NORMALIZE)
+ file(GLOB_RECURSE TZ_FILES RELATIVE "${TZ_FILES_DIR}" "${TZ_FILES_DIR}*")
+ string(REPLACE ";" "\",\"" TZ_FILES "${TZ_FILES}")
+ configure_file(pal_datetime_time_zone_data-config.h.in inc/pal_datetime_time_zone_data-config.h)
+
+ add_library(System.Native.TimeZoneData STATIC pal_datetime_time_zone_data.c)
+ target_compile_options(System.Native.TimeZoneData PRIVATE -Wno-overlength-strings)
+ target_compile_definitions(System.Native.TimeZoneData PRIVATE TZ_DATA_ENABLED)
+ target_include_directories(System.Native.TimeZoneData PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/inc")
+ install(TARGETS System.Native.TimeZoneData DESTINATION ${STATIC_LIB_DESTINATION} COMPONENT libs)
+
+ # Also add a stub to support InvariantTimezone.
+ add_library(System.Native.TimeZoneData.Invariant STATIC pal_datetime_time_zone_data.c)
+ install(TARGETS System.Native.TimeZoneData.Invariant DESTINATION ${STATIC_LIB_DESTINATION} COMPONENT libs)
+endif ()
diff --git a/src/native/libs/System.Native/pal_datetime.c b/src/native/libs/System.Native/pal_datetime.c
index d762fe506811eb..40e5061169aafe 100644
--- a/src/native/libs/System.Native/pal_datetime.c
+++ b/src/native/libs/System.Native/pal_datetime.c
@@ -21,10 +21,6 @@ static const int64_t NANOSECONDS_PER_TICK = 100;
static const int64_t TICKS_PER_MICROSECOND = 10; /* 1000 / 100 */
#endif
-#if defined(TARGET_WASI) || defined(TARGET_BROWSER)
-extern bool mono_bundled_resources_get_data_resource_values (const char *id, const uint8_t **data_out, uint32_t *size_out);
-#endif
-
//
// SystemNative_GetSystemTimeAsTicks return the system time as ticks (100 nanoseconds)
// since 00:00 01 January 1970 UTC (Unix epoch)
@@ -69,27 +65,12 @@ char* SystemNative_GetDefaultTimeZone(void)
}
#endif
+#if !defined(TARGET_WASM)
const char* SystemNative_GetTimeZoneData(const char* name, int* length)
{
- assert(name != NULL);
- assert(length != NULL);
-#if defined(TARGET_WASI) || defined(TARGET_BROWSER)
- const uint8_t *data = NULL;
- uint32_t data_len = 0;
-
- mono_bundled_resources_get_data_resource_values (name, &data, &data_len);
- assert (data_len <= INT_MAX);
- if (data_len > INT_MAX) {
- data_len = 0;
- data = NULL;
- }
-
- *length = (int)data_len;
- return (const char *)data;
-#else
assert_msg(false, "Not supported on this platform", 0);
- (void)name; // unused
- (void)length; // unused
+ (void)name;
+ (void)length;
return NULL;
-#endif
}
+#endif
diff --git a/src/native/libs/System.Native/pal_datetime_time_zone_data-config.h.in b/src/native/libs/System.Native/pal_datetime_time_zone_data-config.h.in
new file mode 100644
index 00000000000000..5bb468901efe97
--- /dev/null
+++ b/src/native/libs/System.Native/pal_datetime_time_zone_data-config.h.in
@@ -0,0 +1,2 @@
+#cmakedefine TZ_FILES_DIR "${TZ_FILES_DIR}"
+#cmakedefine TZ_FILES "${TZ_FILES}"
diff --git a/src/native/libs/System.Native/pal_datetime_time_zone_data.c b/src/native/libs/System.Native/pal_datetime_time_zone_data.c
new file mode 100644
index 00000000000000..f0941de608931b
--- /dev/null
+++ b/src/native/libs/System.Native/pal_datetime_time_zone_data.c
@@ -0,0 +1,93 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+//
+
+#include "pal_datetime.h"
+#include
+#include
+#include
+#include
+#include
+#include
+
+#ifdef TZ_DATA_ENABLED
+#include
+
+#define STR_IMPL(...) #__VA_ARGS__
+#define STR(...) STR_IMPL(__VA_ARGS__)
+
+// Generate both the index and data in one macro loop, switching
+// between their respective sections:
+//
+// foreach (data_id in TZ_FILES)
+// switch to the 'data' section
+// data_id_i:
+// .incbin TZ_FILES_DIR/data_id
+// switch to the 'index' section
+// g_dataIndex[i] = data_id_i
+//
+// Also add the end location of data to the index, so that when
+// searching, the last entry doesn't need to be special-cased.
+//
+__asm(
+#ifdef TARGET_64BIT
+#define POINTER_SIZE "8"
+#define POINTER_RELOC ".int64"
+#else
+#define POINTER_SIZE "4"
+#define POINTER_RELOC ".int32"
+#endif
+
+ " .macro GENERATE_SINGLE_DATA data_id\n"
+ " .section .data.tzdata,\"\",@\n"
+ "data_id_\\@:\n"
+ " .size data_id_\\@, 0\n"
+ " .incbin \"" TZ_FILES_DIR "\\data_id\"\n"
+ " .section .data.tzdata.index,\"\",@\n"
+ " " POINTER_RELOC " data_id_\\@\n"
+ " .endm\n"
+
+ " .section .data.tzdata.index,\"\",@\n"
+ " .balign " POINTER_SIZE "\n"
+ "g_dataIndex:\n"
+
+ " .section .data.tzdata,\"\",@\n"
+ "data:\n"
+ " .irp data_id," STR(TZ_FILES) "\n"
+ " GENERATE_SINGLE_DATA \\data_id\n"
+ " .endr\n"
+ " .section .data.tzdata,\"\",@\n"
+ "data_end:"
+ " .size data, data_end - data\n"
+ " .size data_end, 0\n"
+ " .section .data.tzdata.index,\"\",@\n"
+ " " POINTER_RELOC " data_end\n"
+ " .size g_dataIndex, . - g_dataIndex\n"
+);
+
+static const char *g_nameIndex[] = { TZ_FILES };
+extern const char *g_dataIndex[];
+#endif // TZ_DATA_ENABLED
+
+const char* SystemNative_GetTimeZoneData(const char* name, int* length)
+{
+#ifdef TZ_DATA_ENABLED
+ // Small size and speed optimization: skip comparing the prefix.
+ static const char TZ_PREFIX[] = "/usr/share/zoneinfo/";
+ static const size_t TZ_PREFIX_LENGTH = STRING_LENGTH(TZ_PREFIX);
+
+ // TODO: use a binary search here. The index is ~500 entries long.
+ assert(strncmp(TZ_PREFIX, name, TZ_PREFIX_LENGTH) == 0);
+ for (size_t i = 0; i < ARRAY_SIZE(g_nameIndex); i++)
+ {
+ if (strcmp(name + TZ_PREFIX_LENGTH, g_nameIndex[i]) == 0)
+ {
+ *length = (int)(g_dataIndex[i + 1] - g_dataIndex[i]);
+ return g_dataIndex[i];
+ }
+ }
+#endif // TZ_DATA_ENABLED
+
+ *length = 0;
+ return NULL;
+}
diff --git a/src/native/libs/build-native.proj b/src/native/libs/build-native.proj
index 62cd41efcd579f..45d0d4ca65f843 100644
--- a/src/native/libs/build-native.proj
+++ b/src/native/libs/build-native.proj
@@ -15,9 +15,11 @@
<_RuntimeVariant Condition="'$(WasmEnableThreads)' == 'true'">-threads
<_IcuDir Condition="'$(PkgMicrosoft_NETCore_Runtime_ICU_Transport)' != ''">$(PkgMicrosoft_NETCore_Runtime_ICU_Transport)/runtimes/$(TargetOS)-$(TargetArchitecture)$(_RuntimeVariant)/native
<_IcuDirArg Condition="'$(_IcuDir)' != ''"> icudir "$(_IcuDir)"
+ <_TzdDir Condition="'$(PkgSystem_Runtime_TimeZoneData)' != ''">$([MSBuild]::NormalizePath('$(PkgSystem_Runtime_TimeZoneData)', 'contentFiles', 'any', 'any', 'data'))
<_CMakeArgs Condition="'$(CMakeArgs)' != ''"> -cmakeargs "$(CMakeArgs)"
<_CMakeArgs Condition="'$(WasmEnableThreads)' == 'true'">$(_CMakeArgs) -cmakeargs "-DCMAKE_USE_PTHREADS=1"
+ <_CMakeArgs Condition="'$(_TzdDir)' != ''">$(_CMakeArgs) -cmakeargs "-DCMAKE_TZD_DIR=$(_TzdDir)"
<_BuildNativeArgs>$(_BuildNativeArgs)$(_IcuDirArg)$(_CMakeArgs)
@@ -28,6 +30,7 @@
+