Skip to content

Commit 3fa2c2a

Browse files
committed
Initial static ICU support for wasm
1 parent 4a21529 commit 3fa2c2a

File tree

9 files changed

+70
-2
lines changed

9 files changed

+70
-2
lines changed

src/libraries/Native/Unix/System.Globalization.Native/pal_icushim.c

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include <stdlib.h>
77
#include "pal_icushim_internal.h"
88

9+
#if !defined(STATIC_ICU)
910
#if defined(TARGET_UNIX)
1011
#include <dlfcn.h>
1112
#elif defined(TARGET_WINDOWS)
@@ -482,3 +483,34 @@ int32_t GlobalizationNative_GetICUVersion()
482483

483484
return (versionInfo[0] << 24) + (versionInfo[1] << 16) + (versionInfo[2] << 8) + versionInfo[3];
484485
}
486+
487+
#else // !defined(STATIC_ICU)
488+
489+
#include <unicode/putil.h>
490+
#include <unicode/uversion.h>
491+
492+
int32_t GlobalizationNative_LoadICU(void)
493+
{
494+
const char* icudir = getenv("DOTNET_ICU_DIR");
495+
if (!icudir)
496+
return 0;
497+
498+
// path to a directory with icudt___.dat (e.g. icudt67l.dat)
499+
// we can also use `udata_setCommonData(const void *data, UErrorCode *err)` API here
500+
u_setDataDirectory(icudir);
501+
return 1;
502+
}
503+
504+
void GlobalizationNative_InitICUFunctions(void* icuuc, void* icuin, const char* version, const char* suffix)
505+
{
506+
// no-op for static
507+
}
508+
509+
int32_t GlobalizationNative_GetICUVersion(void)
510+
{
511+
UVersionInfo versionInfo;
512+
u_getVersion(versionInfo);
513+
514+
return (versionInfo[0] << 24) + (versionInfo[1] << 16) + (versionInfo[2] << 8) + versionInfo[3];
515+
}
516+
#endif // defined(STATIC_ICU)

src/libraries/Native/Unix/System.Globalization.Native/pal_icushim_internal.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@
5656

5757
#include "pal_compiler.h"
5858

59+
#if !defined(STATIC_ICU)
5960
// List of all functions from the ICU libraries that are used in the System.Globalization.Native.so
6061
#define FOR_ALL_UNCONDITIONAL_ICU_FUNCTIONS \
6162
PER_FUNCTION_BLOCK(u_charsToUChars, libicuuc) \
@@ -280,3 +281,4 @@ FOR_ALL_ICU_FUNCTIONS
280281
#define usearch_getMatchedLength(...) usearch_getMatchedLength_ptr(__VA_ARGS__)
281282
#define usearch_last(...) usearch_last_ptr(__VA_ARGS__)
282283
#define usearch_openFromCollator(...) usearch_openFromCollator_ptr(__VA_ARGS__)
284+
#endif // !defined(STATIC_ICU)

src/mono/cmake/config.h.in

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,9 @@
210210
/* Use static zlib */
211211
#cmakedefine HAVE_STATIC_ZLIB 1
212212

213+
/* Use static ICU */
214+
#cmakedefine STATIC_ICU 1
215+
213216
/* Use OS-provided zlib */
214217
#cmakedefine HAVE_SYS_ZLIB 1
215218

