Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support loading ICU data from managed Interop #49406

Merged
merged 5 commits into from
Mar 13, 2021
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/libraries/Common/src/Interop/Interop.ICU.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ internal static partial class Globalization
[DllImport(Libraries.GlobalizationNative, EntryPoint = "GlobalizationNative_LoadICU")]
internal static extern int LoadICU();

[DllImport(Libraries.GlobalizationNative, EntryPoint = "GlobalizationNative_LoadICUData")]
internal static extern int LoadICUData(string? path);
steveisok marked this conversation as resolved.
Show resolved Hide resolved

internal static void InitICUFunctions(IntPtr icuuc, IntPtr icuin, ReadOnlySpan<char> version, ReadOnlySpan<char> suffix)
{
Debug.Assert(icuuc != IntPtr.Zero);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ static const Entry s_globalizationNative[] =
DllImportEntry(GlobalizationNative_IsPredefinedLocale)
DllImportEntry(GlobalizationNative_LastIndexOf)
DllImportEntry(GlobalizationNative_LoadICU)
#if defined(STATIC_ICU)
DllImportEntry(GlobalizationNative_LoadICUData)
#endif
DllImportEntry(GlobalizationNative_NormalizeString)
DllImportEntry(GlobalizationNative_StartsWith)
DllImportEntry(GlobalizationNative_ToAscii)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ PALEXPORT int32_t GlobalizationNative_GetICUVersion(void);

#if defined(STATIC_ICU)

PALEXPORT int32_t GlobalizationNative_LoadICUData(char* path);
PALEXPORT int32_t GlobalizationNative_LoadICUData(const char* path);

PALEXPORT const char* GlobalizationNative_GetICUDTName(const char* culture);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ static int32_t load_icu_data(void* pData)
}
}

int32_t GlobalizationNative_LoadICUData(char* path)
int32_t GlobalizationNative_LoadICUData(const char* path)
{
int32_t ret = -1;
char* icu_data;
Expand Down Expand Up @@ -127,7 +127,12 @@ int32_t GlobalizationNative_LoadICUData(char* path)

fclose (fp);

return load_icu_data (icu_data);
if (load_icu_data (icu_data) == 0) {
steveisok marked this conversation as resolved.
Show resolved Hide resolved
fprintf (stderr, "ICU BAD EXIT %d.", ret);
steveisok marked this conversation as resolved.
Show resolved Hide resolved
return ret;
}

return GlobalizationNative_LoadICU ();
steveisok marked this conversation as resolved.
Show resolved Hide resolved
}

const char* GlobalizationNative_GetICUDTName(const char* culture)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1838,6 +1838,8 @@
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\CultureData.Unix.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\CultureInfo.Unix.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\GlobalizationMode.Unix.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\GlobalizationMode.LoadICU.Unix.cs" Condition="'$(TargetsMacCatalyst)' != 'true' and '$(TargetsiOS)' != 'true' and '$(TargetstvOS)' != 'true'" />
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\GlobalizationMode.LoadICU.iOS.cs" Condition="'$(TargetsMacCatalyst)' == 'true' or '$(TargetsiOS)' == 'true' or '$(TargetstvOS)' == 'true'" />
steveisok marked this conversation as resolved.
Show resolved Hide resolved
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\HijriCalendar.Unix.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Guid.Unix.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\IO\FileStreamHelpers.Unix.cs" />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

namespace System.Globalization
{
internal static partial class GlobalizationMode
{
private static int LoadICUCore()
{
return Interop.Globalization.LoadICU();
}
steveisok marked this conversation as resolved.
Show resolved Hide resolved
}
}
steveisok marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

