Add Android build configurations for Mono/Libraries (#33881)
authorAlexander Köplinger <alex.koeplinger@outlook.com>
Tue, 24 Mar 2020 22:39:42 +0000 (23:39 +0100)
committerGitHub <noreply@github.com>
Tue, 24 Mar 2020 22:39:42 +0000 (23:39 +0100)
* Add Android build configurations

* Enable System.Globalization.Native on Android

Dynamically load the libicu from the system. Android NDK doesn't ship with icu headers so for now define prototypes for all the functions we use ourselves.

* Add temporary stub HashProvider that throws NIE on Android

We still need to hook up the native System.Security.Native library.

Unblocks Xamarin.Forms startup.

30 files changed:
eng/Subsets.props
eng/build.sh
eng/codeOptimization.targets
eng/native/configureplatform.cmake
eng/native/configuretools.cmake
eng/native/init-distro-rid.sh
src/libraries/Directory.Build.props
src/libraries/Native/Unix/CMakeLists.txt
src/libraries/Native/Unix/Common/pal_config.h.in
src/libraries/Native/Unix/System.Globalization.Native/CMakeLists.txt
src/libraries/Native/Unix/System.Globalization.Native/configure.cmake
src/libraries/Native/Unix/System.Globalization.Native/pal_icushim.c
src/libraries/Native/Unix/System.Globalization.Native/pal_icushim_internal.h
src/libraries/Native/Unix/System.Globalization.Native/pal_icushim_internal_android.h [new file with mode: 0644]
src/libraries/Native/Unix/System.IO.Compression.Native/CMakeLists.txt
src/libraries/Native/Unix/System.Native/pal_console.c
src/libraries/Native/Unix/System.Native/pal_interfaceaddresses.c
src/libraries/Native/Unix/System.Native/pal_networking.c
src/libraries/Native/Unix/System.Native/pal_process.c
src/libraries/Native/Unix/configure.cmake
src/libraries/Native/build-native.sh
src/libraries/OSGroups.json
src/libraries/System.Security.Cryptography.Algorithms/src/Internal/Cryptography/HashProviderDispenser.Android.cs [new file with mode: 0644]
src/libraries/System.Security.Cryptography.Algorithms/src/System.Security.Cryptography.Algorithms.csproj
src/libraries/restore/runtime/runtime.depproj
src/mono/Directory.Build.props
src/mono/mono.proj
src/mono/netcore/nuget/Directory.Build.props
src/mono/netcore/nuget/Microsoft.NETCore.Runtime.Mono/runtime.Android.Microsoft.NETCore.Runtime.Mono.props [new file with mode: 0644]
src/mono/netcore/nuget/Microsoft.NETCore.Tool.MonoAOT/runtime.Android.Microsoft.NETCore.Tool.MonoAOT.props [new file with mode: 0644]

index 9218251..ef7ed62 100644 (file)
@@ -58,7 +58,7 @@
 
   <PropertyGroup>
     <DefaultSubsetCategories>libraries-installer-coreclr-mono</DefaultSubsetCategories>
-    <DefaultSubsetCategories Condition="'$(TargetOS)' == 'iOS'">libraries-mono</DefaultSubsetCategories>
+    <DefaultSubsetCategories Condition="'$(TargetOS)' == 'iOS' or '$(TargetOS)' == 'Android'">libraries-mono</DefaultSubsetCategories>
     <DefaultInstallerSubsets>corehost-managed-depproj-pkgproj-bundle-installers-test</DefaultInstallerSubsets>
     <!-- TODO: Split into multiple sets. -->
     <DefaultLibrariesSubsets>all</DefaultLibrariesSubsets>
@@ -78,7 +78,7 @@
   </PropertyGroup>
 
   <PropertyGroup>
-    <RuntimeFlavor Condition="'$(TargetOS)' == 'iOS'">Mono</RuntimeFlavor>
+    <RuntimeFlavor Condition="'$(TargetOS)' == 'iOS' or '$(TargetOS)' == 'Android'">Mono</RuntimeFlavor>
     <RuntimeFlavor Condition="'$(RuntimeFlavor)' == '' and $(_subsetCategory.Contains('mono')) and !$(_subsetCategory.Contains('coreclr'))">Mono</RuntimeFlavor>
     <RuntimeFlavor Condition="'$(RuntimeFlavor)' == ''">CoreCLR</RuntimeFlavor>
   </PropertyGroup>
index 1a3c988..48ee6d9 100755 (executable)
@@ -19,7 +19,7 @@ usage()
   echo "Common settings:"
   echo "  --subset                   Build a subset, print available subsets with -subset help"
   echo "  --subsetCategory           Build a subsetCategory, print available subsetCategories with -subset help"
-  echo "  --os                       Build operating system: Windows_NT or Unix"
+  echo "  --os                       Build operating system: Windows_NT, Linux, FreeBSD, OSX, iOS or Android"
   echo "  --arch                     Build platform: x86, x64, arm or arm64"
   echo "  --configuration            Build configuration: Debug, Release or [CoreCLR]Checked (short: -c)"
   echo "  --runtimeConfiguration     Runtime build configuration: Debug, Release or [CoreCLR]Checked"
index 24e9c76..922c210 100644 (file)
@@ -9,7 +9,7 @@
            IBCMerge optimizations on Mac for now to unblock the offical build.
            See issue https://github.com/dotnet/runtime/issues/33303
       -->
-      <IsEligibleForNgenOptimization Condition="'$(TargetOS)' == 'OSX' or '$(TargetOS)' == 'iOS'">false</IsEligibleForNgenOptimization>
+      <IsEligibleForNgenOptimization Condition="'$(TargetOS)' == 'OSX' or '$(TargetOS)' == 'iOS' or '$(TargetOS)' == 'Android'">false</IsEligibleForNgenOptimization>
   </PropertyGroup>
 
   <Target Name="SetApplyNgenOptimization"
index 11ac264..4e25a3d 100644 (file)
@@ -11,9 +11,9 @@ set(PRERELEASE 1)
 #     - for windows we use the passed in parameter to CMAKE to determine build arch
 #----------------------------------------
 set(CLR_CMAKE_HOST_OS ${CMAKE_SYSTEM_NAME})
-if(CLR_CMAKE_HOST_OS STREQUAL Linux OR CLR_CMAKE_HOST_OS STREQUAL Android)
+if(CLR_CMAKE_HOST_OS STREQUAL Linux)
     set(CLR_CMAKE_HOST_UNIX 1)
-    if(CLR_CROSS_COMPONENTS_BUILD AND NOT CLR_CMAKE_HOST_OS STREQUAL Android)
+    if(CLR_CROSS_COMPONENTS_BUILD)
         # CMAKE_HOST_SYSTEM_PROCESSOR returns the value of `uname -p` on host.
         if(CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL x86_64 OR CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL amd64)
             if(CLR_CMAKE_TARGET_ARCH STREQUAL "arm" OR CLR_CMAKE_TARGET_ARCH STREQUAL "armel")
@@ -74,12 +74,7 @@ if(CLR_CMAKE_HOST_OS STREQUAL Linux OR CLR_CMAKE_HOST_OS STREQUAL Android)
             set(CLR_CMAKE_HOST_OS ${CLR_CMAKE_LINUX_ID})
         endif()
     endif(DEFINED CLR_CMAKE_LINUX_ID)
-
-    if(CLR_CMAKE_HOST_OS STREQUAL Android)
-        set(CLR_CMAKE_HOST_ANDROID 1)
-        set(CLR_CMAKE_HOST_OS ${CLR_CMAKE_HOST_OS})
-    endif()
-endif(CLR_CMAKE_HOST_OS STREQUAL Linux OR CLR_CMAKE_HOST_OS STREQUAL Android)
+endif(CLR_CMAKE_HOST_OS STREQUAL Linux)
 
 if(CLR_CMAKE_HOST_OS STREQUAL Darwin)
     set(CLR_CMAKE_HOST_UNIX 1)
@@ -102,6 +97,23 @@ if(CLR_CMAKE_HOST_OS STREQUAL iOS)
     endif()
 endif(CLR_CMAKE_HOST_OS STREQUAL iOS)
 
+if(CLR_CMAKE_HOST_OS STREQUAL Android)
+    set(CLR_CMAKE_HOST_UNIX 1)
+    set(CLR_CMAKE_HOST_LINUX 1)
+    set(CLR_CMAKE_HOST_ANDROID 1)
+    if(CMAKE_SYSTEM_PROCESSOR STREQUAL x86_64)
+        set(CLR_CMAKE_HOST_UNIX_AMD64 1)
+    elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL armv7-a)
+        set(CLR_CMAKE_HOST_UNIX_ARM 1)
+    elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL aarch64)
+        set(CLR_CMAKE_HOST_UNIX_ARM64 1)
+    elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL i686)
+        set(CLR_CMAKE_HOST_UNIX_X86 1)
+    else()
+        clr_unknown_arch()
+    endif()
+endif(CLR_CMAKE_HOST_OS STREQUAL Android)
+
 if(CLR_CMAKE_HOST_OS STREQUAL FreeBSD)
     set(CLR_CMAKE_HOST_UNIX 1)
     set(CLR_CMAKE_HOST_UNIX_AMD64 1)
@@ -315,6 +327,7 @@ else()
 endif()
 
 if(NOT CLR_CMAKE_HOST_ARCH_WASM)
+if(NOT CLR_CMAKE_TARGET_ANDROID) # Android requires PIC and CMake handles this so we don't need the check
     # All code we build should be compiled as position independent
     get_property(languages GLOBAL PROPERTY ENABLED_LANGUAGES)
     if("CXX" IN_LIST languages)
@@ -328,6 +341,5 @@ if(NOT CLR_CMAKE_HOST_ARCH_WASM)
                   "PIE link options will not be passed to linker.")
     endif()
     set(CMAKE_POSITION_INDEPENDENT_CODE ON)
+endif(NOT CLR_CMAKE_TARGET_ANDROID)
 endif(NOT CLR_CMAKE_HOST_ARCH_WASM)
-
-set(CLR_CMAKE_CONFIGURE_PLATFORM_INCLUDED 1)
index 9e3a877..72c67de 100644 (file)
@@ -47,11 +47,11 @@ if(NOT WIN32)
     locate_toolchain_exec(ranlib CMAKE_RANLIB)
   endif()
 
-  if(NOT CLR_CMAKE_TARGET_OSX AND NOT CLR_CMAKE_TARGET_IOS)
+  if(NOT CLR_CMAKE_TARGET_OSX AND NOT CLR_CMAKE_TARGET_IOS AND (NOT CLR_CMAKE_TARGET_ANDROID OR CROSS_ROOTFS))
     locate_toolchain_exec(objdump CMAKE_OBJDUMP)
 
-    if(CMAKE_SYSTEM_NAME STREQUAL Android)
-      set(TOOSET_PREFIX ${ANDROID_TOOLCHAIN_PREFIX})
+    if(CLR_CMAKE_TARGET_ANDROID)
+      set(TOOLSET_PREFIX ${ANDROID_TOOLCHAIN_PREFIX})
     elseif(CMAKE_CROSSCOMPILING AND NOT DEFINED CLR_CROSS_COMPONENTS_BUILD AND (CMAKE_SYSTEM_PROCESSOR STREQUAL armv7l OR
        CMAKE_SYSTEM_PROCESSOR STREQUAL aarch64 OR CMAKE_SYSTEM_PROCESSOR STREQUAL arm))
       set(TOOLSET_PREFIX "${TOOLCHAIN}-")
@@ -60,5 +60,5 @@ if(NOT WIN32)
     endif()
 
     locate_toolchain_exec(objcopy CMAKE_OBJCOPY)
-  endif(NOT CLR_CMAKE_TARGET_OSX AND NOT CLR_CMAKE_TARGET_IOS)
+  endif()
 endif()
index 3c7f475..5bf8083 100644 (file)
@@ -163,6 +163,8 @@ initDistroRidGlobal()
                 distroRid="osx-$buildArch"
             elif [ "$targetOs" = "iOS" ]; then
                 distroRid="ios-$buildArch"
+            elif [ "$targetOs" = "Android" ]; then
+                distroRid="android-$buildArch"
             elif [ "$targetOs" = "FreeBSD" ]; then
                 distroRid="freebsd-$buildArch"
             fi
index bd273ec..0d1f1d6 100644 (file)
     <ArchGroup Condition="'$(ArchGroup)' == '' and '$(HostArch)' == 'arm64'">arm64</ArchGroup>
     <ArchGroup Condition="'$(ArchGroup)' == '' and '$(TargetOS)' == 'WebAssembly'">wasm</ArchGroup>
     <ArchGroup Condition="'$(ArchGroup)' == '' and '$(TargetOS)' == 'iOS'">x64</ArchGroup>
+    <ArchGroup Condition="'$(ArchGroup)' == '' and '$(TargetOS)' == 'Android'">x64</ArchGroup>
     <ArchGroup Condition="'$(ArchGroup)' == ''">x64</ArchGroup>
 
-    <!-- RuntimeOS is calculated based on the build system OS, however if building for WebAssembly or iOS we need to let
-         the build system to use webassembly/ios as the RuntimeOS for produced package RIDs. -->
+    <!-- RuntimeOS is calculated based on the build system OS, however if building for WebAssembly/iOS/Android we need to let
+         the build system to use webassembly/ios/android as the RuntimeOS for produced package RIDs. -->
     <RuntimeOS Condition="'$(TargetOS)' == 'WebAssembly'">$(TargetOS.ToLowerInvariant())</RuntimeOS>
     <RuntimeOS Condition="'$(TargetOS)' == 'iOS'">$(TargetOS.ToLowerInvariant())</RuntimeOS>
