diff --git a/dotnet/targets/Xamarin.Shared.Sdk.targets b/dotnet/targets/Xamarin.Shared.Sdk.targets index 53fd67e4de..24fb98a540 100644 --- a/dotnet/targets/Xamarin.Shared.Sdk.targets +++ b/dotnet/targets/Xamarin.Shared.Sdk.targets @@ -357,6 +357,7 @@ <_CustomLinkerOptions> AssemblyName=$(AssemblyName).dll + AOTCompiler=$(_AOTCompiler) AOTOutputDirectory=$(_AOTOutputDirectory) CacheDirectory=$(_LinkerCacheDirectory) Debug=$(_BundlerDebug) @@ -383,6 +384,7 @@ SdkVersion=$(_SdkVersion) TargetArchitectures=$(TargetArchitectures) TargetFramework=$(_ComputedTargetFrameworkMoniker) + UseLlvm=$(MtouchUseLlvm) Verbosity=$(_BundlerVerbosity) XamarinRuntime=$(_XamarinRuntime) @@ -704,7 +706,7 @@ Condition="'$(_SdkIsSimulator)' != 'true' And '$(_PlatformName)' != 'macOS'" DependsOnTargets="_ComputeVariables" Inputs="@(_AssembliesToAOT)" - Outputs="@(_AssembliesToAOT -> '$(_AOTOutputDirectory)%(Arch)\%(Filename)%(Extension).o')"> + Outputs="@(_AssembliesToAOT -> '%(ObjectFile)');@(_AssembliesToAOT -> '%(LLVMFile)');"> @@ -720,7 +722,7 @@ TargetFrameworkMoniker="$(_ComputedTargetFrameworkMoniker)" > - + - - <_XamarinMainLibraries Include="@(_AOTObjectFiles)" /> + <_XamarinMainLibraries Include="@(_AssembliesToAOT -> '%(ObjectFile)')" /> + <_XamarinMainLibraries Include="@(_AssembliesToAOT -> '%(LLVMFile)')" /> diff --git a/msbuild/Xamarin.MacDev.Tasks.Core/Tasks/AOTCompileTaskBase.cs b/msbuild/Xamarin.MacDev.Tasks.Core/Tasks/AOTCompileTaskBase.cs index 3f764fc0ac..fcba3b9fea 100644 --- a/msbuild/Xamarin.MacDev.Tasks.Core/Tasks/AOTCompileTaskBase.cs +++ b/msbuild/Xamarin.MacDev.Tasks.Core/Tasks/AOTCompileTaskBase.cs @@ -36,7 +36,7 @@ namespace Xamarin.MacDev.Tasks { public ITaskItem[] AssemblyFiles { get; set; } [Output] - public ITaskItem[] AOTData { get; set; } + public ITaskItem[] FileWrites { get; set; } #endregion public override bool Execute () @@ -64,9 +64,7 @@ namespace Xamarin.MacDev.Tasks { Directory.CreateDirectory (OutputDirectory); var aotAssemblyFiles = new List (); - var aotDataFiles = new List (); var processes = new Task [Assemblies.Length]; - var objectFiles = new List (); var environment = new Dictionary { { "MONO_PATH", Path.GetFullPath (InputDirectory) }, @@ -85,7 +83,6 @@ namespace Xamarin.MacDev.Tasks { aotAssemblyItem.SetMetadata ("Arguments", "-Xlinker -rpath -Xlinker @executable_path/ -Qunused-arguments -x assembler -D DEBUG"); aotAssemblyItem.SetMetadata ("Arch", arch); aotAssemblyFiles.Add (aotAssemblyItem); - aotDataFiles.Add (new TaskItem (aotData)); var arguments = new List (); if (!StringUtils.TryParseArguments (aotArguments, out var parsedArguments, out var ex)) { @@ -111,9 +108,14 @@ namespace Xamarin.MacDev.Tasks { System.Threading.Tasks.Task.WaitAll (processes); - AOTData = aotDataFiles.ToArray (); AssemblyFiles = aotAssemblyFiles.ToArray (); + // For Windows support it's necessary to have the files we're going to create as an Output parameter, so that the files are + // created on the windows side too, which makes the Inputs/Outputs logic work properly when working from Windows. + var objectFiles = Assemblies.Select (v => v.GetMetadata ("ObjectFile")).Where (v => !string.IsNullOrEmpty (v)); + var llvmFiles = Assemblies.Select (v => v.GetMetadata ("LLVMFile")).Where (v => !string.IsNullOrEmpty (v)); + FileWrites = objectFiles.Union (llvmFiles).Select (v => new TaskItem (v)).ToArray (); + return !Log.HasLoggedErrors; } diff --git a/msbuild/Xamarin.MacDev.Tasks.Core/Tasks/CompileNativeCodeTaskBase.cs b/msbuild/Xamarin.MacDev.Tasks.Core/Tasks/CompileNativeCodeTaskBase.cs index edae141d26..0675498435 100644 --- a/msbuild/Xamarin.MacDev.Tasks.Core/Tasks/CompileNativeCodeTaskBase.cs +++ b/msbuild/Xamarin.MacDev.Tasks.Core/Tasks/CompileNativeCodeTaskBase.cs @@ -21,9 +21,6 @@ namespace Xamarin.MacDev.Tasks { [Required] public string MinimumOSVersion { get; set; } - [Output] - public ITaskItem [] ObjectFiles { get; set; } - [Required] public string SdkDevPath { get; set; } @@ -37,10 +34,6 @@ namespace Xamarin.MacDev.Tasks { public override bool Execute () { var processes = new Task [CompileInfo.Length]; - var objectFiles = new List (); - - if (ObjectFiles != null) - objectFiles.AddRange (ObjectFiles); for (var i = 0; i < CompileInfo.Length; i++) { var info = CompileInfo [i]; @@ -99,7 +92,6 @@ namespace Xamarin.MacDev.Tasks { outputFile = Path.GetFullPath (outputFile); arguments.Add ("-o"); arguments.Add (outputFile); - objectFiles.Add (new TaskItem (outputFile)); arguments.Add ("-c"); arguments.Add (src); @@ -109,8 +101,6 @@ namespace Xamarin.MacDev.Tasks { System.Threading.Tasks.Task.WaitAll (processes); - ObjectFiles = objectFiles.ToArray (); - return !Log.HasLoggedErrors; } } diff --git a/tests/dotnet/MySimpleApp/iOS/Makefile b/tests/dotnet/MySimpleApp/iOS/Makefile index 5a1e3a910e..dd344c76b8 100644 --- a/tests/dotnet/MySimpleApp/iOS/Makefile +++ b/tests/dotnet/MySimpleApp/iOS/Makefile @@ -1,9 +1,13 @@ -TOP=../../../.. +include ../shared.mk -include $(TOP)/Make.config +dev: + $(Q) $(MAKE) build BUILD_ARGUMENTS="/p:RuntimeIdentifier=ios-arm64" -build: - $(DOTNET6) build /bl *.csproj $(MSBUILD_VERBOSITY) +run-dev: + $(Q) $(MAKE) build BUILD_ARGUMENTS="/p:RuntimeIdentifier=ios-arm64 /t:Run" -run: - $(DOTNET6) build /bl *.csproj $(MSBUILD_VERBOSITY) -t:Run +llvm: + $(Q) $(MAKE) build BUILD_ARGUMENTS="/p:RuntimeIdentifier=ios-arm64 /p:MtouchUseLlvm=true /p:MtouchLink=SdkOnly /p:Configuration=Release-llvm /bl:@.binlog" + +norm: + $(Q) $(MAKE) build BUILD_ARGUMENTS="/p:RuntimeIdentifier=ios-arm64 /p:MtouchLink=SdkOnly /p:Configuration=Release-norm /bl:@.binlog" diff --git a/tests/dotnet/MySimpleApp/shared.mk b/tests/dotnet/MySimpleApp/shared.mk new file mode 100644 index 0000000000..b31ea91a76 --- /dev/null +++ b/tests/dotnet/MySimpleApp/shared.mk @@ -0,0 +1,28 @@ +TOP=../../../.. +include $(TOP)/Make.config + +prepare: + $(Q) $(MAKE) -C $(TOP)/tests/dotnet copy-dotnet-config + +reload: + $(Q) rm -Rf $(TOP)/tests/dotnet/packages + $(Q) $(MAKE) -C $(TOP) -j8 all + $(Q) $(MAKE) -C $(TOP) -j8 install + $(Q) git clean -xfdq + +reload-and-build: + $(Q) $(MAKE) reload + $(Q) $(MAKE) build + +reload-and-run: + $(Q) $(MAKE) reload + $(Q) $(MAKE) run + +build: prepare + $(Q) $(DOTNET6) build /bl *.csproj $(MSBUILD_VERBOSITY) $(BUILD_ARGUMENTS) + +run: prepare + $(Q) $(DOTNET6) build /bl *.csproj $(MSBUILD_VERBOSITY) $(BUILD_ARGUMENTS) -t:Run + +diag: prepare + $(Q) $(DOTNET6) build /v:diag msbuild.binlog diff --git a/tests/monotouch-test/dotnet/iOS/Makefile b/tests/monotouch-test/dotnet/iOS/Makefile index f1a4290889..64ff0f2024 100644 --- a/tests/monotouch-test/dotnet/iOS/Makefile +++ b/tests/monotouch-test/dotnet/iOS/Makefile @@ -1,4 +1,16 @@ include ../shared.mk dev: - $(DOTNET6) build /bl *.csproj $(MSBUILD_VERBOSITY) /p:RuntimeIdentifier=ios-arm64 + $(Q) $(MAKE) build BUILD_ARGUMENTS="/p:RuntimeIdentifier=ios-arm64" + +llvm: + $(Q) $(MAKE) build BUILD_ARGUMENTS="/p:RuntimeIdentifier=ios-arm64 /p:MtouchUseLlvm=true /p:MtouchLink=SdkOnly /p:Configuration=Release-llvm /bl:$@.binlog" + +run-llvm: + $(Q) $(MAKE) build BUILD_ARGUMENTS="/p:RuntimeIdentifier=ios-arm64 /p:MtouchUseLlvm=true /p:MtouchLink=SdkOnly /p:Configuration=Release-llvm /bl:$@.binlog /t:Run" + +norm: + $(Q) $(MAKE) build BUILD_ARGUMENTS="/p:RuntimeIdentifier=ios-arm64 /p:MtouchLink=SdkOnly /p:Configuration=Release-norm /bl:$@.binlog" + +run-norm: + $(Q) $(MAKE) build BUILD_ARGUMENTS="/p:RuntimeIdentifier=ios-arm64 /p:MtouchLink=SdkOnly /p:Configuration=Release-norm /bl:$@.binlog /t:Run" diff --git a/tests/monotouch-test/dotnet/shared.mk b/tests/monotouch-test/dotnet/shared.mk index fd9d980533..bc7ccd2596 100644 --- a/tests/monotouch-test/dotnet/shared.mk +++ b/tests/monotouch-test/dotnet/shared.mk @@ -1,17 +1,16 @@ TOP=../../../.. - include $(TOP)/Make.config include $(TOP)/mk/colors.mk +prepare: + $(Q) $(MAKE) -C $(TOP)/tests/dotnet copy-dotnet-config + reload: $(Q) rm -Rf $(TOP)/tests/dotnet/packages $(Q) $(MAKE) -C $(TOP) -j8 all $(Q) $(MAKE) -C $(TOP) -j8 install $(Q) git clean -xfdq -prepare: - $(Q) $(MAKE) -C $(TOP)/tests/dotnet copy-dotnet-config - reload-and-build: $(Q) $(MAKE) reload $(Q) $(MAKE) build @@ -21,10 +20,10 @@ reload-and-run: $(Q) $(MAKE) run build: prepare - $(DOTNET6) build /bl *.csproj $(MSBUILD_VERBOSITY) + $(Q) $(DOTNET6) build /bl *.csproj $(MSBUILD_VERBOSITY) $(BUILD_ARGUMENTS) run: prepare - $(DOTNET6) build /bl *.csproj $(MSBUILD_VERBOSITY) -t:Run + $(Q) $(DOTNET6) build /bl *.csproj $(MSBUILD_VERBOSITY) $(BUILD_ARGUMENTS) -t:Run -diag: - $(DOTNET6) build /v:diag msbuild.binlog +diag: prepare + $(Q) $(DOTNET6) build /v:diag msbuild.binlog diff --git a/tests/xharness/Jenkins/TestData.cs b/tests/xharness/Jenkins/TestData.cs index aa8e340c2b..043bd26d86 100644 --- a/tests/xharness/Jenkins/TestData.cs +++ b/tests/xharness/Jenkins/TestData.cs @@ -18,6 +18,7 @@ namespace Xharness.Jenkins { public bool? Ignored; public bool EnableSGenConc; public bool UseThumb; + public bool UseLlvm; public bool? UseMonoRuntime; public MonoNativeLinkMode MonoNativeLinkMode; public IEnumerable Candidates; diff --git a/tests/xharness/Jenkins/TestVariationsFactory.cs b/tests/xharness/Jenkins/TestVariationsFactory.cs index 4b63c2a52f..5e7925ed4d 100644 --- a/tests/xharness/Jenkins/TestVariationsFactory.cs +++ b/tests/xharness/Jenkins/TestVariationsFactory.cs @@ -83,6 +83,8 @@ namespace Xharness.Jenkins { } yield return new TestData { Variation = "Release (interpreter -mscorlib)", MTouchExtraArgs = "--interpreter=-mscorlib", Debug = false, Profiling = false, Undefines = "FULL_AOT_RUNTIME", Ignored = ignore }; } + if (test.TestProject.IsDotNetProject) + yield return new TestData { Variation = "Release (LLVM)", Debug = false, UseLlvm = true, Ignored = ignore }; break; case string name when name.StartsWith ("mscorlib", StringComparison.Ordinal): if (supports_debug) @@ -182,6 +184,7 @@ namespace Xharness.Jenkins { var use_mono_runtime = test_data.UseMonoRuntime; var xammac_arch = test_data.XamMacArch; var runtime_identifer = test_data.RuntimeIdentifier; + var use_llvm = test_data.UseLlvm; if (task.TestProject.IsDotNetProject) variation += " [dotnet]"; @@ -232,6 +235,8 @@ namespace Xharness.Jenkins { clone.Xml.SetNode ("MtouchEnableSGenConc", "true", task.ProjectPlatform, configuration); if (test_data.UseThumb) // no need to check the platform, already done at the data iterator clone.Xml.SetNode ("MtouchUseThumb", "true", task.ProjectPlatform, configuration); + if (use_llvm) + clone.Xml.SetTopLevelPropertyGroupValue ("MtouchUseLlvm", "true"); if (!debug && !isMac) clone.Xml.SetMtouchUseLlvm (true, task.ProjectPlatform, configuration); diff --git a/tools/common/Application.cs b/tools/common/Application.cs index 8bf93ee708..dd83b7993c 100644 --- a/tools/common/Application.cs +++ b/tools/common/Application.cs @@ -1408,7 +1408,7 @@ namespace Xamarin.Bundler { return processArguments; } - public void GetAotArguments (string filename, Abi abi, string outputDir, string outputFile, string llvmOutputFile, string dataFile, out List processArguments, out List aotArguments) + public void GetAotArguments (string filename, Abi abi, string outputDir, string outputFile, string llvmOutputFile, string dataFile, out List processArguments, out List aotArguments, string llvm_path = null) { string fname = Path.GetFileName (filename); processArguments = new List (); @@ -1472,8 +1472,13 @@ namespace Xamarin.Bundler { aotArguments.Add ($"msym-dir={msymdir}"); } - if (enable_llvm) - aotArguments.Add ($"llvm-path={Driver.GetFrameworkCurrentDirectory (app)}/LLVM/bin/"); + if (enable_llvm) { + if (!string.IsNullOrEmpty (llvm_path)) { + aotArguments.Add ($"llvm-path={llvm_path}"); + } else { + aotArguments.Add ($"llvm-path={Driver.GetFrameworkCurrentDirectory (app)}/LLVM/bin/"); + } + } aotArguments.Add ($"outfile={outputFile}"); if (enable_llvm) diff --git a/tools/dotnet-linker/LinkerConfiguration.cs b/tools/dotnet-linker/LinkerConfiguration.cs index 0e5635d5ed..1008854862 100644 --- a/tools/dotnet-linker/LinkerConfiguration.cs +++ b/tools/dotnet-linker/LinkerConfiguration.cs @@ -17,6 +17,7 @@ using ObjCRuntime; namespace Xamarin.Linker { public class LinkerConfiguration { public List Abis; + public string AOTCompiler; public string AOTOutputDirectory; public string CacheDirectory { get; private set; } public Version DeploymentTarget { get; private set; } @@ -79,6 +80,7 @@ namespace Xamarin.Linker { Target = new Target (Application); CompilerFlags = new CompilerFlags (Target); + var use_llvm = false; var lines = File.ReadAllLines (linker_file); var significantLines = new List (); // This is the input the cache uses to verify if the cache is still valid for (var i = 0; i < lines.Length; i++) { @@ -103,6 +105,9 @@ namespace Xamarin.Linker { // This is the AssemblyName MSBuild property for the main project (which is also the root/entry assembly) Application.RootAssemblies.Add (value); break; + case "AOTCompiler": + AOTCompiler = value; + break; case "AOTOutputDirectory": AOTOutputDirectory = value; break; @@ -223,6 +228,9 @@ namespace Xamarin.Linker { throw new InvalidOperationException ($"Invalid TargetFramework '{value}' in {linker_file}"); Driver.TargetFramework = TargetFramework.Parse (value); break; + case "UseLlvm": + use_llvm = string.Equals ("true", value, StringComparison.OrdinalIgnoreCase); + break; case "Verbosity": if (!int.TryParse (value, out var verbosity)) throw new InvalidOperationException ($"Invalid Verbosity '{value}' in {linker_file}"); @@ -253,6 +261,12 @@ namespace Xamarin.Linker { ErrorHelper.Show (messages); } + if (use_llvm) { + for (var i = 0; i < Abis.Count; i++) { + Abis [i] |= Abi.LLVM; + } + } + Application.CreateCache (significantLines.ToArray ()); Application.Cache.Location = CacheDirectory; Application.DeploymentTarget = DeploymentTarget; @@ -314,6 +328,7 @@ namespace Xamarin.Linker { Console.WriteLine ($" SdkRootDirectory: {SdkRootDirectory}"); Console.WriteLine ($" SdkVersion: {SdkVersion}"); Console.WriteLine ($" UseInterpreter: {Application.UseInterpreter}"); + Console.WriteLine ($" UseLlvm: {Application.IsLLVM}"); Console.WriteLine ($" Verbosity: {Verbosity}"); Console.WriteLine ($" XamarinRuntime: {Application.XamarinRuntime}"); } diff --git a/tools/dotnet-linker/Steps/ComputeAOTArguments.cs b/tools/dotnet-linker/Steps/ComputeAOTArguments.cs index 079b08e2f5..0f84e396f1 100644 --- a/tools/dotnet-linker/Steps/ComputeAOTArguments.cs +++ b/tools/dotnet-linker/Steps/ComputeAOTArguments.cs @@ -36,16 +36,17 @@ namespace Xamarin.Linker { var arch = abi.AsArchString (); var aotAssembly = Path.Combine (outputDirectory, arch, Path.GetFileName (input) + ".s"); var aotData = Path.Combine (outputDirectory, arch, Path.GetFileNameWithoutExtension (input) + ".aotdata"); - var llvmFile = string.Empty; - if ((abi & Abi.LLVM) == Abi.LLVM) - throw ErrorHelper.CreateError (99, $"Support for LLVM hasn't been implemented yet."); - app.GetAotArguments (asm.FullPath, abi, outputDirectory, aotAssembly, llvmFile, aotData, out var processArguments, out var aotArguments); + var llvmFile = Configuration.Application.IsLLVM ? Path.Combine (outputDirectory, arch, Path.GetFileName (input) + ".llvm.o") : string.Empty; + var objectFile = Path.Combine (outputDirectory, arch, Path.GetFileName (input) + ".o"); + app.GetAotArguments (asm.FullPath, abi, outputDirectory, aotAssembly, llvmFile, aotData, out var processArguments, out var aotArguments, Path.GetDirectoryName (Configuration.AOTCompiler)); item.Metadata.Add ("Arguments", StringUtils.FormatArguments (aotArguments)); item.Metadata.Add ("ProcessArguments", StringUtils.FormatArguments (processArguments)); item.Metadata.Add ("Abi", abiString); item.Metadata.Add ("Arch", arch); item.Metadata.Add ("AOTData", aotData); item.Metadata.Add ("AOTAssembly", aotAssembly); + item.Metadata.Add ("LLVMFile", llvmFile); + item.Metadata.Add ("ObjectFile", objectFile); } assembliesToAOT.Add (item);