namespace System.Globalization
{
internal static partial class GlobalizationMode
{
private static int LoadICUCore()
{
object? datPath = AppContext.GetData("ICU_DAT_FILE_PATH");
return (datPath != null) ? Interop.Globalization.LoadICUData(datPath.ToString()) : Interop.Globalization.LoadICU();
}
}
}
steveisok marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ private static bool GetGlobalizationInvariantMode()
}
else
{
int loaded = Interop.Globalization.LoadICU();
int loaded = LoadICUCore();
steveisok marked this conversation as resolved.
Show resolved Hide resolved
if (loaded == 0 && !OperatingSystem.IsBrowser())
{
// This can't go into resources, because a resource lookup requires globalization, which requires ICU
Expand Down
1 change: 1 addition & 0 deletions src/mono/mono/mini/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ if(HAVE_SYS_ICU)
if(STATIC_ICU)
set(pal_icushim_sources_base
pal_icushim_static.c)
add_definitions(-DSTATIC_ICU=1)
else()
set(pal_icushim_sources_base
pal_icushim.c)
Expand Down
2 changes: 1 addition & 1 deletion src/tasks/AppleAppBuilder/AppleAppBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ public override bool Execute()

if (GenerateXcodeProject)
{
Xcode generator = new Xcode(TargetOS);
Xcode generator = new Xcode(TargetOS, Arch);
generator.EnableRuntimeLogging = EnableRuntimeLogging;

XcodeProjectPath = generator.GenerateXCode(ProjectName, MainLibraryFileName, assemblerFiles,
Expand Down
37 changes: 25 additions & 12 deletions src/tasks/AppleAppBuilder/Templates/runtime.m
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
#define MONO_ENTER_GC_UNSAFE
#define MONO_EXIT_GC_UNSAFE

#define APPLE_RUNTIME_IDENTIFIER "//%APPLE_RUNTIME_IDENTIFIER%"

const char *
get_bundle_path (void)
{
Expand Down Expand Up @@ -237,16 +239,6 @@ static int32_t load_icu_data ()
setenv ("MONO_LOG_MASK", "all", TRUE);
#endif

#if !INVARIANT_GLOBALIZATION
int32_t ret = load_icu_data ();

if (ret == 0) {
os_log_info (OS_LOG_DEFAULT, "ICU BAD EXIT %d.", ret);
exit (ret);
return;
}
#endif

id args_array = [[NSProcessInfo processInfo] arguments];
assert ([args_array count] <= 128);
const char *managed_argv [128];
Expand All @@ -261,8 +253,29 @@ static int32_t load_icu_data ()
const char* bundle = get_bundle_path ();
chdir (bundle);

char icu_dat_path[1024];
steveisok marked this conversation as resolved.
Show resolved Hide resolved
int res;

res = snprintf (icu_dat_path, sizeof (icu_dat_path) - 1, "%s/%s", bundle, "icudt.dat");
assert (res > 0);

// TODO: set TRUSTED_PLATFORM_ASSEMBLIES, APP_PATHS and NATIVE_DLL_SEARCH_DIRECTORIES
monovm_initialize(0, NULL, NULL);
const char *appctx_keys[] = {
steveisok marked this conversation as resolved.
Show resolved Hide resolved
"RUNTIME_IDENTIFIER",
safern marked this conversation as resolved.
Show resolved Hide resolved
#ifndef INVARIANT_GLOBALIZATION
steveisok marked this conversation as resolved.
Show resolved Hide resolved
"ICU_DAT_FILE_PATH",
#endif
steveisok marked this conversation as resolved.
Show resolved Hide resolved
"APP_CONTEXT_BASE_DIRECTORY"
};
const char *appctx_values [] = {
APPLE_RUNTIME_IDENTIFIER,
#ifndef INVARIANT_GLOBALIZATION
steveisok marked this conversation as resolved.
Show resolved Hide resolved
icu_dat_path,
#endif
steveisok marked this conversation as resolved.
Show resolved Hide resolved
bundle
};

monovm_initialize(sizeof (appctx_keys) / sizeof (appctx_keys [0]), appctx_keys, appctx_values);
steveisok marked this conversation as resolved.
Show resolved Hide resolved

#if FORCE_INTERPRETER
os_log_info (OS_LOG_DEFAULT, "INTERP Enabled");
Expand Down Expand Up @@ -300,7 +313,7 @@ static int32_t load_icu_data ()
assert (assembly);
os_log_info (OS_LOG_DEFAULT, "Executable: %{public}s", executable);

int res = mono_jit_exec (mono_domain_get (), assembly, argi, managed_argv);
res = mono_jit_exec (mono_domain_get (), assembly, argi, managed_argv);
// Print this so apps parsing logs can detect when we exited
os_log_info (OS_LOG_DEFAULT, "Exit code: %d.", res);

Expand Down
6 changes: 5 additions & 1 deletion src/tasks/AppleAppBuilder/Xcode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,11 @@

internal class Xcode
{
private string RuntimeIdentifier { get; set; }
private string SysRoot { get; set; }
private string Target { get; set; }

public Xcode(string target)
public Xcode(string target, string arch)
{
Target = target;
switch (Target)
Expand All @@ -27,6 +28,8 @@ public Xcode(string target)
SysRoot = Utils.RunProcess("xcrun", "--sdk macosx --show-sdk-path");
break;
}

RuntimeIdentifier = $"{Target}-{arch}";
}

public bool EnableRuntimeLogging { get; set; }
Expand Down Expand Up @@ -175,6 +178,7 @@ public string GenerateXCode(
File.WriteAllText(Path.Combine(binDir, "runtime.m"),
Utils.GetEmbeddedResource("runtime.m")
.Replace("//%DllMap%", dllMap.ToString())
.Replace("//%APPLE_RUNTIME_IDENTIFIER%", RuntimeIdentifier)
.Replace("%EntryPointLibName%", Path.GetFileName(entryPointLib)));

Utils.RunProcess("cmake", cmakeArgs.ToString(), workingDir: binDir);
Expand Down