+    <RuntimeOS Condition="'$(TargetOS)' == 'Android'">$(TargetOS.ToLowerInvariant())</RuntimeOS>
  
     <!-- Initialize BuildSettings from the individual properties if it wasn't already explicitly set -->
     <Configuration Condition="'$(Configuration)'==''">Debug</Configuration>
         <PackageTargetRuntime>linux</PackageTargetRuntime>
       </PropertyGroup>
     </When>
+    <When Condition="'$(TargetFrameworkSuffix)' == 'Android'">
+      <PropertyGroup>
+        <TargetsUnix>true</TargetsUnix>
+        <TargetsLinux>true</TargetsLinux>
+        <TargetsAndroid>true</TargetsAndroid>
+        <PackageTargetRuntime>android</PackageTargetRuntime>
+      </PropertyGroup>
+    </When>
     <When Condition="'$(TargetFrameworkSuffix)' == 'OSX'">
       <PropertyGroup>
         <TargetsUnix>true</TargetsUnix>
     <_portableOS Condition="'$(_runtimeOSFamily)' == 'FreeBSD'">freebsd</_portableOS>
     <_portableOS Condition="'$(RuntimeOS)' == 'WebAssembly'">webassembly</_portableOS>
     <_portableOS Condition="'$(RuntimeOS)' == 'ios'">ios</_portableOS>
+    <_portableOS Condition="'$(RuntimeOS)' == 'android'">android</_portableOS>
 
     <_runtimeOS>$(RuntimeOS)</_runtimeOS>
     <_runtimeOS Condition="'$(_runtimeOS)' == 'tizen.4.0.0'">linux</_runtimeOS>
     <ToolRuntimeRID Condition="'$(RuntimeOS)' == 'webassembly' and '$(TargetOS)' != 'Windows_NT' and $(_buildingInOSX)">osx-x64</ToolRuntimeRID>
     <ToolRuntimeRID Condition="'$(RuntimeOS)' == 'webassembly' and '$(TargetOS)' != 'Windows_NT' and !$(_buildingInOSX)">linux-x64</ToolRuntimeRID>
 
+    <!-- There are no Android tools, so use the default ones -->
+    <ToolRuntimeRID Condition="'$(RuntimeOS)' == 'android' and '$(TargetOS)' == 'Windows_NT'">win-x64</ToolRuntimeRID>
+    <ToolRuntimeRID Condition="'$(RuntimeOS)' == 'android' and '$(TargetOS)' != 'Windows_NT' and $(_buildingInOSX)">osx-x64</ToolRuntimeRID>
+    <ToolRuntimeRID Condition="'$(RuntimeOS)' == 'android' and '$(TargetOS)' != 'Windows_NT' and !$(_buildingInOSX)">linux-x64</ToolRuntimeRID>
+
     <!-- There are no iOS tools and it can be built on OSX only, so use that -->
     <ToolRuntimeRID Condition="'$(RuntimeOS)' == 'ios'">osx-x64</ToolRuntimeRID>
 
index 5f20c76..4cf2236 100644 (file)
@@ -91,7 +91,9 @@ endif ()
 
 if(CLR_CMAKE_TARGET_ANDROID)
     add_definitions(-DTARGET_ANDROID)
-    include_directories(SYSTEM "${CROSS_ROOTFS}/usr/include")
+    if(CROSS_ROOTFS)
+        include_directories(SYSTEM "${CROSS_ROOTFS}/usr/include")
+    endif()
 endif()
 
 string(TOUPPER ${CMAKE_BUILD_TYPE} UPPERCASE_CMAKE_BUILD_TYPE)
@@ -195,18 +197,22 @@ endif()
 
 add_subdirectory(System.Native)
 
-if (NOT CLR_CMAKE_TARGET_ARCH_WASM)
+if(CLR_CMAKE_TARGET_ARCH_WASM)
+    # skip for now
+elseif(CLR_CMAKE_TARGET_IOS)
     add_subdirectory(System.Net.Security.Native)
-
-if (NOT CLR_CMAKE_TARGET_IOS)
-    # TODO: reenable for iOS
+    #add_subdirectory(System.Globalization.Native) # TODO: reenable
+    # System.Security.Cryptography.Native is intentionally disabled on iOS
+    # it is only used for interacting with OpenSSL which isn't useful there
+elseif(CLR_CMAKE_TARGET_ANDROID AND NOT CROSS_ROOTFS)
     add_subdirectory(System.Globalization.Native)
-
-    # disable System.Security.Cryptography.Native build on iOS,
-    # only used for interacting with OpenSSL which isn't useful there
+    #add_subdirectory(System.Net.Security.Native) # TODO: reenable
+    #add_subdirectory(System.Security.Cryptography.Native) # TODO: reenable
+else()
+    add_subdirectory(System.Globalization.Native)
+    add_subdirectory(System.Net.Security.Native)
     add_subdirectory(System.Security.Cryptography.Native)
 endif()
-endif()
 
 if(CLR_CMAKE_TARGET_OSX OR CLR_CMAKE_TARGET_IOS)
     add_subdirectory(System.Security.Cryptography.Native.Apple)
index e1b4a3f..d177e66 100644 (file)
@@ -35,6 +35,7 @@
 #cmakedefine01 HAVE_TIOCGWINSZ
 #cmakedefine01 HAVE_SCHED_GETAFFINITY
 #cmakedefine01 HAVE_SCHED_SETAFFINITY
+#cmakedefine01 HAVE_PTHREAD_SETCANCELSTATE
 #cmakedefine01 HAVE_ARC4RANDOM_BUF
 #cmakedefine01 KEVENT_HAS_VOID_UDATA
 #cmakedefine01 HAVE_FDS_BITS
 #cmakedefine01 HAVE_TCP_H_TCP_KEEPALIVE
 #cmakedefine01 HAVE_BUILTIN_MUL_OVERFLOW
 #cmakedefine01 HAVE_DISCONNECTX
-#cmakedefine01 HAVE_PTHREAD_SETCANCELSTATE
 
 // Mac OS X has stat64, but it is deprecated since plain stat now
 // provides the same 64-bit aware struct when targeting OS X > 10.5
index 86ddba4..4b1afef 100644 (file)
@@ -13,37 +13,39 @@ if(CLR_CMAKE_TARGET_UNIX)
     add_compile_options(-Wno-extra-semi-stmt)
     add_compile_options(-Wno-unknown-warning-option)
 
-    set(ICU_HOMEBREW_INC_PATH "/usr/local/opt/icu4c/include")
+    if (NOT CLR_CMAKE_TARGET_ANDROID)
+        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_OSX)
-        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)")
+        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()
 
-        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()
+        if(CLR_CMAKE_TARGET_OSX)
+            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()
-    endif()
 
-    include_directories(${UTYPES_H})
+        include_directories(${UTYPES_H})
+    endif()
 endif()
 
 include(configure.cmake)
@@ -86,7 +88,7 @@ set_target_properties(System.Globalization.Native-Static PROPERTIES OUTPUT_NAME
 
 install (TARGETS System.Globalization.Native-Static DESTINATION .)
 
-if(NOT CLR_CMAKE_TARGET_OSX AND NOT CLR_CMAKE_TARGET_IOS)
+if(NOT CLR_CMAKE_TARGET_OSX AND NOT CLR_CMAKE_TARGET_IOS AND NOT CLR_CMAKE_TARGET_ANDROID)
     if (GEN_SHARED_LIB)
         add_custom_command(TARGET System.Globalization.Native POST_BUILD
             COMMENT "Verifying System.Globalization.Native.so dependencies"
index 8919b80..f0042b1 100644 (file)
@@ -1,32 +1,32 @@
-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()
+    set(HAVE_SET_MAX_VARIABLE 1)
+    set(HAVE_UDAT_STANDALONE_SHORTER_WEEKDAYS 1)
+else()
+    include(CheckCSourceCompiles)
+    include(CheckSymbolExists)
 
-if (CLR_CMAKE_TARGET_UNIX)
-    set(CMAKE_REQUIRED_INCLUDES ${UTYPES_H} ${ICU_HOMEBREW_INC_PATH})
+    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)
+        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_OSX)
-        set(CMAKE_REQUIRED_LIBRARIES ${ICUCORE})
-    else()
-        set(CMAKE_REQUIRED_LIBRARIES ${ICUUC} ${ICUI18N})
-    endif()
+        if(CLR_CMAKE_TARGET_OSX)
+            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)
+        check_symbol_exists(
+            ucol_setMaxVariable
+            "unicode/ucol.h"
+            HAVE_SET_MAX_VARIABLE)
 
-    unset(CMAKE_REQUIRED_LIBRARIES)
-    unset(CMAKE_REQUIRED_INCLUDES)
+        unset(CMAKE_REQUIRED_LIBRARIES)
+        unset(CMAKE_REQUIRED_INCLUDES)
+    endif()
 endif()
 
 configure_file(
index 6d4dc1e..b1a8849 100644 (file)
@@ -63,7 +63,54 @@ static int FindICULibs()
     return TRUE;
 }
 
-#else // !TARGET_WINDOWS && !TARGET_OSX
+#elif defined(TARGET_ANDROID)
+
+// support ICU versions from 50-255
+#define MinICUVersion 50
+#define MaxICUVersion 255
+#define MaxICUVersionStringLength 4
+
+static int FindSymbolVersion(char* symbolName, char* symbolVersion)
+{
+    for (int i = MinICUVersion; i <= MaxICUVersion; i++)
+    {
+        sprintf(symbolVersion, "_%d", i);
+        sprintf(symbolName, "u_strlen%s", symbolVersion);
+        if (dlsym(libicuuc, symbolName) != NULL)
+        {
+            return TRUE;
+        }
+    }
+
+    return FALSE;
+}
+
+static int FindICULibs(char* symbolName, char* symbolVersion)
+{
+    libicui18n = dlopen("libicui18n.so", RTLD_LAZY);
+
+    if (libicui18n == NULL)
+    {
+        return FALSE;
+    }
+
+    libicuuc = dlopen("libicuuc.so", RTLD_LAZY);
+
+    if (libicuuc == NULL)
+    {
+        return FALSE;
+    }
+
+    if (!FindSymbolVersion(symbolName, symbolVersion))
+    {
+        fprintf(stderr, "Cannot determine ICU version.");
+        return FALSE;
+    }
+
+    return TRUE;
+}
+
+#else // !TARGET_WINDOWS && !TARGET_OSX && !TARGET_ANDROID
 
 #define VERSION_PREFIX_NONE ""
 #define VERSION_PREFIX_SUSE "suse"
@@ -299,6 +346,12 @@ int32_t GlobalizationNative_LoadICU()
     char symbolName[128];
     char symbolVersion[MaxICUVersionStringLength + 1] = "";
 
+#if defined(TARGET_ANDROID)
+    if (!FindICULibs(symbolName, symbolVersion))
+    {
+        return FALSE;
+    }
+#else
     if (!FindICULibs(VERSION_PREFIX_NONE, symbolName, symbolVersion))
     {
         if (!FindICULibs(VERSION_PREFIX_SUSE, symbolName, symbolVersion))
@@ -306,6 +359,7 @@ int32_t GlobalizationNative_LoadICU()
             return FALSE;
         }
     }
+#endif
 
     // Get pointers to all the ICU functions that are needed
 #define PER_FUNCTION_BLOCK(fn, lib) \
index 2ee8fab..a13ea5f 100644 (file)
 
 #include "config.h"
 
+#if defined(TARGET_ANDROID)
+#include "pal_icushim_internal_android.h"
+#else
+
 #define U_DISABLE_RENAMING 1
 
 // All ICU headers need to be included here so that all function prototypes are
@@ -35,6 +39,8 @@
 #include <unicode/urename.h>
 #include <unicode/ustring.h>
 
+#endif
+
 #elif defined(TARGET_WINDOWS)
 
 #include "icu.h"
