Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
9 changes: 7 additions & 2 deletions src/coreclr/dlls/mscoree/coreclr/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -167,10 +167,15 @@ if(FEATURE_MERGE_JIT_AND_ENGINE)
set(CLRJIT_STATIC clrjit_static)
endif(FEATURE_MERGE_JIT_AND_ENGINE)

if (CLR_CMAKE_TARGET_OSX OR CLR_CMAKE_TARGET_MACCATALYST)
include(CMakeFindFrameworks)
find_library(FOUNDATION Foundation REQUIRED)
endif()

target_sources(coreclr PUBLIC $<TARGET_OBJECTS:cee_wks_core>)
target_link_libraries(coreclr PUBLIC ${CORECLR_LIBRARIES} ${CLRJIT_STATIC} cee_wks)
target_link_libraries(coreclr PUBLIC ${CORECLR_LIBRARIES} ${CLRJIT_STATIC} cee_wks ${FOUNDATION})
target_sources(coreclr_static PUBLIC $<TARGET_OBJECTS:cee_wks_core>)
target_link_libraries(coreclr_static PUBLIC ${CORECLR_LIBRARIES} clrjit_static cee_wks_mergeable)
target_link_libraries(coreclr_static PUBLIC ${CORECLR_LIBRARIES} clrjit_static cee_wks_mergeable ${FOUNDATION})
target_compile_definitions(coreclr_static PUBLIC CORECLR_EMBEDDED)

if(CLR_CMAKE_TARGET_WIN32)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,10 @@ set(NATIVEGLOBALIZATION_SOURCES
pal_icushim.c
)

if (CLR_CMAKE_TARGET_OSX OR CLR_CMAKE_TARGET_MACCATALYST OR CLR_CMAKE_TARGET_IOS OR CLR_CMAKE_TARGET_TVOS)
set(NATIVEGLOBALIZATION_SOURCES ${NATIVEGLOBALIZATION_SOURCES} pal_locale.m)
endif()

# time zone names are filtered out of icu data for the browser and associated functionality is disabled
if (NOT CLR_CMAKE_TARGET_BROWSER)
set(NATIVEGLOBALIZATION_SOURCES ${NATIVEGLOBALIZATION_SOURCES} pal_timeZoneInfo.c)
Expand All @@ -80,6 +84,11 @@ endif()
include_directories("../Common")

if (GEN_SHARED_LIB)
if (CLR_CMAKE_TARGET_OSX OR CLR_CMAKE_TARGET_MACCATALYST OR CLR_CMAKE_TARGET_IOS OR CLR_CMAKE_TARGET_TVOS)
include(CMakeFindFrameworks)
find_library(FOUNDATION Foundation REQUIRED)
endif()

add_library(System.Globalization.Native
SHARED
${NATIVEGLOBALIZATION_SOURCES}
Expand All @@ -88,12 +97,12 @@ if (GEN_SHARED_LIB)

target_link_libraries(System.Globalization.Native
dl
${FOUNDATION}
)

install_with_stripped_symbols (System.Globalization.Native PROGRAMS .)
endif()


add_library(System.Globalization.Native-Static
STATIC
${NATIVEGLOBALIZATION_SOURCES}
Expand Down
24 changes: 21 additions & 3 deletions src/libraries/Native/Unix/System.Globalization.Native/pal_locale.c
Original file line number Diff line number Diff line change
Expand Up @@ -129,12 +129,15 @@ int32_t FixupLocaleName(UChar* value, int32_t valueLength)
return i;
}

// We use whatever ICU give us as the default locale except if it is en_US_POSIX. We'll map
// this POSIX locale to Invariant instead. The reason is POSIX locale collation behavior
// is not desirable at all because it doesn't support case insensitive string comparisons.
// We use whatever ICU give us as the default locale except if it is en_US_POSIX.
//
// On Apple related platforms (OSX, iOS, tvOS, MacCatalyst), we'll take what the system locale is.
// On all other platforms we'll map this POSIX locale to Invariant instead.
// The reason is POSIX locale collation behavior is not desirable at all because it doesn't support case insensitive string comparisons.
const char* DetectDefaultLocaleName()
{
const char* icuLocale = uloc_getDefault();

if (strcmp(icuLocale, "en_US_POSIX") == 0)
{
return "";
Expand Down Expand Up @@ -216,6 +219,16 @@ int32_t GlobalizationNative_GetDefaultLocaleName(UChar* value, int32_t valueLeng

const char* defaultLocale = DetectDefaultLocaleName();

#ifdef __APPLE__
char* appleLocale = NULL;

if (strcmp(defaultLocale, "") == 0)
{
appleLocale = DetectDefaultAppleLocaleName();
defaultLocale = appleLocale;
}
#endif

uloc_getBaseName(defaultLocale, localeNameBuffer, ULOC_FULLNAME_CAPACITY, &status);
u_charsToUChars_safe(localeNameBuffer, value, valueLength, &status);

Expand All @@ -236,6 +249,11 @@ int32_t GlobalizationNative_GetDefaultLocaleName(UChar* value, int32_t valueLeng
}
}

#ifdef __APPLE__
if (appleLocale)
free(appleLocale);
#endif

return UErrorCodeToBool(status);
}

Expand Down
30 changes: 30 additions & 0 deletions src/libraries/Native/Unix/System.Globalization.Native/pal_locale.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

#include <stdlib.h>
#include "pal_locale_internal.h"

#import <Foundation/Foundation.h>

char* DetectDefaultAppleLocaleName()
{
NSLocale *currentLocale = [NSLocale currentLocale];
NSString *localeName = @"";

if (!currentLocale)
{
return strdup([localeName UTF8String]);
}

if ([currentLocale.languageCode length] > 0 && [currentLocale.countryCode length] > 0)
{
localeName = [NSString stringWithFormat:@"%@-%@", currentLocale.languageCode, currentLocale.countryCode];
}
else
{
localeName = currentLocale.localeIdentifier;
}

return strdup([localeName UTF8String]);
}

Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,13 @@ Detect the default locale for the machine, defaulting to Invaraint if
we can't compute one (different from uloc_getDefault()) would do.
*/
const char* DetectDefaultLocaleName(void);

#ifdef __APPLE__
/*
Function:
DetectDefaultSystemLocaleName

Detects the default locale string for Apple platforms
*/
char* DetectDefaultAppleLocaleName(void);
#endif
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,17 @@ public void CurrentCulture()
}
}

