Skip to content

Commit 7ea3ab4

Browse files
github-actions[bot]jkurdeksteveisokfilipnavarajeffschwMSFT
authored
[release/8.0-staging] Change assembler to clang in android MonoAOT (#111666)
* Change assembler to clang in android MonoAOT * Disabled NdkToolFinder task * Port changes to sample app * Allowed overwriting AsOptions * Since we bumped the NDK in dotnet/dotnet-buildtools-prereqs-docker#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. * Backported parts of #96332 * 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 --------- Co-authored-by: Jeremi Kurdek <[email protected]> Co-authored-by: Steve Pfister <[email protected]> Co-authored-by: Filip Navara <[email protected]> Co-authored-by: Jeremi Kurdek <[email protected]> Co-authored-by: Jeff Schwartz <[email protected]>
1 parent 1f87c0a commit 7ea3ab4

File tree

8 files changed

+122
-52
lines changed

8 files changed

+122
-52
lines changed

src/mono/mono.proj

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -688,7 +688,9 @@
688688

689689
<!-- Linux specific options -->
690690
<ItemGroup Condition="'$(AotHostOS)' == 'linux'">
691-
<_LibClang Include="$(ANDROID_NDK_ROOT)/toolchains/llvm/prebuilt/$(MonoToolchainPrebuiltOS)/lib64/libclang.so.*"/>
691+
<_LibClang Include="$(ANDROID_NDK_ROOT)/toolchains/llvm/prebuilt/$(MonoToolchainPrebuiltOS)/lib/libclang.so" Condition=" Exists('$(ANDROID_NDK_ROOT)/toolchains/llvm/prebuilt/$(MonoToolchainPrebuiltOS)/lib/libclang.so') "/>
692+
<_LibClang Include="$(ANDROID_NDK_ROOT)/toolchains/llvm/prebuilt/$(MonoToolchainPrebuiltOS)/lib64/libclang.so.*" Condition=" '@(_LibClang)' == '' "/>
693+
<_LibClang Include="/usr/local/lib/libclang.so" Condition="'@(_LibClang)' == ''" />
692694
</ItemGroup>
693695
<PropertyGroup Condition="'$(TargetsLinux)' == 'true' and '$(Platform)' == 'arm64'">
694696
<MonoUseCrossTool>true</MonoUseCrossTool>

src/mono/mono/mini/aot-compiler.c

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -240,8 +240,11 @@ typedef struct MonoAotOptions {
240240
gboolean allow_errors;
241241
char *tool_prefix;
242242
char *as_prefix;
243+
char *as_name;
244+
char *as_options;
243245
char *ld_flags;
244246
char *ld_name;
247+
char *ld_options;
245248
char *mtriple;
246249
char *llvm_path;
247250
char *temp_path;
@@ -8866,10 +8869,16 @@ mono_aot_parse_options (const char *aot_options, MonoAotOptions *opts)
88668869
opts->tool_prefix = g_strdup (arg + strlen ("tool-prefix="));
88678870
} else if (str_begins_with (arg, "as-prefix=")) {
88688871
opts->as_prefix = g_strdup (arg + strlen ("as-prefix="));
8872+
} else if (str_begins_with (arg, "as-name=")) {
8873+
opts->as_name = g_strdup (arg + strlen ("as-name="));
8874+
} else if (str_begins_with (arg, "as-options=")) {
8875+
opts->as_options = g_strdup (arg + strlen ("as-options="));
88698876
} else if (str_begins_with (arg, "ld-flags=")) {
88708877
opts->ld_flags = g_strdup (arg + strlen ("ld-flags="));
88718878
} else if (str_begins_with (arg, "ld-name=")) {
88728879
opts->ld_name = g_strdup (arg + strlen ("ld-name="));
8880+
} else if (str_begins_with (arg, "ld-options=")) {
8881+
opts->ld_options = g_strdup (arg + strlen ("ld-options="));
88738882
} else if (str_begins_with (arg, "soft-debug")) {
88748883
opts->soft_debug = TRUE;
88758884
// Intentionally undocumented x2-- deprecated
@@ -13275,7 +13284,16 @@ compile_asm (MonoAotCompile *acfg)
1327513284
g_string_append (acfg->as_args, "-c -x assembler ");
1327613285
#endif
1327713286

13278-
command = g_strdup_printf ("\"%s%s\" %s %s -o %s %s", as_prefix, AS_NAME, AS_OPTIONS,
13287+
const char *as_binary_name = acfg->aot_opts.as_name;
13288+
if (as_binary_name == NULL) {
13289+
as_binary_name = AS_NAME;
13290+
}
13291+
const char *as_options = acfg->aot_opts.as_options;
13292+
if (as_options == NULL) {
13293+
as_options = AS_OPTIONS;
13294+
}
13295+
13296+
command = g_strdup_printf ("\"%s%s\" %s %s -o %s %s", as_prefix, as_binary_name, as_options,
1327913297
acfg->as_args ? acfg->as_args->str : "",
1328013298
wrap_path (objfile), wrap_path (acfg->tmpfname));
1328113299
aot_printf (acfg, "Executing the native assembler: %s\n", command);
@@ -13286,7 +13304,7 @@ compile_asm (MonoAotCompile *acfg)
1328613304
}
1328713305

1328813306
if (acfg->llvm && !acfg->llvm_owriter) {
13289-
command = g_strdup_printf ("\"%s%s\" %s %s -o %s %s", as_prefix, AS_NAME, AS_OPTIONS,
13307+
command = g_strdup_printf ("\"%s%s\" %s %s -o %s %s", as_prefix, as_binary_name, as_options,
1329013308
acfg->as_args ? acfg->as_args->str : "",
1329113309
wrap_path (acfg->llvm_ofile), wrap_path (acfg->llvm_sfile));
1329213310
aot_printf (acfg, "Executing the native assembler: %s\n", command);
@@ -13335,16 +13353,21 @@ compile_asm (MonoAotCompile *acfg)
1333513353

1333613354
str = g_string_new ("");
1333713355
const char *ld_binary_name = acfg->aot_opts.ld_name;
13356+
13357+
const char *ld_options = acfg->aot_opts.ld_options;
13358+
if (ld_options == NULL) {
13359+
ld_options = LD_OPTIONS;
13360+
}
1333813361
#if defined(LD_NAME)
1333913362
if (ld_binary_name == NULL) {
1334013363
ld_binary_name = LD_NAME;
1334113364
}
1334213365
if (acfg->aot_opts.tool_prefix)
13343-
g_string_append_printf (str, "\"%s%s\" %s", tool_prefix, ld_binary_name, LD_OPTIONS);
13366+
g_string_append_printf (str, "\"%s%s\" %s", tool_prefix, ld_binary_name, ld_options);
1334413367
else if (acfg->aot_opts.llvm_only)
1334513368
g_string_append_printf (str, "%s", acfg->aot_opts.clangxx);
1334613369
else
13347-
g_string_append_printf (str, "\"%s%s\" %s", tool_prefix, ld_binary_name, LD_OPTIONS);
13370+
g_string_append_printf (str, "\"%s%s\" %s", tool_prefix, ld_binary_name, ld_options);
1334813371
#else
1334913372
if (ld_binary_name == NULL) {
1335013373
ld_binary_name = "ld";
@@ -13353,7 +13376,7 @@ compile_asm (MonoAotCompile *acfg)
1335313376
// Default (linux)
1335413377
if (acfg->aot_opts.tool_prefix)
1335513378
/* Cross compiling */
13356-
g_string_append_printf (str, "\"%s%s\" %s", tool_prefix, ld_binary_name, LD_OPTIONS);
13379+
g_string_append_printf (str, "\"%s%s\" %s", tool_prefix, ld_binary_name, ld_options);
1335713380
else if (acfg->aot_opts.llvm_only)
1335813381
g_string_append_printf (str, "%s", acfg->aot_opts.clangxx);
1335913382
else
@@ -14284,8 +14307,11 @@ aot_opts_free (MonoAotOptions *aot_opts)
1428414307
g_free (aot_opts->dedup_include);
1428514308
g_free (aot_opts->tool_prefix);
1428614309
g_free (aot_opts->as_prefix);
14310+
g_free (aot_opts->as_name);
14311+
g_free (aot_opts->as_options);
1428714312
g_free (aot_opts->ld_flags);
1428814313
g_free (aot_opts->ld_name);
14314+
g_free (aot_opts->ld_options);
1428914315
g_free (aot_opts->mtriple);
1429014316
g_free (aot_opts->llvm_path);
1429114317
g_free (aot_opts->temp_path);

src/mono/msbuild/android/build/AndroidBuild.targets

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -125,12 +125,21 @@
125125
<_AotOutputType>ObjectFile</_AotOutputType>
126126
</PropertyGroup>
127127

128-
<ItemGroup>
129-
<MonoAOTCompilerDefaultAotArguments Condition="'$(TargetArchitecture)' == 'arm'" Include="mtriple=armv7-linux-gnueabi" />
130-
<MonoAOTCompilerDefaultAotArguments Condition="'$(TargetArchitecture)' == 'arm64'" Include="mtriple=aarch64-linux-android" />
131-
<MonoAOTCompilerDefaultAotArguments Condition="'$(TargetArchitecture)' == 'x86'" Include="mtriple=i686-linux-android" />
132-
<MonoAOTCompilerDefaultAotArguments Condition="'$(TargetArchitecture)' == 'x64'" Include="mtriple=x86_64-linux-android" />
128+
<PropertyGroup>
129+
<_Triple Condition="'$(TargetArchitecture)' == 'arm'">armv7-linux-gnueabi</_Triple>
130+
<_Triple Condition="'$(TargetArchitecture)' == 'arm64'">aarch64-linux-android</_Triple>
131+
<_Triple Condition="'$(TargetArchitecture)' == 'x86'">i686-linux-android</_Triple>
132+
<_Triple Condition="'$(TargetArchitecture)' == 'x64'">x86_64-linux-android</_Triple>
133+
</PropertyGroup>
134+
135+
<PropertyGroup>
136+
<_AsOptions>-target $(_Triple) -c -x assembler</_AsOptions>
137+
<_LdName>clang</_LdName>
138+
<_LdOptions>-fuse-ld=lld</_LdOptions>
139+
<_AsName>clang</_AsName>
140+
</PropertyGroup>
133141

142+
<ItemGroup>
134143
<MonoAOTCompilerDefaultAotArguments Include="static" />
135144
<MonoAOTCompilerDefaultAotArguments Include="dwarfdebug" />
136145
<MonoAOTCompilerDefaultAotArguments Condition="'$(_IsLibraryMode)' == 'true'" Include="direct-icalls" />
@@ -154,19 +163,6 @@
154163
<AndroidLibraryMinApiLevel Condition="'$(AndroidLibraryMinApiLevel)' == ''">21</AndroidLibraryMinApiLevel>
155164
</PropertyGroup>
156165

157-
<NdkToolFinderTask
158-
Condition="'$(AOTWithLibraryFiles)' == 'true' or '$(_IsLibraryMode)' == 'true'"
159-
Architecture="$(TargetArchitecture)"
160-
HostOS="$(_HostOS)"
161-
MinApiLevel="$(AndroidLibraryMinApiLevel)">
162-
<Output TaskParameter="AsPrefixPath" PropertyName="_AsPrefixPath" />
163-
<Output TaskParameter="ToolPrefixPath" PropertyName="_ToolPrefixPath" />
164-
<Output TaskParameter="Triple" PropertyName="_Triple" />
165-
<Output TaskParameter="LdName" PropertyName="_LdName" />
166-
<Output TaskParameter="LdPath" PropertyName="_LdPath" />
167-
<Output TaskParameter="ClangPath" PropertyName="_ClangPath" />
168-
</NdkToolFinderTask>
169-
170166
<PropertyGroup Condition="'$(AOTWithLibraryFiles)' == 'true' or '$(_IsLibraryMode)' == 'true'">
171167
<_AsPrefixPath>$([MSBuild]::EnsureTrailingSlash('$(_AsPrefixPath)'))</_AsPrefixPath>
172168
<_ToolPrefixPath>$([MSBuild]::EnsureTrailingSlash('$(_ToolPrefixPath)'))</_ToolPrefixPath>
@@ -234,20 +230,23 @@
234230

235231
<MonoAOTCompiler
236232
AotModulesTablePath="$(_AotModuleTablePath)"
237-
AsPrefix="$(_AsPrefixPath)"
233+
AsName="$(_AsName)"
234+
AsOptions="$(_AsOptions)"
238235
Assemblies="@(_AotInputAssemblies)"
239236
CompilerBinaryPath="$(_CompilerBinaryPath)"
240237
DirectPInvokes="@(DirectPInvokes)"
241238
DirectPInvokeLists="@(DirectPInvokeLists)"
242239
EnableUnmanagedCallersOnlyMethodsExport="$(_EnableUnmanagedCallersOnlyMethodsExport)"
243240
IntermediateOutputPath="$(_MobileIntermediateOutputPath)"
241+
LdName="$(_LdName)"
242+
LdOptions="$(_LdOptions)"
244243
LibraryFormat="$(_AotLibraryFormat)"
245244
LLVMPath="$(_MonoLLVMPath)"
246245
MibcProfilePath="@(ProfiledAOTProfilePaths)"
247246
Mode="$(_AOTMode)"
248247
OutputDir="$(_MobileIntermediateOutputPath)"
249248
OutputType="$(_AotOutputType)"
250-
ToolPrefix="$(_ToolPrefixPath)"
249+
Triple="$(_Triple)"
251250
UseAotDataFile="$(_UseAotDataFile)"
252251
UseLLVM="$(MonoEnableLLVM)">
253252
<Output TaskParameter="CompiledAssemblies" ItemName="_AssembliesToBundleInternal" />

src/mono/sample/Android/AndroidSampleApp.csproj

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -70,36 +70,40 @@
7070
<AndroidLibraryMinApiLevel Condition="'$(AndroidLibraryMinApiLevel)' == ''">21</AndroidLibraryMinApiLevel>
7171
</PropertyGroup>
7272

73-
<NdkToolFinderTask
74-
Condition="'$(AOTWithLibraryFiles)' == 'true'"
75-
Architecture="$(TargetArchitecture)"
76-
HostOS="$(_HostOS)"
77-
MinApiLevel="$(AndroidLibraryMinApiLevel)">
78-
<Output TaskParameter="AsPrefixPath" PropertyName="_AsPrefixPath" />
79-
<Output TaskParameter="ToolPrefixPath" PropertyName="_ToolPrefixPath" />
80-
<Output TaskParameter="Triple" PropertyName="_Triple" />
81-
<Output TaskParameter="LdName" PropertyName="_LdName" />
82-
<Output TaskParameter="LdPath" PropertyName="_LdPath" />
83-
<Output TaskParameter="ClangPath" PropertyName="_ClangPath" />
84-
</NdkToolFinderTask>
85-
8673
<PropertyGroup Condition="'$(AOTWithLibraryFiles)' == 'true'">
8774
<_AsPrefixPath>$([MSBuild]::EnsureTrailingSlash('$(_AsPrefixPath)'))</_AsPrefixPath>
8875
<_ToolPrefixPath>$([MSBuild]::EnsureTrailingSlash('$(_ToolPrefixPath)'))</_ToolPrefixPath>
8976
</PropertyGroup>
9077

78+
<PropertyGroup>
79+
<_Triple Condition="'$(TargetArchitecture)' == 'arm'">armv7-linux-gnueabi</_Triple>
80+
<_Triple Condition="'$(TargetArchitecture)' == 'arm64'">aarch64-linux-android</_Triple>
81+
<_Triple Condition="'$(TargetArchitecture)' == 'x86'">i686-linux-android</_Triple>
82+
<_Triple Condition="'$(TargetArchitecture)' == 'x64'">x86_64-linux-android</_Triple>
83+
</PropertyGroup>
84+
85+
<PropertyGroup>
86+
<_AsOptions>-target $(_Triple) -c -x assembler</_AsOptions>
87+
<_LdName>clang</_LdName>
88+
<_LdOptions>-fuse-ld=lld</_LdOptions>
89+
<_AsName>clang</_AsName>
90+
</PropertyGroup>
91+
9192
<MonoAOTCompiler Condition="'$(ForceAOT)' == 'true'"
9293
AotModulesTablePath="$(_AotModulesTablePath)"
93-
AsPrefix="$(_AsPrefixPath)"
94+
AsName="$(_AsName)"
95+
AsOptions="$(_AsOptions)"
9496
Assemblies="@(AotInputAssemblies)"
9597
CompilerBinaryPath="@(MonoAotCrossCompiler->WithMetadataValue('RuntimeIdentifier','$(TargetOS)-$(TargetArchitecture.ToLowerInvariant())'))"
9698
IntermediateOutputPath="$(IntermediateOutputPath)"
99+
LdName="$(_LdName)"
100+
LdOptions="$(_LdOptions)"
97101
LibraryFormat="$(_AotLibraryFormat)"
98102
LLVMPath="$(MonoAotCrossDir)"
99103
Mode="$(_AotMode)"
100104
OutputDir="$(_MobileIntermediateOutputPath)"
101105
OutputType="$(_AotOutputType)"
102-
ToolPrefix="$(_ToolPrefixPath)"
106+
Triple="$(_Triple)"
103107
UseAotDataFile="false"
104108
UseLLVM="$(UseLLVM)">
105109
<Output TaskParameter="CompiledAssemblies" ItemName="BundleAssemblies" />

src/native/libs/System.Native/pal_interfaceaddresses.c

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ static inline uint8_t mask2prefix(uint8_t* mask, int length)
117117
static int (*getifaddrs)(struct ifaddrs**) = NULL;
118118
static void (*freeifaddrs)(struct ifaddrs*) = NULL;
119119

120-
static void try_loading_getifaddrs()
120+
static void try_loading_getifaddrs(void)
121121
{
122122
if (android_get_device_api_level() >= 24)
123123
{
@@ -139,7 +139,7 @@ static void try_loading_getifaddrs()
139139
}
140140
}
141141

142-
static bool ensure_getifaddrs_is_loaded()
142+
static bool ensure_getifaddrs_is_loaded(void)
143143
{
144144
static pthread_once_t getifaddrs_is_loaded = PTHREAD_ONCE_INIT;
145145
pthread_once(&getifaddrs_is_loaded, try_loading_getifaddrs);
@@ -169,11 +169,12 @@ int32_t SystemNative_EnumerateInterfaceAddresses(void* context,
169169

170170
for (struct ifaddrs* current = headAddr; current != NULL; current = current->ifa_next)
171171
{
172-
if (current->ifa_addr == NULL)
172+
char *ifa_name = current->ifa_name;
173+
if (current->ifa_addr == NULL || ifa_name == NULL)
173174
{
174175
continue;
175176
}
176-
uint32_t interfaceIndex = if_nametoindex(current->ifa_name);
177+
uint32_t interfaceIndex = if_nametoindex(ifa_name);
177178
// ifa_name may be an aliased interface name.
178179
// Use if_indextoname to map back to the true device name.
179180
char actualName[IF_NAMESIZE];
@@ -376,9 +377,17 @@ int32_t SystemNative_GetNetworkInterfaces(int32_t * interfaceCount, NetworkInter
376377

377378
while (ifaddrsEntry != NULL)
378379
{
380+
char *ifa_name = ifaddrsEntry->ifa_name;
381+
382+
if (ifa_name == NULL)
383+
{
384+
ifaddrsEntry = ifaddrsEntry->ifa_next;
385+
continue;
386+
}
387+
379388
//current = NULL;
380389
nii = NULL;
381-
uint ifindex = if_nametoindex(ifaddrsEntry->ifa_name);
390+
uint ifindex = if_nametoindex(ifa_name);
382391
for (index = 0; index < (int)ifcount; index ++)
383392
{
384393
if (((NetworkInterfaceInfo*)memoryBlock)[index].InterfaceIndex == ifindex)
@@ -393,8 +402,8 @@ int32_t SystemNative_GetNetworkInterfaces(int32_t * interfaceCount, NetworkInter
393402
// We git new interface.
394403
nii = &((NetworkInterfaceInfo*)memoryBlock)[ifcount++];
395404

396-
memcpy(nii->Name, ifaddrsEntry->ifa_name, sizeof(nii->Name));
397-
nii->InterfaceIndex = if_nametoindex(ifaddrsEntry->ifa_name);
405+
memcpy(nii->Name, ifa_name, sizeof(nii->Name));
406+
nii->InterfaceIndex = ifindex;
398407
nii->Speed = -1;
399408
nii->HardwareType = ((ifaddrsEntry->ifa_flags & IFF_LOOPBACK) == IFF_LOOPBACK) ? NetworkInterfaceType_Loopback : NetworkInterfaceType_Unknown;
400409

src/native/libs/System.Security.Cryptography.Native.Android/pal_cipher.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ typedef struct CipherInfo
2020
} CipherInfo;
2121

2222
#define DEFINE_CIPHER(cipherId, width, javaName, flags) \
23-
CipherInfo* AndroidCryptoNative_ ## cipherId() \
23+
CipherInfo* AndroidCryptoNative_ ## cipherId(void) \
2424
{ \
2525
static CipherInfo info = { flags, width, javaName }; \
2626
return &info; \

src/tasks/AotCompilerTask/MonoAOTCompiler.cs

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Licensed to the .NET Foundation under one or more agreements.
1+
// Licensed to the .NET Foundation under one or more agreements.
22
// The .NET Foundation licenses this file to you under the MIT license.
33

44
using System;
@@ -231,6 +231,16 @@ public class MonoAOTCompiler : Microsoft.Build.Utilities.Task
231231
/// </summary>
232232
public string? ToolPrefix { get; set; }
233233

234+
/// <summary>
235+
/// Name of the assembler tool ran by the AOT compiler.
236+
/// </summary>
237+
public string? AsName { get; set; }
238+
239+
/// <summary>
240+
/// Passes as-options to the AOT compiler
241+
/// </summary>
242+
public string? AsOptions { get; set; }
243+
234244
/// <summary>
235245
/// Prepends a prefix to the name of the assembler (as) tool ran by the AOT compiler.
236246
/// </summary>
@@ -278,6 +288,11 @@ public class MonoAOTCompiler : Microsoft.Build.Utilities.Task
278288
/// </summary>
279289
public string? LdFlags { get; set; }
280290

291+
/// <summary>
292+
/// Passes ld-options to the AOT compiler
293+
/// </summary>
294+
public string? LdOptions { get; set; }
295+
281296
/// <summary>
282297
/// Specify WorkingDirectory for the AOT compiler
283298
/// </summary>
@@ -728,6 +743,16 @@ private PrecompileArguments GetPrecompileArgumentsFor(ITaskItem assemblyItem, st
728743
aotArgs.Add($"tool-prefix={ToolPrefix}");
729744
}
730745

746+
if (!string.IsNullOrEmpty(AsName))
747+
{
748+
aotArgs.Add($"as-name={AsName}");
749+
}
750+
751+
if (!string.IsNullOrEmpty(AsOptions))
752+
{
753+
aotArgs.Add($"as-options={AsOptions}");
754+
}
755+
731756
if (!string.IsNullOrEmpty(AsPrefix))
732757
{
733758
aotArgs.Add($"as-prefix={AsPrefix}");
@@ -943,6 +968,11 @@ private PrecompileArguments GetPrecompileArgumentsFor(ITaskItem assemblyItem, st
943968
aotArgs.Add($"ld-flags={LdFlags}");
944969
}
945970

971+
if (!string.IsNullOrEmpty(LdOptions))
972+
{
973+
aotArgs.Add($"ld-options={LdOptions}");
974+
}
975+
946976
// we need to quote the entire --aot arguments here to make sure it is parsed
947977
// on Windows as one argument. Otherwise it will be split up into multiple
948978
// values, which wont work.

src/tasks/MobileBuildTasks/Android/Ndk/NdkTools.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,9 +101,9 @@ public string ClangPath
101101

102102
private void ValidateRequiredProps(string hostOS)
103103
{
104-
if (Ndk.NdkVersion.Main.Major != 23)
104+
if (Ndk.NdkVersion.Main.Major != 27)
105105
{
106-
throw new Exception($"NDK 23 is required. An unsupported NDK version was found ({Ndk.NdkVersion.Main.Major}).");
106+
throw new Exception($"NDK 27 is required. An unsupported NDK version was found ({Ndk.NdkVersion.Main.Major}).");
107107
}
108108

109109
try

0 commit comments

Comments
 (0)