From 6361fed294a99792513665fac902fd55d7daebc3 Mon Sep 17 00:00:00 2001 From: Jeremi Kurdek Date: Wed, 4 Dec 2024 13:21:28 +0100 Subject: [PATCH 1/9] Change assembler to clang in android MonoAOT --- .../android/build/AndroidBuild.targets | 31 ++++++++++-------- src/tasks/AotCompilerTask/MonoAOTCompiler.cs | 32 ++++++++++++++++++- .../MobileBuildTasks/Android/Ndk/NdkTools.cs | 4 +-- 3 files changed, 51 insertions(+), 16 deletions(-) diff --git a/src/mono/msbuild/android/build/AndroidBuild.targets b/src/mono/msbuild/android/build/AndroidBuild.targets index 99a226aafc603a..8db260e498f11d 100644 --- a/src/mono/msbuild/android/build/AndroidBuild.targets +++ b/src/mono/msbuild/android/build/AndroidBuild.targets @@ -125,12 +125,20 @@ <_AotOutputType>ObjectFile - - - - - + + <_Triple Condition="'$(TargetArchitecture)' == 'arm'">armv7-linux-gnueabi + <_Triple Condition="'$(TargetArchitecture)' == 'arm64'">aarch64-linux-android + <_Triple Condition="'$(TargetArchitecture)' == 'x86'">i686-linux-android + <_Triple Condition="'$(TargetArchitecture)' == 'x64'">x86_64-linux-android + + + <_LdName>clang + <_LdOptions>-fuse-ld=lld + <_AsName>clang + + + @@ -159,12 +167,6 @@ Architecture="$(TargetArchitecture)" HostOS="$(_HostOS)" MinApiLevel="$(AndroidLibraryMinApiLevel)"> - - - - - - @@ -234,20 +236,23 @@ diff --git a/src/tasks/AotCompilerTask/MonoAOTCompiler.cs b/src/tasks/AotCompilerTask/MonoAOTCompiler.cs index 0a761b44a4c8f2..f4be178f274919 100644 --- a/src/tasks/AotCompilerTask/MonoAOTCompiler.cs +++ b/src/tasks/AotCompilerTask/MonoAOTCompiler.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System; @@ -231,6 +231,16 @@ public class MonoAOTCompiler : Microsoft.Build.Utilities.Task /// public string? ToolPrefix { get; set; } + /// + /// Name of the assembler tool ran by the AOT compiler. + /// + public string? AsName { get; set; } + + /// + /// Passes as-options to the AOT compiler + /// + public string? AsOptions { get; set; } + /// /// Prepends a prefix to the name of the assembler (as) tool ran by the AOT compiler. /// @@ -278,6 +288,11 @@ public class MonoAOTCompiler : Microsoft.Build.Utilities.Task /// public string? LdFlags { get; set; } + /// + /// Passes ld-options to the AOT compiler + /// + public string? LdOptions { get; set; } + /// /// Specify WorkingDirectory for the AOT compiler /// @@ -728,6 +743,16 @@ private PrecompileArguments GetPrecompileArgumentsFor(ITaskItem assemblyItem, st aotArgs.Add($"tool-prefix={ToolPrefix}"); } + if (!string.IsNullOrEmpty(AsName)) + { + aotArgs.Add($"as-name={AsName}"); + } + + if (!string.IsNullOrEmpty(AsOptions)) + { + aotArgs.Add($"as-options={AsOptions}"); + } + if (!string.IsNullOrEmpty(AsPrefix)) { aotArgs.Add($"as-prefix={AsPrefix}"); @@ -943,6 +968,11 @@ private PrecompileArguments GetPrecompileArgumentsFor(ITaskItem assemblyItem, st aotArgs.Add($"ld-flags={LdFlags}"); } + if (!string.IsNullOrEmpty(LdOptions)) + { + aotArgs.Add($"ld-options={LdOptions}"); + } + // we need to quote the entire --aot arguments here to make sure it is parsed // on Windows as one argument. Otherwise it will be split up into multiple // values, which wont work. diff --git a/src/tasks/MobileBuildTasks/Android/Ndk/NdkTools.cs b/src/tasks/MobileBuildTasks/Android/Ndk/NdkTools.cs index 6370c49df85405..0741e92dfe8116 100644 --- a/src/tasks/MobileBuildTasks/Android/Ndk/NdkTools.cs +++ b/src/tasks/MobileBuildTasks/Android/Ndk/NdkTools.cs @@ -101,9 +101,9 @@ public string ClangPath private void ValidateRequiredProps(string hostOS) { - if (Ndk.NdkVersion.Main.Major != 23) + if (Ndk.NdkVersion.Main.Major != 27) { - throw new Exception($"NDK 23 is required. An unsupported NDK version was found ({Ndk.NdkVersion.Main.Major})."); + throw new Exception($"NDK 27 is required. An unsupported NDK version was found ({Ndk.NdkVersion.Main.Major})."); } try From 3637021360d25cde392196014592f9d3c69909fa Mon Sep 17 00:00:00 2001 From: Jeremi Kurdek Date: Thu, 5 Dec 2024 14:11:41 +0100 Subject: [PATCH 2/9] Disabled NdkToolFinder task --- src/mono/msbuild/android/build/AndroidBuild.targets | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/mono/msbuild/android/build/AndroidBuild.targets b/src/mono/msbuild/android/build/AndroidBuild.targets index 8db260e498f11d..d7b4b1bb634632 100644 --- a/src/mono/msbuild/android/build/AndroidBuild.targets +++ b/src/mono/msbuild/android/build/AndroidBuild.targets @@ -162,13 +162,6 @@ 21 - - - <_AsPrefixPath>$([MSBuild]::EnsureTrailingSlash('$(_AsPrefixPath)')) <_ToolPrefixPath>$([MSBuild]::EnsureTrailingSlash('$(_ToolPrefixPath)')) From 9166c64695da58e497272e2bf03f5aa096a1cd6d Mon Sep 17 00:00:00 2001 From: Jeremi Kurdek Date: Thu, 5 Dec 2024 14:22:32 +0100 Subject: [PATCH 3/9] Port changes to sample app --- .../sample/Android/AndroidSampleApp.csproj | 33 ++++++++++--------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/src/mono/sample/Android/AndroidSampleApp.csproj b/src/mono/sample/Android/AndroidSampleApp.csproj index c5316052559933..ddc98d77eead91 100644 --- a/src/mono/sample/Android/AndroidSampleApp.csproj +++ b/src/mono/sample/Android/AndroidSampleApp.csproj @@ -70,36 +70,39 @@ 21 - - - - - - - - - <_AsPrefixPath>$([MSBuild]::EnsureTrailingSlash('$(_AsPrefixPath)')) <_ToolPrefixPath>$([MSBuild]::EnsureTrailingSlash('$(_ToolPrefixPath)')) + + <_Triple Condition="'$(TargetArchitecture)' == 'arm'">armv7-linux-gnueabi + <_Triple Condition="'$(TargetArchitecture)' == 'arm64'">aarch64-linux-android + <_Triple Condition="'$(TargetArchitecture)' == 'x86'">i686-linux-android + <_Triple Condition="'$(TargetArchitecture)' == 'x64'">x86_64-linux-android + + + + <_LdName>clang + <_LdOptions>-fuse-ld=lld + <_AsName>clang + + From 9c1c5ded2c00fe94faba889228ce02da022c5e6d Mon Sep 17 00:00:00 2001 From: Jeremi Kurdek Date: Wed, 18 Dec 2024 12:59:23 +0100 Subject: [PATCH 4/9] Allowed overwriting AsOptions --- src/mono/msbuild/android/build/AndroidBuild.targets | 3 ++- src/mono/sample/Android/AndroidSampleApp.csproj | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/mono/msbuild/android/build/AndroidBuild.targets b/src/mono/msbuild/android/build/AndroidBuild.targets index d7b4b1bb634632..f8cca5121ea20c 100644 --- a/src/mono/msbuild/android/build/AndroidBuild.targets +++ b/src/mono/msbuild/android/build/AndroidBuild.targets @@ -133,6 +133,7 @@ + <_AsOptions>-target $(_Triple) -c -x assembler <_LdName>clang <_LdOptions>-fuse-ld=lld <_AsName>clang @@ -230,7 +231,7 @@ + <_AsOptions>-target $(_Triple) -c -x assembler <_LdName>clang <_LdOptions>-fuse-ld=lld <_AsName>clang @@ -91,7 +92,7 @@ Date: Tue, 14 Jan 2025 14:20:21 -0500 Subject: [PATCH 5/9] Since we bumped the NDK in https://github.com/dotnet/dotnet-buildtools-prereqs-docker/pull/1278, libClang.so is no longer found in the place we expect. As a result, the android aot offsets won't be generated and the dedicated CI leg will fail. This change fixes the path. --- src/mono/mono.proj | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/mono/mono.proj b/src/mono/mono.proj index a643e5a049e79c..d0e704abbdf5a7 100644 --- a/src/mono/mono.proj +++ b/src/mono/mono.proj @@ -688,7 +688,9 @@ - <_LibClang Include="$(ANDROID_NDK_ROOT)/toolchains/llvm/prebuilt/$(MonoToolchainPrebuiltOS)/lib64/libclang.so.*"/> + <_LibClang Include="$(ANDROID_NDK_ROOT)/toolchains/llvm/prebuilt/$(MonoToolchainPrebuiltOS)/lib/libclang.so" Condition=" Exists('$(ANDROID_NDK_ROOT)/toolchains/llvm/prebuilt/$(MonoToolchainPrebuiltOS)/lib/libclang.so') "/> + <_LibClang Include="$(ANDROID_NDK_ROOT)/toolchains/llvm/prebuilt/$(MonoToolchainPrebuiltOS)/lib64/libclang.so.*" Condition=" '@(_LibClang)' == '' "/> + <_LibClang Include="/usr/local/lib/libclang.so" Condition="'@(_LibClang)' == ''" /> true From 51ca3c21dd833976a010cfad704c2d4b63993842 Mon Sep 17 00:00:00 2001 From: Jeremi Kurdek Date: Tue, 4 Feb 2025 20:25:08 +0100 Subject: [PATCH 6/9] Backported parts of #96332 --- src/mono/mono/mini/aot-compiler.c | 36 ++++++++++++++++++++++++++----- 1 file changed, 31 insertions(+), 5 deletions(-) diff --git a/src/mono/mono/mini/aot-compiler.c b/src/mono/mono/mini/aot-compiler.c index c342ef5d007571..9b4527cfb6f97b 100644 --- a/src/mono/mono/mini/aot-compiler.c +++ b/src/mono/mono/mini/aot-compiler.c @@ -240,8 +240,11 @@ typedef struct MonoAotOptions { gboolean allow_errors; char *tool_prefix; char *as_prefix; + char *as_name; + char *as_options; char *ld_flags; char *ld_name; + char *ld_options; char *mtriple; char *llvm_path; char *temp_path; @@ -8866,10 +8869,16 @@ mono_aot_parse_options (const char *aot_options, MonoAotOptions *opts) opts->tool_prefix = g_strdup (arg + strlen ("tool-prefix=")); } else if (str_begins_with (arg, "as-prefix=")) { opts->as_prefix = g_strdup (arg + strlen ("as-prefix=")); + } else if (str_begins_with (arg, "as-name=")) { + opts->as_name = g_strdup (arg + strlen ("as-name=")); + } else if (str_begins_with (arg, "as-options=")) { + opts->as_options = g_strdup (arg + strlen ("as-options=")); } else if (str_begins_with (arg, "ld-flags=")) { opts->ld_flags = g_strdup (arg + strlen ("ld-flags=")); } else if (str_begins_with (arg, "ld-name=")) { opts->ld_name = g_strdup (arg + strlen ("ld-name=")); + } else if (str_begins_with (arg, "ld-options=")) { + opts->ld_options = g_strdup (arg + strlen ("ld-options=")); } else if (str_begins_with (arg, "soft-debug")) { opts->soft_debug = TRUE; // Intentionally undocumented x2-- deprecated @@ -13275,7 +13284,16 @@ compile_asm (MonoAotCompile *acfg) g_string_append (acfg->as_args, "-c -x assembler "); #endif - command = g_strdup_printf ("\"%s%s\" %s %s -o %s %s", as_prefix, AS_NAME, AS_OPTIONS, + const char *as_binary_name = acfg->aot_opts.as_name; + if (as_binary_name == NULL) { + as_binary_name = AS_NAME; + } + const char *as_options = acfg->aot_opts.as_options; + if (as_options == NULL) { + as_options = AS_OPTIONS; + } + + command = g_strdup_printf ("\"%s%s\" %s %s -o %s %s", as_prefix, as_binary_name, as_options, acfg->as_args ? acfg->as_args->str : "", wrap_path (objfile), wrap_path (acfg->tmpfname)); aot_printf (acfg, "Executing the native assembler: %s\n", command); @@ -13286,7 +13304,7 @@ compile_asm (MonoAotCompile *acfg) } if (acfg->llvm && !acfg->llvm_owriter) { - command = g_strdup_printf ("\"%s%s\" %s %s -o %s %s", as_prefix, AS_NAME, AS_OPTIONS, + command = g_strdup_printf ("\"%s%s\" %s %s -o %s %s", as_prefix, as_binary_name, as_options, acfg->as_args ? acfg->as_args->str : "", wrap_path (acfg->llvm_ofile), wrap_path (acfg->llvm_sfile)); aot_printf (acfg, "Executing the native assembler: %s\n", command); @@ -13335,16 +13353,21 @@ compile_asm (MonoAotCompile *acfg) str = g_string_new (""); const char *ld_binary_name = acfg->aot_opts.ld_name; + + const char *ld_options = acfg->aot_opts.ld_options; + if (ld_options == NULL) { + ld_options = LD_OPTIONS; + } #if defined(LD_NAME) if (ld_binary_name == NULL) { ld_binary_name = LD_NAME; } if (acfg->aot_opts.tool_prefix) - g_string_append_printf (str, "\"%s%s\" %s", tool_prefix, ld_binary_name, LD_OPTIONS); + g_string_append_printf (str, "\"%s%s\" %s", tool_prefix, ld_binary_name, ld_options); else if (acfg->aot_opts.llvm_only) g_string_append_printf (str, "%s", acfg->aot_opts.clangxx); else - g_string_append_printf (str, "\"%s%s\" %s", tool_prefix, ld_binary_name, LD_OPTIONS); + g_string_append_printf (str, "\"%s%s\" %s", tool_prefix, ld_binary_name, ld_options); #else if (ld_binary_name == NULL) { ld_binary_name = "ld"; @@ -13353,7 +13376,7 @@ compile_asm (MonoAotCompile *acfg) // Default (linux) if (acfg->aot_opts.tool_prefix) /* Cross compiling */ - g_string_append_printf (str, "\"%s%s\" %s", tool_prefix, ld_binary_name, LD_OPTIONS); + g_string_append_printf (str, "\"%s%s\" %s", tool_prefix, ld_binary_name, ld_options); else if (acfg->aot_opts.llvm_only) g_string_append_printf (str, "%s", acfg->aot_opts.clangxx); else @@ -14284,8 +14307,11 @@ aot_opts_free (MonoAotOptions *aot_opts) g_free (aot_opts->dedup_include); g_free (aot_opts->tool_prefix); g_free (aot_opts->as_prefix); + g_free (aot_opts->as_name); + g_free (aot_opts->as_options); g_free (aot_opts->ld_flags); g_free (aot_opts->ld_name); + g_free (aot_opts->ld_options); g_free (aot_opts->mtriple); g_free (aot_opts->llvm_path); g_free (aot_opts->temp_path); From 250c4b80cbe7b4e55e77250a74cd405e40931146 Mon Sep 17 00:00:00 2001 From: Filip Navara Date: Mon, 12 Feb 2024 12:29:14 +0100 Subject: [PATCH 7/9] Fix build with Android 26 NDK (which has some nullability annotations) (#97976) * Fix build with Android 26 NDK (which has some nullability annotations) * One more error in System.Security.Cryptography.Native.Android --- .../System.Native/pal_interfaceaddresses.c | 23 +++++++++++++------ .../pal_cipher.c | 2 +- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/src/native/libs/System.Native/pal_interfaceaddresses.c b/src/native/libs/System.Native/pal_interfaceaddresses.c index 8fee3e0e3e9649..fe42cd91dac609 100644 --- a/src/native/libs/System.Native/pal_interfaceaddresses.c +++ b/src/native/libs/System.Native/pal_interfaceaddresses.c @@ -117,7 +117,7 @@ static inline uint8_t mask2prefix(uint8_t* mask, int length) static int (*getifaddrs)(struct ifaddrs**) = NULL; static void (*freeifaddrs)(struct ifaddrs*) = NULL; -static void try_loading_getifaddrs() +static void try_loading_getifaddrs(void) { if (android_get_device_api_level() >= 24) { @@ -139,7 +139,7 @@ static void try_loading_getifaddrs() } } -static bool ensure_getifaddrs_is_loaded() +static bool ensure_getifaddrs_is_loaded(void) { static pthread_once_t getifaddrs_is_loaded = PTHREAD_ONCE_INIT; pthread_once(&getifaddrs_is_loaded, try_loading_getifaddrs); @@ -169,11 +169,12 @@ int32_t SystemNative_EnumerateInterfaceAddresses(void* context, for (struct ifaddrs* current = headAddr; current != NULL; current = current->ifa_next) { - if (current->ifa_addr == NULL) + char *ifa_name = current->ifa_name; + if (current->ifa_addr == NULL || ifa_name == NULL) { continue; } - uint32_t interfaceIndex = if_nametoindex(current->ifa_name); + uint32_t interfaceIndex = if_nametoindex(ifa_name); // ifa_name may be an aliased interface name. // Use if_indextoname to map back to the true device name. char actualName[IF_NAMESIZE]; @@ -376,9 +377,17 @@ int32_t SystemNative_GetNetworkInterfaces(int32_t * interfaceCount, NetworkInter while (ifaddrsEntry != NULL) { + char *ifa_name = ifaddrsEntry->ifa_name; + + if (ifa_name == NULL) + { + ifaddrsEntry = ifaddrsEntry->ifa_next; + continue; + } + //current = NULL; nii = NULL; - uint ifindex = if_nametoindex(ifaddrsEntry->ifa_name); + uint ifindex = if_nametoindex(ifa_name); for (index = 0; index < (int)ifcount; index ++) { if (((NetworkInterfaceInfo*)memoryBlock)[index].InterfaceIndex == ifindex) @@ -393,8 +402,8 @@ int32_t SystemNative_GetNetworkInterfaces(int32_t * interfaceCount, NetworkInter // We git new interface. nii = &((NetworkInterfaceInfo*)memoryBlock)[ifcount++]; - memcpy(nii->Name, ifaddrsEntry->ifa_name, sizeof(nii->Name)); - nii->InterfaceIndex = if_nametoindex(ifaddrsEntry->ifa_name); + memcpy(nii->Name, ifa_name, sizeof(nii->Name)); + nii->InterfaceIndex = ifindex; nii->Speed = -1; nii->HardwareType = ((ifaddrsEntry->ifa_flags & IFF_LOOPBACK) == IFF_LOOPBACK) ? NetworkInterfaceType_Loopback : NetworkInterfaceType_Unknown; diff --git a/src/native/libs/System.Security.Cryptography.Native.Android/pal_cipher.c b/src/native/libs/System.Security.Cryptography.Native.Android/pal_cipher.c index b09932392eea08..d60dbdd02df060 100644 --- a/src/native/libs/System.Security.Cryptography.Native.Android/pal_cipher.c +++ b/src/native/libs/System.Security.Cryptography.Native.Android/pal_cipher.c @@ -20,7 +20,7 @@ typedef struct CipherInfo } CipherInfo; #define DEFINE_CIPHER(cipherId, width, javaName, flags) \ -CipherInfo* AndroidCryptoNative_ ## cipherId() \ +CipherInfo* AndroidCryptoNative_ ## cipherId(void) \ { \ static CipherInfo info = { flags, width, javaName }; \ return &info; \ From 9c75470463d92d79a5f4f76784279f491a38d0f6 Mon Sep 17 00:00:00 2001 From: Jeremi Kurdek Date: Wed, 12 Feb 2025 12:53:33 +0100 Subject: [PATCH 8/9] Change docker images for test --- eng/pipelines/common/templates/pipeline-with-resources.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/eng/pipelines/common/templates/pipeline-with-resources.yml b/eng/pipelines/common/templates/pipeline-with-resources.yml index da0c42177690c4..bc6ee55812edd9 100644 --- a/eng/pipelines/common/templates/pipeline-with-resources.yml +++ b/eng/pipelines/common/templates/pipeline-with-resources.yml @@ -49,15 +49,15 @@ extends: # This container contains all required toolsets to build for Android and for Linux with bionic libc. android: - image: mcr.microsoft.com/dotnet-buildtools/prereqs:azurelinux-3.0-net8.0-cross-android-amd64 + image: jeremikurdek.azurecr.io/net8.0-ndk27-cross:v1 # This container contains all required toolsets to build for Android and for Linux with bionic libc and a special layout of OpenSSL. linux_bionic: - image: mcr.microsoft.com/dotnet-buildtools/prereqs:azurelinux-3.0-net8.0-android-openssl + image: jeremikurdek.azurecr.io/net8.0-ndk27-openssl:v1 # This container contains all required toolsets to build for Android as well as tooling to build docker images. android_docker: - image: mcr.microsoft.com/dotnet-buildtools/prereqs:azurelinux-3.0-net8.0-android-docker-amd64 + image: jeremikurdek.azurecr.io/net8.0-ndk27:v1 linux_x64: image: mcr.microsoft.com/dotnet-buildtools/prereqs:azurelinux-3.0-net8.0-cross-amd64 From 4a06f93eb2721d2eaab9f07b8462dcd85b5fdd88 Mon Sep 17 00:00:00 2001 From: Jeremi Kurdek <59935235+jkurdek@users.noreply.github.com> Date: Thu, 13 Feb 2025 11:30:35 +0100 Subject: [PATCH 9/9] Update container images to version v2 --- eng/pipelines/common/templates/pipeline-with-resources.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/eng/pipelines/common/templates/pipeline-with-resources.yml b/eng/pipelines/common/templates/pipeline-with-resources.yml index bc6ee55812edd9..1d3c4c8cd569ef 100644 --- a/eng/pipelines/common/templates/pipeline-with-resources.yml +++ b/eng/pipelines/common/templates/pipeline-with-resources.yml @@ -49,15 +49,15 @@ extends: # This container contains all required toolsets to build for Android and for Linux with bionic libc. android: - image: jeremikurdek.azurecr.io/net8.0-ndk27-cross:v1 + image: jeremikurdek.azurecr.io/net8.0-ndk27-cross:v2 # This container contains all required toolsets to build for Android and for Linux with bionic libc and a special layout of OpenSSL. linux_bionic: - image: jeremikurdek.azurecr.io/net8.0-ndk27-openssl:v1 + image: jeremikurdek.azurecr.io/net8.0-ndk27-openssl:v2 # This container contains all required toolsets to build for Android as well as tooling to build docker images. android_docker: - image: jeremikurdek.azurecr.io/net8.0-ndk27:v1 + image: jeremikurdek.azurecr.io/net8.0-ndk27:v2 linux_x64: image: mcr.microsoft.com/dotnet-buildtools/prereqs:azurelinux-3.0-net8.0-cross-amd64