From e0b8ca37b57d93c43a67af6a872df20f7d763b86 Mon Sep 17 00:00:00 2001 From: Ivan Povazan Date: Thu, 16 Feb 2023 14:00:11 +0100 Subject: [PATCH 01/10] Integrate AppleAppBuilder with NativeAOT runtime --- src/tasks/AppleAppBuilder/AppleAppBuilder.cs | 14 +++++ .../Templates/CMakeLists.txt.template | 7 +++ .../AppleAppBuilder/Templates/main-simple.m | 8 +-- src/tasks/AppleAppBuilder/Templates/util.h | 10 ++++ src/tasks/AppleAppBuilder/Templates/util.m | 52 +++++++++++++++++++ src/tasks/AppleAppBuilder/Xcode.cs | 5 ++ 6 files changed, 93 insertions(+), 3 deletions(-) create mode 100644 src/tasks/AppleAppBuilder/Templates/util.h create mode 100644 src/tasks/AppleAppBuilder/Templates/util.m diff --git a/src/tasks/AppleAppBuilder/AppleAppBuilder.cs b/src/tasks/AppleAppBuilder/AppleAppBuilder.cs index 6182f971f0860..98c06f8ac5fc8 100644 --- a/src/tasks/AppleAppBuilder/AppleAppBuilder.cs +++ b/src/tasks/AppleAppBuilder/AppleAppBuilder.cs @@ -171,6 +171,11 @@ public string TargetOS /// public bool UseNativeAOTRuntime { get; set; } + /// + /// List of static libraries to link with the program. + /// + public ITaskItem[] NativeLibraries { get; set; } = Array.Empty(); + public void ValidateRuntimeSelection() { if (UseNativeAOTRuntime) @@ -267,6 +272,15 @@ public override bool Execute() } } + foreach (ITaskItem nativeLibrary in NativeLibraries) + { + string nativeLibraryFile = nativeLibrary.GetMetadata("Identity"); + if (!string.IsNullOrEmpty(nativeLibraryFile)) + { + assemblerFilesToLink.Add(nativeLibraryFile); + } + } + if (!ForceInterpreter && (isDevice || ForceAOT) && (assemblerFiles.Count == 0 && !UseNativeAOTRuntime)) { throw new InvalidOperationException("Need list of AOT files for device builds."); diff --git a/src/tasks/AppleAppBuilder/Templates/CMakeLists.txt.template b/src/tasks/AppleAppBuilder/Templates/CMakeLists.txt.template index aba07978fb990..7952a3bcb29a9 100644 --- a/src/tasks/AppleAppBuilder/Templates/CMakeLists.txt.template +++ b/src/tasks/AppleAppBuilder/Templates/CMakeLists.txt.template @@ -20,6 +20,12 @@ if(NOT %UseNativeAOTRuntime%) %AotModulesSource% runtime.h runtime.m) +else() + target_sources( + %ProjectName% + PRIVATE + util.h + util.m) endif() %AotSources% @@ -73,5 +79,6 @@ target_link_libraries( "-lz" "-lc++" "-liconv" + "-Wl,-u,_NativeAOT_StaticInitialization" %NativeLibrariesToLink% ) diff --git a/src/tasks/AppleAppBuilder/Templates/main-simple.m b/src/tasks/AppleAppBuilder/Templates/main-simple.m index 270bf23d93f94..5364779a5ac82 100644 --- a/src/tasks/AppleAppBuilder/Templates/main-simple.m +++ b/src/tasks/AppleAppBuilder/Templates/main-simple.m @@ -5,7 +5,7 @@ #if !USE_NATIVE_AOT #import "runtime.h" #else -extern void* NativeAOT_StaticInitialization(); +#import "util.h" extern int __managed__Main(int argc, char* argv[]); #endif @@ -57,8 +57,10 @@ - (void)viewDidLoad { #if INVARIANT_GLOBALIZATION setenv ("DOTNET_SYSTEM_GLOBALIZATION_INVARIANT", "1", TRUE); #endif - NativeAOT_StaticInitialization(); - int ret_val = __managed__Main(0, NULL); + char **managed_argv; + int managed_argc = get_managed_args (&managed_argv); + int ret_val = __managed__Main (managed_argc, managed_argv); + free_managed_args (&managed_argv, managed_argc); #endif }); } diff --git a/src/tasks/AppleAppBuilder/Templates/util.h b/src/tasks/AppleAppBuilder/Templates/util.h new file mode 100644 index 0000000000000..e1ec72e12f7ed --- /dev/null +++ b/src/tasks/AppleAppBuilder/Templates/util.h @@ -0,0 +1,10 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +#ifndef util_h +#define util_h + +size_t get_managed_args (char*** managed_args_array); +void free_managed_args (char*** managed_args_array, size_t array_size); + +#endif /* util_h */ diff --git a/src/tasks/AppleAppBuilder/Templates/util.m b/src/tasks/AppleAppBuilder/Templates/util.m new file mode 100644 index 0000000000000..e20b77f1bde11 --- /dev/null +++ b/src/tasks/AppleAppBuilder/Templates/util.m @@ -0,0 +1,52 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +#import + +//--------------------------------------------------------------------------------------- +// +// get_managed_args: converts arguments passed to the Objective-C program to their +// C-representation so they can be passed to the managed side. +// The caller is responsible for freeing up the allocated memory. +// This can be achieved by calling the accompanied 'free_managed_args' function. +// +// Arguments: +// * managed_args_array - pointer to array of strings to hold converted arguments. +// +// Return Value: +// int - number of arguments (size of the array of string) +// +size_t get_managed_args (char*** managed_args_array) +{ + id args_array = [[NSProcessInfo processInfo] arguments]; + size_t args_count = [args_array count]; + assert (args_count <= 128); + *managed_args_array = (char**) malloc (sizeof(char**) * args_count); + size_t argi; + for (argi = 0; argi < args_count; argi++) { + NSString* arg = [args_array objectAtIndex: argi]; + const char* cstring = [arg UTF8String]; + size_t cstring_len = strlen(cstring) + 1; + (*managed_args_array)[argi] = (char*) malloc (sizeof(char*) * cstring_len); + strcpy((*managed_args_array)[argi], cstring); + } + return argi; +} + +//--------------------------------------------------------------------------------------- +// +// free_managed_args: frees up the allocated memory for the program arguments. +// +// Arguments: +// * managed_args_array - pointer to array of strings which converted program arguments +// * array_size - number of arguments (size of the array of string) +// +void free_managed_args (char*** managed_args_array, size_t array_size) +{ + if (*managed_args_array != NULL) + { + for (size_t i = 0; i < array_size; i++) + free((*managed_args_array)[i]); + free(*managed_args_array); + } +} \ No newline at end of file diff --git a/src/tasks/AppleAppBuilder/Xcode.cs b/src/tasks/AppleAppBuilder/Xcode.cs index ea6e0dd31aaeb..07d0fcc84882f 100644 --- a/src/tasks/AppleAppBuilder/Xcode.cs +++ b/src/tasks/AppleAppBuilder/Xcode.cs @@ -455,6 +455,11 @@ public string GenerateCMake( .Replace("//%APPLE_RUNTIME_IDENTIFIER%", RuntimeIdentifier) .Replace("%EntryPointLibName%", Path.GetFileName(entryPointLib))); } + else + { + File.WriteAllText(Path.Combine(binDir, "util.h"), Utils.GetEmbeddedResource("util.h")); + File.WriteAllText(Path.Combine(binDir, "util.m"), Utils.GetEmbeddedResource("util.m")); + } return binDir; } From 53baa49163c4436d0e21a33373db17c279b448ef Mon Sep 17 00:00:00 2001 From: Ivan Povazan Date: Thu, 16 Feb 2023 14:01:27 +0100 Subject: [PATCH 02/10] Add HelloiOS sample variant for NativeAOT --- src/mono/sample/iOS-NativeAOT/Makefile | 51 +++++++++++ src/mono/sample/iOS-NativeAOT/Program.csproj | 96 ++++++++++++++++++++ 2 files changed, 147 insertions(+) create mode 100644 src/mono/sample/iOS-NativeAOT/Makefile create mode 100644 src/mono/sample/iOS-NativeAOT/Program.csproj diff --git a/src/mono/sample/iOS-NativeAOT/Makefile b/src/mono/sample/iOS-NativeAOT/Makefile new file mode 100644 index 0000000000000..6cfe6f9f3f230 --- /dev/null +++ b/src/mono/sample/iOS-NativeAOT/Makefile @@ -0,0 +1,51 @@ +.DEFAULT_GOAL := all + +TOP=../../../../ + +BUILD_CONFIG?=Debug +TARGET_ARCH?=$(shell . $(TOP)eng/native/init-os-and-arch.sh && echo $${arch}) +TARGET_OS?=iossimulator +DEPLOY_AND_RUN?=false +STRIP_DEBUG_SYMBOLS?=false + +REPO_DIR=$(realpath $(TOP)) +TASKS_DIR=$(REPO_DIR)/src/tasks +DOTNET=$(REPO_DIR)/dotnet.sh +BUILD_SCRIPT=$(REPO_DIR)/build.sh + +world: build-deps all + +# build all dependencies: runtime, nativeAot and all the libs +build-deps: build-runtime-ilc build-libs-all + +# building for host +build-runtime-ilc: + $(BUILD_SCRIPT) clr+clr.aot -c $(BUILD_CONFIG) + +build-ilc: + $(BUILD_SCRIPT) clr.aot -c $(BUILD_CONFIG) + +# building for target platform +build-libs-all: + $(BUILD_SCRIPT) clr.nativeaotruntime+clr.nativeaotlibs+libs -c $(BUILD_CONFIG) -os $(TARGET_OS) -arch $(TARGET_ARCH) + +build-libs-nativeaot: + $(BUILD_SCRIPT) clr.nativeaotruntime+clr.nativeaotlibs -c $(BUILD_CONFIG) -os $(TARGET_OS) -arch $(TARGET_ARCH) + +all: appbuilder hello-app + +appbuilder: + $(DOTNET) build -c $(BUILD_CONFIG) $(TASKS_DIR)/AppleAppBuilder/AppleAppBuilder.csproj + +hello-app: clean + $(DOTNET) \ + build -c $(BUILD_CONFIG) \ + /p:TargetOS=$(TARGET_OS) \ + /p:TargetArchitecture=$(TARGET_ARCH) \ + /p:RepoDir=$(REPO_DIR) \ + /p:DeployAndRun=$(DEPLOY_AND_RUN) \ + /p:StripDebugSymbols=$(STRIP_DEBUG_SYMBOLS) \ + -bl + +clean: + rm -rf obj bin \ No newline at end of file diff --git a/src/mono/sample/iOS-NativeAOT/Program.csproj b/src/mono/sample/iOS-NativeAOT/Program.csproj new file mode 100644 index 0000000000000..85c697fa6307a --- /dev/null +++ b/src/mono/sample/iOS-NativeAOT/Program.csproj @@ -0,0 +1,96 @@ + + + Exe + bin + $(MSBuildThisFileDirectory)/obj/ + net7.0 + ios + iossimulator + true + $(TargetOS)-$(TargetArchitecture) + HelloiOS + false + + static + true + true + + true + + $(OutputPath)/publish + + + + + + + + + adhoc + false + + + + + + + + $(RepoDir)/artifacts/bin/runtime/net8.0-$(TargetOS)-$(Configuration)-$(TargetArchitecture)/ + $(RepoDir)/artifacts/bin/coreclr/$(TargetOS).$(TargetArchitecture).$(Configuration)/ + $([System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture.ToString().ToLowerInvariant) + $(RepoDir)/artifacts/bin/coreclr/osx.$(IlcHostArchitecture).$(Configuration)/ilc/ + $(IlcPath) + $(NativeAotRuntimeLibsDir)/aotsdk/ + $(NativeAotFrameworkLibsDir) + $(NativeAotFrameworkLibsDir) + + + + + + $(MSBuildThisFileDirectory)$(PublishDir)\app + iPhone 11 + True + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From 433f8dfb9116096de98da2d58fe186ca7514e5ff Mon Sep 17 00:00:00 2001 From: Ivan Povazan Date: Thu, 16 Feb 2023 18:18:12 +0100 Subject: [PATCH 03/10] Adding a README.md --- src/mono/sample/iOS-NativeAOT/README.md | 55 +++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 src/mono/sample/iOS-NativeAOT/README.md diff --git a/src/mono/sample/iOS-NativeAOT/README.md b/src/mono/sample/iOS-NativeAOT/README.md new file mode 100644 index 0000000000000..b3d6ada48df12 --- /dev/null +++ b/src/mono/sample/iOS-NativeAOT/README.md @@ -0,0 +1,55 @@ +# NativeAOT iOS sample app + +This sample application should be used as PoC for verifying that NativeAOT can be used for targeting iOS-like platforms: +- ios +- iossimulator +- tvos +- tvossimulator +- maccatalyst + +The sample shares the source code with the Mono sample specified at: `../iOS/Program.cs` and in general should have the same behavior as MonoAOT. + +## How to build + +### Building for the first time + +When building for the first time (on a clean checkout) run from this directory the following `make` command: +``` bash +make world +``` +This will first build all required runtime components and dependencies, after which it will build the sample app and bundle it into an application bundle. +By default the build will use `Debug` build configuration and target `iossimulator`. +To change this behavior, specify the desired setting in the following way: +``` bash +make world BUILD_CONFIG=Release TARGET_OS=ios +``` + +### To avoid building all the dependencies + +For future builds, you can run just: +``` bash +make +``` +which will skip building all the runtime dependencies, assuming those have been already properly built, and build the MSBuild task used for bundling the application and the application it self. + +For convenience, it is also possible to rebuild only the application it self with: +``` bash +make hello-app +``` + +### Deploy and run + +To test the application on a simulator include the following in your make command `DEPLOY_AND_RUN=true` e.g.,: +``` bash +make hello-app DEPLOY_AND_RUN=true +``` + +To test the application on a device, a provisioning profile needs to be specified. +This can be achieved by defining `DevTeamProvisioning` environment variable with a valid team ID (see [developer.apple.com/account/#/membership](https://developer.apple.com/account/#/membership), scroll down to `Team ID`) for example: +``` bash +export DevTeamProvisioning=H1A2B3C4D5; make hello-app TARGET_OS=ios DEPLOY_AND_RUN=true +``` + +### Custom builds + +Check the `Makefile` for individual list of targets and variables to customize the build. From ba174d28e14fa14774f6e0470c24810f659bb65b Mon Sep 17 00:00:00 2001 From: Ivan Povazan Date: Thu, 16 Feb 2023 18:19:31 +0100 Subject: [PATCH 04/10] Bump the version displayed on the screen when running HelloiOS app --- src/mono/sample/iOS/Program.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mono/sample/iOS/Program.cs b/src/mono/sample/iOS/Program.cs index 603ff2e4ebca3..1c9839a8ae0a2 100644 --- a/src/mono/sample/iOS/Program.cs +++ b/src/mono/sample/iOS/Program.cs @@ -35,7 +35,7 @@ public static async Task Main(string[] args) delegate* unmanaged unmanagedPtr = &OnButtonClick; ios_register_button_click(unmanagedPtr); } - const string msg = "Hello World!\n.NET 5.0"; + const string msg = "Hello World!\n.NET 8.0"; for (int i = 0; i < msg.Length; i++) { // a kind of an animation From 65b08e379cdffd7b2af499eea7803bf7b54f6a3b Mon Sep 17 00:00:00 2001 From: Ivan Povazan Date: Fri, 17 Feb 2023 12:38:01 +0100 Subject: [PATCH 05/10] Use util.m with Mono as well and fix the build --- .../Templates/CMakeLists.txt.template | 16 +++++++++------- src/tasks/AppleAppBuilder/Templates/runtime.m | 14 ++++++-------- src/tasks/AppleAppBuilder/Templates/util.m | 2 +- src/tasks/AppleAppBuilder/Xcode.cs | 8 +++----- 4 files changed, 19 insertions(+), 21 deletions(-) diff --git a/src/tasks/AppleAppBuilder/Templates/CMakeLists.txt.template b/src/tasks/AppleAppBuilder/Templates/CMakeLists.txt.template index 7952a3bcb29a9..3053a7e6b049b 100644 --- a/src/tasks/AppleAppBuilder/Templates/CMakeLists.txt.template +++ b/src/tasks/AppleAppBuilder/Templates/CMakeLists.txt.template @@ -11,6 +11,8 @@ add_executable( %ProjectName% %MainSource% ${APP_RESOURCES} + util.h + util.m ) if(NOT %UseNativeAOTRuntime%) @@ -20,12 +22,6 @@ if(NOT %UseNativeAOTRuntime%) %AotModulesSource% runtime.h runtime.m) -else() - target_sources( - %ProjectName% - PRIVATE - util.h - util.m) endif() %AotSources% @@ -79,6 +75,12 @@ target_link_libraries( "-lz" "-lc++" "-liconv" + %NativeLibrariesToLink% +) + +if(%UseNativeAOTRuntime%) +target_link_libraries( + %ProjectName% "-Wl,-u,_NativeAOT_StaticInitialization" -%NativeLibrariesToLink% ) +endif() \ No newline at end of file diff --git a/src/tasks/AppleAppBuilder/Templates/runtime.m b/src/tasks/AppleAppBuilder/Templates/runtime.m index 1d0cd6ff0076f..5e3b3390f629f 100644 --- a/src/tasks/AppleAppBuilder/Templates/runtime.m +++ b/src/tasks/AppleAppBuilder/Templates/runtime.m @@ -20,6 +20,8 @@ #include #include +#import "util.h" + static char *bundle_path; #define APPLE_RUNTIME_IDENTIFIER "//%APPLE_RUNTIME_IDENTIFIER%" @@ -254,14 +256,8 @@ setenv ("DOTNET_DiagnosticPorts", DIAGNOSTIC_PORTS, true); #endif - id args_array = [[NSProcessInfo processInfo] arguments]; - assert ([args_array count] <= 128); - const char *managed_argv [128]; - int argi; - for (argi = 0; argi < [args_array count]; argi++) { - NSString* arg = [args_array objectAtIndex: argi]; - managed_argv[argi] = [arg UTF8String]; - } + char **managed_argv; + int argi = get_managed_args (&managed_argv); bool wait_for_debugger = FALSE; @@ -373,5 +369,7 @@ mono_jit_cleanup (domain); + free_managed_args (&managed_argv, argi); + exit (res); } diff --git a/src/tasks/AppleAppBuilder/Templates/util.m b/src/tasks/AppleAppBuilder/Templates/util.m index e20b77f1bde11..7308f5c435fd1 100644 --- a/src/tasks/AppleAppBuilder/Templates/util.m +++ b/src/tasks/AppleAppBuilder/Templates/util.m @@ -49,4 +49,4 @@ void free_managed_args (char*** managed_args_array, size_t array_size) free((*managed_args_array)[i]); free(*managed_args_array); } -} \ No newline at end of file +} diff --git a/src/tasks/AppleAppBuilder/Xcode.cs b/src/tasks/AppleAppBuilder/Xcode.cs index 07d0fcc84882f..4561df0c4f7a7 100644 --- a/src/tasks/AppleAppBuilder/Xcode.cs +++ b/src/tasks/AppleAppBuilder/Xcode.cs @@ -455,11 +455,9 @@ public string GenerateCMake( .Replace("//%APPLE_RUNTIME_IDENTIFIER%", RuntimeIdentifier) .Replace("%EntryPointLibName%", Path.GetFileName(entryPointLib))); } - else - { - File.WriteAllText(Path.Combine(binDir, "util.h"), Utils.GetEmbeddedResource("util.h")); - File.WriteAllText(Path.Combine(binDir, "util.m"), Utils.GetEmbeddedResource("util.m")); - } + + File.WriteAllText(Path.Combine(binDir, "util.h"), Utils.GetEmbeddedResource("util.h")); + File.WriteAllText(Path.Combine(binDir, "util.m"), Utils.GetEmbeddedResource("util.m")); return binDir; } From c09b462d2c6cff976512d1a0e3b486dd37b23cc4 Mon Sep 17 00:00:00 2001 From: Ivan Povazan Date: Fri, 17 Feb 2023 17:40:09 +0100 Subject: [PATCH 06/10] Use NativeDependencies property instead to align with AndroidAppBuilder changes --- src/mono/sample/iOS-NativeAOT/Program.csproj | 2 +- src/tasks/AppleAppBuilder/AppleAppBuilder.cs | 12 ++++-------- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/src/mono/sample/iOS-NativeAOT/Program.csproj b/src/mono/sample/iOS-NativeAOT/Program.csproj index 85c697fa6307a..ec90992e8f6af 100644 --- a/src/mono/sample/iOS-NativeAOT/Program.csproj +++ b/src/mono/sample/iOS-NativeAOT/Program.csproj @@ -64,7 +64,7 @@ - /// List of static libraries to link with the program. + /// Extra native dependencies to link into the app /// - public ITaskItem[] NativeLibraries { get; set; } = Array.Empty(); + public string[] NativeDependencies { get; set; } = Array.Empty(); public void ValidateRuntimeSelection() { @@ -272,13 +272,9 @@ public override bool Execute() } } - foreach (ITaskItem nativeLibrary in NativeLibraries) + foreach (var nativeDependency in NativeDependencies) { - string nativeLibraryFile = nativeLibrary.GetMetadata("Identity"); - if (!string.IsNullOrEmpty(nativeLibraryFile)) - { - assemblerFilesToLink.Add(nativeLibraryFile); - } + assemblerFilesToLink.Add(nativeDependency); } if (!ForceInterpreter && (isDevice || ForceAOT) && (assemblerFiles.Count == 0 && !UseNativeAOTRuntime)) From b369a36adbba804708c1e9100e279bafa12009da Mon Sep 17 00:00:00 2001 From: Ivan Povazan Date: Tue, 21 Feb 2023 14:14:43 +0100 Subject: [PATCH 07/10] Adding fixes according to review feedback --- src/mono/sample/iOS-NativeAOT/Makefile | 10 +++++----- src/mono/sample/iOS-NativeAOT/Program.csproj | 2 +- src/tasks/AppleAppBuilder/Templates/util.m | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/mono/sample/iOS-NativeAOT/Makefile b/src/mono/sample/iOS-NativeAOT/Makefile index 6cfe6f9f3f230..757a513454f0f 100644 --- a/src/mono/sample/iOS-NativeAOT/Makefile +++ b/src/mono/sample/iOS-NativeAOT/Makefile @@ -40,11 +40,11 @@ appbuilder: hello-app: clean $(DOTNET) \ build -c $(BUILD_CONFIG) \ - /p:TargetOS=$(TARGET_OS) \ - /p:TargetArchitecture=$(TARGET_ARCH) \ - /p:RepoDir=$(REPO_DIR) \ - /p:DeployAndRun=$(DEPLOY_AND_RUN) \ - /p:StripDebugSymbols=$(STRIP_DEBUG_SYMBOLS) \ + -p:TargetOS=$(TARGET_OS) \ + -p:TargetArchitecture=$(TARGET_ARCH) \ + -p:RepoDir=$(REPO_DIR) \ + -p:DeployAndRun=$(DEPLOY_AND_RUN) \ + -p:StripDebugSymbols=$(STRIP_DEBUG_SYMBOLS) \ -bl clean: diff --git a/src/mono/sample/iOS-NativeAOT/Program.csproj b/src/mono/sample/iOS-NativeAOT/Program.csproj index ec90992e8f6af..b4eda50137b5a 100644 --- a/src/mono/sample/iOS-NativeAOT/Program.csproj +++ b/src/mono/sample/iOS-NativeAOT/Program.csproj @@ -26,7 +26,7 @@ - adhoc + adhoc false diff --git a/src/tasks/AppleAppBuilder/Templates/util.m b/src/tasks/AppleAppBuilder/Templates/util.m index 7308f5c435fd1..b80b56d7e2be7 100644 --- a/src/tasks/AppleAppBuilder/Templates/util.m +++ b/src/tasks/AppleAppBuilder/Templates/util.m @@ -21,13 +21,13 @@ size_t get_managed_args (char*** managed_args_array) id args_array = [[NSProcessInfo processInfo] arguments]; size_t args_count = [args_array count]; assert (args_count <= 128); - *managed_args_array = (char**) malloc (sizeof(char**) * args_count); + *managed_args_array = (char**) malloc (sizeof(char*) * args_count); size_t argi; for (argi = 0; argi < args_count; argi++) { NSString* arg = [args_array objectAtIndex: argi]; const char* cstring = [arg UTF8String]; size_t cstring_len = strlen(cstring) + 1; - (*managed_args_array)[argi] = (char*) malloc (sizeof(char*) * cstring_len); + (*managed_args_array)[argi] = (char*) malloc (sizeof(char) * cstring_len); strcpy((*managed_args_array)[argi], cstring); } return argi; From b62122120e0c6dc09af02ab17ae1136789dd19e3 Mon Sep 17 00:00:00 2001 From: Ivan Povazan Date: Thu, 23 Feb 2023 14:48:29 +0100 Subject: [PATCH 08/10] Adding fixes according to review feedback --- src/mono/sample/iOS-NativeAOT/Makefile | 1 - src/mono/sample/iOS-NativeAOT/Program.csproj | 25 +++++++++---------- .../AppleAppBuilder/Templates/main-simple.m | 3 +++ src/tasks/AppleAppBuilder/Templates/runtime.m | 3 --- src/tasks/AppleAppBuilder/Templates/util.h | 3 +++ 5 files changed, 18 insertions(+), 17 deletions(-) diff --git a/src/mono/sample/iOS-NativeAOT/Makefile b/src/mono/sample/iOS-NativeAOT/Makefile index 757a513454f0f..e1e295a75d9e7 100644 --- a/src/mono/sample/iOS-NativeAOT/Makefile +++ b/src/mono/sample/iOS-NativeAOT/Makefile @@ -42,7 +42,6 @@ hello-app: clean build -c $(BUILD_CONFIG) \ -p:TargetOS=$(TARGET_OS) \ -p:TargetArchitecture=$(TARGET_ARCH) \ - -p:RepoDir=$(REPO_DIR) \ -p:DeployAndRun=$(DEPLOY_AND_RUN) \ -p:StripDebugSymbols=$(STRIP_DEBUG_SYMBOLS) \ -bl diff --git a/src/mono/sample/iOS-NativeAOT/Program.csproj b/src/mono/sample/iOS-NativeAOT/Program.csproj index b4eda50137b5a..aa08743cddbab 100644 --- a/src/mono/sample/iOS-NativeAOT/Program.csproj +++ b/src/mono/sample/iOS-NativeAOT/Program.csproj @@ -3,7 +3,7 @@ Exe bin $(MSBuildThisFileDirectory)/obj/ - net7.0 + $(NetCoreAppCurrent) ios iossimulator true @@ -30,25 +30,24 @@ false - + - - $(RepoDir)/artifacts/bin/runtime/net8.0-$(TargetOS)-$(Configuration)-$(TargetArchitecture)/ - $(RepoDir)/artifacts/bin/coreclr/$(TargetOS).$(TargetArchitecture).$(Configuration)/ - $([System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture.ToString().ToLowerInvariant) - $(RepoDir)/artifacts/bin/coreclr/osx.$(IlcHostArchitecture).$(Configuration)/ilc/ - $(IlcPath) - $(NativeAotRuntimeLibsDir)/aotsdk/ - $(NativeAotFrameworkLibsDir) - $(NativeAotFrameworkLibsDir) - + + + $([MSBuild]::NormalizeDirectory('$(RepoRoot)', 'artifacts', 'bin', 'coreclr', '$(HostOS).$(BuildArchitecture).$(CoreCLRConfiguration)', 'ilc')) + $(IlcPath) + $(CoreCLRAotSdkDir) + $(LibrariesAllBinArtifactsPath) + $(LibrariesAllBinArtifactsPath) + + + DependsOnTargets="ConfigureIlcPathsForiOSCrossCompilation;SetupProperties;ComputeIlcCompileInputs;IlcCompile"> $(MSBuildThisFileDirectory)$(PublishDir)\app diff --git a/src/tasks/AppleAppBuilder/Templates/main-simple.m b/src/tasks/AppleAppBuilder/Templates/main-simple.m index 5364779a5ac82..f34d4c960fac9 100644 --- a/src/tasks/AppleAppBuilder/Templates/main-simple.m +++ b/src/tasks/AppleAppBuilder/Templates/main-simple.m @@ -5,6 +5,7 @@ #if !USE_NATIVE_AOT #import "runtime.h" #else +#import #import "util.h" extern int __managed__Main(int argc, char* argv[]); #endif @@ -61,6 +62,8 @@ - (void)viewDidLoad { int managed_argc = get_managed_args (&managed_argv); int ret_val = __managed__Main (managed_argc, managed_argv); free_managed_args (&managed_argv, managed_argc); + os_log_info (OS_LOG_DEFAULT, EXIT_CODE_TAG ": %d", ret_val); + exit (ret_val); #endif }); } diff --git a/src/tasks/AppleAppBuilder/Templates/runtime.m b/src/tasks/AppleAppBuilder/Templates/runtime.m index 5e3b3390f629f..9cc38793dee6a 100644 --- a/src/tasks/AppleAppBuilder/Templates/runtime.m +++ b/src/tasks/AppleAppBuilder/Templates/runtime.m @@ -28,9 +28,6 @@ #define RUNTIMECONFIG_BIN_FILE "runtimeconfig.bin" -// XHarness is looking for this tag in app's output to determine the exit code -#define EXIT_CODE_TAG "DOTNET.APP_EXIT_CODE" - const char * get_bundle_path (void) { diff --git a/src/tasks/AppleAppBuilder/Templates/util.h b/src/tasks/AppleAppBuilder/Templates/util.h index e1ec72e12f7ed..c81697abbf552 100644 --- a/src/tasks/AppleAppBuilder/Templates/util.h +++ b/src/tasks/AppleAppBuilder/Templates/util.h @@ -4,6 +4,9 @@ #ifndef util_h #define util_h +// XHarness is looking for this tag in app's output to determine the exit code +#define EXIT_CODE_TAG "DOTNET.APP_EXIT_CODE" + size_t get_managed_args (char*** managed_args_array); void free_managed_args (char*** managed_args_array, size_t array_size); From d42f3e30316eb0f68b60d94de5953deffa1f8545 Mon Sep 17 00:00:00 2001 From: Ivan Povazan Date: Fri, 24 Feb 2023 12:05:47 +0100 Subject: [PATCH 09/10] Adding more details into the app README.md file to clarify the application's purpose --- src/mono/sample/iOS-NativeAOT/README.md | 30 ++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/src/mono/sample/iOS-NativeAOT/README.md b/src/mono/sample/iOS-NativeAOT/README.md index b3d6ada48df12..8c4af89c405c3 100644 --- a/src/mono/sample/iOS-NativeAOT/README.md +++ b/src/mono/sample/iOS-NativeAOT/README.md @@ -1,6 +1,8 @@ # NativeAOT iOS sample app -This sample application should be used as PoC for verifying that NativeAOT can be used for targeting iOS-like platforms: +## Description + +This sample application is intended to be used by developers who work on enabling NativeAOT on iOS-like platforms and can serve as PoC for verifying support for the following systems: - ios - iossimulator - tvos @@ -9,7 +11,14 @@ This sample application should be used as PoC for verifying that NativeAOT can b The sample shares the source code with the Mono sample specified at: `../iOS/Program.cs` and in general should have the same behavior as MonoAOT. -## How to build +## Limitations + +The application is **_currently_** relying on the following: +1. Internal dependencies - locally building the internals is required as runtime and tools nuget packages are still not being produced +2. Invariant globalization - `System.Globalization.Native` is currently not being built as part of NativeAOT framework for iOS-like platforms +3. No publish targets - the SDK and MSBuild integration is still not complete + +## How to build and test ### Building for the first time @@ -39,16 +48,31 @@ make hello-app ### Deploy and run +#### Simulator + To test the application on a simulator include the following in your make command `DEPLOY_AND_RUN=true` e.g.,: ``` bash make hello-app DEPLOY_AND_RUN=true ``` +#### Device + To test the application on a device, a provisioning profile needs to be specified. This can be achieved by defining `DevTeamProvisioning` environment variable with a valid team ID (see [developer.apple.com/account/#/membership](https://developer.apple.com/account/#/membership), scroll down to `Team ID`) for example: ``` bash -export DevTeamProvisioning=H1A2B3C4D5; make hello-app TARGET_OS=ios DEPLOY_AND_RUN=true +export DevTeamProvisioning=A1B2C3D4E5; make hello-app TARGET_OS=ios DEPLOY_AND_RUN=true ``` +Assuming `A1B2C3D4E5` is a valid team ID. + +#### Oneliner + +On a clean dotnet/runtime checkout, from this directory, run: + +``` bash +export DevTeamProvisioning=A1B2C3D4E5; make world BUILD_CONFIG=Release TARGET_OS=ios DEPLOY_AND_RUN=true +``` + +This command will build everything necessary to run and deploy the application on an iOS device. ### Custom builds From d69ba2ef9f6619e9b33aa3cb1d849dc83a329a1d Mon Sep 17 00:00:00 2001 From: Ivan Povazan Date: Fri, 24 Feb 2023 12:21:42 +0100 Subject: [PATCH 10/10] Markdown cleanup --- src/mono/sample/iOS-NativeAOT/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/mono/sample/iOS-NativeAOT/README.md b/src/mono/sample/iOS-NativeAOT/README.md index 8c4af89c405c3..fe6fcb1a45cd6 100644 --- a/src/mono/sample/iOS-NativeAOT/README.md +++ b/src/mono/sample/iOS-NativeAOT/README.md @@ -1,6 +1,6 @@ # NativeAOT iOS sample app -## Description +## Description This sample application is intended to be used by developers who work on enabling NativeAOT on iOS-like platforms and can serve as PoC for verifying support for the following systems: - ios @@ -16,7 +16,7 @@ The sample shares the source code with the Mono sample specified at: `../iOS/Pro The application is **_currently_** relying on the following: 1. Internal dependencies - locally building the internals is required as runtime and tools nuget packages are still not being produced 2. Invariant globalization - `System.Globalization.Native` is currently not being built as part of NativeAOT framework for iOS-like platforms -3. No publish targets - the SDK and MSBuild integration is still not complete +3. No publish targets - the SDK and MSBuild integration is still not complete ## How to build and test @@ -64,7 +64,7 @@ export DevTeamProvisioning=A1B2C3D4E5; make hello-app TARGET_OS=ios DEPLOY_AND_R ``` Assuming `A1B2C3D4E5` is a valid team ID. -#### Oneliner +#### One-liner On a clean dotnet/runtime checkout, from this directory, run: