From 6a864c048c6750306e174a9b74336ddddbe1fa49 Mon Sep 17 00:00:00 2001
From: Adeel <3840695+am11@users.noreply.github.com>
Date: Fri, 21 Mar 2025 15:37:58 +0200
Subject: [PATCH] Allow embeded ICU data with StaticICULinking
---
.../Microsoft.NETCore.Native.Unix.targets | 2 +-
src/coreclr/nativeaot/docs/compiling.md | 20 +++++++++++++++++++
.../pal_icushim_static.c | 9 +++++++++
src/native/libs/build-local.sh | 20 ++++++++++++++++++-
4 files changed, 49 insertions(+), 2 deletions(-)
diff --git a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets
index a11ba22a977ceb..acb9e60318c743 100644
--- a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets
+++ b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets
@@ -356,7 +356,7 @@ The .NET Foundation licenses this file to you under the MIT license.
-
true
+
+
+ /usr/share/icu/74.2/icudt74l.dat
```
+> [!NOTE]
+> Some distros, such as Alpine and Gentoo, currently package ICU data as a `icudt*.dat` archive,
+> while others, like Ubuntu, do not.
+> To use `EmbedIcuDataPath` on a distro that does not provide the `.dat` file,
+> you may need to build ICU with `--with-data-packaging=archive` to generate it.
+> See https://unicode-org.github.io/icu/userguide/icu_data#building-and-linking-against-icu-data.
+> ```sh
+> # e.g. to obtain icudt*.dat on Ubuntu
+> $ curl -sSL https://github.com/unicode-org/icu/releases/download/release-74-2/icu4c-74_2-src.tgz | tar xzf -
+> $ cd icu/source
+> $ ./configure --with-data-packaging=archive --enable-static --disable-shared --disable-samples
+> $ make -j
+> $ find . -path *out/* -name icudt*.dat -exec echo $(pwd)/{} \;
+> ```
+
This feature is only supported on Linux. This feature is not supported when crosscompiling.
License (Unicode): https://github.com/unicode-org/icu/blob/main/icu4c/LICENSE
diff --git a/src/native/libs/System.Globalization.Native/pal_icushim_static.c b/src/native/libs/System.Globalization.Native/pal_icushim_static.c
index ecef84ab793350..ba6d76d82c9837 100644
--- a/src/native/libs/System.Globalization.Native/pal_icushim_static.c
+++ b/src/native/libs/System.Globalization.Native/pal_icushim_static.c
@@ -216,6 +216,15 @@ int32_t GlobalizationNative_LoadICU(void)
}
#endif
+#if defined(EMBEDDED_ICU_DATA_HEADER)
+ #include EMBEDDED_ICU_DATA_HEADER
+
+ if (!load_icu_data(icu_data))
+ {
+ return 0;
+ }
+#endif
+
UErrorCode status = 0;
UVersionInfo version;
// Request the CLDR version to perform basic ICU initialization and find out
diff --git a/src/native/libs/build-local.sh b/src/native/libs/build-local.sh
index a885243f1ccb70..7ec16a42592d14 100755
--- a/src/native/libs/build-local.sh
+++ b/src/native/libs/build-local.sh
@@ -13,6 +13,24 @@
SHIM_SOURCE_DIR="$1"/native/src
INTERMEDIATE_OUTPUT_PATH="$2"
TARGET_LIBRARY="$3"
+EMBED_ICU_DATA_PATH="$4"
+
+if [ -n "$EMBED_ICU_DATA_PATH" ]; then
+ header="${INTERMEDIATE_OUTPUT_PATH}embedded_icu_data.h"
+
+ cat < "$header"
+#ifndef EMBEDDED_ICU_DATA
+#define EMBEDDED_ICU_DATA
+
+static const unsigned char icu_data[] __attribute__((aligned(16))) = {
+$(od -An -vtx1 "$EMBED_ICU_DATA_PATH" | tr -d ' \n' | sed 's/\(..\)/0x\1, /g')
+};
+
+#endif // EMBEDDED_ICU_DATA
+EOF
+
+ CMAKE_EXTRA_ARGS=-DCMAKE_C_FLAGS="-DEMBEDDED_ICU_DATA_HEADER='\"$header\"'"
+fi
if [ -d "$SHIM_SOURCE_DIR" ]; then
LOCAL_SHIM_DIR="$INTERMEDIATE_OUTPUT_PATH"/libs/$TARGET_LIBRARY/build
@@ -22,7 +40,7 @@ if [ -d "$SHIM_SOURCE_DIR" ]; then
exit 1
fi
- if ! cmake -S "$SHIM_SOURCE_DIR/libs/$TARGET_LIBRARY/" -DLOCAL_BUILD:STRING=1 -DCLR_CMAKE_TARGET_UNIX:STRING=1; then
+ if ! cmake -S "$SHIM_SOURCE_DIR/libs/$TARGET_LIBRARY/" -DLOCAL_BUILD:STRING=1 -DCLR_CMAKE_TARGET_UNIX:STRING=1 $CMAKE_EXTRA_ARGS; then
echo "local_build.sh::ERROR: cmake failed"
exit 1
fi