diff --git a/src/libraries/Native/Unix/System.Globalization.Native/pal_icushim_internal_android.h b/src/libraries/Native/Unix/System.Globalization.Native/pal_icushim_internal_android.h
new file mode 100644 (file)
index 0000000..5a3ac55
--- /dev/null
@@ -0,0 +1,515 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+//
+
+// definitions for ICU types and functions available in Android,
+// extracted from ICU header files
+
+#pragma once
+
+#define U_MAX_VERSION_LENGTH 4
+
+#define U_SUCCESS(x) ((x)<=U_ZERO_ERROR)
+#define U_FAILURE(x) ((x)>U_ZERO_ERROR)
+
+typedef struct UCollator UCollator;
+typedef struct UCollationElements UCollationElements;
+typedef struct UEnumeration UEnumeration;
+typedef struct UIDNA UIDNA;
+typedef struct UNormalizer2 UNormalizer2;
+typedef struct ULocaleDisplayNames ULocaleDisplayNames;
+typedef struct UResourceBundle UResourceBundle;
+typedef struct UStringSearch UStringSearch;
+typedef struct UBreakIterator UBreakIterator;
+
+typedef int8_t UBool;
+typedef uint16_t UChar;
+typedef int32_t UChar32;
+typedef uint8_t UVersionInfo[U_MAX_VERSION_LENGTH];
+
+typedef void* UNumberFormat;
+typedef void* UDateFormat;
+typedef void* UDateTimePatternGenerator;
+typedef void* UCalendar;
+
+#ifndef TRUE
+#   define TRUE  1
+#endif
+#ifndef FALSE
+#   define FALSE 0
+#endif
+
+#define USEARCH_DONE -1
+
+#define UCOL_NULLORDER ((int32_t)0xFFFFFFFF)
+#define UCOL_BUILDER_VERSION 9
+#define UCOL_RUNTIME_VERSION 9
+
+#define ULOC_FULLNAME_CAPACITY 157
+#define ULOC_LANG_CAPACITY 12
+#define ULOC_KEYWORDS_CAPACITY 96
+#define ULOC_ENGLISH "en"
+#define ULOC_US "en_US"
+
+#define U16_IS_LEAD(c) (((c)&0xfffffc00)==0xd800)
+#define U16_IS_TRAIL(c) (((c)&0xfffffc00)==0xdc00)
+#define U16_SURROGATE_OFFSET ((0xd800<<10UL)+0xdc00-0x10000)
+
+#define U16_GET_SUPPLEMENTARY(lead, trail) \
+    (((UChar32)(lead)<<10UL)+(UChar32)(trail)-U16_SURROGATE_OFFSET)
+
+#define U16_APPEND(s, i, capacity, c, isError) { \
+    if((uint32_t)(c)<=0xffff) { \
+        (s)[(i)++]=(uint16_t)(c); \
+    } else if((uint32_t)(c)<=0x10ffff && (i)+1<(capacity)) { \
+        (s)[(i)++]=(uint16_t)(((c)>>10)+0xd7c0); \
+        (s)[(i)++]=(uint16_t)(((c)&0x3ff)|0xdc00); \
+    } else { \
+        (isError)=TRUE; \
+    } \
+}
+
+#define U16_NEXT(s, i, length, c) { \
+    (c)=(s)[(i)++]; \
+    if(U16_IS_LEAD(c)) { \
+        uint16_t __c2; \
+        if((i)!=(length) && U16_IS_TRAIL(__c2=(s)[(i)])) { \
+            ++(i); \
+            (c)=U16_GET_SUPPLEMENTARY((c), __c2); \
+        } \
+    } \
+}
+
+#define U16_FWD_1(s, i, length) { \
+    if(U16_IS_LEAD((s)[(i)++]) && (i)!=(length) && U16_IS_TRAIL((s)[i])) { \
+        ++(i); \
+    } \
+}
+
+#define UIDNA_INFO_INITIALIZER { \
+    (int16_t)sizeof(UIDNAInfo), \
+    FALSE, FALSE, \
+    0, 0, 0 }
+
+typedef enum UErrorCode {
+    U_STRING_NOT_TERMINATED_WARNING = -124,
+    U_ZERO_ERROR =  0,
+    U_ILLEGAL_ARGUMENT_ERROR = 1,
+    U_INTERNAL_PROGRAM_ERROR = 5,
+    U_MEMORY_ALLOCATION_ERROR = 7,
+    U_BUFFER_OVERFLOW_ERROR = 15,
+    U_UNSUPPORTED_ERROR = 16,
+} UErrorCode;
+
+typedef enum UCalendarDateFields {
+    UCAL_ERA,
+    UCAL_YEAR,
+    UCAL_MONTH,
+    UCAL_WEEK_OF_YEAR,
+    UCAL_WEEK_OF_MONTH,
+    UCAL_DATE,
+    UCAL_DAY_OF_YEAR,
+    UCAL_DAY_OF_WEEK,
+    UCAL_DAY_OF_WEEK_IN_MONTH,
+    UCAL_AM_PM,
+    UCAL_HOUR,
+    UCAL_HOUR_OF_DAY,
+    UCAL_MINUTE,
+    UCAL_SECOND,
+    UCAL_MILLISECOND,
+    UCAL_ZONE_OFFSET,
+    UCAL_DST_OFFSET,
+    UCAL_YEAR_WOY,
+    UCAL_DOW_LOCAL,
+    UCAL_EXTENDED_YEAR,
+    UCAL_JULIAN_DAY,
+    UCAL_MILLISECONDS_IN_DAY,
+    UCAL_IS_LEAP_MONTH,
+    UCAL_FIELD_COUNT,
+    UCAL_DAY_OF_MONTH = UCAL_DATE
+} UCalendarDateFields;
+
+typedef enum UColAttribute {
+    UCOL_FRENCH_COLLATION,
+    UCOL_ALTERNATE_HANDLING,
+    UCOL_CASE_FIRST,
+    UCOL_CASE_LEVEL,
+    UCOL_NORMALIZATION_MODE,
+    UCOL_DECOMPOSITION_MODE = UCOL_NORMALIZATION_MODE,
+    UCOL_STRENGTH,
+    UCOL_NUMERIC_COLLATION = UCOL_STRENGTH + 2,
+    UCOL_ATTRIBUTE_COUNT
+} UColAttribute;
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wduplicate-enum"
+typedef enum UColAttributeValue {
+    UCOL_DEFAULT = -1,
+    UCOL_PRIMARY = 0,
+    UCOL_SECONDARY = 1,
+    UCOL_TERTIARY = 2,
+    UCOL_DEFAULT_STRENGTH = UCOL_TERTIARY,
+    UCOL_CE_STRENGTH_LIMIT,
+    UCOL_QUATERNARY=3,
+    UCOL_IDENTICAL=15,
+    UCOL_STRENGTH_LIMIT,
+    UCOL_OFF = 16,
+    UCOL_ON = 17,
+    UCOL_SHIFTED = 20,
+    UCOL_NON_IGNORABLE = 21,
+    UCOL_LOWER_FIRST = 24,
+    UCOL_UPPER_FIRST = 25,
+} UColAttributeValue;
+#pragma clang diagnostic pop
+
+typedef UColAttributeValue UCollationStrength;
+
+typedef enum UCalendarAttribute {
+    UCAL_LENIENT,
+    UCAL_FIRST_DAY_OF_WEEK,
+    UCAL_MINIMAL_DAYS_IN_FIRST_WEEK,
+    UCAL_REPEATED_WALL_TIME,
+    UCAL_SKIPPED_WALL_TIME
+} UCalendarAttribute;
+
+typedef enum UCalendarLimitType {
+    UCAL_MINIMUM,
+    UCAL_MAXIMUM,
+    UCAL_GREATEST_MINIMUM,
+    UCAL_LEAST_MAXIMUM,
+    UCAL_ACTUAL_MINIMUM,
+    UCAL_ACTUAL_MAXIMUM
+} UCalendarLimitType;
+
+typedef enum UCalendarDisplayNameType {
+    UCAL_STANDARD,
+    UCAL_SHORT_STANDARD,
+    UCAL_DST,
+    UCAL_SHORT_DST
+} UCalendarDisplayNameType;
+
+typedef enum ULayoutType {
+    ULOC_LAYOUT_LTR = 0,
+    ULOC_LAYOUT_RTL = 1,
+    ULOC_LAYOUT_TTB = 2,
+    ULOC_LAYOUT_BTT = 3,
+    ULOC_LAYOUT_UNKNOWN
+} ULayoutType;
+
+typedef enum UDialectHandling {
+    ULDN_STANDARD_NAMES = 0,
+    ULDN_DIALECT_NAMES
+} UDialectHandling;
+
+typedef enum UMeasurementSystem {
+    UMS_SI,
+    UMS_US,
+    UMS_UK,
+} UMeasurementSystem;
+
+typedef enum UNumberFormatSymbol {
+    UNUM_DECIMAL_SEPARATOR_SYMBOL = 0,
+    UNUM_GROUPING_SEPARATOR_SYMBOL = 1,
+    UNUM_PATTERN_SEPARATOR_SYMBOL = 2,
+    UNUM_PERCENT_SYMBOL = 3,
+    UNUM_ZERO_DIGIT_SYMBOL = 4,
+    UNUM_DIGIT_SYMBOL = 5,
+    UNUM_MINUS_SIGN_SYMBOL = 6,
+    UNUM_PLUS_SIGN_SYMBOL = 7,
+    UNUM_CURRENCY_SYMBOL = 8,
+    UNUM_INTL_CURRENCY_SYMBOL = 9,
+    UNUM_MONETARY_SEPARATOR_SYMBOL = 10,
+    UNUM_EXPONENTIAL_SYMBOL = 11,
+    UNUM_PERMILL_SYMBOL = 12,
+    UNUM_PAD_ESCAPE_SYMBOL = 13,
+    UNUM_INFINITY_SYMBOL = 14,
+    UNUM_NAN_SYMBOL = 15,
+    UNUM_SIGNIFICANT_DIGIT_SYMBOL = 16,
+    UNUM_MONETARY_GROUPING_SEPARATOR_SYMBOL = 17,
+    UNUM_ONE_DIGIT_SYMBOL = 18,
+    UNUM_TWO_DIGIT_SYMBOL = 19,
+    UNUM_THREE_DIGIT_SYMBOL = 20,
+    UNUM_FOUR_DIGIT_SYMBOL = 21,
+    UNUM_FIVE_DIGIT_SYMBOL = 22,
+    UNUM_SIX_DIGIT_SYMBOL = 23,
+    UNUM_SEVEN_DIGIT_SYMBOL = 24,
+    UNUM_EIGHT_DIGIT_SYMBOL = 25,
+    UNUM_NINE_DIGIT_SYMBOL = 26,
+    UNUM_EXPONENT_MULTIPLICATION_SYMBOL = 27,
+} UNumberFormatSymbol;
+
+typedef enum UNumberFormatAttribute {
+    UNUM_PARSE_INT_ONLY,
+    UNUM_GROUPING_USED,
+    UNUM_DECIMAL_ALWAYS_SHOWN,
+    UNUM_MAX_INTEGER_DIGITS,
+    UNUM_MIN_INTEGER_DIGITS,
+    UNUM_INTEGER_DIGITS,
+    UNUM_MAX_FRACTION_DIGITS,
+    UNUM_MIN_FRACTION_DIGITS,
+    UNUM_FRACTION_DIGITS,
+    UNUM_MULTIPLIER,
+    UNUM_GROUPING_SIZE,
+    UNUM_ROUNDING_MODE,
+    UNUM_ROUNDING_INCREMENT,
+    UNUM_FORMAT_WIDTH,
+    UNUM_PADDING_POSITION,
+    UNUM_SECONDARY_GROUPING_SIZE,
+    UNUM_SIGNIFICANT_DIGITS_USED,
+    UNUM_MIN_SIGNIFICANT_DIGITS,
+    UNUM_MAX_SIGNIFICANT_DIGITS,
+    UNUM_LENIENT_PARSE,
+    UNUM_SCALE = 21,
+    UNUM_CURRENCY_USAGE = 23,
+    UNUM_MAX_NONBOOLEAN_ATTRIBUTE = 0x0FFF,
+    UNUM_FORMAT_FAIL_IF_MORE_THAN_MAX_DIGITS = 0x1000,
+    UNUM_PARSE_NO_EXPONENT,
+    UNUM_PARSE_DECIMAL_MARK_REQUIRED = 0x1002,
+    UNUM_LIMIT_BOOLEAN_ATTRIBUTE = 0x1003
+} UNumberFormatAttribute;
+
+typedef enum UNumberFormatStyle {
+    UNUM_PATTERN_DECIMAL = 0,
+    UNUM_DECIMAL = 1,
+    UNUM_CURRENCY = 2,
+    UNUM_PERCENT = 3,
+    UNUM_SCIENTIFIC = 4,
+    UNUM_SPELLOUT = 5,
+    UNUM_ORDINAL = 6,
+    UNUM_DURATION = 7,
+    UNUM_NUMBERING_SYSTEM = 8,
+    UNUM_PATTERN_RULEBASED = 9,
+    UNUM_CURRENCY_ISO = 10,
+    UNUM_CURRENCY_PLURAL = 11,
+    UNUM_CURRENCY_ACCOUNTING = 12,
+    UNUM_CASH_CURRENCY = 13,
+    UNUM_DECIMAL_COMPACT_SHORT = 14,
+    UNUM_DECIMAL_COMPACT_LONG = 15,
+    UNUM_CURRENCY_STANDARD = 16,
+    UNUM_DEFAULT = UNUM_DECIMAL,
+    UNUM_IGNORE = UNUM_PATTERN_DECIMAL
+} UNumberFormatStyle;
+
+typedef enum UScriptCode {
+    USCRIPT_UNKNOWN                       = 103,
+} UScriptCode;
+
+typedef enum UColReorderCode {
+    UCOL_REORDER_CODE_DEFAULT = -1,
+    UCOL_REORDER_CODE_NONE = USCRIPT_UNKNOWN,
+    UCOL_REORDER_CODE_OTHERS = USCRIPT_UNKNOWN,
+    UCOL_REORDER_CODE_SPACE = 0x1000,
+    UCOL_REORDER_CODE_FIRST = UCOL_REORDER_CODE_SPACE,
+    UCOL_REORDER_CODE_PUNCTUATION = 0x1001,
+    UCOL_REORDER_CODE_SYMBOL = 0x1002,
+    UCOL_REORDER_CODE_CURRENCY = 0x1003,
+    UCOL_REORDER_CODE_DIGIT = 0x1004,
+} UColReorderCode;
+
+typedef enum UDateFormatStyle {
+    UDAT_FULL,
+    UDAT_LONG,
+    UDAT_MEDIUM,
+    UDAT_SHORT,
+    UDAT_DEFAULT = UDAT_MEDIUM,
+    UDAT_RELATIVE = (1 << 7),
+    UDAT_FULL_RELATIVE = UDAT_FULL | UDAT_RELATIVE,
+    UDAT_LONG_RELATIVE = UDAT_LONG | UDAT_RELATIVE,
+    UDAT_MEDIUM_RELATIVE = UDAT_MEDIUM | UDAT_RELATIVE,
+    UDAT_SHORT_RELATIVE = UDAT_SHORT | UDAT_RELATIVE,
+    UDAT_NONE = -1,
+    UDAT_PATTERN = -2,
+} UDateFormatStyle;
+
+typedef enum UDateFormatSymbolType {
+    UDAT_ERAS,
+    UDAT_MONTHS,
+    UDAT_SHORT_MONTHS,
+    UDAT_WEEKDAYS,
+    UDAT_SHORT_WEEKDAYS,
+    UDAT_AM_PMS,
+    UDAT_LOCALIZED_CHARS,
+    UDAT_ERA_NAMES,
+    UDAT_NARROW_MONTHS,
+    UDAT_NARROW_WEEKDAYS,
+    UDAT_STANDALONE_MONTHS,
+    UDAT_STANDALONE_SHORT_MONTHS,
+    UDAT_STANDALONE_NARROW_MONTHS,
+    UDAT_STANDALONE_WEEKDAYS,
+    UDAT_STANDALONE_SHORT_WEEKDAYS,
+    UDAT_STANDALONE_NARROW_WEEKDAYS,
+    UDAT_QUARTERS,
+    UDAT_SHORT_QUARTERS,
+    UDAT_STANDALONE_QUARTERS,
+    UDAT_STANDALONE_SHORT_QUARTERS,
+    UDAT_SHORTER_WEEKDAYS,
+    UDAT_STANDALONE_SHORTER_WEEKDAYS,
+    UDAT_CYCLIC_YEARS_WIDE,
+    UDAT_CYCLIC_YEARS_ABBREVIATED,
+    UDAT_CYCLIC_YEARS_NARROW,
+    UDAT_ZODIAC_NAMES_WIDE,
+    UDAT_ZODIAC_NAMES_ABBREVIATED,
+    UDAT_ZODIAC_NAMES_NARROW
+} UDateFormatSymbolType;
+
+typedef enum UCurrNameStyle {
+    UCURR_SYMBOL_NAME,
+    UCURR_LONG_NAME
+} UCurrNameStyle;
+
+typedef enum UCalendarType {
+    UCAL_TRADITIONAL,
+    UCAL_DEFAULT = UCAL_TRADITIONAL,
+    UCAL_GREGORIAN
+} UCalendarType;
+
+typedef enum UCollationResult {
+    UCOL_EQUAL = 0,
+    UCOL_GREATER = 1,
+    UCOL_LESS = -1
+} UCollationResult;
+
+enum {
+    UIDNA_ERROR_EMPTY_LABEL = 1,
+    UIDNA_ERROR_LABEL_TOO_LONG = 2,
+    UIDNA_ERROR_DOMAIN_NAME_TOO_LONG = 4,
+    UIDNA_ERROR_LEADING_HYPHEN = 8,
+    UIDNA_ERROR_TRAILING_HYPHEN = 0x10,
+    UIDNA_ERROR_HYPHEN_3_4 = 0x20,
+    UIDNA_ERROR_LEADING_COMBINING_MARK = 0x40,
+    UIDNA_ERROR_DISALLOWED = 0x80,
+    UIDNA_ERROR_PUNYCODE = 0x100,
+    UIDNA_ERROR_LABEL_HAS_DOT = 0x200,
+    UIDNA_ERROR_INVALID_ACE_LABEL = 0x400,
+    UIDNA_ERROR_BIDI = 0x800,
+    UIDNA_ERROR_CONTEXTJ = 0x1000,
+    UIDNA_ERROR_CONTEXTO_PUNCTUATION = 0x2000,
+    UIDNA_ERROR_CONTEXTO_DIGITS = 0x4000
+};
+
+enum {
+    UIDNA_DEFAULT = 0,
+    UIDNA_ALLOW_UNASSIGNED = 1,
+    UIDNA_USE_STD3_RULES = 2,
+    UIDNA_CHECK_BIDI = 4,
+    UIDNA_CHECK_CONTEXTJ = 8,
+    UIDNA_NONTRANSITIONAL_TO_ASCII = 0x10,
+    UIDNA_NONTRANSITIONAL_TO_UNICODE = 0x20,
+    UIDNA_CHECK_CONTEXTO = 0x40
+};
+
+enum {
+    U_PARSE_CONTEXT_LEN = 16
+};
+
+typedef struct UParseError {
+    int32_t line;
+    int32_t offset;
+    UChar preContext[U_PARSE_CONTEXT_LEN];
+    UChar postContext[U_PARSE_CONTEXT_LEN];
+
+} UParseError;
+
+typedef struct UIDNAInfo {
+    int16_t size;
+    UBool isTransitionalDifferent;
+    UBool reservedB3;
+    uint32_t errors;
+    int32_t reservedI2;
+    int32_t reservedI3;
+} UIDNAInfo;
+
+
+
+void u_charsToUChars(const char * cs, UChar * us, int32_t length);
+void u_getVersion(UVersionInfo versionArray);
+int32_t u_strlen(const UChar * s);
+UChar * u_strncpy(UChar * dst, const UChar * src, int32_t n);
+UChar32 u_tolower(UChar32 c);
+UChar32 u_toupper(UChar32 c);
+void ucal_add(UCalendar * cal, UCalendarDateFields field, int32_t amount, UErrorCode * status);
+void ucal_close(UCalendar * cal);
+int32_t ucal_get(const UCalendar * cal, UCalendarDateFields field, UErrorCode * status);
+int32_t ucal_getAttribute(const UCalendar * cal, UCalendarAttribute attr);
+UEnumeration * ucal_getKeywordValuesForLocale(const char * key, const char * locale, UBool commonlyUsed, UErrorCode * status);
+int32_t ucal_getLimit(const UCalendar * cal, UCalendarDateFields field, UCalendarLimitType type, UErrorCode * status);
+int32_t ucal_getTimeZoneDisplayName(const UCalendar * cal, UCalendarDisplayNameType type, const char * locale, UChar * result, int32_t resultLength, UErrorCode * status);
+UCalendar * ucal_open(const UChar * zoneID, int32_t len, const char * locale, UCalendarType type, UErrorCode * status);
+void ucal_set(UCalendar * cal, UCalendarDateFields field, int32_t value);
+void ucol_close(UCollator * coll);
+void ucol_closeElements(UCollationElements * elems);
+const UChar * ucol_getRules(const UCollator * coll, int32_t * length);
+int32_t ucol_getSortKey(const UCollator * coll, const UChar * source, int32_t sourceLength, uint8_t * result, int32_t resultLength);
+UCollationStrength ucol_getStrength(const UCollator * coll);
+void ucol_getVersion(const UCollator * coll, UVersionInfo info);
+int32_t ucol_next(UCollationElements * elems, UErrorCode * status);
+int32_t ucol_previous(UCollationElements * elems, UErrorCode * status);
+UCollator * ucol_open(const char * loc, UErrorCode * status);
+UCollationElements * ucol_openElements(const UCollator * coll, const UChar * text, int32_t textLength, UErrorCode * status);
+UCollator * ucol_openRules(const UChar * rules, int32_t rulesLength, UColAttributeValue normalizationMode, UCollationStrength strength, UParseError * parseError, UErrorCode * status);
+UCollator * ucol_safeClone(const UCollator * coll, void * stackBuffer, int32_t * pBufferSize, UErrorCode * status);
+void ucol_setAttribute(UCollator * coll, UColAttribute attr, UColAttributeValue value, UErrorCode * status);
+UCollationResult ucol_strcoll(const UCollator * coll, const UChar * source, int32_t sourceLength, const UChar * target, int32_t targetLength);
+int32_t ucurr_forLocale(const char * locale, UChar * buff, int32_t buffCapacity, UErrorCode * ec);
+const UChar * ucurr_getName(const UChar * currency, const char * locale, UCurrNameStyle nameStyle, UBool * isChoiceFormat, int32_t * len, UErrorCode * ec);
+void udat_close(UDateFormat * format);
+int32_t udat_countSymbols(const UDateFormat * fmt, UDateFormatSymbolType type);
+int32_t udat_getSymbols(const UDateFormat * fmt, UDateFormatSymbolType type, int32_t symbolIndex, UChar * result, int32_t resultLength, UErrorCode * status);
+UDateFormat * udat_open(UDateFormatStyle timeStyle, UDateFormatStyle dateStyle, const char * locale, const UChar * tzID, int32_t tzIDLength, const UChar * pattern, int32_t patternLength, UErrorCode * status);
+void udat_setCalendar(UDateFormat * fmt, const UCalendar * calendarToSet);
+int32_t udat_toPattern(const UDateFormat * fmt, UBool localized, UChar * result, int32_t resultLength, UErrorCode * status);
+void udatpg_close(UDateTimePatternGenerator * dtpg);
+int32_t udatpg_getBestPattern(UDateTimePatternGenerator * dtpg, const UChar * skeleton, int32_t length, UChar * bestPattern, int32_t capacity, UErrorCode * pErrorCode);
+UDateTimePatternGenerator * udatpg_open(const char * locale, UErrorCode * pErrorCode);
+void uenum_close(UEnumeration * en);
+int32_t uenum_count(UEnumeration * en, UErrorCode * status);
+const char * uenum_next(UEnumeration * en, int32_t * resultLength, UErrorCode * status);
+void uidna_close(UIDNA * idna);
+int32_t uidna_nameToASCII(const UIDNA * idna, const UChar * name, int32_t length, UChar * dest, int32_t capacity, UIDNAInfo * pInfo, UErrorCode * pErrorCode);
+int32_t uidna_nameToUnicode(const UIDNA * idna, const UChar * name, int32_t length, UChar * dest, int32_t capacity, UIDNAInfo * pInfo, UErrorCode * pErrorCode);
+UIDNA * uidna_openUTS46(uint32_t options, UErrorCode * pErrorCode);
+void uldn_close(ULocaleDisplayNames * ldn);
+int32_t uldn_keyValueDisplayName(const ULocaleDisplayNames * ldn, const char * key, const char * value, UChar * result, int32_t maxResultSize, UErrorCode * pErrorCode);
+ULocaleDisplayNames * uldn_open(const char * locale, UDialectHandling dialectHandling, UErrorCode * pErrorCode);
+int32_t uloc_canonicalize(const char * localeID, char * name, int32_t nameCapacity, UErrorCode * err);
+int32_t uloc_countAvailable(void);
+const char * uloc_getAvailable(int32_t n);
+int32_t uloc_getBaseName(const char * localeID, char * name, int32_t nameCapacity, UErrorCode * err);
+ULayoutType uloc_getCharacterOrientation(const char * localeId, UErrorCode * status);
+int32_t uloc_getCountry(const char * localeID, char * country, int32_t countryCapacity, UErrorCode * err);
+const char * uloc_getDefault(void);
+int32_t uloc_getDisplayCountry(const char * locale, const char * displayLocale, UChar * country, int32_t countryCapacity, UErrorCode * status);
+int32_t uloc_getDisplayLanguage(const char * locale, const char * displayLocale, UChar * language, int32_t languageCapacity, UErrorCode * status);
+int32_t uloc_getDisplayName(const char * localeID, const char * inLocaleID, UChar * result, int32_t maxResultSize, UErrorCode * err);
+const char * uloc_getISO3Country(const char * localeID);
+const char * uloc_getISO3Language(const char * localeID);
+int32_t uloc_getKeywordValue(const char * localeID, const char * keywordName, char * buffer, int32_t bufferCapacity, UErrorCode * status);
+int32_t uloc_getLanguage(const char * localeID, char * language, int32_t languageCapacity, UErrorCode * err);
+uint32_t uloc_getLCID(const char * localeID);
+int32_t uloc_getName(const char * localeID, char * name, int32_t nameCapacity, UErrorCode * err);
+int32_t uloc_getParent(const char * localeID, char * parent, int32_t parentCapacity, UErrorCode * err);
+int32_t uloc_setKeywordValue(const char * keywordName, const char * keywordValue, char * buffer, int32_t bufferCapacity, UErrorCode * status);
+UMeasurementSystem ulocdata_getMeasurementSystem(const char * localeID, UErrorCode * status);
+const UNormalizer2 * unorm2_getNFCInstance(UErrorCode * pErrorCode);
+const UNormalizer2 * unorm2_getNFDInstance(UErrorCode * pErrorCode);
+const UNormalizer2 * unorm2_getNFKCInstance(UErrorCode * pErrorCode);
+const UNormalizer2 * unorm2_getNFKDInstance(UErrorCode * pErrorCode);
+UBool unorm2_isNormalized(const UNormalizer2 * norm2, const UChar * s, int32_t length, UErrorCode * pErrorCode);
+int32_t unorm2_normalize(const UNormalizer2 * norm2, const UChar * src, int32_t length, UChar * dest, int32_t capacity, UErrorCode * pErrorCode);
+void unum_close(UNumberFormat * fmt);
+int32_t unum_getAttribute(const UNumberFormat * fmt, UNumberFormatAttribute attr);
+int32_t unum_getSymbol(const UNumberFormat * fmt, UNumberFormatSymbol symbol, UChar * buffer, int32_t size, UErrorCode * status);
+UNumberFormat * unum_open(UNumberFormatStyle style, const UChar * pattern, int32_t patternLength, const char * locale, UParseError * parseErr, UErrorCode * status);
+int32_t unum_toPattern(const UNumberFormat * fmt, UBool isPatternLocalized, UChar * result, int32_t resultLength, UErrorCode * status);
+void ures_close(UResourceBundle * resourceBundle);
+UResourceBundle * ures_getByKey(const UResourceBundle * resourceBundle, const char * key, UResourceBundle * fillIn, UErrorCode * status);
+int32_t ures_getSize(const UResourceBundle * resourceBundle);
+const UChar * ures_getStringByIndex(const UResourceBundle * resourceBundle, int32_t indexS, int32_t * len, UErrorCode * status);
+UResourceBundle * ures_open(const char * packageName, const char * locale, UErrorCode * status);
+void usearch_close(UStringSearch * searchiter);
+int32_t usearch_first(UStringSearch * strsrch, UErrorCode * status);
+int32_t usearch_getMatchedLength(const UStringSearch * strsrch);
+int32_t usearch_last(UStringSearch * strsrch, UErrorCode * status);
+UStringSearch * usearch_openFromCollator(const UChar * pattern, int32_t patternlength, const UChar * text, int32_t textlength, const UCollator * collator, UBreakIterator * breakiter, UErrorCode * status);
+void ucol_setMaxVariable(UCollator * coll, UColReorderCode group, UErrorCode * pErrorCode);
index b01e521..aea1624 100644 (file)
@@ -2,6 +2,9 @@ project(System.IO.Compression.Native C)
 
 if (CLR_CMAKE_TARGET_WASM)
     add_definitions(-s USE_ZLIB)