src/mono/configure.ac

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1309,6 +1309,12 @@ AC_ARG_WITH(spectre-mitigation, [ --with-spectre-mitigation=yes,no
13091309
AC_ARG_WITH(spectre-indirect-branch-choice, [ --with-spectre-indirect-branch-choice=keep,thunk,inline,extern Convert indirect branches to the specified kind of thunk (defaults to inline)], [], [with_spectre_indirect_branch_choice=inline])
13101310
AC_ARG_WITH(spectre-function-return-choice, [ --with-spectre-function-return-choice=keep,thunk,inline,extern Convert function return instructions to the specified kind of thunk (defaults to inline)], [], [with_spectre_function_return_choice=inline])
13111311

1312+
AC_ARG_WITH(static_icu, [ --with-static-icu=yes|no Integrate ICU statically into the runtime (defaults to no)],[
1313+
if test x$with_static_icu = xyes ; then
1314+
AC_DEFINE(STATIC_ICU,1,[Integrate ICU statically into the runtime.])
1315+
fi
1316+
], [with_static_icu=no])
1317+
13121318
dnl
13131319
dnl Spectre compiler mitigation flag checks
13141320
dnl
@@ -1696,6 +1702,7 @@ AM_CONDITIONAL(INSTALL_MONOTOUCH, [test "x$with_monotouch" != "xno"])
16961702
AM_CONDITIONAL(INSTALL_MONOTOUCH_WATCH, [test "x$with_monotouch_watch" != "xno"])
16971703
AM_CONDITIONAL(INSTALL_MONOTOUCH_TV, [test "x$with_monotouch_tv" != "xno"])
16981704
AM_CONDITIONAL(BITCODE, test "x$with_bitcode" = "xyes")
1705+
AM_CONDITIONAL(STATIC_ICU, test "x$with_static_icu" = "xyes")
16991706
AM_CONDITIONAL(INSTALL_XAMMAC, [test "x$with_xammac" != "xno"])
17001707
AM_CONDITIONAL(INSTALL_TESTING_AOT_FULL_INTERP, [test "x$with_testing_aot_full_interp" != "xno"])
17011708
AM_CONDITIONAL(INSTALL_TESTING_AOT_HYBRID, [test "x$with_testing_aot_hybrid" != "xno"])
@@ -6836,7 +6843,10 @@ if test x$with_core = xonly; then
68366843
fi
68376844
if test x$have_shim_globalization = xyes || test x$cross_compiling = xyes; then
68386845
ICU_SHIM_PATH=../../../libraries/Native/Unix/System.Globalization.Native
6839-
if test x$target_osx = xyes; then
6846+
if test x$target_wasm = xyes && test x$with_static_icu = xyes; then
6847+
ICU_CFLAGS="-DTARGET_UNIX -DU_DISABLE_RENAMING"
6848+
have_sys_icu=yes
6849+
elif test x$target_osx = xyes; then
68406850
ORIG_CPPFLAGS=$CPPFLAGS
68416851
# adding icu path to pkg_config_path
68426852
PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/local/lib/pkgconfig:/usr/local/opt/icu4c/lib/pkgconfig

src/mono/mono.proj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -635,6 +635,7 @@
635635
<_MonoConfigureParams Include="--disable-icall-tables"/>
636636
<_MonoConfigureParams Include="--disable-crash-reporting"/>
637637
<_MonoConfigureParams Include="--with-bitcode=yes"/>
638+
<_MonoConfigureParams Condition="'$(ICU_REPO)' != ''" Include="--with-static-icu=yes"/>
638639
<_MonoConfigureParams Include="--enable-minimal=ssa,com,jit,reflection_emit_save,portability,assembly_remapping,attach,verifier,full_messages,appdomains,shadowcopy,security,sgen_marksweep_conc,sgen_split_nursery,sgen_gc_bridge,logging,remoting,shared_perfcounters,sgen_debug_helpers,soft_debug,interpreter,assert_messages,cleanup,mdb,gac,threads,$(_MonoEnableMinimal)"/>
639640
<_MonoCFLAGS Include="-fexceptions" />
640641
<_MonoCXXFLAGS Include="-fexceptions -s DISABLE_EXCEPTION_CATCHING=0" />

src/mono/mono/metadata/Makefile.am

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,14 @@ nodist_libmonoruntime_shimglobalization_la_SOURCES = \
158158
@ICU_SHIM_PATH@/entrypoints.c
159159

160160
libmonoruntime_shimglobalization_la_CFLAGS = @ICU_CFLAGS@ -I$(top_srcdir)/../libraries/Native/Unix/System.Globalization.Native/ -I$(top_srcdir)/../libraries/Native/Unix/Common/
161+
162+
if STATIC_ICU
163+
nodist_libmonoruntime_shimglobalization_la_SOURCES += @ICU_SHIM_PATH@/pal_icushim_static.c
164+
libmonoruntime_shimglobalization_la_CFLAGS += -I$(ICU_REPO)/icu4c/source/wasm-usr/include/ \
165+
-L$(ICU_REPO)/icu4c/source/wasm-build/lib/ -licui18n -licuuc -licutu -licuio \
166+
-L$(ICU_REPO)/icu4c/source/wasm-build/stubdata -licudata
167+
endif
168+
161169
endif
162170
endif
163171

src/mono/wasm/Makefile

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,17 @@ MONO_LIBS = \
5656
$(MONO_BIN_DIR)/libmono-icall-table.a \
5757
${SYS_NATIVE_DIR}/libSystem.Native.a
5858

59+
ifeq ($(ICU_REPO),)
60+
@echo "ICU_REPO is not set."
61+
else
62+
MONO_LIBS := $(MONO_LIBS) \
63+
$(ICU_REPO)/icu4c/source/wasm-build/lib/libicui18n.a \
64+
$(ICU_REPO)/icu4c/source/wasm-build/lib/libicuio.a \
65+
$(ICU_REPO)/icu4c/source/wasm-build/lib/libicuuc.a \
66+
$(ICU_REPO)/icu4c/source/wasm-build/lib/libicutu.a \
67+
$(ICU_REPO)/icu4c/source/wasm-build/stubdata/libicudata.a
68+
endif
69+
5970
EMCC_FLAGS=--profiling-funcs -s WASM=1 -s ALLOW_MEMORY_GROWTH=1 -s BINARYEN=1 -s ALIASING_FUNCTION_POINTERS=0 -s NO_EXIT_RUNTIME=1 -s "EXTRA_EXPORTED_RUNTIME_METHODS=['ccall', 'FS_createPath', 'FS_createDataFile', 'cwrap', 'setValue', 'getValue', 'UTF8ToString', 'addFunction']" -s "EXPORTED_FUNCTIONS=['_putchar']" --source-map-base http://example.com -s WASM_OBJECT_FILES=0 -s FORCE_FILESYSTEM=1 -s USE_ZLIB=1
6071
EMCC_DEBUG_FLAGS =-g -Os -s ASSERTIONS=1 -DENABLE_NETCORE=1 -DDEBUG=1
6172
EMCC_RELEASE_FLAGS=-Oz --llvm-opts 2 --llvm-lto 1 -DENABLE_NETCORE=1

src/mono/wasm/runtime/driver.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -322,7 +322,7 @@ mono_wasm_load_runtime (const char *managed_path, int enable_debugging)
322322
monoeg_g_setenv ("COMPlus_DebugWriteToStdErr", "1", 0);
323323
#endif
324324
#ifdef ENABLE_NETCORE
325-
monoeg_g_setenv ("DOTNET_SYSTEM_GLOBALIZATION_INVARIANT", "1", 0);
325+
monoeg_g_setenv ("DOTNET_SYSTEM_GLOBALIZATION_INVARIANT", getenv("DOTNET_ICU_DIR") ? "0" : "1", 0);
326326
#endif
327327

328328
mini_parse_debug_option ("top-runtime-invoke-unhandled");

src/mono/wasm/wasm.targets

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
<ItemGroup>
1111
<WasmPInvokeModules Include="libSystem.Native"/>
12+
<WasmPInvokeModules Include="QCall"/>
1213
<WasmPInvokeAssemblies Include="$(MonoArtifactsPath)\System.Private.CoreLib.dll"/>
1314
<WasmPInvokeAssemblies Include="$(ArtifactsBinDir)\System.Runtime\$(NetCoreAppCurrent)-$(Configuration)\System.Runtime.dll"/>
1415
<WasmPInvokeAssemblies Include="$(ArtifactsBinDir)\System.Console\$(NetCoreAppCurrent)-Browser-$(Configuration)\System.Console.dll"/>

0 commit comments

Comments
 (0)