Skip to content

Commit

Permalink
Add System.Globalization.Native support for Windows
Browse files Browse the repository at this point in the history
  • Loading branch information
safern committed Mar 19, 2020
1 parent e3fd0e0 commit c1216d2
Show file tree
Hide file tree
Showing 107 changed files with 402 additions and 291 deletions.
2 changes: 1 addition & 1 deletion src/coreclr/build-runtime.cmd
Original file line number Diff line number Diff line change
Expand Up @@ -500,7 +500,7 @@ if %__BuildNative% EQU 1 (

echo %__MsgPrefix%Regenerating the Visual Studio solution

set __ExtraCmakeArgs="-DCMAKE_SYSTEM_VERSION=10.0" !___CrossBuildDefine! "-DCLR_CMAKE_PGO_INSTRUMENT=%__PgoInstrument%" "-DCLR_CMAKE_OPTDATA_PATH=%__PgoOptDataPath%" "-DCLR_CMAKE_PGO_OPTIMIZE=%__PgoOptimize%" "-DCLR_ENG_NATIVE_DIR=%__RepoRootDir%/eng/native"
set __ExtraCmakeArgs="-DCMAKE_SYSTEM_VERSION=10.0" !___CrossBuildDefine! "-DCLR_CMAKE_PGO_INSTRUMENT=%__PgoInstrument%" "-DCLR_CMAKE_OPTDATA_PATH=%__PgoOptDataPath%" "-DCLR_CMAKE_PGO_OPTIMIZE=%__PgoOptimize%" "-DCLR_ENG_NATIVE_DIR=%__RepoRootDir%/eng/native" "-DCLR_REPO_ROOT_DIR=%__RepoRootDir%"
call "%__SourceDir%\pal\tools\gen-buildsys.cmd" "%__ProjectDir%" "%__IntermediatesDir%" %__VSVersion% %__BuildArch% !__ExtraCmakeArgs!
if not !errorlevel! == 0 (
echo %__ErrMsgPrefix%%__MsgPrefix%Error: failed to generate native component build project!
Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/build.cmd
Original file line number Diff line number Diff line change
Expand Up @@ -561,7 +561,7 @@ if %__BuildNative% EQU 1 (

echo %__MsgPrefix%Regenerating the Visual Studio solution

set __ExtraCmakeArgs="-DCMAKE_SYSTEM_VERSION=10.0" !___CrossBuildDefine! "-DCLR_CMAKE_PGO_INSTRUMENT=%__PgoInstrument%" "-DCLR_CMAKE_OPTDATA_PATH=%__PgoOptDataPath%" "-DCLR_CMAKE_PGO_OPTIMIZE=%__PgoOptimize%" "-DCLR_ENG_NATIVE_DIR=%__RepoRootDir%/eng/native"
set __ExtraCmakeArgs="-DCMAKE_SYSTEM_VERSION=10.0" !___CrossBuildDefine! "-DCLR_CMAKE_PGO_INSTRUMENT=%__PgoInstrument%" "-DCLR_CMAKE_OPTDATA_PATH=%__PgoOptDataPath%" "-DCLR_CMAKE_PGO_OPTIMIZE=%__PgoOptimize%" "-DCLR_ENG_NATIVE_DIR=%__RepoRootDir%/eng/native" "-DCLR_REPO_ROOT_DIR=%__RepoRootDir%"
call "%__SourceDir%\pal\tools\gen-buildsys.cmd" "%__ProjectDir%" "%__IntermediatesDir%" %__VSVersion% %__BuildArch% !__ExtraCmakeArgs!
if not !errorlevel! == 0 (
echo %__ErrMsgPrefix%%__MsgPrefix%Error: failed to generate native component build project!
Expand Down
3 changes: 1 addition & 2 deletions src/coreclr/src/dlls/mscoree/coreclr/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ set(CORECLR_LIBRARIES
gcinfo # Condition="'$(TargetCpu)'=='amd64' or '$(TargetCpu)' == 'arm' or '$(TargetCpu)' == 'arm64'"
ildbsymlib
utilcode
v3binder
System.Globalization.Native-Static
libraries-native
interop
)
Expand Down Expand Up @@ -136,7 +136,6 @@ else()
${END_WHOLE_ARCHIVE}
mscorrc
palrt
System.Globalization.Native-Static
)
endif(CLR_CMAKE_TARGET_WIN32)

Expand Down
12 changes: 7 additions & 5 deletions src/coreclr/src/libraries-native/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(GLOBALIZATION_NATIVE_DIR ${CLR_REPO_ROOT_DIR}/src/libraries/Native/Unix/System.Globalization.Native)
set(GLOBALIZATION_NATIVE_DIR ${CLR_REPO_ROOT_DIR}/src/libraries/Native/AnyOS/System.Globalization.Native)

# Suppress exporting of the PAL APIs
add_definitions(-DPALEXPORT=)

if(CLR_CMAKE_HOST_UNIX)
include_directories("${CLR_REPO_ROOT_DIR}/src/libraries/Native/Unix/Common")
include_directories("${GLOBALIZATION_NATIVE_DIR}")
include_directories("${GLOBALIZATION_NATIVE_DIR}")
include_directories("${CLR_REPO_ROOT_DIR}/src/libraries/Native/AnyOS/Common")

add_subdirectory(${GLOBALIZATION_NATIVE_DIR} System.Globalization.Native)

add_subdirectory(${GLOBALIZATION_NATIVE_DIR} System.Globalization.Native)
if(CLR_CMAKE_HOST_UNIX)
include_directories("${CLR_REPO_ROOT_DIR}/src/libraries/Native/Unix/Common")
endif()

add_library(libraries-native
Expand Down
9 changes: 2 additions & 7 deletions src/coreclr/src/libraries-native/entrypoints.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

#ifdef TARGET_UNIX

#include "pal_types.h"
#include <stdint.h>

typedef uint16_t UChar;

Expand All @@ -19,15 +17,13 @@ typedef uint16_t UChar;
#include "pal_idna.h"
#include "pal_normalization.h"
#include "pal_timeZoneInfo.h"
#endif // TARGET_UNIX

#define FCFuncStart(name) extern const void* name[]; const void* name[] = {
#define FCFuncStart(name) EXTERN_C const void* name[]; const void* name[] = {
#define FCFuncEnd() (void*)0x01 /* FCFuncFlag_EndOfArray */ };

#define QCFuncElement(name,impl) \
(void*)0x8 /* FCFuncFlag_QCall */, (void*)(impl), (void*)name,

#ifdef TARGET_UNIX
FCFuncStart(gPalGlobalizationNative)
QCFuncElement("ChangeCase", GlobalizationNative_ChangeCase)
QCFuncElement("ChangeCaseInvariant", GlobalizationNative_ChangeCaseInvariant)
Expand Down Expand Up @@ -64,4 +60,3 @@ FCFuncStart(gPalGlobalizationNative)
QCFuncElement("ToAscii", GlobalizationNative_ToAscii)
QCFuncElement("ToUnicode", GlobalizationNative_ToUnicode)
FCFuncEnd()
#endif // TARGET_UNIX
2 changes: 0 additions & 2 deletions src/coreclr/src/vm/ecalllist.h
Original file line number Diff line number Diff line change
Expand Up @@ -1239,11 +1239,9 @@ FCClassElement("FileLoadException", "System.IO", gFileLoadExceptionFuncs)
FCClassElement("GC", "System", gGCInterfaceFuncs)
FCClassElement("GCHandle", "System.Runtime.InteropServices", gGCHandleFuncs)
FCClassElement("GCSettings", "System.Runtime", gGCSettingsFuncs)
#ifdef TARGET_UNIX
#ifndef CROSSGEN_COMPILE
FCClassElement("Globalization", "", gPalGlobalizationNative)
#endif
#endif
#ifdef FEATURE_COMINTEROP
FCClassElement("IEnumerable", "System.Collections", gStdMngIEnumerableFuncs)
FCClassElement("IEnumerator", "System.Collections", gStdMngIEnumeratorFuncs)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,17 @@
#endif

#ifndef PALEXPORT
#ifdef TARGET_UNIX
#define PALEXPORT __attribute__ ((__visibility__ ("default")))
#endif // ifndef PALEXPORT
#else
#define PALEXPORT
#endif
#endif // PALEXPORT

#ifndef EXTERN_C
#ifdef __cplusplus
#define EXTERN_C extern "C"
#else
#define EXTERN_C
#endif // __cplusplus
#endif // EXTERN_C
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
project(System.Globalization.Native C)

if(CLR_CMAKE_TARGET_UNIX)
add_compile_options(-Wno-switch-enum)
add_compile_options(-Wno-covered-switch-default)

# Workaround for warnings produced by ICU headers
add_compile_options(-Wno-reserved-id-macro)
add_compile_options(-Wno-documentation)
add_compile_options(-Wno-documentation-unknown-command)

# Workaround for https://unicode-org.atlassian.net/browse/ICU-20601
add_compile_options(-Wno-extra-semi-stmt)
add_compile_options(-Wno-unknown-warning-option)

set(ICU_HOMEBREW_INC_PATH "/usr/local/opt/icu4c/include")

find_path(UTYPES_H "unicode/utypes.h" PATHS ${ICU_HOMEBREW_INC_PATH})
if(UTYPES_H STREQUAL UTYPES_H-NOTFOUND)
message(FATAL_ERROR "Cannot find utypes.h, try installing libicu-dev (or the appropriate package for your platform)")
return()
endif()

if(CLR_CMAKE_TARGET_DARWIN)
find_library(ICUCORE icucore)
if(ICUCORE STREQUAL ICUCORE-NOTFOUND)
message(FATAL_ERROR "Cannot find libicucore, skipping build for System.Globalization.Native. .NET globalization is not expected to function.")
return()
endif()
add_definitions(-DOSX_ICU_LIBRARY_PATH=\"${ICUCORE}\")
add_definitions(-DU_DISABLE_RENAMING)
else()
find_library(ICUUC icuuc)
if(ICUUC STREQUAL ICUUC-NOTFOUND)
message(FATAL_ERROR "Cannot find libicuuc, try installing libicu-dev (or the appropriate package for your platform)")
return()
endif()

find_library(ICUI18N icui18n)
if(ICUI18N STREQUAL ICUI18N-NOTFOUND)
message(FATAL_ERROR "Cannot find libicui18n, try installing libicu-dev (or the appropriate package for your platform)")
return()
endif()
endif()

include_directories(${UTYPES_H})
endif()

include(configure.cmake)

set(NATIVEGLOBALIZATION_SOURCES
pal_calendarData.c
pal_casing.c
pal_collation.c
pal_idna.c
pal_locale.c
pal_localeNumberData.c
pal_localeStringData.c
pal_normalization.c
pal_timeZoneInfo.c
pal_icushim.c
)

include_directories("../Common")

if (GEN_SHARED_LIB)
add_library(System.Globalization.Native
SHARED
${NATIVEGLOBALIZATION_SOURCES}
${VERSION_FILE_PATH}
)

target_link_libraries(System.Globalization.Native
dl
)

install_library_and_symbols (System.Globalization.Native)
endif()

add_library(System.Globalization.Native-Static
STATIC
${NATIVEGLOBALIZATION_SOURCES}
)

set_target_properties(System.Globalization.Native-Static PROPERTIES OUTPUT_NAME System.Globalization.Native CLEAN_DIRECT_OUTPUT 1)

install (TARGETS System.Globalization.Native-Static DESTINATION .)

if(NOT CLR_CMAKE_TARGET_DARWIN)
if (GEN_SHARED_LIB)
add_custom_command(TARGET System.Globalization.Native POST_BUILD
COMMENT "Verifying System.Globalization.Native.so dependencies"
COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/../verify-so.sh
$<TARGET_FILE:System.Globalization.Native>
"Verification failed. System.Globalization.Native.so has undefined dependencies. These are likely ICU APIs that need to be added to icushim.h."
VERBATIM
)
endif()
endif()
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
include(CheckCSourceCompiles)
include(CheckSymbolExists)

if(CLR_CMAKE_TARGET_ANDROID)
string(REPLACE ";" ":" ANDROID_RPATHS "${CMAKE_C_IMPLICIT_LINK_DIRECTORIES}:${CMAKE_SYSTEM_LIBRARY_PATH}")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -rpath ${ANDROID_RPATHS}")
endif()

if (CLR_CMAKE_TARGET_UNIX)
set(CMAKE_REQUIRED_INCLUDES ${UTYPES_H} ${ICU_HOMEBREW_INC_PATH})

CHECK_C_SOURCE_COMPILES("
#include <unicode/udat.h>
int main(void) { enum UDateFormatSymbolType e = UDAT_STANDALONE_SHORTER_WEEKDAYS; }
" HAVE_UDAT_STANDALONE_SHORTER_WEEKDAYS)

if(CLR_CMAKE_TARGET_DARWIN)
set(CMAKE_REQUIRED_LIBRARIES ${ICUCORE})
else()
set(CMAKE_REQUIRED_LIBRARIES ${ICUUC} ${ICUI18N})
endif()

check_symbol_exists(
ucol_setMaxVariable
"unicode/ucol.h"
HAVE_SET_MAX_VARIABLE)

unset(CMAKE_REQUIRED_LIBRARIES)
unset(CMAKE_REQUIRED_INCLUDES)
endif()

configure_file(
${CMAKE_CURRENT_SOURCE_DIR}/config.h.in
${CMAKE_CURRENT_BINARY_DIR}/config.h)
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,19 @@
#include <assert.h>
#include <stdlib.h>
#include <string.h>

#ifdef TARGET_UNIX
#include <strings.h>
#endif

#include "pal_locale_internal.h"
#include "pal_errors_internal.h"
#include "pal_calendarData.h"

#ifndef TARGET_UNIX
#define strcasecmp _stricmp
#endif

#define GREGORIAN_NAME "gregorian"
#define JAPANESE_NAME "japanese"
#define BUDDHIST_NAME "buddhist"
Expand Down Expand Up @@ -226,7 +233,7 @@ static int InvokeCallbackForDatePattern(const char* locale,
UErrorCode ignore = U_ZERO_ERROR;
int32_t patternLen = udat_toPattern(pFormat, FALSE, NULL, 0, &ignore) + 1;

UChar* pattern = calloc((size_t)patternLen, sizeof(UChar));
UChar* pattern = (UChar*)calloc((size_t)patternLen, sizeof(UChar));
if (pattern == NULL)
{
udat_close(pFormat);
Expand Down Expand Up @@ -266,7 +273,7 @@ static int InvokeCallbackForDateTimePattern(const char* locale,
UErrorCode ignore = U_ZERO_ERROR;
int32_t patternLen = udatpg_getBestPattern(pGenerator, patternSkeleton, -1, NULL, 0, &ignore) + 1;

UChar* bestPattern = calloc((size_t)patternLen, sizeof(UChar));
UChar* bestPattern = (UChar*)calloc((size_t)patternLen, sizeof(UChar));
if (bestPattern == NULL)
{
udatpg_close(pGenerator);
Expand Down Expand Up @@ -306,7 +313,11 @@ static int32_t EnumSymbols(const char* locale,
return FALSE;

char localeWithCalendarName[ULOC_FULLNAME_CAPACITY];
#ifdef TARGET_UNIX
strncpy(localeWithCalendarName, locale, ULOC_FULLNAME_CAPACITY);
#else
strncpy_s(localeWithCalendarName, sizeof(locale), locale, ULOC_FULLNAME_CAPACITY);
#endif
localeWithCalendarName[ULOC_FULLNAME_CAPACITY - 1] = 0;

uloc_setKeywordValue("calendar", GetCalendarName(calendarId), localeWithCalendarName, ULOC_FULLNAME_CAPACITY, &err);
Expand Down Expand Up @@ -336,7 +347,7 @@ static int32_t EnumSymbols(const char* locale,
}
else
{
symbolBuf = calloc((size_t)symbolLen, sizeof(UChar));
symbolBuf = (UChar*)calloc((size_t)symbolLen, sizeof(UChar));
if (symbolBuf == NULL)
{
err = U_MEMORY_ALLOCATION_ERROR;
Expand Down Expand Up @@ -414,8 +425,11 @@ static int32_t EnumAbbrevEraNames(const char* locale,

char* localeNamePtr = localeNameBuf;
char* parentNamePtr = parentNameBuf;

#ifdef TARGET_UNIX
strncpy(localeNamePtr, locale, ULOC_FULLNAME_CAPACITY);
#else
strncpy_s(localeNamePtr, sizeof(locale), locale, ULOC_FULLNAME_CAPACITY);
#endif
localeNamePtr[ULOC_FULLNAME_CAPACITY - 1] = 0;

while (TRUE)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
#include <stdlib.h>

#include "pal_locale.h"
#include "pal_compiler.h"
#include "compiler.h"
#include "pal_errors.h"

/*
Expand Down Expand Up @@ -70,25 +70,25 @@ typedef enum
// the function pointer definition for the callback used in EnumCalendarInfo
typedef void (*EnumCalendarInfoCallback)(const UChar*, const void*);

PALEXPORT int32_t GlobalizationNative_GetCalendars(const UChar* localeName,
EXTERN_C PALEXPORT int32_t GlobalizationNative_GetCalendars(const UChar* localeName,
CalendarId* calendars,
int32_t calendarsCapacity);

PALEXPORT ResultCode GlobalizationNative_GetCalendarInfo(const UChar* localeName,
EXTERN_C PALEXPORT ResultCode GlobalizationNative_GetCalendarInfo(const UChar* localeName,
CalendarId calendarId,
CalendarDataType dataType,
UChar* result,
int32_t resultCapacity);

PALEXPORT int32_t GlobalizationNative_EnumCalendarInfo(EnumCalendarInfoCallback callback,
EXTERN_C PALEXPORT int32_t GlobalizationNative_EnumCalendarInfo(EnumCalendarInfoCallback callback,
const UChar* localeName,
CalendarId calendarId,
CalendarDataType dataType,
const void* context);

PALEXPORT int32_t GlobalizationNative_GetLatestJapaneseEra(void);
EXTERN_C PALEXPORT int32_t GlobalizationNative_GetLatestJapaneseEra(void);

PALEXPORT int32_t GlobalizationNative_GetJapaneseEraStartDate(int32_t era,
EXTERN_C PALEXPORT int32_t GlobalizationNative_GetJapaneseEraStartDate(int32_t era,
int32_t* startYear,
int32_t* startMonth,
int32_t* startDay);
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@
#include "pal_icushim_internal.h"
#include "pal_casing.h"

#ifdef __clang__
// Workaround for warnings produced by U16_NEXT and U16_APPEND macro expansions
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wsign-conversion"
#endif

/*
Function:
Expand Down Expand Up @@ -146,4 +148,6 @@ void GlobalizationNative_ChangeCaseTurkish(
}
}

#ifdef __clang__
#pragma clang diagnostic pop
#endif
Loading

0 comments on commit c1216d2

Please sign in to comment.