[Fact]
[PlatformSpecific(TestPlatforms.OSX | TestPlatforms.iOS | TestPlatforms.MacCatalyst | TestPlatforms.tvOS)]
public void CurrentCulture_Default_Not_Invariant()
{
// On OSX-like platforms, it should default to what the default system culture is
// set to. Since we shouldn't assume en-US, we just test if it's not the invariant
// culture.
Assert.NotEqual(CultureInfo.CurrentCulture, CultureInfo.InvariantCulture);
Assert.NotEqual(CultureInfo.CurrentUICulture, CultureInfo.InvariantCulture);
}

[Fact]
public void CurrentCulture_Set_Null_ThrowsArgumentNullException()
{
Expand Down Expand Up @@ -125,7 +136,7 @@ public void CurrentCulture_BasedOnLangEnvVar(string langEnvVar, string expectedC
}, expectedCultureName, new RemoteInvokeOptions { StartInfo = psi }).Dispose();
}

[PlatformSpecific(TestPlatforms.AnyUnix)] // When LANG is empty or unset, should default to the invariant culture on Unix.
[PlatformSpecific(TestPlatforms.AnyUnix)]
[ConditionalTheory(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))]
[InlineData("")]
[InlineData(null)]
Expand All @@ -141,13 +152,28 @@ public void CurrentCulture_DefaultWithNoLang(string langEnvVar)
psi.Environment["LANG"] = langEnvVar;
}

// When LANG is empty or unset, on Unix it should default to the invariant culture.
// On OSX-like platforms, it should default to what the default system culture is
// set to. Since we shouldn't assume en-US, we just test if it's not the invariant
// culture.
RemoteExecutor.Invoke(() =>
{
Assert.NotNull(CultureInfo.CurrentCulture);
Assert.NotNull(CultureInfo.CurrentUICulture);

Assert.Equal("", CultureInfo.CurrentCulture.Name);
Assert.Equal("", CultureInfo.CurrentUICulture.Name);
if (PlatformDetection.IsOSXLike)
{
Assert.NotEqual("", CultureInfo.CurrentCulture.Name);
Assert.NotEqual("", CultureInfo.CurrentUICulture.Name);

Assert.NotEqual(CultureInfo.CurrentCulture, CultureInfo.InvariantCulture);
Assert.NotEqual(CultureInfo.CurrentUICulture, CultureInfo.InvariantCulture);
}
else
{
Assert.Equal("", CultureInfo.CurrentCulture.Name);
Assert.Equal("", CultureInfo.CurrentUICulture.Name);
}
}, new RemoteInvokeOptions { StartInfo = psi }).Dispose();
}

Expand Down
9 changes: 8 additions & 1 deletion src/mono/mono/mini/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ if(HOST_DARWIN)
set(OS_LIBS "-framework CoreFoundation" "-framework Foundation")

if(CMAKE_SYSTEM_VARIANT STREQUAL "MacCatalyst")
set(OS_LIBS "-lobjc" "-lc++")
set(OS_LIBS ${OS_LIBS} "-lobjc" "-lc++")
endif()
elseif(HOST_IOS)
set(OS_LIBS "-framework CoreFoundation" "-lobjc" "-lc++")
Expand Down Expand Up @@ -79,6 +79,13 @@ if(HAVE_SYS_ICU)
pal_timeZoneInfo.c
entrypoints.c
${pal_icushim_sources_base})

if (TARGET_DARWIN)
set(icu_shim_sources_base
${icu_shim_sources_base}
pal_locale.m)
endif()

addprefix(icu_shim_sources "${ICU_SHIM_PATH}" "${icu_shim_sources_base}")
set_source_files_properties(${icu_shim_sources} PROPERTIES COMPILE_DEFINITIONS OSX_ICU_LIBRARY_PATH="${OSX_ICU_LIBRARY_PATH}")
set_source_files_properties(${icu_shim_sources} PROPERTIES COMPILE_FLAGS "-I\"${ICU_INCLUDEDIR}\" -I\"${CMAKE_CURRENT_SOURCE_DIR}/../../../libraries/Native/Unix/System.Globalization.Native/\" -I\"${CMAKE_CURRENT_SOURCE_DIR}/../../../libraries/Native/Unix/Common/\" ${ICU_FLAGS}")
Expand Down