+elseif (CLR_CMAKE_TARGET_ANDROID)
+    # need special case here since we want to link against libz.so but find_package() would resolve libz.a
+    set(ZLIB_LIBRARIES z)
 else ()
     find_package(ZLIB REQUIRED)
 endif ()
index 00ca624..9841a1b 100644 (file)
@@ -34,7 +34,7 @@ int32_t SystemNative_GetWindowSize(WinSize* windowSize)
 
     return error;
 #else
-    (void)windowSize; // unused
+    memset(windowSize, 0, sizeof(WinSize)); // managed out param must be initialized
     errno = ENOTSUP;
     return -1;
 #endif
index 4d090d3..a182578 100644 (file)
@@ -48,6 +48,7 @@
 #endif
 #endif
 
+#if HAVE_GETIFADDRS
 // Convert mask to prefix length e.g. 255.255.255.0 -> 24
 // mask parameter is pointer to buffer where address starts and length is
 // buffer length e.g. 4 for IPv4 and 16 for IPv6.
@@ -87,11 +88,13 @@ static inline uint8_t mask2prefix(uint8_t* mask, int length)
 
     return len;
 }
+#endif
 
 int32_t SystemNative_EnumerateInterfaceAddresses(IPv4AddressFound onIpv4Found,
                                                IPv6AddressFound onIpv6Found,
                                                LinkLayerAddressFound onLinkLayerFound)
 {
+#if HAVE_GETIFADDRS
     struct ifaddrs* headAddr;
     if (getifaddrs(&headAddr) == -1)
     {
@@ -203,10 +206,19 @@ int32_t SystemNative_EnumerateInterfaceAddresses(IPv4AddressFound onIpv4Found,
 
     freeifaddrs(headAddr);
     return 0;
+#else
+    // Not supported on e.g. Android. Also, prevent a compiler error because parameters are unused
+    (void)onIpv4Found;
+    (void)onIpv6Found;
+    (void)onLinkLayerFound;
+    errno = ENOTSUP;
+    return -1;
+#endif
 }
 
 int32_t SystemNative_GetNetworkInterfaces(int32_t * interfaceCount, NetworkInterfaceInfo **interfaceList, int32_t * addressCount, IpAddressInfo **addressList )
 {
+#if HAVE_GETIFADDRS
     struct ifaddrs* head;   // Pointer to block allocated by getifaddrs().
     struct ifaddrs* ifaddrsEntry;
     IpAddressInfo *ai;
@@ -408,6 +420,15 @@ int32_t SystemNative_GetNetworkInterfaces(int32_t * interfaceCount, NetworkInter
     }
 
     return 0;
+#else
+    // Not supported on e.g. Android. Also, prevent a compiler error because parameters are unused
+    (void)interfaceCount;
+    (void)interfaceList;
+    (void)addressCount;
+    (void)addressList;
+    errno = ENOTSUP;
+    return -1;
+#endif
 }
 
 #if HAVE_RT_MSGHDR
index f036fe9..7faa21b 100644 (file)
@@ -531,7 +531,7 @@ int32_t SystemNative_GetDomainName(uint8_t* name, int32_t nameLength)
     // On Android, there's no getdomainname but we can use uname to fetch the domain name
     // of the current device
     size_t namelen = (uint32_t)nameLength;
-    utsname  uts;
+    struct utsname  uts;
 
     // If uname returns an error, bail out.
     if (uname(&uts) == -1)
@@ -547,7 +547,7 @@ int32_t SystemNative_GetDomainName(uint8_t* name, int32_t nameLength)
     }
 
     // Copy the domain name
-    SafeStringCopy((char*)name, nameLength, uts.domainname);
+    SafeStringCopy((char*)name, namelen, uts.domainname);
     return 0;
 #else
     // GetDomainName is not supported on this platform.
index 641ac12..d05eb93 100644 (file)
@@ -230,7 +230,7 @@ int32_t SystemNative_ForkAndExecProcess(const char* filename,
     sigset_t signal_set;
     sigset_t old_signal_set;
 
-#ifndef HAVE_PTHREAD_SETCANCELSTATE
+#if HAVE_PTHREAD_SETCANCELSTATE
     int thread_cancel_state;
 
     // None of this code can be canceled without leaking handles, so just don't allow it
@@ -382,7 +382,7 @@ int32_t SystemNative_ForkAndExecProcess(const char* filename,
             }
             if (!sigaction(sig, NULL, &sa_old))
             {
-                void (*oldhandler)(int) = (sa_old.sa_flags & SA_SIGINFO) ? (void (*)(int))sa_old.sa_sigaction : sa_old.sa_handler;
+                void (*oldhandler)(int) = (((unsigned int)sa_old.sa_flags) & SA_SIGINFO) ? (void (*)(int))sa_old.sa_sigaction : sa_old.sa_handler;
                 if (oldhandler != SIG_IGN && oldhandler != SIG_DFL)
                 {
                     // It has a custom handler, put the default handler back.
@@ -501,7 +501,7 @@ done:;
         errno = priorErrno;
     }
 
-#ifndef HAVE_PTHREAD_SETCANCELSTATE
+#if HAVE_PTHREAD_SETCANCELSTATE
     // Restore thread cancel state
     pthread_setcancelstate(thread_cancel_state, &thread_cancel_state);
 #endif
index 30b76c0..bba87eb 100644 (file)
@@ -6,9 +6,11 @@ include(CheckPrototypeDefinition)
 include(CheckStructHasMember)
 include(CheckSymbolExists)
 include(CheckTypeSize)
-include(CheckFunctionExists)
 
-if (CLR_CMAKE_TARGET_LINUX)
+
+if (CLR_CMAKE_TARGET_ANDROID)
+    set(PAL_UNIX_NAME \"ANDROID\")
+elseif (CLR_CMAKE_TARGET_LINUX)
     set(PAL_UNIX_NAME \"LINUX\")
 elseif (CLR_CMAKE_TARGET_OSX)
     set(PAL_UNIX_NAME \"OSX\")
@@ -179,6 +181,11 @@ check_symbol_exists(
     HAVE_SCHED_SETAFFINITY)
 
 check_symbol_exists(
+    pthread_setcancelstate
+    "pthread.h"
+    HAVE_PTHREAD_SETCANCELSTATE)
+
+check_symbol_exists(
     arc4random_buf
     "stdlib.h"
     HAVE_ARC4RANDOM_BUF)
@@ -450,6 +457,11 @@ if(CLR_CMAKE_TARGET_IOS)
     unset(HAVE_SHM_OPEN_THAT_WORKS_WELL_ENOUGH_WITH_MMAP)
     unset(HAVE_CLOCK_MONOTONIC) # only exists on iOS 10+
     unset(HAVE_CLOCK_REALTIME)  # only exists on iOS 10+
+elseif(CLR_CMAKE_TARGET_ANDROID)
+    # Manually set results from check_c_source_runs() since it's not possible to actually run it during CMake configure checking
+    unset(HAVE_SHM_OPEN_THAT_WORKS_WELL_ENOUGH_WITH_MMAP)
+    set(HAVE_CLOCK_MONOTONIC 1)
+    set(HAVE_CLOCK_REALTIME 1)
 else()
     check_c_source_runs(
         "
@@ -900,8 +912,6 @@ check_c_source_compiles(
     "
     HAVE_BUILTIN_MUL_OVERFLOW)
 
-check_function_exists(pthread_setcancelstate HAVE_PTHREAD_SETCANCELSTATE)
-
 configure_file(
     ${CMAKE_CURRENT_SOURCE_DIR}/Common/pal_config.h.in
     ${CMAKE_CURRENT_BINARY_DIR}/Common/pal_config.h)
index 4c7d440..ec5fea0 100755 (executable)
@@ -56,6 +56,9 @@ if [[ "$__BuildArch" == wasm ]]; then
 elif [[ "$__TargetOS" == iOS ]]; then
     # nothing to do here
     true
+elif [[ "$__TargetOS" == Android && -z "$ROOTFS_DIR" ]]; then
+    # nothing to do here
+    true
 else
     __CMakeArgs="-DFEATURE_DISTRO_AGNOSTIC_SSL=$__PortableBuild $__CMakeArgs"
     __CMakeArgs="-DCMAKE_STATIC_LIB_LINK=$__StaticLibLink $__CMakeArgs"
@@ -69,6 +72,27 @@ fi
 if [[ "$__TargetOS" == OSX ]]; then
     # set default OSX deployment target
     __CMakeArgs="-DCMAKE_OSX_DEPLOYMENT_TARGET=10.13 $__CMakeArgs"
+elif [[ "$__TargetOS" == Android && -z "$ROOTFS_DIR" ]]; then
+    if [[ -z "$ANDROID_NDK_HOME" ]]; then
+        echo "Error: You need to set the ANDROID_NDK_HOME environment variable pointing to the Android NDK root."
+        exit 1
+    fi
+
+    # keep ANDROID_NATIVE_API_LEVEL in sync with src/mono/Directory.Build.props
+    __CMakeArgs="-DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK_HOME/build/cmake/android.toolchain.cmake -DANDROID_STL=none -DANDROID_NATIVE_API_LEVEL=21 $__CMakeArgs"
+
+    if [[ "$__BuildArch" == x64 ]]; then
+        __CMakeArgs="-DANDROID_ABI=x86_64 $__CMakeArgs"
+    elif [[ "$__BuildArch" == x86 ]]; then
+        __CMakeArgs="-DANDROID_ABI=x86 $__CMakeArgs"
+    elif [[ "$__BuildArch" == arm64 ]]; then
+        __CMakeArgs="-DANDROID_ABI=arm64-v8a $__CMakeArgs"
+    elif [[ "$__BuildArch" == arm ]]; then
+        __CMakeArgs="-DANDROID_ABI=armeabi-v7a $__CMakeArgs"
+    else
+        echo "Error: Unknown Android architecture $__BuildArch."
+        exit 1
+    fi
 elif [[ "$__TargetOS" == iOS ]]; then
     __CMakeArgs="-DCMAKE_SYSTEM_NAME=iOS $__CMakeArgs"
     if [[ "$__BuildArch" == x64 ]]; then
index 7d8e9fc..31cccf1 100644 (file)
         "Unix"
         ]
       },
+    "Android": {
+      "#import": [
+        "Linux"
+        ]
+      },
     "FreeBSD": {
       "#import": [
         "Unix"
diff --git a/src/libraries/System.Security.Cryptography.Algorithms/src/Internal/Cryptography/HashProviderDispenser.Android.cs b/src/libraries/System.Security.Cryptography.Algorithms/src/Internal/Cryptography/HashProviderDispenser.Android.cs
new file mode 100644 (file)
index 0000000..55e60eb
--- /dev/null
@@ -0,0 +1,83 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+using System.Diagnostics;
+using System.Runtime.InteropServices;
+using System.Security.Cryptography;
+using Microsoft.Win32.SafeHandles;
+
+namespace Internal.Cryptography
+{
+    internal static partial class HashProviderDispenser
+    {
+        public static HashProvider CreateHashProvider(string hashAlgorithmId)
+        {
+            switch (hashAlgorithmId)
+            {
+                case HashAlgorithmNames.SHA1:
+                    return new NotImplementedHashProvider();
+                case HashAlgorithmNames.SHA256:
+                    return new NotImplementedHashProvider();
+                case HashAlgorithmNames.SHA384:
+                    return new NotImplementedHashProvider();
+                case HashAlgorithmNames.SHA512:
+                    return new NotImplementedHashProvider();
+                case HashAlgorithmNames.MD5:
+                    return new NotImplementedHashProvider();
+            }
+            throw new CryptographicException(SR.Format(SR.Cryptography_UnknownHashAlgorithm, hashAlgorithmId));
+        }
+
+        public static unsafe HashProvider CreateMacProvider(string hashAlgorithmId, ReadOnlySpan<byte> key)
+        {
+            switch (hashAlgorithmId)
+            {
+                case HashAlgorithmNames.SHA1:
+                    return new NotImplementedHashProvider();
+                case HashAlgorithmNames.SHA256:
+                    return new NotImplementedHashProvider();
+                case HashAlgorithmNames.SHA384:
+                    return new NotImplementedHashProvider();
+                case HashAlgorithmNames.SHA512:
+                    return new NotImplementedHashProvider();
+                case HashAlgorithmNames.MD5:
+                    return new NotImplementedHashProvider();
+            }
+            throw new CryptographicException(SR.Format(SR.Cryptography_UnknownHashAlgorithm, hashAlgorithmId));
+        }
+
+        // -----------------------------
+        // ---- PAL layer ends here ----
+        // -----------------------------
+
+        private sealed class NotImplementedHashProvider : HashProvider
+        {
+            public NotImplementedHashProvider()
+            {
+            }
+
+            public override void AppendHashData(ReadOnlySpan<byte> data)
+            {
+                throw new NotImplementedException();
+            }
+
+            public override byte[] FinalizeHashAndReset()
+            {
+                throw new NotImplementedException();
+            }
+
+            public override bool TryFinalizeHashAndReset(Span<byte> destination, out int bytesWritten)
+            {
+                throw new NotImplementedException();
+            }
+
+            public override int HashSizeInBytes => throw new NotImplementedException();
+
+            public override void Dispose(bool disposing)
+            {
+            }
+        }
+    }
+}
index bc99913..680eedd 100644 (file)
@@ -3,7 +3,7 @@
     <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
     <DefineConstants>$(DefineConstants);INTERNAL_ASYMMETRIC_IMPLEMENTATIONS</DefineConstants>
     <NoWarn>CS1573;CS3016;CA5350;CA5351;CA5379;CA5384;CA5385;$(NoWarn)</NoWarn>
-    <TargetFrameworks>$(NetCoreAppCurrent)-Windows_NT;$(NetCoreAppCurrent)-Unix;$(NetCoreAppCurrent)-OSX;$(NetCoreAppCurrent)-iOS</TargetFrameworks>
+    <TargetFrameworks>$(NetCoreAppCurrent)-Windows_NT;$(NetCoreAppCurrent)-Unix;$(NetCoreAppCurrent)-Android;$(NetCoreAppCurrent)-OSX;$(NetCoreAppCurrent)-iOS</TargetFrameworks>
     <Nullable>enable</Nullable>
   </PropertyGroup>
   <Import Project="$(CommonPath)System\Security\Cryptography\Asn1\AsnXml.targets" />
     </Compile>
     <Compile Include="Internal\Cryptography\AesImplementation.Unix.cs" />
     <Compile Include="Internal\Cryptography\DesImplementation.Unix.cs" />
-    <Compile Include="Internal\Cryptography\HashProviderDispenser.Unix.cs" />
+    <Compile Condition="'$(TargetsAndroid)' != 'true'" Include="Internal\Cryptography\HashProviderDispenser.Unix.cs" />
+    <Compile Condition="'$(TargetsAndroid)' == 'true'" Include="Internal\Cryptography\HashProviderDispenser.Android.cs" />
     <Compile Include="Internal\Cryptography\OpenSslCipher.cs" />
     <Compile Include="Internal\Cryptography\RandomNumberGeneratorImplementation.Unix.cs" />
     <Compile Include="Internal\Cryptography\RC2Implementation.Unix.cs" />
index 88b9952..4271b7e 100644 (file)
@@ -1,8 +1,8 @@
 <Project Sdk="Microsoft.NET.Sdk">
   <PropertyGroup>
     <RuntimeIdentifier>$(PackageRID)</RuntimeIdentifier>
-    <!-- We're using ToolRuntimeRID as a placeholder for the real corelib/runtime components until we have an actual set of runtime bits to consume for webassembly/ios. -->
-    <RuntimeIdentifier Condition="'$(RuntimeOS)' == 'webassembly' or '$(RuntimeOS)' == 'ios'">$(ToolRuntimeRID)</RuntimeIdentifier>
+    <!-- We're using ToolRuntimeRID as a placeholder for the real corelib/runtime components until we have an actual set of runtime bits to consume for webassembly/ios/android. -->
+    <RuntimeIdentifier Condition="'$(RuntimeOS)' == 'webassembly' or '$(RuntimeOS)' == 'ios' or '$(RuntimeOS)' == 'android'">$(ToolRuntimeRID)</RuntimeIdentifier>
     <NoWarn>$(NoWarn);NU1603;NU1605</NoWarn>
     <SwapNativeForIL Condition="'$(SwapNativeForIL)' == '' and ('$(Configuration)' == 'Debug' or '$(Coverage)' == 'true') and '$(RuntimeFlavor)' != 'Mono'">true</SwapNativeForIL>
     <CoreCLRTargetOS Condition="'$(CoreCLRTargetOS)' == ''">$(TargetOS)</CoreCLRTargetOS>
index bfb1333..ee344cc 100644 (file)
   <!-- Set up common target properties that we use to conditionally include sources -->
   <PropertyGroup>
     <TargetsFreeBSD Condition="'$(TargetOS)' == 'FreeBSD'">true</TargetsFreeBSD>
-    <TargetsLinux Condition="'$(TargetOS)' == 'Linux'">true</TargetsLinux>
+    <TargetsLinux Condition="'$(TargetOS)' == 'Linux' or '$(TargetOS)' == 'Android'">true</TargetsLinux>
     <TargetsNetBSD Condition="'$(TargetOS)' == 'NetBSD'">true</TargetsNetBSD>
     <TargetsOSX Condition="'$(TargetOS)' == 'OSX'">true</TargetsOSX>
     <TargetsiOS Condition="'$(TargetOS)' == 'iOS'">true</TargetsiOS>
     <TargetsiOSSimulator Condition="'$(TargetsiOS)' == 'true' and '$(Platform)' == 'x64'">true</TargetsiOSSimulator>
+    <TargetsAndroid Condition="'$(TargetOS)' == 'Android'">true</TargetsAndroid>
     <TargetsWindows Condition="'$(TargetOS)' == 'Windows_NT'">true</TargetsWindows>
-    <TargetsUnix Condition="'$(TargetsFreeBSD)' == 'true' or '$(TargetsLinux)' == 'true' or '$(TargetsNetBSD)' == 'true' or '$(TargetsOSX)' == 'true' or '$(TargetsiOS)' == 'true'">true</TargetsUnix>
+    <TargetsUnix Condition="'$(TargetsFreeBSD)' == 'true' or '$(TargetsLinux)' == 'true' or '$(TargetsNetBSD)' == 'true' or '$(TargetsOSX)' == 'true' or '$(TargetsiOS)' == 'true' or '$(TargetsAndroid)' == 'true'">true</TargetsUnix>
   </PropertyGroup>
 
   <PropertyGroup>
     <!-- Minimum target OS version, keep in sync with src/libraries/Native/build-native.sh -->
-    <iOSVersionMin Condition="'$(TargetOS)' == 'iOS' and '$(TargetsiOSSimulator)' != 'true'">7.0</iOSVersionMin>
-    <iOSVersionMin Condition="'$(TargetOS)' == 'iOS' and '$(TargetsiOSSimulator)' == 'true'">8.0</iOSVersionMin>
+    <iOSVersionMin Condition="'$(TargetsiOS)' == 'true' and '$(TargetsiOSSimulator)' != 'true'">7.0</iOSVersionMin>
+    <iOSVersionMin Condition="'$(TargetsiOS)' == 'true' and '$(TargetsiOSSimulator)' == 'true'">8.0</iOSVersionMin>
     <tvOSVersionMin>9.0</tvOSVersionMin>
     <watchOSVersionMin>2.0</watchOSVersionMin>
     <watchOS64_32VersionMin>5.1</watchOS64_32VersionMin>
@@ -58,6 +59,9 @@
     <watchOSVersion></watchOSVersion>
     <watchOS64_32Version></watchOS64_32Version>
     <macOSVersion></macOSVersion>
+
+    <!-- Version of the Android SDK we target, keep in sync with src/libraries/Native/build-native.sh -->
+    <AndroidApiVersion>21</AndroidApiVersion>
   </PropertyGroup>
 
   <!-- Set the kind of PDB to Portable -->
index 4736fca..bfc84a8 100644 (file)
@@ -19,7 +19,9 @@
     <CoreClrFileName Condition="'$(TargetsOSX)' == 'true'">libcoreclr.dylib</CoreClrFileName>
     <CoreClrFileName Condition="'$(CoreClrFileName)' == ''">libcoreclr.so</CoreClrFileName>
     <MonoFileName Condition="'$(TargetsiOS)' == 'true'">libmono.dylib</MonoFileName>
+    <MonoFileName Condition="'$(TargetsAndroid)' == 'true'">libmonosgen-2.0.so</MonoFileName>
     <MonoStaticFileName Condition="'$(TargetsiOS)' == 'true'">libmono.a</MonoStaticFileName>
+    <MonoStaticFileName Condition="'$(TargetsAndroid)' == 'true'">libmonosgen-2.0.a</MonoStaticFileName>
     <MonoFileName Condition="'$(MonoFileName)' == ''">$(CoreClrFileName)</MonoFileName>
     <CoreClrTestConfig Condition="'$(CoreClrTestConfig)' == ''">$(Configuration)</CoreClrTestConfig>
     <LibrariesTestConfig Condition="'$(LibrariesTestConfig)' == ''">$(Configuration)</LibrariesTestConfig>
     <XcodeDir Condition="'$(XcodeDir)' == ''">/Applications/Xcode.app/Contents/Developer</XcodeDir>
   </PropertyGroup>
 
-  <!-- OSX/iOS/Linux Mono runtime build -->
+  <!-- OSX/iOS/Android/Linux Mono runtime build -->
   <Target Name="ConfigureMonoRuntimeUnix" Condition="'$(OS)' != 'Windows_NT'" Inputs="$(MonoProjectRoot)configure.ac" Outputs="$(MonoObjDir)config.h">
 
     <!-- Sanity checks -->
-    <Error Condition="'$(TargetOS)' == 'iOS' and '$(Platform)' != 'x64' and '$(Platform)' != 'arm64' and '$(Platform)' != 'arm'" Text="Error: Invalid platform for $(TargetOS): $(Platform)." />
-    <Error Condition="'$(TargetOS)' == 'iOS' and !$([MSBuild]::IsOSPlatform('OSX'))" Text="Error: $(TargetOS) can only be built on macOS." />
+    <Error Condition="'$(TargetsiOS)' == 'true' and '$(Platform)' != 'x64' and '$(Platform)' != 'arm64' and '$(Platform)' != 'arm'" Text="Error: Invalid platform for $(TargetOS): $(Platform)." />
+    <Error Condition="'$(TargetsiOS)' == 'true' and !$([MSBuild]::IsOSPlatform('OSX'))" Text="Error: $(TargetOS) can only be built on macOS." />
+    <Error Condition="'$(TargetsAndroid)' == 'true' and '$(Platform)' != 'x64' and '$(Platform)' != 'x86' and '$(Platform)' != 'arm64' and '$(Platform)' != 'arm'" Text="Error: Invalid platform for $(TargetOS): $(Platform)." />
+    <Error Condition="'$(TargetsAndroid)' == 'true' and '$(ANDROID_NDK_HOME)' == ''" Text="Error: You need to set the ANDROID_NDK_HOME environment variable pointing to the Android NDK root." />
 
     <!-- Common options -->
     <ItemGroup>
@@ -42,7 +46,7 @@
       <_MonoConfigureParams Include="--enable-maintainer-mode" />
       <_MonoConfigureParams Include="--enable-compile-warnings" />
       <_MonoConfigureParams Include="--prefix=$(MonoObjDir)out" />
-      <_MonoConfigureParams Condition="'$(MonoEnableLLVM)' == 'true'" Include="--with-llvm=$(MonoLLVMDir)" /> <!-- TODO: integrate for iOS -->
+      <_MonoConfigureParams Condition="'$(MonoEnableLLVM)' == 'true'" Include="--with-llvm=$(MonoLLVMDir)" /> <!-- TODO: integrate for iOS/Android -->
       <_MonoConfigureParams Condition="'$(MonoEnableCXX)' == 'true'" Include="--enable-cxx" />
     </ItemGroup>
 
@@ -71,7 +75,7 @@
     </ItemGroup>
 
     <!-- iOS device specific options -->
-    <ItemGroup Condition="'$(TargetOS)' == 'iOS' and '$(TargetsiOSSimulator)' != 'true'">
+    <ItemGroup Condition="'$(TargetsiOS)' == 'true' and '$(TargetsiOSSimulator)' != 'true'">
       <_MonoConfigureParams Condition="'$(Platform)' == 'arm64'" Include="--host=aarch64-apple-darwin10" />
       <_MonoConfigureParams Condition="'$(Platform)' == 'arm'" Include="--host=arm-apple-darwin10" />
       <_MonoConfigureParams Include="--disable-boehm" />
     </ItemGroup>
 
     <!-- iOS simulator specific options -->
-    <ItemGroup Condition="'$(TargetOS)' == 'iOS' and '$(TargetsiOSSimulator)' == 'true'">
+    <ItemGroup Condition="'$(TargetsiOS)' == 'true' and '$(TargetsiOSSimulator)' == 'true'">
       <_MonoConfigureParams Include="--host=x86_64-apple-darwin10" />
       <_MonoConfigureParams Include="--disable-boehm" />
       <_MonoConfigureParams Include="--disable-btls" />
       <_MonoCPPFLAGS Include="-DHOST_IOS" />
     </ItemGroup>
 
+    <!-- Android specific options -->
+    <ItemGroup Condition="'$(TargetsAndroid)' == 'true'">
+      <_MonoConfigureParams Condition="'$(Platform)' == 'arm64'" Include="--host=aarch64-linux-android" />
+      <_MonoConfigureParams Condition="'$(Platform)' == 'arm'" Include="--host=armv5-linux-androideabi" />
+      <_MonoConfigureParams Condition="'$(Platform)' == 'x86'" Include="--host=i686-linux-android" />
+      <_MonoConfigureParams Condition="'$(Platform)' == 'x64'" Include="--host=x86_64-linux-android" />
+      <_MonoConfigureParams Include="--disable-boehm" />
+      <_MonoConfigureParams Include="--disable-executables" />
+      <_MonoConfigureParams Include="--disable-iconv" />
+      <_MonoConfigureParams Include="--disable-mcs-build" />
+      <_MonoConfigureParams Include="--disable-nls" />
+      <_MonoConfigureParams Include="--enable-maintainer-mode" />
+      <_MonoConfigureParams Include="--enable-minimal=ssa,portability,attach,verifier,full_messages,sgen_remset,sgen_marksweep_par,sgen_marksweep_fixed,sgen_marksweep_fixed_par,sgen_copying,logging,security,shared_handles,interpreter,,gac,cfgdir_config" />
+      <_MonoConfigureParams Include="--enable-monodroid" />
+      <_MonoConfigureParams Include="--enable-dynamic-btls" />
+      <_MonoConfigureParams Include="--with-btls-android-ndk=$(ANDROID_NDK_HOME)" />
+      <_MonoConfigureParams Include="--with-btls-android-api=$(AndroidApiVersion)" />
+      <_MonoConfigureParams Include="--with-btls-android-ndk-asm-workaround" />
+      <_MonoConfigureParams Include="--with-btls-android-cmake-toolchain=$(ANDROID_NDK_HOME)/build/cmake/android.toolchain.cmake" />
+      <_MonoConfigureParams Include="--with-sigaltstack=yes" />
+      <_MonoConfigureParams Include="--with-tls=pthread" />
+      <_MonoConfigureParams Include="--without-ikvm-native" />
+      <_MonoConfigureParams Include="--disable-cooperative-suspend" />
+      <_MonoConfigureParams Include="--disable-hybrid-suspend" />
+      <_MonoConfigureParams Include="--disable-crash-reporting" />
+
+      <_MonoAC_VARS Include="ac_cv_func_shm_open_working_with_mmap=no" />
+      <_MonoAC_VARS Include="ac_cv_func_sched_getaffinity=no" />
+      <_MonoAC_VARS Include="ac_cv_func_sched_setaffinity=no" />
+      <_MonoAC_VARS Include="mono_cv_uscore=yes" />
+
+      <_MonoCFLAGS Condition="'$(Platform)' == 'arm'" Include="-march=armv7-a" />
+      <_MonoCFLAGS Condition="'$(Platform)' == 'arm'" Include="-mtune=cortex-a8" />
+      <_MonoCFLAGS Condition="'$(Platform)' == 'arm'" Include="-mfpu=vfp" />
+      <_MonoCFLAGS Condition="'$(Platform)' == 'arm'" Include="-mfloat-abi=softfp" />
+      <_MonoCFLAGS Condition="'$(Platform)' == 'arm64' or '$(Platform)' == 'arm'" Include="-fpic" />
+      <_MonoCFLAGS Include="-fstack-protector" />
+
+      <_MonoCXXFLAGS Condition="'$(Platform)' == 'arm'" Include="-march=armv7-a" />
+      <_MonoCXXFLAGS Condition="'$(Platform)' == 'arm'" Include="-mtune=cortex-a8" />
+      <_MonoCXXFLAGS Condition="'$(Platform)' == 'arm'" Include="-mfpu=vfp" />
+      <_MonoCXXFLAGS Condition="'$(Platform)' == 'arm'" Include="-mfloat-abi=softfp" />
+      <_MonoCXXFLAGS Condition="'$(Platform)' == 'arm64' or '$(Platform)' == 'arm'" Include="-fpic" />
+      <_MonoCXXFLAGS Include="-fstack-protector" />
+
+      <_MonoCPPFLAGS Condition="'$(Platform)' == 'arm64'" Include="-DANDROID64" />
+      <_MonoCPPFLAGS Condition="'$(Platform)' == 'arm64'" Include="-I$(ANDROID_NDK_HOME)/sysroot/usr/include/aarch64-linux-android" />
+      <_MonoCPPFLAGS Condition="'$(Platform)' == 'arm'" Include="-I$(ANDROID_NDK_HOME)/sysroot/usr/include/arm-linux-androideabi" />
+      <_MonoCPPFLAGS Condition="'$(Platform)' == 'x64'" Include="-I$(ANDROID_NDK_HOME)/sysroot/usr/include/x86_64-linux-android" />
+      <_MonoCPPFLAGS Condition="'$(Platform)' == 'x86'" Include="-I$(ANDROID_NDK_HOME)/sysroot/usr/include/i686-linux-android" />
+      <_MonoCPPFLAGS Condition="'$(Platform)' == 'x64'" Include="-m64" />
+      <_MonoCPPFLAGS Condition="'$(Platform)' == 'x86'" Include="-m32" />
+      <_MonoCPPFLAGS Condition="'$(Platform)' == 'arm64' or '$(Platform)' == 'x64'" Include="-DL_cuserid=9" />
+      <_MonoCPPFLAGS Condition="'$(Platform)' == 'arm64' or '$(Platform)' == 'arm'" Include="-D__POSIX_VISIBLE=201002" />
+      <_MonoCPPFLAGS Condition="'$(Platform)' == 'arm64' or '$(Platform)' == 'arm'" Include="-DSK_RELEASE" />
+      <_MonoCPPFLAGS Condition="'$(Platform)' == 'arm64' or '$(Platform)' == 'arm'" Include="-DNDEBUG" />
+      <_MonoCPPFLAGS Condition="'$(Platform)' == 'arm64' or '$(Platform)' == 'arm'" Include="-UDEBUG" />
+      <_MonoCPPFLAGS Include="-I$(ANDROID_NDK_HOME)/sysroot/usr/include" />
+      <_MonoCPPFLAGS Include="-DMONODROID=1" />
+      <_MonoCPPFLAGS Include="-D__ANDROID_API__=$(AndroidApiVersion)" />
+
+      <_MonoCXXCPPFLAGS Condition="'$(Platform)' == 'arm64'" Include="-DANDROID64" />
+      <_MonoCXXCPPFLAGS Condition="'$(Platform)' == 'arm64'" Include="-I$(ANDROID_NDK_HOME)/sysroot/usr/include/aarch64-linux-android" />
+      <_MonoCXXCPPFLAGS Condition="'$(Platform)' == 'arm'" Include="-I$(ANDROID_NDK_HOME)/sysroot/usr/include/arm-linux-androideabi" />
+      <_MonoCXXCPPFLAGS Condition="'$(Platform)' == 'x64'" Include="-I$(ANDROID_NDK_HOME)/sysroot/usr/include/x86_64-linux-android" />
+      <_MonoCXXCPPFLAGS Condition="'$(Platform)' == 'x86'" Include="-I$(ANDROID_NDK_HOME)/sysroot/usr/include/i686-linux-android" />
+      <_MonoCXXCPPFLAGS Condition="'$(Platform)' == 'x64'" Include="-m64" />
+      <_MonoCXXCPPFLAGS Condition="'$(Platform)' == 'x86'" Include="-m32" />
+      <_MonoCXXCPPFLAGS Condition="'$(Platform)' == 'arm64' or '$(Platform)' == 'x64'" Include="-DL_cuserid=9" />
+      <_MonoCXXCPPFLAGS Condition="'$(Platform)' == 'arm64' or '$(Platform)' == 'arm'" Include="-D__POSIX_VISIBLE=201002" />
+      <_MonoCXXCPPFLAGS Condition="'$(Platform)' == 'arm64' or '$(Platform)' == 'arm'" Include="-DSK_RELEASE" />
+      <_MonoCXXCPPFLAGS Condition="'$(Platform)' == 'arm64' or '$(Platform)' == 'arm'" Include="-DNDEBUG" />
+      <_MonoCXXCPPFLAGS Condition="'$(Platform)' == 'arm64' or '$(Platform)' == 'arm'" Include="-UDEBUG" />
+      <_MonoCXXCPPFLAGS Include="-I$(ANDROID_NDK_HOME)/sysroot/usr/include" />
+      <_MonoCXXCPPFLAGS Include="-DMONODROID=1" />
+      <_MonoCXXCPPFLAGS Include="-D__ANDROID_API__=$(AndroidApiVersion)" />
+
+      <_MonoLDFLAGS Condition="'$(Platform)' == 'arm64'" Include="-L$(ANDROID_NDK_HOME)/platforms/android-$(AndroidApiVersion)/arch-arm64/usr/lib" />
+      <_MonoLDFLAGS Condition="'$(Platform)' == 'arm64'" Include="-Wl,-rpath-link=$(ANDROID_NDK_HOME)/platforms/android-$(AndroidApiVersion)/arch-arm64/usr/lib,-dynamic-linker=/system/bin/linker" />
+      <_MonoLDFLAGS Condition="'$(Platform)' == 'arm'" Include="-L$(ANDROID_NDK_HOME)/platforms/android-$(AndroidApiVersion)/arch-arm/usr/lib" />
+      <_MonoLDFLAGS Condition="'$(Platform)' == 'arm'" Include="-Wl,-rpath-link=$(ANDROID_NDK_HOME)/platforms/android-$(AndroidApiVersion)/arch-arm/usr/lib,-dynamic-linker=/system/bin/linker" />
+      <_MonoLDFLAGS Condition="'$(Platform)' == 'arm'" Include="-Wl,--fix-cortex-a8" />
+      <_MonoLDFLAGS Condition="'$(Platform)' == 'x86'" Include="-L$(ANDROID_NDK_HOME)/platforms/android-$(AndroidApiVersion)/arch-x86/usr/lib" />
+      <_MonoLDFLAGS Condition="'$(Platform)' == 'x86'" Include="-Wl,-rpath-link=$(ANDROID_NDK_HOME)/platforms/android-$(AndroidApiVersion)/arch-x86/usr/lib,-dynamic-linker=/system/bin/linker" />
+      <_MonoLDFLAGS Condition="'$(Platform)' == 'x64'" Include="-L$(ANDROID_NDK_HOME)/platforms/android-$(AndroidApiVersion)/arch-x86_64/usr/lib" />
+      <_MonoLDFLAGS Condition="'$(Platform)' == 'x64'" Include="-Wl,-rpath-link=$(ANDROID_NDK_HOME)/platforms/android-$(AndroidApiVersion)/arch-x86_64/usr/lib,-dynamic-linker=/system/bin/linker" />
+      <_MonoLDFLAGS Include="-z now" />
+      <_MonoLDFLAGS Include="-z relro" />
+      <_MonoLDFLAGS Include="-z noexecstack" />
+      <_MonoLDFLAGS Include="-ldl" />
+      <_MonoLDFLAGS Include="-lm" />
+      <_MonoLDFLAGS Include="-llog" />
+      <_MonoLDFLAGS Include="-lc" />
+      <_MonoLDFLAGS Include="-lgcc" />
+    </ItemGroup>
+
     <!-- iOS device/simulator specific options -->
-    <PropertyGroup Condition="'$(TargetOS)' == 'iOS'">
+    <PropertyGroup Condition="'$(TargetsiOS)' == 'true'">
       <_MonoCCOption>CC="$(XcodeDir)/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang"</_MonoCCOption>
       <_MonoCXXOption>CXX="$(XcodeDir)/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang++"</_MonoCXXOption>
       <_MonoAROption>AR=""</_MonoAROption>
       <_MonoSTRIPOption>STRIP=""</_MonoSTRIPOption>
     </PropertyGroup>
 
+    <!-- Android specific options -->
+    <PropertyGroup Condition="'$(TargetsAndroid)' == 'true'">
+      <_MonoAndroidTargetTuple Condition="'$(Platform)' == 'x64'" >x86_64-linux-android</_MonoAndroidTargetTuple>
+      <_MonoAndroidTargetTuple Condition="'$(Platform)' == 'x86'" >i686-linux-android</_MonoAndroidTargetTuple>
+      <_MonoAndroidTargetTuple Condition="'$(Platform)' == 'arm64'" >aarch64-linux-android</_MonoAndroidTargetTuple>
+      <_MonoAndroidTargetTuple Condition="'$(Platform)' == 'arm'" >arm-linux-androideabi</_MonoAndroidTargetTuple>
+
+      <_MonoAndroidBuildHost Condition="$([MSBuild]::IsOSPlatform('OSX'))">darwin-x86_64</_MonoAndroidBuildHost>
+      <_MonoAndroidBuildHost Condition="$([MSBuild]::IsOSPlatform('Linux'))">linux-x86_64</_MonoAndroidBuildHost>
+
+      <_MonoAndroidToolchainPrefix>$(ANDROID_NDK_HOME)/toolchains/llvm/prebuilt/$(_MonoAndroidBuildHost)/bin/$(_MonoAndroidTargetTuple)</_MonoAndroidToolchainPrefix>
+      <_MonoAndroidToolchainPrefixClang Condition="'$(Platform)' == 'arm'">$(ANDROID_NDK_HOME)/toolchains/llvm/prebuilt/$(_MonoAndroidBuildHost)/bin/armv7a-linux-androideabi$(AndroidApiVersion)</_MonoAndroidToolchainPrefixClang>
+      <_MonoAndroidToolchainPrefixClang Condition="'$(Platform)' != 'arm'">$(_MonoAndroidToolchainPrefix)$(AndroidApiVersion)</_MonoAndroidToolchainPrefixClang>
+
+      <_MonoCCOption>CC="$(_MonoAndroidToolchainPrefixClang)-clang"</_MonoCCOption>
+      <_MonoCXXOption>CXX="$(_MonoAndroidToolchainPrefixClang)-clang++"</_MonoCXXOption>
+      <_MonoAROption>AR="$(_MonoAndroidToolchainPrefix)-ar"</_MonoAROption>
+      <_MonoASOption>AS="$(_MonoAndroidToolchainPrefix)-as"</_MonoASOption>
+      <_MonoCPPOption>CPP="$(_MonoAndroidToolchainPrefixClang)-clang -E"</_MonoCPPOption>
+      <_MonoCXXCPPOption>CXXCPP="$(_MonoAndroidToolchainPrefixClang)-clang++ -E"</_MonoCXXCPPOption>
+      <_MonoDLLTOOLOption>DLLTOOL=""</_MonoDLLTOOLOption>
+      <_MonoLDOption>LD="$(_MonoAndroidToolchainPrefix)-ld"</_MonoLDOption>
+      <_MonoOBJDUMPOption>OBJDUMP="$(_MonoAndroidToolchainPrefix)-objdump"</_MonoOBJDUMPOption>
+      <_MonoRANLIBOption>RANLIB="$(_MonoAndroidToolchainPrefix)-ranlib"</_MonoRANLIBOption>
+      <_MonoCMAKEOption>CMAKE=""</_MonoCMAKEOption>
+      <_MonoSTRIPOption>STRIP="$(_MonoAndroidToolchainPrefix)-strip"</_MonoSTRIPOption>
+    </PropertyGroup>
+
     <!-- ARM Linux cross build options -->
-    <PropertyGroup Condition="'$(MonoCrossDir)' != '' and ('$(TargetArchitecture)' == 'arm' Or '$(TargetArchitecture)' == 'arm64')">
+    <PropertyGroup Condition="'$(TargetsAndroid)' != 'true' and '$(MonoCrossDir)' != '' and ('$(TargetArchitecture)' == 'arm' Or '$(TargetArchitecture)' == 'arm64')">
       <_MonoTuple Condition="'$(TargetArchitecture)' == 'arm64'">aarch64-linux-gnu</_MonoTuple>
       <_MonoTuple Condition="'$(TargetArchitecture)' == 'arm'">arm-linux-gnueabihf</_MonoTuple>
 
     </PropertyGroup>
 
     <!-- Linux options -->
-    <ItemGroup Condition="'$(TargetsLinux)' == true">
+    <ItemGroup Condition="'$(TargetsLinux)' == true and '$(TargetsAndroid)' != 'true'">
       <_MonoCFLAGS Include="-Wl,--build-id" />
       <_MonoCXXFLAGS Include="-Wl,--build-id" />
     </ItemGroup>
     </PropertyGroup>
 
     <!-- AOT cross-compiler specific options -->
-    <PropertyGroup Condition="'$(TargetOS)' == 'iOS' and '$(TargetsiOSSimulator)' != 'true'">
+    <PropertyGroup Condition="'$(TargetsiOS)' == 'true' and '$(TargetsiOSSimulator)' != 'true'">
       <_MonoAotCrossCFLAGSOption Condition="@(_MonoAotCrossCFLAGS->Count()) &gt; 0">CFLAGS="@(_MonoAotCrossCFLAGS, ' ')"</_MonoAotCrossCFLAGSOption>
       <_MonoAotCrossCXXFLAGSOption Condition="@(_MonoAotCrossCXXFLAGS->Count()) &gt; 0">CXXFLAGS="@(_MonoAotCrossCXXFLAGS, ' ')"</_MonoAotCrossCXXFLAGSOption>
       <_MonoAotCrossCPPFLAGSOption Condition="@(_MonoAotCrossCPPFLAGS->Count()) &gt; 0">CPPFLAGS="@(_MonoAotCrossCPPFLAGS, ' ')"</_MonoAotCrossCPPFLAGSOption>
   <Target Name="BuildMonoRuntimeUnix" Condition="'$(OS)' != 'Windows_NT'" DependsOnTargets="ConfigureMonoRuntimeUnix">
     <Message Text="--- Building Mono ---" Importance="High" />
     <Exec Command="make -j$([System.Environment]::ProcessorCount)" IgnoreStandardErrorWarningFormat="true" WorkingDirectory="$(MonoObjDir)" />
-    <Exec Condition="'$(TargetsiOS)' == 'true'" Command="make install -j$([System.Environment]::ProcessorCount)" IgnoreStandardErrorWarningFormat="true" WorkingDirectory="$(MonoObjDir)" />
+    <Exec Condition="'$(TargetsiOS)' == 'true' or '$(TargetsAndroid)' == 'true'" Command="make install -j$([System.Environment]::ProcessorCount)" IgnoreStandardErrorWarningFormat="true" WorkingDirectory="$(MonoObjDir)" />
 
     <Message Condition="'$(TargetsiOS)' == 'true' and '$(TargetsiOSSimulator)' != 'true'" Text="--- Building Mono AOT cross-compiler ---" Importance="High" />
     <Exec Condition="'$(TargetsiOS)' == 'true' and '$(TargetsiOSSimulator)' != 'true'" Command="make -j$([System.Environment]::ProcessorCount)" IgnoreStandardErrorWarningFormat="true" WorkingDirectory="$(MonoObjDir)cross" />
   <Target Name="BuildMonoRuntimeWindows" Condition="'$(OS)' == 'Windows_NT'">
 
     <!-- Sanity checks -->
-    <Error Condition="'$(TargetOS)' == 'iOS'" Text="Error: Mono runtime for $(TargetOS) can't be built on Windows." />
+    <Error Condition="'$(TargetsiOS)' == 'true'" Text="Error: Mono runtime for $(TargetOS) can't be built on Windows." />
 
     <ItemGroup>
       <_MonoBuildParams Include="/p:MONO_BUILD_DIR_PREFIX=&quot;&quot;$(MonoObjDir)&quot;&quot;" />
       <_MonoRuntimeFilePath Condition="'$(TargetsWindows)' == 'true' and '$(Platform)' == 'x86'">$(MonoObjDir)Win32\Bin\$(Configuration)\mono-2.0-sgen.dll</_MonoRuntimeFilePath>
       <_MonoRuntimeFilePath Condition="'$(TargetsOSX)' == 'true'">$(MonoObjDir)mono\mini\.libs\libmonosgen-2.0.dylib</_MonoRuntimeFilePath>
       <_MonoRuntimeFilePath Condition="'$(TargetsiOS)' == 'true'">$(MonoObjDir)out\lib\libmonosgen-2.0.dylib</_MonoRuntimeFilePath>
+      <_MonoRuntimeFilePath Condition="'$(TargetsAndroid)' == 'true'">$(MonoObjDir)out\lib\libmonosgen-2.0.so</_MonoRuntimeFilePath>
       <_MonoRuntimeFilePath Condition="'$(_MonoRuntimeFilePath)' == ''">$(MonoObjDir)mono\mini\.libs\libmonosgen-2.0.so</_MonoRuntimeFilePath>
-      <_MonoRuntimeStaticFilePath Condition="'$(TargetsiOS)' == 'true'">$(MonoObjDir)out\lib\libmonosgen-2.0.a</_MonoRuntimeStaticFilePath>
+      <_MonoRuntimeStaticFilePath Condition="'$(TargetsiOS)' == 'true' or '$(TargetsAndroid)' == 'true'">$(MonoObjDir)out\lib\libmonosgen-2.0.a</_MonoRuntimeStaticFilePath>
       <_MonoAotCrossFilePath Condition="'$(TargetsiOS)' == 'true' and '$(Platform)' == 'arm64'">$(MonoObjDir)cross\out\bin\aarch64-darwin-mono-sgen</_MonoAotCrossFilePath>
       <_MonoAotCrossFilePath Condition="'$(TargetsiOS)' == 'true' and '$(Platform)' == 'arm'">$(MonoObjDir)cross\out\bin\arm-darwin-mono-sgen</_MonoAotCrossFilePath>
     </PropertyGroup>
     <Copy SourceFiles="@(_MonoIncludeArtifacts)"
           DestinationFiles="@(_MonoIncludeArtifacts->'$(BinDir)include\%(RecursiveDir)%(Filename)%(Extension)')"
           SkipUnchangedFiles="true"
-          Condition="'$(TargetsiOS)' == 'true'"/>
+          Condition="'$(TargetsiOS)' == 'true' or '$(TargetsAndroid)' == 'true'"/>
 
     <Exec Condition="'$(TargetsOSX)' == 'true' or '$(TargetsiOS)' == 'true'" Command="install_name_tool -id @rpath/$(MonoFileName) $(BinDir)$(MonoFileName)" />
   </Target>
index 94c0475..82c4ae1 100644 (file)
@@ -51,9 +51,7 @@
   <!-- _packageTargetOSGroup is used to control the runtime package imports, don't import runtime package targets for
        an unsupported OS Group -->
   <PropertyGroup Condition="'$(PackageTargetRuntime)' != '' and '$(_isSupportedOSGroup)' == 'true'">
-    <!-- Android will use Linux package definitions -->
     <_packageTargetOSGroup>$(_derivedPackageTargetOSGroup)</_packageTargetOSGroup>
-    <_packageTargetOSGroup Condition="'$(_derivedPackageTargetOSGroup)' == 'Android'">Linux</_packageTargetOSGroup>
   </PropertyGroup>
   <PropertyGroup>
     <SkipPackageFileCheck>true</SkipPackageFileCheck>
       <Platform>arm64</Platform>
     </OfficialBuildRID>
   </ItemGroup>
+  <ItemGroup Condition="$(SupportedPackageOSGroups.Contains(';Android;'))">
+    <OfficialBuildRID Include="android-x64" />
+    <OfficialBuildRID Include="android-x86">
+      <Platform>x86</Platform>
+    </OfficialBuildRID>
+    <OfficialBuildRID Include="android-arm">
+      <Platform>arm</Platform>
+    </OfficialBuildRID>
+    <OfficialBuildRID Include="android-arm64">
+      <Platform>arm64</Platform>
+    </OfficialBuildRID>
+  </ItemGroup>
   <ItemGroup Condition="$(SupportedPackageOSGroups.Contains(';FreeBSD;'))">
     <OfficialBuildRID Include="freebsd-x64" />
   </ItemGroup>
diff --git a/src/mono/netcore/nuget/Microsoft.NETCore.Runtime.Mono/runtime.Android.Microsoft.NETCore.Runtime.Mono.props b/src/mono/netcore/nuget/Microsoft.NETCore.Runtime.Mono/runtime.Android.Microsoft.NETCore.Runtime.Mono.props
new file mode 100644 (file)
index 0000000..fb6909a
--- /dev/null
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project>
+  <ItemGroup>
+    <NativeBinary Include="$(BinDir)libmonosgen-2.0.so" />
+    <NativeBinary Include="$(BinDir)libmonosgen-2.0.a" />
+    <ArchitectureSpecificLibFile Include="$(BinDir)System.Private.CoreLib.dll" />
+    <File Include="$(BinDir)include\**">
+      <SkipPackageFileCheck>true</SkipPackageFileCheck>
+      <TargetPath>tools\include\%(RecursiveDir)%(Filename)%(Extension)</TargetPath>
+    </File>
+  </ItemGroup>
+</Project>
diff --git a/src/mono/netcore/nuget/Microsoft.NETCore.Tool.MonoAOT/runtime.Android.Microsoft.NETCore.Tool.MonoAOT.props b/src/mono/netcore/nuget/Microsoft.NETCore.Tool.MonoAOT/runtime.Android.Microsoft.NETCore.Tool.MonoAOT.props
new file mode 100644 (file)
index 0000000..6ed7866
--- /dev/null
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project>
+  <ItemGroup>
+<!-- TODO 
+    <File Include="$(BinDir)/cross/mono-aot-cross">
+      <SkipPackageFileCheck>true</SkipPackageFileCheck>
+      <TargetPath>tools</TargetPath>
+    </File>
+-->
+  </ItemGroup>
+</Project>