From d4662b154e25957d6b30b072b83b6ee1fdfa0bfb Mon Sep 17 00:00:00 2001 From: Rolf Bjarne Kvinge Date: Thu, 16 Oct 2025 09:21:42 +0200 Subject: [PATCH 01/23] [msbuild] Improve how we handle the path to Xcode. WIP WIP WIP * Add support for an MSBuild property to set the Xcode location. * Deprecate the file-based locations. * Always set DEVELOPER_DIR when executing subprocesses. --- .../Xamarin.MacDev.Tasks/Tasks/AOTCompile.cs | 5 +---- msbuild/Xamarin.MacDev.Tasks/Tasks/AlTool.cs | 3 --- .../Xamarin.MacDev.Tasks/Tasks/Codesign.cs | 2 +- .../Tasks/CompileNativeCode.cs | 5 +---- .../Tasks/CompileSceneKitAssets.cs | 6 +----- .../Tasks/CoreMLCompiler.cs | 5 ----- .../Xamarin.MacDev.Tasks/Tasks/DSymUtil.cs | 5 +---- .../Tasks/DetectSdkLocation.cs | 2 +- .../Tasks/GetMlaunchArguments.cs | 7 ++----- .../Tasks/InstallNameTool.cs | 5 +---- .../Tasks/LinkNativeCode.cs | 7 ++----- .../Tasks/MergeAppBundles.cs | 5 +---- msbuild/Xamarin.MacDev.Tasks/Tasks/Metal.cs | 5 +---- .../Xamarin.MacDev.Tasks/Tasks/MetalLib.cs | 5 +---- .../Tasks/OptimizeImage.cs | 3 --- .../Tasks/OptimizePropertyList.cs | 2 +- msbuild/Xamarin.MacDev.Tasks/Tasks/ScnTool.cs | 5 +---- .../Tasks/SpotlightIndexer.cs | 2 +- .../Xamarin.MacDev.Tasks/Tasks/XamarinTask.cs | 19 +++++++++++++++++-- .../Tasks/XcodeBuildTask.cs | 4 +--- .../Tasks/XcodeCompilerToolTask.cs | 15 +-------------- .../Xamarin.MacDev.Tasks/Tasks/XcodeTool.cs | 3 --- msbuild/Xamarin.Shared/Xamarin.Shared.targets | 2 ++ .../Xamarin.Shared/Xamarin.iOS.Common.targets | 1 + 24 files changed, 39 insertions(+), 84 deletions(-) diff --git a/msbuild/Xamarin.MacDev.Tasks/Tasks/AOTCompile.cs b/msbuild/Xamarin.MacDev.Tasks/Tasks/AOTCompile.cs index 3adaa8afd0d9..f43551989ee6 100644 --- a/msbuild/Xamarin.MacDev.Tasks/Tasks/AOTCompile.cs +++ b/msbuild/Xamarin.MacDev.Tasks/Tasks/AOTCompile.cs @@ -36,9 +36,6 @@ public class AOTCompile : XamarinParallelTask, ITaskCallback, ICancelableTask { [Required] public string OutputDirectory { get; set; } = string.Empty; - [Required] - public string SdkDevPath { get; set; } = string.Empty; - #region Output [Output] public ITaskItem []? AssemblyFiles { get; set; } @@ -341,7 +338,7 @@ public override bool Execute () environment [item.ItemSpec] = item.GetMetadata ("Value"); ForEach (listOfArguments, (arg) => { - ExecuteAsync (AOTCompilerPath, arg.Arguments, environment: environment, sdkDevPath: SdkDevPath, showErrorIfFailure: false /* we show our own error below */) + ExecuteAsync (AOTCompilerPath, arg.Arguments, environment: environment, showErrorIfFailure: false /* we show our own error below */) .ContinueWith ((v) => { if (v.Result.ExitCode != 0) Log.LogError (MSBStrings.E7118 /* Failed to AOT compile {0}, the AOT compiler exited with code {1} */, Path.GetFileName (arg.Input), v.Result.ExitCode); diff --git a/msbuild/Xamarin.MacDev.Tasks/Tasks/AlTool.cs b/msbuild/Xamarin.MacDev.Tasks/Tasks/AlTool.cs index 63e0de67c8bb..f602b4810ea7 100644 --- a/msbuild/Xamarin.MacDev.Tasks/Tasks/AlTool.cs +++ b/msbuild/Xamarin.MacDev.Tasks/Tasks/AlTool.cs @@ -27,9 +27,6 @@ public abstract class ALToolTaskBase : XamarinTask, ICancelableTask { [Required] public string FilePath { get; set; } = string.Empty; - [Required] - public string SdkDevPath { get; set; } = string.Empty; - protected abstract string ALToolAction { get; } public override bool Execute () diff --git a/msbuild/Xamarin.MacDev.Tasks/Tasks/Codesign.cs b/msbuild/Xamarin.MacDev.Tasks/Tasks/Codesign.cs index f1c25499eb98..d7d7579ff711 100644 --- a/msbuild/Xamarin.MacDev.Tasks/Tasks/Codesign.cs +++ b/msbuild/Xamarin.MacDev.Tasks/Tasks/Codesign.cs @@ -362,7 +362,7 @@ void Sign (SignInfo info) var environment = new Dictionary () { { "CODESIGN_ALLOCATE", GetCodesignAllocate (item) }, }; - var rv = ExecuteAsync (fileName, arguments, null, environment, mergeOutput: false).Result; + var rv = ExecuteAsync (fileName, arguments, environment, mergeOutput: false).Result; var exitCode = rv.ExitCode; var messages = rv.StandardOutput?.ToString () ?? string.Empty; diff --git a/msbuild/Xamarin.MacDev.Tasks/Tasks/CompileNativeCode.cs b/msbuild/Xamarin.MacDev.Tasks/Tasks/CompileNativeCode.cs index ea95c3530e4a..affd9e1f3fae 100644 --- a/msbuild/Xamarin.MacDev.Tasks/Tasks/CompileNativeCode.cs +++ b/msbuild/Xamarin.MacDev.Tasks/Tasks/CompileNativeCode.cs @@ -25,9 +25,6 @@ public class CompileNativeCode : XamarinTask, ICancelableTask, ITaskCallback { [Required] public string MinimumOSVersion { get; set; } = ""; - [Required] - public string SdkDevPath { get; set; } = ""; - [Required] public string SdkRoot { get; set; } = ""; @@ -142,7 +139,7 @@ public override bool Execute () arguments.Add ("-c"); arguments.Add (src); - processes [i] = ExecuteAsync ("xcrun", arguments, sdkDevPath: SdkDevPath); + processes [i] = ExecuteAsync ("xcrun", arguments); } System.Threading.Tasks.Task.WaitAll (processes); diff --git a/msbuild/Xamarin.MacDev.Tasks/Tasks/CompileSceneKitAssets.cs b/msbuild/Xamarin.MacDev.Tasks/Tasks/CompileSceneKitAssets.cs index 3f50e6199dee..effd0434c231 100644 --- a/msbuild/Xamarin.MacDev.Tasks/Tasks/CompileSceneKitAssets.cs +++ b/msbuild/Xamarin.MacDev.Tasks/Tasks/CompileSceneKitAssets.cs @@ -37,9 +37,6 @@ public class CompileSceneKitAssets : XamarinTask, ICancelableTask, IHasProjectDi [Required] public ITaskItem [] SceneKitAssets { get; set; } = Array.Empty (); - [Required] - public string SdkDevPath { get; set; } = ""; - [Required] public string SdkPlatform { get; set; } = ""; @@ -86,8 +83,7 @@ Task CopySceneKitAssets (string scnassets, string output, string intermediate) args.Add ($"--resources-folder-path={AppBundleName}"); var executable = GetExecutable (args, ToolName, CopySceneKitAssetsPath); - - return ExecuteAsync (executable, args, sdkDevPath: SdkDevPath, environment: environment, showErrorIfFailure: true); + return ExecuteAsync (executable, args, environment: environment, showErrorIfFailure: true); } static bool TryGetScnAssetsPath (string file, out string scnassets) diff --git a/msbuild/Xamarin.MacDev.Tasks/Tasks/CoreMLCompiler.cs b/msbuild/Xamarin.MacDev.Tasks/Tasks/CoreMLCompiler.cs index 29f19cff1f89..a86b89278332 100644 --- a/msbuild/Xamarin.MacDev.Tasks/Tasks/CoreMLCompiler.cs +++ b/msbuild/Xamarin.MacDev.Tasks/Tasks/CoreMLCompiler.cs @@ -30,11 +30,6 @@ public class CoreMLCompiler : XamarinTask, ICancelableTask, IHasProjectDir, IHas [Required] public string ResourcePrefix { get; set; } = ""; - string sdkDevPath = ""; - public string SdkDevPath { - get { return string.IsNullOrEmpty (sdkDevPath) ? "/" : sdkDevPath; } - set { sdkDevPath = value; } - } #endregion #region Outputs diff --git a/msbuild/Xamarin.MacDev.Tasks/Tasks/DSymUtil.cs b/msbuild/Xamarin.MacDev.Tasks/Tasks/DSymUtil.cs index 58011d2fbc90..bb3abba9483c 100644 --- a/msbuild/Xamarin.MacDev.Tasks/Tasks/DSymUtil.cs +++ b/msbuild/Xamarin.MacDev.Tasks/Tasks/DSymUtil.cs @@ -21,9 +21,6 @@ public class DSymUtil : XamarinTask, ITaskCallback { [Required] public ITaskItem [] Executable { get; set; } = Array.Empty (); - [Required] - public string SdkDevPath { get; set; } = string.Empty; - #endregion #region Outputs @@ -65,7 +62,7 @@ void ExecuteDSymUtil (ITaskItem item, List contentFiles) args.Add (dSymDir); args.Add (Path.GetFullPath (item.ItemSpec)); - ExecuteAsync ("xcrun", args, sdkDevPath: SdkDevPath).Wait (); + ExecuteAsync ("xcrun", args).Wait (); var contentsDir = Path.Combine (dSymDir, "Contents"); if (Directory.Exists (contentsDir)) diff --git a/msbuild/Xamarin.MacDev.Tasks/Tasks/DetectSdkLocation.cs b/msbuild/Xamarin.MacDev.Tasks/Tasks/DetectSdkLocation.cs index 0249f04a0463..87e52f482933 100644 --- a/msbuild/Xamarin.MacDev.Tasks/Tasks/DetectSdkLocation.cs +++ b/msbuild/Xamarin.MacDev.Tasks/Tasks/DetectSdkLocation.cs @@ -38,7 +38,7 @@ public string SdkBinPath { } = ""; [Output] - public string SdkDevPath { + public new string SdkDevPath { get; set; } = ""; diff --git a/msbuild/Xamarin.MacDev.Tasks/Tasks/GetMlaunchArguments.cs b/msbuild/Xamarin.MacDev.Tasks/Tasks/GetMlaunchArguments.cs index 0c0f8efc00f6..f7356a66b15f 100644 --- a/msbuild/Xamarin.MacDev.Tasks/Tasks/GetMlaunchArguments.cs +++ b/msbuild/Xamarin.MacDev.Tasks/Tasks/GetMlaunchArguments.cs @@ -27,9 +27,6 @@ public class GetMlaunchArguments : XamarinTask, ICancelableTask { public string AppManifestPath { get; set; } = string.Empty; - [Required] - public string SdkDevPath { get; set; } = string.Empty; - public ITaskItem [] AdditionalArguments { get; set; } = Array.Empty (); public string DeviceName { get; set; } = string.Empty; public ITaskItem [] EnvironmentVariables { get; set; } = Array.Empty (); @@ -112,7 +109,7 @@ public IPhoneDeviceType DeviceType { var tmpfile = Path.GetTempFileName (); try { var output = new StringBuilder (); - var result = ExecuteAsync (MlaunchPath, new string [] { "--listsim", tmpfile }, SdkDevPath).Result; + var result = ExecuteAsync (MlaunchPath, new string [] { "--listsim", tmpfile }).Result; if (result.ExitCode != 0) return string.Empty; simulator_list = File.ReadAllText (tmpfile); @@ -130,7 +127,7 @@ public IPhoneDeviceType DeviceType { var tmpfile = Path.GetTempFileName (); try { var output = new StringBuilder (); - var result = ExecuteAsync (MlaunchPath, new string [] { $"--listdev:{tmpfile}", "--output-format:xml", "--use-amdevice:false" }, SdkDevPath).Result; + var result = ExecuteAsync (MlaunchPath, new string [] { $"--listdev:{tmpfile}", "--output-format:xml", "--use-amdevice:false" }).Result; if (result.ExitCode != 0) return string.Empty; device_list = File.ReadAllText (tmpfile); diff --git a/msbuild/Xamarin.MacDev.Tasks/Tasks/InstallNameTool.cs b/msbuild/Xamarin.MacDev.Tasks/Tasks/InstallNameTool.cs index 8430835aefee..16fb7e140fcb 100644 --- a/msbuild/Xamarin.MacDev.Tasks/Tasks/InstallNameTool.cs +++ b/msbuild/Xamarin.MacDev.Tasks/Tasks/InstallNameTool.cs @@ -15,9 +15,6 @@ public class InstallNameTool : XamarinTask, ITaskCallback { [Required] public ITaskItem [] DynamicLibrary { get; set; } = []; - [Required] - public string SdkDevPath { get; set; } = ""; - // This isn't consumed from the targets files, but it's needed for VSX to create corresponding // files on Windows. [Output] @@ -50,7 +47,7 @@ public override bool Execute () arguments.Add (input.GetMetadata ("DynamicLibraryId")); arguments.Add (temporaryTarget); - processes [i] = ExecuteAsync ("xcrun", arguments, sdkDevPath: SdkDevPath).ContinueWith ((v) => { + processes [i] = ExecuteAsync ("xcrun", arguments).ContinueWith ((v) => { if (v.IsFaulted) throw v.Exception; if (v.Status == TaskStatus.RanToCompletion) { diff --git a/msbuild/Xamarin.MacDev.Tasks/Tasks/LinkNativeCode.cs b/msbuild/Xamarin.MacDev.Tasks/Tasks/LinkNativeCode.cs index c7f3d06c0264..62c71cf36dcd 100644 --- a/msbuild/Xamarin.MacDev.Tasks/Tasks/LinkNativeCode.cs +++ b/msbuild/Xamarin.MacDev.Tasks/Tasks/LinkNativeCode.cs @@ -21,9 +21,6 @@ public class LinkNativeCode : XamarinTask, ITaskCallback { // A path to entitlements to be embedded into the executable public string EntitlementsInExecutable { get; set; } = string.Empty; - [Required] - public string SdkDevPath { get; set; } = string.Empty; - [Required] public bool SdkIsSimulator { get; set; } @@ -213,7 +210,7 @@ bool ExecuteUnsafe () arguments.Add (flag.ItemSpec); } - var rv = ExecuteAsync ("xcrun", arguments, sdkDevPath: SdkDevPath, showErrorIfFailure: false).Result; + var rv = ExecuteAsync ("xcrun", arguments, showErrorIfFailure: false).Result; if (rv.ExitCode != 0) { var stderr = rv.StandardError?.ToString ()?.Trim (); #if NET @@ -284,7 +281,7 @@ string ConvertEntitlementsToDerEntitlements (string entitlements) "-o", derEntitlements, "--raw", }; - ExecuteAsync ("xcrun", arguments, sdkDevPath: SdkDevPath).Wait (); + ExecuteAsync ("xcrun", arguments).Wait (); return derEntitlements; } diff --git a/msbuild/Xamarin.MacDev.Tasks/Tasks/MergeAppBundles.cs b/msbuild/Xamarin.MacDev.Tasks/Tasks/MergeAppBundles.cs index 5f8fcf89c516..8cde9a9aa2a6 100644 --- a/msbuild/Xamarin.MacDev.Tasks/Tasks/MergeAppBundles.cs +++ b/msbuild/Xamarin.MacDev.Tasks/Tasks/MergeAppBundles.cs @@ -46,9 +46,6 @@ public partial class MergeAppBundles : XamarinTask { [Required] public string OutputAppBundle { get; set; } = ""; - [Required] - public string SdkDevPath { get; set; } = ""; - #endregion enum FileType { @@ -441,7 +438,7 @@ void MergeMachOFiles (string output, IList input) arguments.Add ("-output"); arguments.Add (output); arguments.AddRange (sourceFiles); - ExecuteAsync ("lipo", arguments, sdkDevPath: SdkDevPath).Wait (); + ExecuteAsync ("lipo", arguments).Wait (); } FileType GetFileType (string path) diff --git a/msbuild/Xamarin.MacDev.Tasks/Tasks/Metal.cs b/msbuild/Xamarin.MacDev.Tasks/Tasks/Metal.cs index 8e5c4b298ebe..14aee97cd3ae 100644 --- a/msbuild/Xamarin.MacDev.Tasks/Tasks/Metal.cs +++ b/msbuild/Xamarin.MacDev.Tasks/Tasks/Metal.cs @@ -32,9 +32,6 @@ public class Metal : XamarinTask, IHasProjectDir, IHasResourcePrefix { [Required] public string ResourcePrefix { get; set; } = string.Empty; - [Required] - public string SdkDevPath { get; set; } = string.Empty; - [Required] public string SdkVersion { get; set; } = string.Empty; @@ -96,7 +93,7 @@ public override bool Execute () args.Add (SourceFile!.ItemSpec); cancellationTokenSource = new CancellationTokenSource (); - ExecuteAsync (Log, executable, args, environment: env, cancellationToken: cancellationTokenSource.Token).Wait (); + ExecuteAsync (Log, executable, args, environment: env, sdkDevPath: SdkDevPath, cancellationToken: cancellationTokenSource.Token).Wait (); return !Log.HasLoggedErrors; } diff --git a/msbuild/Xamarin.MacDev.Tasks/Tasks/MetalLib.cs b/msbuild/Xamarin.MacDev.Tasks/Tasks/MetalLib.cs index 804c846c14fe..402403ab238c 100644 --- a/msbuild/Xamarin.MacDev.Tasks/Tasks/MetalLib.cs +++ b/msbuild/Xamarin.MacDev.Tasks/Tasks/MetalLib.cs @@ -25,9 +25,6 @@ public class MetalLib : XamarinTask, ITaskCallback { [Required] public string OutputLibrary { get; set; } = string.Empty; - [Required] - public string SdkDevPath { get; set; } = string.Empty; - [Required] public string SdkRoot { get; set; } = string.Empty; @@ -54,7 +51,7 @@ public override bool Execute () var executable = GetExecutable (args, "metallib", MetalLibPath); cancellationTokenSource = new CancellationTokenSource (); - ExecuteAsync (Log, executable, args, environment: env, cancellationToken: cancellationTokenSource.Token).Wait (); + ExecuteAsync (Log, executable, args, environment: env, sdkDevPath: SdkDevPath, cancellationToken: cancellationTokenSource.Token).Wait (); return !Log.HasLoggedErrors; } diff --git a/msbuild/Xamarin.MacDev.Tasks/Tasks/OptimizeImage.cs b/msbuild/Xamarin.MacDev.Tasks/Tasks/OptimizeImage.cs index 1b2dab4b0d55..162149772781 100644 --- a/msbuild/Xamarin.MacDev.Tasks/Tasks/OptimizeImage.cs +++ b/msbuild/Xamarin.MacDev.Tasks/Tasks/OptimizeImage.cs @@ -29,9 +29,6 @@ public class OptimizeImage : XamarinParallelTask, ICancelableTask { public string PngCrushPath { get; set; } = string.Empty; - [Required] - public string SdkDevPath { get; set; } = string.Empty; - #endregion static List GenerateCommandLineCommands (string inputImage, string outputImage) diff --git a/msbuild/Xamarin.MacDev.Tasks/Tasks/OptimizePropertyList.cs b/msbuild/Xamarin.MacDev.Tasks/Tasks/OptimizePropertyList.cs index a98b1f365849..5f2b4fcc5e31 100644 --- a/msbuild/Xamarin.MacDev.Tasks/Tasks/OptimizePropertyList.cs +++ b/msbuild/Xamarin.MacDev.Tasks/Tasks/OptimizePropertyList.cs @@ -50,7 +50,7 @@ public override bool Execute () var args = GenerateCommandLineCommands (); var executable = GetExecutable (args, "plutil", PlutilPath); cancellationTokenSource = new CancellationTokenSource (); - ExecuteAsync (Log, executable, args, cancellationToken: cancellationTokenSource.Token).Wait (); + ExecuteAsync (Log, executable, args, sdkDevPath: SdkDevPath, cancellationToken: cancellationTokenSource.Token).Wait (); return !Log.HasLoggedErrors; } diff --git a/msbuild/Xamarin.MacDev.Tasks/Tasks/ScnTool.cs b/msbuild/Xamarin.MacDev.Tasks/Tasks/ScnTool.cs index 5f8e9617c1a8..e1cb9484c562 100644 --- a/msbuild/Xamarin.MacDev.Tasks/Tasks/ScnTool.cs +++ b/msbuild/Xamarin.MacDev.Tasks/Tasks/ScnTool.cs @@ -39,9 +39,6 @@ public class ScnTool : XamarinParallelTask, IHasProjectDir, IHasResourcePrefix { [Required] public string SdkVersion { get; set; } = string.Empty; - [Required] - public string SdkDevPath { get; set; } = string.Empty; - #endregion #region Outputs @@ -91,7 +88,7 @@ public override bool Execute () } ForEach (listOfArguments, (arg) => { - ExecuteAsync ("xcrun", arg.Arguments, sdkDevPath: SdkDevPath).Wait (); + ExecuteAsync ("xcrun", arg.Arguments).Wait (); }); BundleResources = bundleResources.ToArray (); diff --git a/msbuild/Xamarin.MacDev.Tasks/Tasks/SpotlightIndexer.cs b/msbuild/Xamarin.MacDev.Tasks/Tasks/SpotlightIndexer.cs index eff7361b6429..20483fa1389f 100644 --- a/msbuild/Xamarin.MacDev.Tasks/Tasks/SpotlightIndexer.cs +++ b/msbuild/Xamarin.MacDev.Tasks/Tasks/SpotlightIndexer.cs @@ -33,7 +33,7 @@ public override bool Execute () }; var executable = GetExecutable (args, "mdimport", MdimportPath); cancellationTokenSource = new CancellationTokenSource (); - ExecuteAsync (Log, executable, args, cancellationToken: cancellationTokenSource.Token).Wait (); + ExecuteAsync (Log, executable, args, sdkDevPath: SdkDevPath, cancellationToken: cancellationTokenSource.Token).Wait (); return !Log.HasLoggedErrors; } diff --git a/msbuild/Xamarin.MacDev.Tasks/Tasks/XamarinTask.cs b/msbuild/Xamarin.MacDev.Tasks/Tasks/XamarinTask.cs index 1a7ef1623ae1..67b0852fcec0 100644 --- a/msbuild/Xamarin.MacDev.Tasks/Tasks/XamarinTask.cs +++ b/msbuild/Xamarin.MacDev.Tasks/Tasks/XamarinTask.cs @@ -23,6 +23,18 @@ public abstract class XamarinTask : Task, IHasSessionId, ICustomLogger { public string TargetFrameworkMoniker { get; set; } = string.Empty; + string sdkDevPath = string.Empty; + public string SdkDevPath { + get { + if (string.IsNullOrEmpty (sdkDevPath)) + Log.LogError ($"The task {GetType ().Name} requires 'SdkDevPath' to be set."); + return sdkDevPath; + } + set { + sdkDevPath = value; + } + } + void VerifyTargetFrameworkMoniker () { if (!string.IsNullOrEmpty (TargetFrameworkMoniker)) @@ -97,9 +109,9 @@ protected string GetSdkPlatform (bool isSimulator) return PlatformFrameworkHelper.GetSdkPlatform (Platform, isSimulator); } - protected System.Threading.Tasks.Task ExecuteAsync (string fileName, IList arguments, string? sdkDevPath = null, Dictionary? environment = null, bool mergeOutput = true, bool showErrorIfFailure = true, string? workingDirectory = null) + protected System.Threading.Tasks.Task ExecuteAsync (string fileName, IList arguments, Dictionary? environment = null, bool mergeOutput = true, bool showErrorIfFailure = true, string? workingDirectory = null) { - return ExecuteAsync (Log, fileName, arguments, sdkDevPath, environment, mergeOutput, showErrorIfFailure, workingDirectory); + return ExecuteAsync (Log, fileName, arguments, SdkDevPath, environment, mergeOutput, showErrorIfFailure, workingDirectory); } static int executionCounter; @@ -110,6 +122,9 @@ internal protected static async System.Threading.Tasks.Task ExecuteAs if (!string.IsNullOrEmpty (sdkDevPath)) launchEnvironment ["DEVELOPER_DIR"] = sdkDevPath; + if (fileName == "xcrun" && string.IsNullOrEmpty (sdkDevPath)) + log.LogError ($"Calling xcrun without specifying the Xcode path! StackTrace: {Environment.StackTrace}"); + var currentId = Interlocked.Increment (ref executionCounter); log.LogMessage (MessageImportance.Normal, MSBStrings.M0001, currentId, fileName, StringUtils.FormatArguments (arguments)); // Started external tool execution #{0}: {1} {2} if (!string.IsNullOrEmpty (workingDirectory)) { diff --git a/msbuild/Xamarin.MacDev.Tasks/Tasks/XcodeBuildTask.cs b/msbuild/Xamarin.MacDev.Tasks/Tasks/XcodeBuildTask.cs index dff2c77c4f0f..e71840ed899f 100644 --- a/msbuild/Xamarin.MacDev.Tasks/Tasks/XcodeBuildTask.cs +++ b/msbuild/Xamarin.MacDev.Tasks/Tasks/XcodeBuildTask.cs @@ -5,8 +5,6 @@ namespace Xamarin.MacDev.Tasks { public abstract class XcodeBuildTask : XamarinTask { // Task input parameters - public string SdkDevPath { get; set; } = string.Empty; - public string WorkingDirectory { get; set; } = string.Empty; public string OutputPath { get; set; } = string.Empty; @@ -25,7 +23,7 @@ public override bool Execute () } args.AddRange (GenerateCommandLineCommands ()); - ExecuteAsync ("xcrun", args, sdkDevPath: SdkDevPath, mergeOutput: false, workingDirectory: WorkingDirectory).Wait (); + ExecuteAsync ("xcrun", args, mergeOutput: false, workingDirectory: WorkingDirectory).Wait (); return !Log.HasLoggedErrors; } diff --git a/msbuild/Xamarin.MacDev.Tasks/Tasks/XcodeCompilerToolTask.cs b/msbuild/Xamarin.MacDev.Tasks/Tasks/XcodeCompilerToolTask.cs index c7f8762a91fd..e76837730b26 100644 --- a/msbuild/Xamarin.MacDev.Tasks/Tasks/XcodeCompilerToolTask.cs +++ b/msbuild/Xamarin.MacDev.Tasks/Tasks/XcodeCompilerToolTask.cs @@ -43,16 +43,6 @@ public abstract class XcodeCompilerToolTask : XamarinTask, IHasProjectDir, IHasR [Required] public string SdkPlatform { get; set; } = string.Empty; - string? sdkDevPath; - public string SdkDevPath { -#if NET - get { return string.IsNullOrEmpty (sdkDevPath) ? "/" : sdkDevPath; } -#else - get { return (sdkDevPath is null || string.IsNullOrEmpty (sdkDevPath)) ? "/" : sdkDevPath; } -#endif - set { sdkDevPath = value; } - } - public string SdkUsrPath { get; set; } = string.Empty; [Required] @@ -190,9 +180,6 @@ protected int Compile (ITaskItem [] items, string output, ITaskItem manifest) if (!string.IsNullOrEmpty (SdkUsrPath)) environment.Add ("XCODE_DEVELOPER_USR_PATH", SdkUsrPath); - if (!string.IsNullOrEmpty (SdkDevPath)) - environment.Add ("DEVELOPER_DIR", SdkDevPath); - // workaround for ibtool[d] bug / asserts if Intel version is loaded string tool; if (IsTranslated ()) { @@ -229,7 +216,7 @@ protected int Compile (ITaskItem [] items, string output, ITaskItem manifest) if (Log.HasLoggedErrors) return 1; - var rv = ExecuteAsync (tool, args, sdkDevPath, environment: environment, mergeOutput: false).Result; + var rv = ExecuteAsync (tool, args, environment: environment, mergeOutput: false).Result; var exitCode = rv.ExitCode; var messages = rv.StandardOutput!.ToString (); File.WriteAllText (manifest.ItemSpec, messages); diff --git a/msbuild/Xamarin.MacDev.Tasks/Tasks/XcodeTool.cs b/msbuild/Xamarin.MacDev.Tasks/Tasks/XcodeTool.cs index d01c1bbd408b..16caad0d91dc 100644 --- a/msbuild/Xamarin.MacDev.Tasks/Tasks/XcodeTool.cs +++ b/msbuild/Xamarin.MacDev.Tasks/Tasks/XcodeTool.cs @@ -30,9 +30,6 @@ public abstract class XcodeToolTaskBase : XamarinTask, IHasProjectDir, IHasResou [Required] public string SdkBinPath { get; set; } = string.Empty; - [Required] - public string SdkDevPath { get; set; } = string.Empty; - [Required] public string SdkUsrPath { get; set; } = string.Empty; diff --git a/msbuild/Xamarin.Shared/Xamarin.Shared.targets b/msbuild/Xamarin.Shared/Xamarin.Shared.targets index 4ae3be09211d..dc4b7c19e83c 100644 --- a/msbuild/Xamarin.Shared/Xamarin.Shared.targets +++ b/msbuild/Xamarin.Shared/Xamarin.Shared.targets @@ -3149,6 +3149,7 @@ Copyright (C) 2018 Microsoft. All rights reserved. Condition="'$(IsMacEnabled)' == 'true'" Input="$(_AppContainerDir)" MdimportPath="$(MdimportPath)" + SdkDevPath="$(_SdkDevPath)" /> @@ -3289,6 +3290,7 @@ Copyright (C) 2018 Microsoft. All rights reserved. ProductBuildPath="$(ProductBuildPath)" ProductDefinition="$(_CompiledProductDefinition)" ProjectPath="$(MSBuildProjectFullPath)" + SdkDevPath="$(_SdkDevPath)" > diff --git a/msbuild/Xamarin.Shared/Xamarin.iOS.Common.targets b/msbuild/Xamarin.Shared/Xamarin.iOS.Common.targets index e41b93ce7ac5..f1e866c37e63 100644 --- a/msbuild/Xamarin.Shared/Xamarin.iOS.Common.targets +++ b/msbuild/Xamarin.Shared/Xamarin.iOS.Common.targets @@ -463,6 +463,7 @@ Copyright (C) 2013-2016 Xamarin. All rights reserved. Source="%(_AssetPack.Identity)" OutputFile="$(IpaPackageDir)OnDemandResources\%(_AssetPack.DirectoryName)" ZipPath="$(ZipPath)" + SdkDevPath="$(_SdkDevPath)" /> Date: Thu, 16 Oct 2025 09:21:42 +0200 Subject: [PATCH 02/23] Codesign task --- msbuild/Xamarin.Shared/Xamarin.Shared.targets | 1 + msbuild/Xamarin.Shared/Xamarin.iOS.Common.targets | 2 ++ 2 files changed, 3 insertions(+) diff --git a/msbuild/Xamarin.Shared/Xamarin.Shared.targets b/msbuild/Xamarin.Shared/Xamarin.Shared.targets index dc4b7c19e83c..3d59c79ba048 100644 --- a/msbuild/Xamarin.Shared/Xamarin.Shared.targets +++ b/msbuild/Xamarin.Shared/Xamarin.Shared.targets @@ -2595,6 +2595,7 @@ Copyright (C) 2018 Microsoft. All rights reserved. DisallowResourcesSubdirectoryInAppBundle="$(CodesignDisallowResourcesSubdirectoryInAppBundle)" MaxDegreeOfParallelism="$(CodesignMaxDegreeOfParallelism)" Resources="@(_ComputedCodesignItems)" + SdkDevPath="$(_SdkDevPath)" TargetFrameworkMoniker="$(_ComputedTargetFrameworkMoniker)" ToolExe="$(CodesignExe)" ToolPath="$(CodesignPath)" diff --git a/msbuild/Xamarin.Shared/Xamarin.iOS.Common.targets b/msbuild/Xamarin.Shared/Xamarin.iOS.Common.targets index f1e866c37e63..fc32d3c45eeb 100644 --- a/msbuild/Xamarin.Shared/Xamarin.iOS.Common.targets +++ b/msbuild/Xamarin.Shared/Xamarin.iOS.Common.targets @@ -416,6 +416,7 @@ Copyright (C) 2013-2016 Xamarin. All rights reserved. Keychain="$(CodesignKeychain)" Entitlements="$(_CompiledCodesignEntitlements)" Resources="@(_AssetPack)" + SdkDevPath="$(_SdkDevPath)" SigningKey="$(_CodeSigningKey)" ExtraArgs="$(CodesignExtraArgs)" > @@ -449,6 +450,7 @@ Copyright (C) 2013-2016 Xamarin. All rights reserved. Entitlements="$(_CompiledCodesignEntitlements)" ResourceRules="$(_PreparedResourceRules)" Resources="@(_IpaAppBundleToSign)" + SdkDevPath="$(_SdkDevPath)" SigningKey="$(_CodeSigningKey)" TargetFrameworkMoniker="$(_ComputedTargetFrameworkMoniker)" ExtraArgs="$(CodesignExtraArgs)" From 6701afdee7feabd11f22e0ca47522cd30511f815 Mon Sep 17 00:00:00 2001 From: Rolf Bjarne Kvinge Date: Mon, 20 Oct 2025 13:39:00 +0200 Subject: [PATCH 03/23] add strip task --- msbuild/Xamarin.Shared/Xamarin.Shared.targets | 1 + 1 file changed, 1 insertion(+) diff --git a/msbuild/Xamarin.Shared/Xamarin.Shared.targets b/msbuild/Xamarin.Shared/Xamarin.Shared.targets index 3d59c79ba048..3ef32807bcfd 100644 --- a/msbuild/Xamarin.Shared/Xamarin.Shared.targets +++ b/msbuild/Xamarin.Shared/Xamarin.Shared.targets @@ -3113,6 +3113,7 @@ Copyright (C) 2018 Microsoft. All rights reserved. Executable="$(_AppContainerDir)%(_NativeStripItems.Identity)" Kind="%(_NativeStripItems.Kind)" MaxDegreeOfParallelism="$(SymbolStripMaxDegreeOfParallelism)" + SdkDevPath="$(_SdkDevPath)" StripPath="$(StripPath)" SymbolFile="%(_NativeStripItems.SymbolFile)" /> From 15de0afc8935e0a43e18a4df76f1e589aaaa74bf Mon Sep 17 00:00:00 2001 From: Rolf Bjarne Kvinge Date: Mon, 20 Oct 2025 17:00:08 +0200 Subject: [PATCH 04/23] A couple more --- msbuild/Xamarin.Shared/Xamarin.Shared.targets | 6 ++++-- .../Xamarin.iOS.Common.After.targets | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/msbuild/Xamarin.Shared/Xamarin.Shared.targets b/msbuild/Xamarin.Shared/Xamarin.Shared.targets index 3ef32807bcfd..3a1935209b3d 100644 --- a/msbuild/Xamarin.Shared/Xamarin.Shared.targets +++ b/msbuild/Xamarin.Shared/Xamarin.Shared.targets @@ -366,7 +366,7 @@ Copyright (C) 2018 Microsoft. All rights reserved. - + @@ -3186,6 +3186,7 @@ Copyright (C) 2018 Microsoft. All rights reserved. ProjectGuid="$(ProjectGuid)" ProjectName="$(MSBuildProjectName)" ProjectTypeGuids="$(ProjectTypeGuids)" + SdkDevPath="$(_SdkDevPath)" SigningKey="$(_CodeSigningKey)" SolutionPath="$(SolutionPath)" RuntimeIdentifiers="$(RuntimeIdentifiers);$(RuntimeIdentifier)" @@ -3269,7 +3270,8 @@ Copyright (C) 2018 Microsoft. All rights reserved. _GetAppBundleEntitlements; Codesign; _CompileProductDefinition; - _WriteAppManifest + _WriteAppManifest; + _DetectSdkLocations; diff --git a/msbuild/Xamarin.iOS.Tasks.Windows/Xamarin.iOS.Common.After.targets b/msbuild/Xamarin.iOS.Tasks.Windows/Xamarin.iOS.Common.After.targets index 18f47cefeb98..96d68b6edadf 100644 --- a/msbuild/Xamarin.iOS.Tasks.Windows/Xamarin.iOS.Common.After.targets +++ b/msbuild/Xamarin.iOS.Tasks.Windows/Xamarin.iOS.Common.After.targets @@ -181,7 +181,7 @@ Copyright (C) 2011-2013 Xamarin. All rights reserved. - + From 727a35d9262ca964d3362359edd954a25ee10e4b Mon Sep 17 00:00:00 2001 From: Rolf Bjarne Kvinge Date: Tue, 21 Oct 2025 13:38:09 +0200 Subject: [PATCH 05/23] Use the instance ExecuteAsync method. --- msbuild/Xamarin.MacDev.Tasks/Tasks/CreateInstallerPackage.cs | 2 +- msbuild/Xamarin.MacDev.Tasks/Tasks/XamarinTask.cs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/msbuild/Xamarin.MacDev.Tasks/Tasks/CreateInstallerPackage.cs b/msbuild/Xamarin.MacDev.Tasks/Tasks/CreateInstallerPackage.cs index 6b3b1509fbf2..9abca409643b 100644 --- a/msbuild/Xamarin.MacDev.Tasks/Tasks/CreateInstallerPackage.cs +++ b/msbuild/Xamarin.MacDev.Tasks/Tasks/CreateInstallerPackage.cs @@ -81,7 +81,7 @@ public override bool Execute () var args = GenerateCommandLineCommands (); var executable = GetExecutable (args, "productbuild", ProductBuildPath); cancellationTokenSource = new CancellationTokenSource (); - ExecuteAsync (Log, executable, args, workingDirectory: OutputDirectory, cancellationToken: cancellationTokenSource.Token).Wait (); + ExecuteAsync (executable, args, workingDirectory: OutputDirectory, cancellationToken: cancellationTokenSource.Token).Wait (); return !Log.HasLoggedErrors; } diff --git a/msbuild/Xamarin.MacDev.Tasks/Tasks/XamarinTask.cs b/msbuild/Xamarin.MacDev.Tasks/Tasks/XamarinTask.cs index 67b0852fcec0..fc7ccfb4fc95 100644 --- a/msbuild/Xamarin.MacDev.Tasks/Tasks/XamarinTask.cs +++ b/msbuild/Xamarin.MacDev.Tasks/Tasks/XamarinTask.cs @@ -109,9 +109,9 @@ protected string GetSdkPlatform (bool isSimulator) return PlatformFrameworkHelper.GetSdkPlatform (Platform, isSimulator); } - protected System.Threading.Tasks.Task ExecuteAsync (string fileName, IList arguments, Dictionary? environment = null, bool mergeOutput = true, bool showErrorIfFailure = true, string? workingDirectory = null) + protected System.Threading.Tasks.Task ExecuteAsync (string fileName, IList arguments, Dictionary? environment = null, bool mergeOutput = true, bool showErrorIfFailure = true, string? workingDirectory = null, CancellationToken? cancellationToken = null) { - return ExecuteAsync (Log, fileName, arguments, SdkDevPath, environment, mergeOutput, showErrorIfFailure, workingDirectory); + return ExecuteAsync (Log, fileName, arguments, SdkDevPath, environment, mergeOutput, showErrorIfFailure, workingDirectory, cancellationToken); } static int executionCounter; From 08cffd4433ab3e8ff2de38f56f72bf461b589ebc Mon Sep 17 00:00:00 2001 From: Rolf Bjarne Kvinge Date: Tue, 21 Oct 2025 14:01:34 +0200 Subject: [PATCH 06/23] Fix msbuild tests. --- .../TaskTests/MergeAppBundleTaskTest.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/msbuild/Xamarin.MacDev.Tasks.Tests/TaskTests/MergeAppBundleTaskTest.cs b/tests/msbuild/Xamarin.MacDev.Tasks.Tests/TaskTests/MergeAppBundleTaskTest.cs index 16a79e70fb84..b5d2723c775d 100644 --- a/tests/msbuild/Xamarin.MacDev.Tasks.Tests/TaskTests/MergeAppBundleTaskTest.cs +++ b/tests/msbuild/Xamarin.MacDev.Tasks.Tests/TaskTests/MergeAppBundleTaskTest.cs @@ -60,6 +60,7 @@ MergeAppBundles CreateTask (string outputBundle, params string [] inputBundles) var task = CreateTask (); task.InputAppBundles = inputItems.ToArray (); task.OutputAppBundle = outputBundle; + task.SdkDevPath = Configuration.xcode_root; return task; } @@ -98,7 +99,7 @@ public void TestLipoExecutable () var outputBundle = Path.Combine (Cache.CreateTemporaryDirectory (), "Merged.app"); var task = CreateTask (outputBundle, bundles); - Assert.IsTrue (task.Execute (), "Task execution"); + ExecuteTask (task); // The bundle should only contain a single file. Assert.AreEqual (1, Directory.GetFileSystemEntries (outputBundle).Length, "Files in bundle"); From 45826c7991e523f57797d46f2aea58a71ed32a08 Mon Sep 17 00:00:00 2001 From: Rolf Bjarne Kvinge Date: Tue, 21 Oct 2025 23:05:10 +0200 Subject: [PATCH 07/23] A few more --- msbuild/Xamarin.Shared/Xamarin.Shared.targets | 4 +++- .../Xamarin.iOS.Common.After.targets | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/msbuild/Xamarin.Shared/Xamarin.Shared.targets b/msbuild/Xamarin.Shared/Xamarin.Shared.targets index 3a1935209b3d..65d9752230d0 100644 --- a/msbuild/Xamarin.Shared/Xamarin.Shared.targets +++ b/msbuild/Xamarin.Shared/Xamarin.Shared.targets @@ -365,7 +365,7 @@ Copyright (C) 2018 Microsoft. All rights reserved. - + @@ -439,6 +439,7 @@ Copyright (C) 2018 Microsoft. All rights reserved. _CompileTextureAtlases; _CompileCoreMLModels; _SetResourceMetadata; + _DetectSdkLocations; @@ -465,6 +466,7 @@ Copyright (C) 2018 Microsoft. All rights reserved. BundleResources="@(Content);@(BundleResource)" ProjectDir="$(MSBuildProjectDirectory)" ResourcePrefix="$(_ResourcePrefix)" + SdkDevPath="$(_SdkDevPath)" TargetFrameworkMoniker="$(_ComputedTargetFrameworkMoniker)" UnpackedResources="@(_UnpackedBundleResourceWithLogicalName)" > diff --git a/msbuild/Xamarin.iOS.Tasks.Windows/Xamarin.iOS.Common.After.targets b/msbuild/Xamarin.iOS.Tasks.Windows/Xamarin.iOS.Common.After.targets index 96d68b6edadf..c46751d4d2bf 100644 --- a/msbuild/Xamarin.iOS.Tasks.Windows/Xamarin.iOS.Common.After.targets +++ b/msbuild/Xamarin.iOS.Tasks.Windows/Xamarin.iOS.Common.After.targets @@ -177,7 +177,7 @@ Copyright (C) 2011-2013 Xamarin. All rights reserved. - + From 3fd06202d32b3d09d8ed9838443cbf554031b506 Mon Sep 17 00:00:00 2001 From: Rolf Bjarne Kvinge Date: Wed, 22 Oct 2025 12:23:05 +0200 Subject: [PATCH 08/23] Some debug spew. --- msbuild/Xamarin.MacDev.Tasks/Tasks/XamarinTask.cs | 2 +- msbuild/Xamarin.Shared/Xamarin.Shared.targets | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/msbuild/Xamarin.MacDev.Tasks/Tasks/XamarinTask.cs b/msbuild/Xamarin.MacDev.Tasks/Tasks/XamarinTask.cs index fc7ccfb4fc95..46403326f2af 100644 --- a/msbuild/Xamarin.MacDev.Tasks/Tasks/XamarinTask.cs +++ b/msbuild/Xamarin.MacDev.Tasks/Tasks/XamarinTask.cs @@ -27,7 +27,7 @@ public abstract class XamarinTask : Task, IHasSessionId, ICustomLogger { public string SdkDevPath { get { if (string.IsNullOrEmpty (sdkDevPath)) - Log.LogError ($"The task {GetType ().Name} requires 'SdkDevPath' to be set."); + Log.LogError ($"The task {GetType ().Name} requires 'SdkDevPath' to be set.\n{Environment.StackTrace}"); return sdkDevPath; } set { diff --git a/msbuild/Xamarin.Shared/Xamarin.Shared.targets b/msbuild/Xamarin.Shared/Xamarin.Shared.targets index 65d9752230d0..787044270ef0 100644 --- a/msbuild/Xamarin.Shared/Xamarin.Shared.targets +++ b/msbuild/Xamarin.Shared/Xamarin.Shared.targets @@ -439,7 +439,6 @@ Copyright (C) 2018 Microsoft. All rights reserved. _CompileTextureAtlases; _CompileCoreMLModels; _SetResourceMetadata; - _DetectSdkLocations; From 8e4916693db3bf4821cd2cdda6c02140d122180f Mon Sep 17 00:00:00 2001 From: Rolf Bjarne Kvinge Date: Thu, 23 Oct 2025 14:45:58 +0200 Subject: [PATCH 09/23] tweak --- .../Xamarin.MacDev.Tasks/Tasks/XamarinTask.cs | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/msbuild/Xamarin.MacDev.Tasks/Tasks/XamarinTask.cs b/msbuild/Xamarin.MacDev.Tasks/Tasks/XamarinTask.cs index 46403326f2af..1a4fbfb989a6 100644 --- a/msbuild/Xamarin.MacDev.Tasks/Tasks/XamarinTask.cs +++ b/msbuild/Xamarin.MacDev.Tasks/Tasks/XamarinTask.cs @@ -23,17 +23,7 @@ public abstract class XamarinTask : Task, IHasSessionId, ICustomLogger { public string TargetFrameworkMoniker { get; set; } = string.Empty; - string sdkDevPath = string.Empty; - public string SdkDevPath { - get { - if (string.IsNullOrEmpty (sdkDevPath)) - Log.LogError ($"The task {GetType ().Name} requires 'SdkDevPath' to be set.\n{Environment.StackTrace}"); - return sdkDevPath; - } - set { - sdkDevPath = value; - } - } + public string SdkDevPath { get; set; } = string.Empty; void VerifyTargetFrameworkMoniker () { @@ -122,8 +112,8 @@ internal protected static async System.Threading.Tasks.Task ExecuteAs if (!string.IsNullOrEmpty (sdkDevPath)) launchEnvironment ["DEVELOPER_DIR"] = sdkDevPath; - if (fileName == "xcrun" && string.IsNullOrEmpty (sdkDevPath)) - log.LogError ($"Calling xcrun without specifying the Xcode path! StackTrace: {Environment.StackTrace}"); + if (string.IsNullOrEmpty (sdkDevPath)) + log.LogError ($"Calling external processes without specifying the Xcode path! StackTrace: {Environment.StackTrace}"); var currentId = Interlocked.Increment (ref executionCounter); log.LogMessage (MessageImportance.Normal, MSBStrings.M0001, currentId, fileName, StringUtils.FormatArguments (arguments)); // Started external tool execution #{0}: {1} {2} From f722c62ad79db863a5716eeafb7ac917726abaae Mon Sep 17 00:00:00 2001 From: Rolf Bjarne Kvinge Date: Thu, 23 Oct 2025 17:24:19 +0200 Subject: [PATCH 10/23] sq --- msbuild/Xamarin.MacDev.Tasks/Tasks/XamarinTask.cs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/msbuild/Xamarin.MacDev.Tasks/Tasks/XamarinTask.cs b/msbuild/Xamarin.MacDev.Tasks/Tasks/XamarinTask.cs index 1a4fbfb989a6..d8d23ba0bdfa 100644 --- a/msbuild/Xamarin.MacDev.Tasks/Tasks/XamarinTask.cs +++ b/msbuild/Xamarin.MacDev.Tasks/Tasks/XamarinTask.cs @@ -101,11 +101,16 @@ protected string GetSdkPlatform (bool isSimulator) protected System.Threading.Tasks.Task ExecuteAsync (string fileName, IList arguments, Dictionary? environment = null, bool mergeOutput = true, bool showErrorIfFailure = true, string? workingDirectory = null, CancellationToken? cancellationToken = null) { - return ExecuteAsync (Log, fileName, arguments, SdkDevPath, environment, mergeOutput, showErrorIfFailure, workingDirectory, cancellationToken); + return ExecuteAsync (this, Log, fileName, arguments, SdkDevPath, environment, mergeOutput, showErrorIfFailure, workingDirectory, cancellationToken); } static int executionCounter; internal protected static async System.Threading.Tasks.Task ExecuteAsync (TaskLoggingHelper log, string fileName, IList arguments, string? sdkDevPath = null, Dictionary? environment = null, bool mergeOutput = true, bool showErrorIfFailure = true, string? workingDirectory = null, CancellationToken? cancellationToken = null) + { + return ExecuteAsync (null, log, fileName, arguments, SdkDevPath, environment, mergeOutput, showErrorIfFailure, workingDirectory, cancellationToken); + } + + internal protected static async System.Threading.Tasks.Task ExecuteAsync (Task? task, TaskLoggingHelper log, string fileName, IList arguments, string? sdkDevPath = null, Dictionary? environment = null, bool mergeOutput = true, bool showErrorIfFailure = true, string? workingDirectory = null, CancellationToken? cancellationToken = null) { // Create a new dictionary if we're given one, to make sure we don't change the caller's dictionary. var launchEnvironment = environment is null ? new Dictionary () : new Dictionary (environment); @@ -113,7 +118,7 @@ internal protected static async System.Threading.Tasks.Task ExecuteAs launchEnvironment ["DEVELOPER_DIR"] = sdkDevPath; if (string.IsNullOrEmpty (sdkDevPath)) - log.LogError ($"Calling external processes without specifying the Xcode path! StackTrace: {Environment.StackTrace}"); + log.LogError ($"Calling external processes without specifying the Xcode path in the task {(task?.GetType ()?.Name ?? "?")}! StackTrace: {Environment.StackTrace}"); var currentId = Interlocked.Increment (ref executionCounter); log.LogMessage (MessageImportance.Normal, MSBStrings.M0001, currentId, fileName, StringUtils.FormatArguments (arguments)); // Started external tool execution #{0}: {1} {2} From 44023802a2ea3182692eb56b9c17d9779e5ef36c Mon Sep 17 00:00:00 2001 From: Rolf Bjarne Kvinge Date: Fri, 24 Oct 2025 14:44:08 +0200 Subject: [PATCH 11/23] fixes --- msbuild/Xamarin.MacDev.Tasks/Decompress.cs | 35 +++++++++++-------- msbuild/Xamarin.MacDev.Tasks/Tasks/AlTool.cs | 2 +- msbuild/Xamarin.MacDev.Tasks/Tasks/BGen.cs | 2 +- .../Tasks/CreateAssetPack.cs | 2 +- .../Tasks/CreateBindingResourcePackage.cs | 2 +- msbuild/Xamarin.MacDev.Tasks/Tasks/Ditto.cs | 2 +- msbuild/Xamarin.MacDev.Tasks/Tasks/Metal.cs | 2 +- .../Xamarin.MacDev.Tasks/Tasks/MetalLib.cs | 2 +- .../Tasks/OptimizeImage.cs | 2 +- .../Tasks/OptimizePropertyList.cs | 2 +- .../Tasks/ResolveNativeReferences.cs | 23 ++++++------ .../Tasks/SpotlightIndexer.cs | 2 +- msbuild/Xamarin.MacDev.Tasks/Tasks/Unzip.cs | 2 +- .../Xamarin.MacDev.Tasks/Tasks/XamarinTask.cs | 12 +++---- msbuild/Xamarin.MacDev.Tasks/Tasks/Zip.cs | 2 +- msbuild/Xamarin.Shared/Xamarin.Shared.targets | 1 + 16 files changed, 50 insertions(+), 45 deletions(-) diff --git a/msbuild/Xamarin.MacDev.Tasks/Decompress.cs b/msbuild/Xamarin.MacDev.Tasks/Decompress.cs index fedb4d3f2027..cfedc62041f3 100644 --- a/msbuild/Xamarin.MacDev.Tasks/Decompress.cs +++ b/msbuild/Xamarin.MacDev.Tasks/Decompress.cs @@ -100,8 +100,10 @@ static string CanonicalizeZipEntryPath (string path) /// The cancellation token (if any= /// The location on disk to the extracted resource /// True if successfully decompressed, false otherwise. - public static bool TryDecompress (TaskLoggingHelper log, string zip, string resource, string decompressionDir, List createdFiles, CancellationToken? cancellationToken, [NotNullWhen (true)] out string? decompressedResource) + public static bool TryDecompress (XamarinTask task, string zip, string resource, string decompressionDir, List createdFiles, CancellationToken? cancellationToken, [NotNullWhen (true)] out string? decompressedResource) { + var log = task.Log; + decompressedResource = Path.Combine (decompressionDir, resource); var stampFile = decompressedResource.TrimEnd ('\\', '/') + ".stamp"; @@ -118,11 +120,11 @@ public static bool TryDecompress (TaskLoggingHelper log, string zip, string reso bool rv; if (Environment.OSVersion.Platform == PlatformID.Win32NT) { - rv = TryDecompressUsingSystemIOCompression (log, zip, resource, decompressionDir, cancellationToken); + rv = TryDecompressUsingSystemIOCompression (task, zip, resource, decompressionDir, cancellationToken); } else if (!string.IsNullOrEmpty (Environment.GetEnvironmentVariable ("XAMARIN_USE_SYSTEM_IO_COMPRESSION"))) { - rv = TryDecompressUsingSystemIOCompression (log, zip, resource, decompressionDir, cancellationToken); + rv = TryDecompressUsingSystemIOCompression (task, zip, resource, decompressionDir, cancellationToken); } else { - rv = TryDecompressUsingUnzip (log, zip, resource, decompressionDir, cancellationToken); + rv = TryDecompressUsingUnzip (task, zip, resource, decompressionDir, cancellationToken); } if (rv) { @@ -145,8 +147,9 @@ public static bool TryDecompress (TaskLoggingHelper log, string zip, string reso // The dir separator character in zip files is always "/", even on Windows const char zipDirectorySeparator = '/'; - static bool TryDecompressUsingUnzip (TaskLoggingHelper log, string zip, string resource, string decompressionDir, CancellationToken? cancellationToken) + static bool TryDecompressUsingUnzip (XamarinTask task, string zip, string resource, string decompressionDir, CancellationToken? cancellationToken) { + var log = task.Log; Directory.CreateDirectory (decompressionDir); var args = new List { "-u", "-o", @@ -176,12 +179,13 @@ static bool TryDecompressUsingUnzip (TaskLoggingHelper log, string zip, string r args.Add (zipPattern); } - var rv = XamarinTask.ExecuteAsync (log, "unzip", args, cancellationToken: cancellationToken).Result; + var rv = task.ExecuteAsync ("unzip", args, cancellationToken: cancellationToken).Result; return rv.ExitCode == 0; } - static bool TryDecompressUsingSystemIOCompression (TaskLoggingHelper log, string zip, string resource, string decompressionDir, CancellationToken? cancellationToken) + static bool TryDecompressUsingSystemIOCompression (XamarinTask task, string zip, string resource, string decompressionDir, CancellationToken? cancellationToken) { + var log = task.Log; var rv = true; // canonicalize input @@ -270,8 +274,9 @@ static bool TryDecompressUsingSystemIOCompression (TaskLoggingHelper log, string /// testing the System.IO.Compression implementation locally (with the caveat that if the resources /// to compress has symlinks, it may not work). /// - public static bool TryCompress (TaskLoggingHelper log, string zip, IEnumerable resources, bool overwrite, string workingDirectory, bool maxCompression = false) + public static bool TryCompress (XamarinTask task, string zip, IEnumerable resources, bool overwrite, string workingDirectory, bool maxCompression = false) { + var log = task.Log; if (overwrite) { if (File.Exists (zip)) { log.LogMessage (MessageImportance.Low, "Replacing zip file {0} with {1}", zip, string.Join (", ", resources)); @@ -293,19 +298,20 @@ public static bool TryCompress (TaskLoggingHelper log, string zip, IEnumerable resources, string workingDirectory, bool maxCompression) + static bool TryCompressUsingZip (XamarinTask task, string zip, IEnumerable resources, string workingDirectory, bool maxCompression) { + var log = task.Log; var zipArguments = new List (); if (maxCompression) zipArguments.Add ("-9"); @@ -318,7 +324,7 @@ static bool TryCompressUsingZip (TaskLoggingHelper log, string zip, IEnumerable< var relativePath = PathUtils.AbsoluteToRelative (workingDirectory, fullPath); zipArguments.Add (relativePath); } - var rv = XamarinTask.ExecuteAsync (log, "zip", zipArguments, workingDirectory: workingDirectory).Result; + var rv = task.ExecuteAsync ("zip", zipArguments, workingDirectory: workingDirectory).Result; log.LogMessage (MessageImportance.Low, "Updated {0} with {1}: {2}", zip, string.Join (", ", resources), rv.ExitCode == 0); return rv.ExitCode == 0; } @@ -330,8 +336,9 @@ static bool TryCompressUsingZip (TaskLoggingHelper log, string zip, IEnumerable< #endif // Will always add to an existing zip file (not replace) - static bool TryCompressUsingSystemIOCompression (TaskLoggingHelper log, string zip, IEnumerable resources, string workingDirectory, bool maxCompression) + static bool TryCompressUsingSystemIOCompression (XamarinTask task, string zip, IEnumerable resources, string workingDirectory, bool maxCompression) { + var log = task.Log; var rv = true; workingDirectory = Path.GetFullPath (workingDirectory); diff --git a/msbuild/Xamarin.MacDev.Tasks/Tasks/AlTool.cs b/msbuild/Xamarin.MacDev.Tasks/Tasks/AlTool.cs index f602b4810ea7..96e96c88fa54 100644 --- a/msbuild/Xamarin.MacDev.Tasks/Tasks/AlTool.cs +++ b/msbuild/Xamarin.MacDev.Tasks/Tasks/AlTool.cs @@ -41,7 +41,7 @@ public override bool Execute () return false; cancellationTokenSource = new CancellationTokenSource (); - var rv = ExecuteAsync (Log, executable, args, sdkDevPath: SdkDevPath, cancellationToken: cancellationTokenSource.Token).Result; + var rv = ExecuteAsync (executable, args, cancellationToken: cancellationTokenSource.Token).Result; LogErrorsFromOutput (rv.StandardOutput?.ToString ()); return !Log.HasLoggedErrors; } diff --git a/msbuild/Xamarin.MacDev.Tasks/Tasks/BGen.cs b/msbuild/Xamarin.MacDev.Tasks/Tasks/BGen.cs index 803842390a4f..99a78200563c 100644 --- a/msbuild/Xamarin.MacDev.Tasks/Tasks/BGen.cs +++ b/msbuild/Xamarin.MacDev.Tasks/Tasks/BGen.cs @@ -286,7 +286,7 @@ public override bool Execute () return false; cancellationTokenSource = new CancellationTokenSource (); - ExecuteAsync (Log, executable, args, environment: env, cancellationToken: cancellationTokenSource.Token).Wait (); + ExecuteAsync (executable, args, environment: env, cancellationToken: cancellationTokenSource.Token).Wait (); return !Log.HasLoggedErrors; } diff --git a/msbuild/Xamarin.MacDev.Tasks/Tasks/CreateAssetPack.cs b/msbuild/Xamarin.MacDev.Tasks/Tasks/CreateAssetPack.cs index e91884c40685..264134ac29d2 100644 --- a/msbuild/Xamarin.MacDev.Tasks/Tasks/CreateAssetPack.cs +++ b/msbuild/Xamarin.MacDev.Tasks/Tasks/CreateAssetPack.cs @@ -80,7 +80,7 @@ public override bool Execute () var args = GenerateCommandLineCommands (); var executable = GetExecutable (args, "zip", ZipPath); cancellationTokenSource = new CancellationTokenSource (); - ExecuteAsync (Log, executable, args, workingDirectory: GetWorkingDirectory (), cancellationToken: cancellationTokenSource.Token).Wait (); + ExecuteAsync (executable, args, workingDirectory: GetWorkingDirectory (), cancellationToken: cancellationTokenSource.Token).Wait (); return !Log.HasLoggedErrors; } diff --git a/msbuild/Xamarin.MacDev.Tasks/Tasks/CreateBindingResourcePackage.cs b/msbuild/Xamarin.MacDev.Tasks/Tasks/CreateBindingResourcePackage.cs index 236255778be5..048c09394d28 100644 --- a/msbuild/Xamarin.MacDev.Tasks/Tasks/CreateBindingResourcePackage.cs +++ b/msbuild/Xamarin.MacDev.Tasks/Tasks/CreateBindingResourcePackage.cs @@ -100,7 +100,7 @@ public override bool Execute () var workingDirectory = Path.GetDirectoryName (nativeRef); if (string.IsNullOrEmpty (workingDirectory)) workingDirectory = Directory.GetCurrentDirectory (); - CompressionHelper.TryCompress (Log, zipFile, new string [] { nativeRef }, false, workingDirectory, true); + CompressionHelper.TryCompress (this, zipFile, new string [] { nativeRef }, false, workingDirectory, true); } packagedFiles.Add (zipFile); } else { diff --git a/msbuild/Xamarin.MacDev.Tasks/Tasks/Ditto.cs b/msbuild/Xamarin.MacDev.Tasks/Tasks/Ditto.cs index 89abe8e02b67..169af8dcddb2 100644 --- a/msbuild/Xamarin.MacDev.Tasks/Tasks/Ditto.cs +++ b/msbuild/Xamarin.MacDev.Tasks/Tasks/Ditto.cs @@ -103,7 +103,7 @@ bool ExecuteImpl () } cancellationTokenSource = new CancellationTokenSource (); - ExecuteAsync (Log, executable, args, cancellationToken: cancellationTokenSource.Token).Wait (); + ExecuteAsync (executable, args, cancellationToken: cancellationTokenSource.Token).Wait (); // Create a list of all the files we've copied if (CreateOutputFiles) { diff --git a/msbuild/Xamarin.MacDev.Tasks/Tasks/Metal.cs b/msbuild/Xamarin.MacDev.Tasks/Tasks/Metal.cs index 14aee97cd3ae..46b75264f693 100644 --- a/msbuild/Xamarin.MacDev.Tasks/Tasks/Metal.cs +++ b/msbuild/Xamarin.MacDev.Tasks/Tasks/Metal.cs @@ -93,7 +93,7 @@ public override bool Execute () args.Add (SourceFile!.ItemSpec); cancellationTokenSource = new CancellationTokenSource (); - ExecuteAsync (Log, executable, args, environment: env, sdkDevPath: SdkDevPath, cancellationToken: cancellationTokenSource.Token).Wait (); + ExecuteAsync (executable, args, environment: env, cancellationToken: cancellationTokenSource.Token).Wait (); return !Log.HasLoggedErrors; } diff --git a/msbuild/Xamarin.MacDev.Tasks/Tasks/MetalLib.cs b/msbuild/Xamarin.MacDev.Tasks/Tasks/MetalLib.cs index 402403ab238c..91fbff871bdd 100644 --- a/msbuild/Xamarin.MacDev.Tasks/Tasks/MetalLib.cs +++ b/msbuild/Xamarin.MacDev.Tasks/Tasks/MetalLib.cs @@ -51,7 +51,7 @@ public override bool Execute () var executable = GetExecutable (args, "metallib", MetalLibPath); cancellationTokenSource = new CancellationTokenSource (); - ExecuteAsync (Log, executable, args, environment: env, sdkDevPath: SdkDevPath, cancellationToken: cancellationTokenSource.Token).Wait (); + ExecuteAsync (executable, args, environment: env, cancellationToken: cancellationTokenSource.Token).Wait (); return !Log.HasLoggedErrors; } diff --git a/msbuild/Xamarin.MacDev.Tasks/Tasks/OptimizeImage.cs b/msbuild/Xamarin.MacDev.Tasks/Tasks/OptimizeImage.cs index 162149772781..27258b512c13 100644 --- a/msbuild/Xamarin.MacDev.Tasks/Tasks/OptimizeImage.cs +++ b/msbuild/Xamarin.MacDev.Tasks/Tasks/OptimizeImage.cs @@ -89,7 +89,7 @@ public override bool Execute () ForEach (listOfArguments, (arg) => { var args = arg.Arguments; var executable = GetExecutable (args, "pngcrush", PngCrushPath); - ExecuteAsync (Log, executable, args, sdkDevPath: SdkDevPath, mergeOutput: true, showErrorIfFailure: false /* we show our own error below */, cancellationToken: cancellationTokenSource.Token) + ExecuteAsync (executable, args, mergeOutput: true, showErrorIfFailure: false /* we show our own error below */, cancellationToken: cancellationTokenSource.Token) .ContinueWith ((v) => { Execution execution = v.Result; if (execution.ExitCode != 0) diff --git a/msbuild/Xamarin.MacDev.Tasks/Tasks/OptimizePropertyList.cs b/msbuild/Xamarin.MacDev.Tasks/Tasks/OptimizePropertyList.cs index 5f2b4fcc5e31..e58b26e7893b 100644 --- a/msbuild/Xamarin.MacDev.Tasks/Tasks/OptimizePropertyList.cs +++ b/msbuild/Xamarin.MacDev.Tasks/Tasks/OptimizePropertyList.cs @@ -50,7 +50,7 @@ public override bool Execute () var args = GenerateCommandLineCommands (); var executable = GetExecutable (args, "plutil", PlutilPath); cancellationTokenSource = new CancellationTokenSource (); - ExecuteAsync (Log, executable, args, sdkDevPath: SdkDevPath, cancellationToken: cancellationTokenSource.Token).Wait (); + ExecuteAsync (executable, args, cancellationToken: cancellationTokenSource.Token).Wait (); return !Log.HasLoggedErrors; } diff --git a/msbuild/Xamarin.MacDev.Tasks/Tasks/ResolveNativeReferences.cs b/msbuild/Xamarin.MacDev.Tasks/Tasks/ResolveNativeReferences.cs index 3aab40aaecd7..a40e837b802b 100644 --- a/msbuild/Xamarin.MacDev.Tasks/Tasks/ResolveNativeReferences.cs +++ b/msbuild/Xamarin.MacDev.Tasks/Tasks/ResolveNativeReferences.cs @@ -198,7 +198,7 @@ void ProcessNativeReference (ITaskItem item, string name, List native // (compressed) xcframework if (name.EndsWith (".xcframework", StringComparison.OrdinalIgnoreCase) || name.EndsWith (".xcframework.zip", StringComparison.OrdinalIgnoreCase)) { - if (!TryResolveXCFramework (Log, TargetFrameworkMoniker, SdkIsSimulator, Architectures, name, GetIntermediateDecompressionDir (item), createdFiles, cancellationToken, out var nativeLibraryPath)) + if (!TryResolveXCFramework (this, TargetFrameworkMoniker, SdkIsSimulator, Architectures, name, GetIntermediateDecompressionDir (item), createdFiles, cancellationToken, out var nativeLibraryPath)) return; var nr = new TaskItem (item); SetMetadataNativeLibrary (nr, nativeLibraryPath); @@ -208,7 +208,7 @@ void ProcessNativeReference (ITaskItem item, string name, List native // compressed framework if (name.EndsWith (".framework.zip", StringComparison.OrdinalIgnoreCase)) { - if (!CompressionHelper.TryDecompress (Log, name, Path.GetFileNameWithoutExtension (name), GetIntermediateDecompressionDir (item), createdFiles, cancellationToken, out var frameworkPath)) + if (!CompressionHelper.TryDecompress (this, name, Path.GetFileNameWithoutExtension (name), GetIntermediateDecompressionDir (item), createdFiles, cancellationToken, out var frameworkPath)) return; var nr = new TaskItem (item); nr.ItemSpec = GetActualLibrary (frameworkPath); @@ -311,14 +311,14 @@ void ProcessSidecar (ITaskItem r, string resources, List native_frame ITaskItem t = new TaskItem (r); var name = referenceNode.Attributes ["Name"].Value.Trim ('\\', '/'); if (name.EndsWith (".xcframework", StringComparison.Ordinal) || name.EndsWith (".xcframework.zip", StringComparison.Ordinal)) { - if (!TryResolveXCFramework (Log, TargetFrameworkMoniker, SdkIsSimulator, Architectures, resources, name, GetIntermediateDecompressionDir (resources), createdFiles, cancellationToken, out var nativeLibraryPath)) + if (!TryResolveXCFramework (this, TargetFrameworkMoniker, SdkIsSimulator, Architectures, resources, name, GetIntermediateDecompressionDir (resources), createdFiles, cancellationToken, out var nativeLibraryPath)) continue; SetMetadataNativeLibrary (t, nativeLibraryPath); } else if (name.EndsWith (".framework", StringComparison.Ordinal)) { string? frameworkPath; if (!isCompressed) { frameworkPath = Path.Combine (resources, name); - } else if (!CompressionHelper.TryDecompress (Log, resources, name, GetIntermediateDecompressionDir (resources), createdFiles, cancellationToken, out frameworkPath)) { + } else if (!CompressionHelper.TryDecompress (this, resources, name, GetIntermediateDecompressionDir (resources), createdFiles, cancellationToken, out frameworkPath)) { continue; } t.ItemSpec = GetActualLibrary (frameworkPath); @@ -330,7 +330,7 @@ void ProcessSidecar (ITaskItem r, string resources, List native_frame string? dylibPath; if (!isCompressed) { dylibPath = Path.Combine (resources, name); - } else if (!CompressionHelper.TryDecompress (Log, resources, name, GetIntermediateDecompressionDir (resources), createdFiles, cancellationToken, out dylibPath)) { + } else if (!CompressionHelper.TryDecompress (this, resources, name, GetIntermediateDecompressionDir (resources), createdFiles, cancellationToken, out dylibPath)) { continue; } t.ItemSpec = dylibPath; @@ -341,7 +341,7 @@ void ProcessSidecar (ITaskItem r, string resources, List native_frame string? aPath; if (!isCompressed) { aPath = Path.Combine (resources, name); - } else if (!CompressionHelper.TryDecompress (Log, resources, name, GetIntermediateDecompressionDir (resources), createdFiles, cancellationToken, out aPath)) { + } else if (!CompressionHelper.TryDecompress (this, resources, name, GetIntermediateDecompressionDir (resources), createdFiles, cancellationToken, out aPath)) { continue; } t.ItemSpec = aPath; @@ -378,7 +378,7 @@ void ProcessSidecar (ITaskItem r, string resources, List native_frame /// A full path to the resolved native library within the xcframework. If 'resourcePath' is compressed, this will point to where the native library is decompressed on disk. /// /// True if a native library was successfully found. Otherwise false, and an error will have been printed to the log. - public static bool TryResolveXCFramework (TaskLoggingHelper log, string targetFrameworkMoniker, bool isSimulator, string? architectures, string path, string intermediateDecompressionDir, List createdFiles, CancellationToken? cancellationToken, [NotNullWhen (true)] out string? nativeLibraryPath) + public static bool TryResolveXCFramework (XamarinTask task, string targetFrameworkMoniker, bool isSimulator, string? architectures, string path, string intermediateDecompressionDir, List createdFiles, CancellationToken? cancellationToken, [NotNullWhen (true)] out string? nativeLibraryPath) { string resourcePath; string xcframework; @@ -390,7 +390,7 @@ public static bool TryResolveXCFramework (TaskLoggingHelper log, string targetFr resourcePath = Path.GetDirectoryName (path); xcframework = Path.GetFileName (path); } - return TryResolveXCFramework (log, targetFrameworkMoniker, isSimulator, architectures, resourcePath, xcframework, intermediateDecompressionDir, createdFiles, cancellationToken, out nativeLibraryPath); + return TryResolveXCFramework (task, targetFrameworkMoniker, isSimulator, architectures, resourcePath, xcframework, intermediateDecompressionDir, createdFiles, cancellationToken, out nativeLibraryPath); } /// @@ -405,8 +405,9 @@ public static bool TryResolveXCFramework (TaskLoggingHelper log, string targetFr /// A full path to the resolved native library within the xcframework. If 'resourcePath' is compressed, this will point to where the native library is decompressed on disk. /// /// True if a native library was successfully found. Otherwise false, and an error will have been printed to the log. - public static bool TryResolveXCFramework (TaskLoggingHelper log, string targetFrameworkMoniker, bool isSimulator, string? architectures, string resourcePath, string xcframework, string intermediateDecompressionDir, List createdFiles, CancellationToken? cancellationToken, [NotNullWhen (true)] out string? nativeLibraryPath) + public static bool TryResolveXCFramework (XamarinTask task, string targetFrameworkMoniker, bool isSimulator, string? architectures, string resourcePath, string xcframework, string intermediateDecompressionDir, List createdFiles, CancellationToken? cancellationToken, [NotNullWhen (true)] out string? nativeLibraryPath) { + var log = task.Log; nativeLibraryPath = null; try { @@ -421,7 +422,7 @@ public static bool TryResolveXCFramework (TaskLoggingHelper log, string targetFr if (!isCompressed && CompressionHelper.IsCompressed (xcframework)) { var zipPath = Path.Combine (resourcePath, xcframework); var xcframeworkName = Path.GetFileNameWithoutExtension (xcframework); - if (!CompressionHelper.TryDecompress (log, zipPath, xcframeworkName, intermediateDecompressionDir, createdFiles, cancellationToken, out var decompressedXcframeworkPath)) + if (!CompressionHelper.TryDecompress (task, zipPath, xcframeworkName, intermediateDecompressionDir, createdFiles, cancellationToken, out var decompressedXcframeworkPath)) return false; nativeLibraryPath = Path.Combine (intermediateDecompressionDir, xcframeworkName, nativeLibraryRelativePath); @@ -434,7 +435,7 @@ public static bool TryResolveXCFramework (TaskLoggingHelper log, string targetFr } var zipResource = Path.Combine (xcframework, Path.GetDirectoryName (nativeLibraryRelativePath)); - if (!CompressionHelper.TryDecompress (log, resourcePath, zipResource, intermediateDecompressionDir, createdFiles, cancellationToken, out var decompressedPath)) + if (!CompressionHelper.TryDecompress (task, resourcePath, zipResource, intermediateDecompressionDir, createdFiles, cancellationToken, out var decompressedPath)) return false; nativeLibraryPath = Path.Combine (intermediateDecompressionDir, xcframework, nativeLibraryRelativePath); diff --git a/msbuild/Xamarin.MacDev.Tasks/Tasks/SpotlightIndexer.cs b/msbuild/Xamarin.MacDev.Tasks/Tasks/SpotlightIndexer.cs index 20483fa1389f..7d35f420e79d 100644 --- a/msbuild/Xamarin.MacDev.Tasks/Tasks/SpotlightIndexer.cs +++ b/msbuild/Xamarin.MacDev.Tasks/Tasks/SpotlightIndexer.cs @@ -33,7 +33,7 @@ public override bool Execute () }; var executable = GetExecutable (args, "mdimport", MdimportPath); cancellationTokenSource = new CancellationTokenSource (); - ExecuteAsync (Log, executable, args, sdkDevPath: SdkDevPath, cancellationToken: cancellationTokenSource.Token).Wait (); + ExecuteAsync (executable, args, cancellationToken: cancellationTokenSource.Token).Wait (); return !Log.HasLoggedErrors; } diff --git a/msbuild/Xamarin.MacDev.Tasks/Tasks/Unzip.cs b/msbuild/Xamarin.MacDev.Tasks/Tasks/Unzip.cs index 5b24af469603..5a4c4afaf1d5 100644 --- a/msbuild/Xamarin.MacDev.Tasks/Tasks/Unzip.cs +++ b/msbuild/Xamarin.MacDev.Tasks/Tasks/Unzip.cs @@ -79,7 +79,7 @@ bool ExecuteLocally () { var createdFiles = new List (); cancellationTokenSource = new CancellationTokenSource (); - if (!CompressionHelper.TryDecompress (Log, ZipFilePath!.ItemSpec, Resource, ExtractionPath, createdFiles, cancellationTokenSource.Token, out var _)) + if (!CompressionHelper.TryDecompress (this, ZipFilePath!.ItemSpec, Resource, ExtractionPath, createdFiles, cancellationTokenSource.Token, out var _)) return false; TouchedFiles = createdFiles.Select (v => new TaskItem (v)).ToArray (); diff --git a/msbuild/Xamarin.MacDev.Tasks/Tasks/XamarinTask.cs b/msbuild/Xamarin.MacDev.Tasks/Tasks/XamarinTask.cs index d8d23ba0bdfa..85264500cddf 100644 --- a/msbuild/Xamarin.MacDev.Tasks/Tasks/XamarinTask.cs +++ b/msbuild/Xamarin.MacDev.Tasks/Tasks/XamarinTask.cs @@ -99,19 +99,15 @@ protected string GetSdkPlatform (bool isSimulator) return PlatformFrameworkHelper.GetSdkPlatform (Platform, isSimulator); } - protected System.Threading.Tasks.Task ExecuteAsync (string fileName, IList arguments, Dictionary? environment = null, bool mergeOutput = true, bool showErrorIfFailure = true, string? workingDirectory = null, CancellationToken? cancellationToken = null) + internal protected System.Threading.Tasks.Task ExecuteAsync (string fileName, IList arguments, Dictionary? environment = null, bool mergeOutput = true, bool showErrorIfFailure = true, string? workingDirectory = null, CancellationToken? cancellationToken = null) { - return ExecuteAsync (this, Log, fileName, arguments, SdkDevPath, environment, mergeOutput, showErrorIfFailure, workingDirectory, cancellationToken); + return ExecuteAsync (this, fileName, arguments, SdkDevPath, environment, mergeOutput, showErrorIfFailure, workingDirectory, cancellationToken); } static int executionCounter; - internal protected static async System.Threading.Tasks.Task ExecuteAsync (TaskLoggingHelper log, string fileName, IList arguments, string? sdkDevPath = null, Dictionary? environment = null, bool mergeOutput = true, bool showErrorIfFailure = true, string? workingDirectory = null, CancellationToken? cancellationToken = null) - { - return ExecuteAsync (null, log, fileName, arguments, SdkDevPath, environment, mergeOutput, showErrorIfFailure, workingDirectory, cancellationToken); - } - - internal protected static async System.Threading.Tasks.Task ExecuteAsync (Task? task, TaskLoggingHelper log, string fileName, IList arguments, string? sdkDevPath = null, Dictionary? environment = null, bool mergeOutput = true, bool showErrorIfFailure = true, string? workingDirectory = null, CancellationToken? cancellationToken = null) + static async System.Threading.Tasks.Task ExecuteAsync (Task task, string fileName, IList arguments, string? sdkDevPath = null, Dictionary? environment = null, bool mergeOutput = true, bool showErrorIfFailure = true, string? workingDirectory = null, CancellationToken? cancellationToken = null) { + var log = task.Log; // Create a new dictionary if we're given one, to make sure we don't change the caller's dictionary. var launchEnvironment = environment is null ? new Dictionary () : new Dictionary (environment); if (!string.IsNullOrEmpty (sdkDevPath)) diff --git a/msbuild/Xamarin.MacDev.Tasks/Tasks/Zip.cs b/msbuild/Xamarin.MacDev.Tasks/Tasks/Zip.cs index 42300770269d..42c4b199a034 100644 --- a/msbuild/Xamarin.MacDev.Tasks/Tasks/Zip.cs +++ b/msbuild/Xamarin.MacDev.Tasks/Tasks/Zip.cs @@ -54,7 +54,7 @@ public override bool Execute () for (int i = 0; i < Sources.Length; i++) sources.Add (Sources [i].GetMetadata ("FullPath")); - if (!CompressionHelper.TryCompress (Log, zip, sources, false, workingDirectory, false)) + if (!CompressionHelper.TryCompress (this, zip, sources, false, workingDirectory, false)) return false; return !Log.HasLoggedErrors; diff --git a/msbuild/Xamarin.Shared/Xamarin.Shared.targets b/msbuild/Xamarin.Shared/Xamarin.Shared.targets index 787044270ef0..5720d35ed78e 100644 --- a/msbuild/Xamarin.Shared/Xamarin.Shared.targets +++ b/msbuild/Xamarin.Shared/Xamarin.Shared.targets @@ -2015,6 +2015,7 @@ Copyright (C) 2018 Microsoft. All rights reserved. ProjectDir="$(MSBuildProjectDirectory)" References="@(ReferencePath);@(BGenReferencePath)" ResponseFilePath="$(DeviceSpecificIntermediateOutputPath)response-file.rsp" + SdkDevPath="$(_SdkDevPath)" TargetFrameworkMoniker="$(_ComputedTargetFrameworkMoniker)" BGenToolPath="$(BGenToolPath)" BGenToolExe="$(BGenToolExe)" From 6d04f16b773ec5077e989ad5193b57199b5ebf8d Mon Sep 17 00:00:00 2001 From: Rolf Bjarne Kvinge Date: Fri, 24 Oct 2025 16:02:28 +0200 Subject: [PATCH 12/23] wip --- dotnet/targets/Xamarin.Shared.Sdk.targets | 5 ++++- msbuild/Xamarin.Shared/Xamarin.Shared.targets | 8 ++++++-- msbuild/Xamarin.Shared/Xamarin.iOS.Common.targets | 9 ++++++--- 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/dotnet/targets/Xamarin.Shared.Sdk.targets b/dotnet/targets/Xamarin.Shared.Sdk.targets index c545cadcee69..1b84c30dfc6a 100644 --- a/dotnet/targets/Xamarin.Shared.Sdk.targets +++ b/dotnet/targets/Xamarin.Shared.Sdk.targets @@ -944,7 +944,7 @@ @@ -967,6 +967,7 @@ Source="%(_DirectoriesToPublish.SourceDirectory)" Destination="%(_DirectoriesToPublish.TargetDirectory)" TouchDestinationFiles="true" + SdkDevPath="$(_SdkDevPath)" StampFile="%(_DirectoriesToPublish.StampLocation)" CreateOutputFiles="false" /> @@ -1972,6 +1973,7 @@ _DetectSigningIdentity; _PrepareResourceRules; _AddDebugSymbolsToBundle; + _DetectSdkLocations; @@ -2203,6 +2205,7 @@ FrameworksDirectory="$(_AppFrameworksRelativePath)" IntermediateOutputPath="$(DeviceSpecificIntermediateOutputPath)" NativeReferences="@(_NativeReferencesToResolve)" + SdkDevPath="$(_SdkDevPath)" SdkIsSimulator="$(_SdkIsSimulator)" TargetFrameworkMoniker="$(_ComputedTargetFrameworkMoniker)" > diff --git a/msbuild/Xamarin.Shared/Xamarin.Shared.targets b/msbuild/Xamarin.Shared/Xamarin.Shared.targets index 5720d35ed78e..0966d6a768cd 100644 --- a/msbuild/Xamarin.Shared/Xamarin.Shared.targets +++ b/msbuild/Xamarin.Shared/Xamarin.Shared.targets @@ -164,6 +164,7 @@ Copyright (C) 2018 Microsoft. All rights reserved. IntermediateOutputPath="$(DeviceSpecificIntermediateOutputPath)" NativeReferences="@(_NativeReferencesToExpand)" References="@(_ReferencesWithNativeReferencesToExpand)" + SdkDevPath="$(_SdkDevPath)" SdkIsSimulator="$(_SdkIsSimulator)" TargetFrameworkMoniker="$(_ComputedTargetFrameworkMoniker)" > @@ -182,7 +183,7 @@ Copyright (C) 2018 Microsoft. All rights reserved. @@ -201,6 +202,7 @@ Copyright (C) 2018 Microsoft. All rights reserved. BindingResourcePath="$(BindingResourcePath)" Compress="$(CompressBindingResourcePackage)" IntermediateOutputPath="$(DeviceSpecificIntermediateOutputPath)" + SdkDevPath="$(_SdkDevPath)" > @@ -1837,6 +1839,7 @@ Copyright (C) 2018 Microsoft. All rights reserved. <_GenerateBindingsDependsOn> + _DetectSdkLocations; _ComputeTargetFrameworkMoniker; $(_GenerateBindingsDependsOn); @@ -2751,7 +2754,7 @@ Copyright (C) 2018 Microsoft. All rights reserved. @@ -2768,6 +2771,7 @@ Copyright (C) 2018 Microsoft. All rights reserved. Source="@(_ResolvedAppExtensionReferences)" Destination="$(_AppExtensionRoot)%(_ResolvedAppExtensionReferences.ContainerName)\%(_ResolvedAppExtensionReferences.FileName)%(_ResolvedAppExtensionReferences.Extension)" TouchDestinationFiles="true" + SdkDevPath="$(_SdkDevPath)" /> diff --git a/msbuild/Xamarin.Shared/Xamarin.iOS.Common.targets b/msbuild/Xamarin.Shared/Xamarin.iOS.Common.targets index fc32d3c45eeb..e99262d00740 100644 --- a/msbuild/Xamarin.Shared/Xamarin.iOS.Common.targets +++ b/msbuild/Xamarin.Shared/Xamarin.iOS.Common.targets @@ -259,17 +259,18 @@ Copyright (C) 2013-2016 Xamarin. All rights reserved. - + - + @@ -283,6 +284,7 @@ Copyright (C) 2013-2016 Xamarin. All rights reserved. SessionId="$(BuildSessionId)" Condition="'$(IsMacEnabled)' == 'true'" DittoPath="$(DittoPath)" + SdkDevPath="$(_SdkDevPath)" Source="$(AppBundleDir)" Destination="$(_IpaAppBundleDir)" /> @@ -346,7 +348,7 @@ Copyright (C) 2013-2016 Xamarin. All rights reserved. - + <_PayloadDir>$(DeviceSpecificIntermediateOutputPath)ipa\Payload\ <_IpaAppBundleDir>$(_PayloadDir)$(_AppBundleName).app\ @@ -372,6 +374,7 @@ Copyright (C) 2013-2016 Xamarin. All rights reserved. SessionId="$(BuildSessionId)" Condition="'$(IsMacEnabled)' == 'true' And Exists('$(DeviceSpecificOutputPath)OnDemandResources\')" DittoPath="$(DittoPath)" + SdkDevPath="$(_SdkDevPath)" Source="$(DeviceSpecificOutputPath)OnDemandResources\" Destination="$(_IntermediateODRDir)" /> From 7d8df537a70355be1570859b8367da2d37aab9be Mon Sep 17 00:00:00 2001 From: Rolf Bjarne Kvinge Date: Fri, 31 Oct 2025 09:21:29 +0100 Subject: [PATCH 13/23] improvements --- dotnet/targets/Xamarin.Shared.Sdk.targets | 2 ++ msbuild/Xamarin.Localization.MSBuild/MSBStrings.resx | 4 ++++ msbuild/Xamarin.MacDev.Tasks/Tasks/XamarinTask.cs | 6 ++++-- .../TaskTests/CreateBindingResourceTaskTests.cs | 4 +++- 4 files changed, 13 insertions(+), 3 deletions(-) diff --git a/dotnet/targets/Xamarin.Shared.Sdk.targets b/dotnet/targets/Xamarin.Shared.Sdk.targets index 1b84c30dfc6a..a996b5eac2c6 100644 --- a/dotnet/targets/Xamarin.Shared.Sdk.targets +++ b/dotnet/targets/Xamarin.Shared.Sdk.targets @@ -2267,6 +2267,7 @@ Condition="'$(IsMacEnabled)' == 'true'" ZipFilePath="%(_CompressedPlugIns.Identity)" ExtractionPath="%(_CompressedPlugIns.ExtractionPath)" + SdkDevPath="$(_SdkDevPath)" > @@ -2310,6 +2311,7 @@ CopyToWindows="true" ZipFilePath="%(_CompressedXpcServices.Identity)" ExtractionPath="%(_CompressedXpcServices.ExtractionPath)" + SdkDevPath="$(_SdkDevPath)" > diff --git a/msbuild/Xamarin.Localization.MSBuild/MSBStrings.resx b/msbuild/Xamarin.Localization.MSBuild/MSBStrings.resx index 492695197ce5..a3e08d454caf 100644 --- a/msbuild/Xamarin.Localization.MSBuild/MSBStrings.resx +++ b/msbuild/Xamarin.Localization.MSBuild/MSBStrings.resx @@ -1629,4 +1629,8 @@ Unable to copy the inputs to this task to the remote build server for unknown reasons. The build log may have more information. + + + The task '{0}' is trying to call an external process, but a path to Xcode has not been provided. Please file an issue at https://github.com/dotnet/macios/issues/new/choose. + diff --git a/msbuild/Xamarin.MacDev.Tasks/Tasks/XamarinTask.cs b/msbuild/Xamarin.MacDev.Tasks/Tasks/XamarinTask.cs index 85264500cddf..de02091bec76 100644 --- a/msbuild/Xamarin.MacDev.Tasks/Tasks/XamarinTask.cs +++ b/msbuild/Xamarin.MacDev.Tasks/Tasks/XamarinTask.cs @@ -113,8 +113,10 @@ static async System.Threading.Tasks.Task ExecuteAsync (Task task, str if (!string.IsNullOrEmpty (sdkDevPath)) launchEnvironment ["DEVELOPER_DIR"] = sdkDevPath; - if (string.IsNullOrEmpty (sdkDevPath)) - log.LogError ($"Calling external processes without specifying the Xcode path in the task {(task?.GetType ()?.Name ?? "?")}! StackTrace: {Environment.StackTrace}"); + if (string.IsNullOrEmpty (sdkDevPath)) { + log.LogError (MSBStrings.E7164 /* The task '{0}' is trying to call an external process, but a path to Xcode has not been provided. Please file an issue at https://github.com/dotnet/macios/issues/new/choose. */, task.GetType ().Name); + log.LogMessage (MessageImportance.Low, Environment.StackTrace); + } var currentId = Interlocked.Increment (ref executionCounter); log.LogMessage (MessageImportance.Normal, MSBStrings.M0001, currentId, fileName, StringUtils.FormatArguments (arguments)); // Started external tool execution #{0}: {1} {2} diff --git a/tests/msbuild/Xamarin.MacDev.Tasks.Tests/TaskTests/CreateBindingResourceTaskTests.cs b/tests/msbuild/Xamarin.MacDev.Tasks.Tests/TaskTests/CreateBindingResourceTaskTests.cs index bcd3e301aa05..6de4730f6840 100644 --- a/tests/msbuild/Xamarin.MacDev.Tasks.Tests/TaskTests/CreateBindingResourceTaskTests.cs +++ b/tests/msbuild/Xamarin.MacDev.Tasks.Tests/TaskTests/CreateBindingResourceTaskTests.cs @@ -9,6 +9,7 @@ using NUnit.Framework; +using Xamarin.Tests; using Xamarin.Utils; namespace Xamarin.MacDev.Tasks { @@ -22,11 +23,12 @@ CreateBindingResourcePackage ExecuteTask (string compress, bool symlinks, out st task.BindingResourcePath = Path.Combine (tmpdir, "CreateBindingResourceTaskTest"); task.IntermediateOutputPath = Path.Combine (tmpdir, "IntermediateOutputPath"); task.NativeReferences = CreateNativeReferences (tmpdir, symlinks); + task.SdkDevPath = Configuration.xcode_root; var currentDir = Environment.CurrentDirectory; try { Environment.CurrentDirectory = tmpdir; - Assert.IsTrue (task.Execute (), "Execute"); + ExecuteTask (task); } finally { Environment.CurrentDirectory = currentDir; } From 9937223b4c3adc0c601b436e0904fa3c575dc9e2 Mon Sep 17 00:00:00 2001 From: Rolf Bjarne Kvinge Date: Fri, 31 Oct 2025 13:25:57 +0100 Subject: [PATCH 14/23] Last one? --- dotnet/targets/Xamarin.Shared.Sdk.targets | 3 ++- msbuild/Xamarin.MacDev.Tasks/Tasks/XamarinTask.cs | 2 +- msbuild/Xamarin.Shared/Xamarin.Shared.targets | 1 + msbuild/Xamarin.Shared/Xamarin.iOS.Common.targets | 1 + 4 files changed, 5 insertions(+), 2 deletions(-) diff --git a/dotnet/targets/Xamarin.Shared.Sdk.targets b/dotnet/targets/Xamarin.Shared.Sdk.targets index a996b5eac2c6..a2bdc375c175 100644 --- a/dotnet/targets/Xamarin.Shared.Sdk.targets +++ b/dotnet/targets/Xamarin.Shared.Sdk.targets @@ -1275,7 +1275,7 @@ - + <_XamarinAOTCompilerCachePath>$(DeviceSpecificIntermediateOutputPath)aot-compiler-path-$(NETCoreSdkVersion).txt @@ -1294,6 +1294,7 @@ KeepTemporaryOutput="$(FindAotCompilerKeepKeepTemporaryOutput)" MonoAotCrossCompiler="@(MonoAotCrossCompiler)" RuntimeIdentifier="$(RuntimeIdentifier)" + SdkDevPath="$(_SdkDevPath)" TargetFrameworkMoniker="$(_ComputedTargetFrameworkMoniker)" > diff --git a/msbuild/Xamarin.MacDev.Tasks/Tasks/XamarinTask.cs b/msbuild/Xamarin.MacDev.Tasks/Tasks/XamarinTask.cs index de02091bec76..b1926ee6ceec 100644 --- a/msbuild/Xamarin.MacDev.Tasks/Tasks/XamarinTask.cs +++ b/msbuild/Xamarin.MacDev.Tasks/Tasks/XamarinTask.cs @@ -113,7 +113,7 @@ static async System.Threading.Tasks.Task ExecuteAsync (Task task, str if (!string.IsNullOrEmpty (sdkDevPath)) launchEnvironment ["DEVELOPER_DIR"] = sdkDevPath; - if (string.IsNullOrEmpty (sdkDevPath)) { + if (Environment.OSVersion.Platform == PlatformID.MacOSX && string.IsNullOrEmpty (sdkDevPath)) { log.LogError (MSBStrings.E7164 /* The task '{0}' is trying to call an external process, but a path to Xcode has not been provided. Please file an issue at https://github.com/dotnet/macios/issues/new/choose. */, task.GetType ().Name); log.LogMessage (MessageImportance.Low, Environment.StackTrace); } diff --git a/msbuild/Xamarin.Shared/Xamarin.Shared.targets b/msbuild/Xamarin.Shared/Xamarin.Shared.targets index 0966d6a768cd..b3669e04c3ab 100644 --- a/msbuild/Xamarin.Shared/Xamarin.Shared.targets +++ b/msbuild/Xamarin.Shared/Xamarin.Shared.targets @@ -1987,6 +1987,7 @@ Copyright (C) 2018 Microsoft. All rights reserved. Condition="'$(IsMacEnabled)' == 'true' And '$(BindingProjectBuildSessionId)' != ''" IntermediateOutputPath="$(IntermediateOutputPath)" TargetFrameworkMoniker="$(_ComputedTargetFrameworkMoniker)" + SdkDevPath="$(_SdkDevPath)" > diff --git a/msbuild/Xamarin.Shared/Xamarin.iOS.Common.targets b/msbuild/Xamarin.Shared/Xamarin.iOS.Common.targets index e99262d00740..4a8fde95d01d 100644 --- a/msbuild/Xamarin.Shared/Xamarin.iOS.Common.targets +++ b/msbuild/Xamarin.Shared/Xamarin.iOS.Common.targets @@ -489,6 +489,7 @@ Copyright (C) 2013-2016 Xamarin. All rights reserved. Sources="@(_IpaPackageSource)" OutputFile="$(IpaPackagePath)" WorkingDirectory="$(DeviceSpecificIntermediateOutputPath)ipa" + SdkDevPath="$(_SdkDevPath)" > From 491a8979a8dda2397edae2784b37d0c08703a9a4 Mon Sep 17 00:00:00 2001 From: Rolf Bjarne Kvinge Date: Tue, 4 Nov 2025 10:39:31 +0100 Subject: [PATCH 15/23] [msbuild] Simplify code --- msbuild/Xamarin.MacDev.Tasks/Tasks/ACTool.cs | 4 -- .../Tasks/DetectSdkLocation.cs | 45 +------------------ msbuild/Xamarin.MacDev.Tasks/Tasks/IBTool.cs | 4 -- .../Tasks/TextureAtlas.cs | 4 -- .../Tasks/XcodeCompilerToolTask.cs | 18 -------- .../Xamarin.MacDev.Tasks/Tasks/XcodeTool.cs | 39 ++-------------- msbuild/Xamarin.Shared/Xamarin.Shared.targets | 15 ++----- .../TaskTests/ACToolTaskTest.cs | 4 -- .../TaskTests/IBToolTaskTests.cs | 4 -- 9 files changed, 8 insertions(+), 129 deletions(-) diff --git a/msbuild/Xamarin.MacDev.Tasks/Tasks/ACTool.cs b/msbuild/Xamarin.MacDev.Tasks/Tasks/ACTool.cs index f7dfbcd5a93d..116dd0963344 100644 --- a/msbuild/Xamarin.MacDev.Tasks/Tasks/ACTool.cs +++ b/msbuild/Xamarin.MacDev.Tasks/Tasks/ACTool.cs @@ -58,10 +58,6 @@ public class ACTool : XcodeCompilerToolTask, ICancelableTask { HashSet brandAssetsInAssets = new (); // tvOS HashSet imageStacksInAssets = new (); // tvOS - protected override string DefaultBinDir { - get { return DeveloperRootBinDir; } - } - protected override string ToolName { get { return "actool"; } } diff --git a/msbuild/Xamarin.MacDev.Tasks/Tasks/DetectSdkLocation.cs b/msbuild/Xamarin.MacDev.Tasks/Tasks/DetectSdkLocation.cs index 87e52f482933..ea83dee857c6 100644 --- a/msbuild/Xamarin.MacDev.Tasks/Tasks/DetectSdkLocation.cs +++ b/msbuild/Xamarin.MacDev.Tasks/Tasks/DetectSdkLocation.cs @@ -15,11 +15,7 @@ public class DetectSdkLocations : XamarinTask, ICancelableTask { const string SdkVersionDefaultValue = "default"; #region Inputs - public string TargetArchitectures { - get; set; - } = ""; - - public string IsDotNetSimulatorBuild { + public string XcodeLocation { get; set; } = ""; @@ -32,27 +28,17 @@ public string SdkRoot { get; set; } = ""; - [Output] - public string SdkBinPath { - get; set; - } = ""; - [Output] public new string SdkDevPath { get; set; } = ""; - [Output] - public string SdkUsrPath { - get; set; - } = ""; [Output] public bool SdkIsSimulator { get; set; } - [Output] public string SdkPlatform { get; set; } = ""; @@ -130,14 +116,6 @@ protected void EnsureSdkPath () SdkRoot = currentSdk.GetSdkPath (SdkVersion, SdkIsSimulator); if (string.IsNullOrEmpty (SdkRoot)) Log.LogError (MSBStrings.E0084 /* Could not locate the {0} '{1}' SDK at path '{2}' */, PlatformName, SdkVersion, SdkRoot); - - SdkUsrPath = DirExists ("SDK usr directory", Path.Combine (currentSdk.DeveloperRoot, "usr")) ?? ""; - if (string.IsNullOrEmpty (SdkUsrPath)) - Log.LogError (MSBStrings.E0085 /* Could not locate the {0} '{1}' SDK usr path at '{2}' */, PlatformName, SdkVersion, SdkRoot); - - SdkBinPath = DirExists ("SDK bin directory", Path.Combine (SdkUsrPath, "bin")) ?? ""; - if (string.IsNullOrEmpty (SdkBinPath)) - Log.LogError (MSBStrings.E0032 /* Could not locate SDK bin directory */); } void EnsureXamarinSdkRoot () @@ -172,8 +150,6 @@ bool ExecuteImpl () AppleSdkSettings.Init (); - SetIsSimulator (); - if (EnsureAppleSdkRoot ()) EnsureSdkPath (); EnsureXamarinSdkRoot (); @@ -183,25 +159,6 @@ bool ExecuteImpl () return !Log.HasLoggedErrors; } - void SetIsSimulator () - { - switch (Platform) { - case ApplePlatform.MacCatalyst: - case ApplePlatform.MacOSX: - return; - } - - TargetArchitecture architectures; - if (string.IsNullOrEmpty (TargetArchitectures) || !Enum.TryParse (TargetArchitectures, out architectures)) - architectures = TargetArchitecture.Default; - - if (!string.IsNullOrEmpty (IsDotNetSimulatorBuild)) { - SdkIsSimulator = string.Equals (IsDotNetSimulatorBuild, "true", StringComparison.OrdinalIgnoreCase); - } else { - SdkIsSimulator = (architectures & (TargetArchitecture.i386 | TargetArchitecture.x86_64)) != 0; - } - } - protected bool EnsureAppleSdkRoot () { var currentSdk = CurrentSdk; diff --git a/msbuild/Xamarin.MacDev.Tasks/Tasks/IBTool.cs b/msbuild/Xamarin.MacDev.Tasks/Tasks/IBTool.cs index 5ae4938b055e..748f1b7949c6 100644 --- a/msbuild/Xamarin.MacDev.Tasks/Tasks/IBTool.cs +++ b/msbuild/Xamarin.MacDev.Tasks/Tasks/IBTool.cs @@ -30,10 +30,6 @@ public class IBTool : XcodeCompilerToolTask, ICancelableTask { #endregion - protected override string DefaultBinDir { - get { return DeveloperRootBinDir; } - } - protected override string ToolName { get { return "ibtool"; } } diff --git a/msbuild/Xamarin.MacDev.Tasks/Tasks/TextureAtlas.cs b/msbuild/Xamarin.MacDev.Tasks/Tasks/TextureAtlas.cs index 5316bf815b4d..d7f098942538 100644 --- a/msbuild/Xamarin.MacDev.Tasks/Tasks/TextureAtlas.cs +++ b/msbuild/Xamarin.MacDev.Tasks/Tasks/TextureAtlas.cs @@ -20,10 +20,6 @@ public class TextureAtlas : XcodeToolTaskBase, ICancelableTask { #endregion - protected override string DefaultBinDir { - get { return DeveloperRootBinDir; } - } - protected override string ToolName { get { return "TextureAtlas"; } } diff --git a/msbuild/Xamarin.MacDev.Tasks/Tasks/XcodeCompilerToolTask.cs b/msbuild/Xamarin.MacDev.Tasks/Tasks/XcodeCompilerToolTask.cs index e76837730b26..204ffcaf8888 100644 --- a/msbuild/Xamarin.MacDev.Tasks/Tasks/XcodeCompilerToolTask.cs +++ b/msbuild/Xamarin.MacDev.Tasks/Tasks/XcodeCompilerToolTask.cs @@ -38,13 +38,9 @@ public abstract class XcodeCompilerToolTask : XamarinTask, IHasProjectDir, IHasR [Required] public string ResourcePrefix { get; set; } = string.Empty; - public string SdkBinPath { get; set; } = string.Empty; - [Required] public string SdkPlatform { get; set; } = string.Empty; - public string SdkUsrPath { get; set; } = string.Empty; - [Required] public string SdkVersion { get; set; } = string.Empty; @@ -91,14 +87,6 @@ public IPhoneDeviceType ParsedUIDeviceFamily { } } - protected abstract string DefaultBinDir { - get; - } - - protected string DeveloperRootBinDir { - get { return Path.Combine (SdkDevPath, "usr", "bin"); } - } - protected abstract string ToolName { get; } protected virtual bool UseCompilationDirectory { @@ -174,12 +162,6 @@ protected int Compile (ITaskItem [] items, string output, ITaskItem manifest) var environment = new Dictionary (); var args = new List (); - if (!string.IsNullOrEmpty (SdkBinPath)) - environment.Add ("PATH", SdkBinPath); - - if (!string.IsNullOrEmpty (SdkUsrPath)) - environment.Add ("XCODE_DEVELOPER_USR_PATH", SdkUsrPath); - // workaround for ibtool[d] bug / asserts if Intel version is loaded string tool; if (IsTranslated ()) { diff --git a/msbuild/Xamarin.MacDev.Tasks/Tasks/XcodeTool.cs b/msbuild/Xamarin.MacDev.Tasks/Tasks/XcodeTool.cs index 16caad0d91dc..ec4f021133ab 100644 --- a/msbuild/Xamarin.MacDev.Tasks/Tasks/XcodeTool.cs +++ b/msbuild/Xamarin.MacDev.Tasks/Tasks/XcodeTool.cs @@ -14,8 +14,6 @@ namespace Xamarin.MacDev.Tasks { public abstract class XcodeToolTaskBase : XamarinTask, IHasProjectDir, IHasResourcePrefix { - string? toolExe; - #region Inputs [Required] @@ -27,16 +25,7 @@ public abstract class XcodeToolTaskBase : XamarinTask, IHasProjectDir, IHasResou [Required] public string ResourcePrefix { get; set; } = string.Empty; - [Required] - public string SdkBinPath { get; set; } = string.Empty; - - [Required] - public string SdkUsrPath { get; set; } = string.Empty; - - public string ToolExe { - get { return toolExe ?? ToolName; } - set { toolExe = value; } - } + public string ToolExe { get; set; } = string.Empty; public string ToolPath { get; set; } = string.Empty; @@ -49,22 +38,6 @@ public string ToolExe { #endregion - protected abstract string DefaultBinDir { - get; - } - - protected string DeveloperRootBinDir { - get { return Path.Combine (SdkDevPath, "usr", "bin"); } - } - - protected string DevicePlatformBinDir { - get { return Path.Combine (SdkDevPath, "Platforms", "iPhoneOS.platform", "Developer", "usr", "bin"); } - } - - protected string SimulatorPlatformBinDir { - get { return Path.Combine (SdkDevPath, "Platforms", "iPhoneSimulator.platform", "Developer", "usr", "bin"); } - } - protected abstract string ToolName { get; } protected abstract IEnumerable EnumerateInputs (); @@ -94,9 +67,7 @@ string GetFullPathToTool () if (!string.IsNullOrEmpty (ToolPath)) return Path.Combine (ToolPath, ToolExe); - var path = Path.Combine (DefaultBinDir, ToolExe); - - return File.Exists (path) ? path : ToolExe; + return ToolExe ?? ""; } int ExecuteTool (ITaskItem input, ITaskItem output) @@ -104,12 +75,10 @@ int ExecuteTool (ITaskItem input, ITaskItem output) var environment = new Dictionary (); var args = new List (); - environment.Add ("PATH", SdkBinPath); - environment.Add ("XCODE_DEVELOPER_USR_PATH", SdkUsrPath); - AppendCommandLineArguments (environment, args, input, output); - var rv = ExecuteAsync (GetFullPathToTool (), args, environment: environment).Result; + var executable = GetExecutable (args, ToolName, GetFullPathToTool ()); + var rv = ExecuteAsync (executable, args, environment: environment).Result; return rv.ExitCode; } diff --git a/msbuild/Xamarin.Shared/Xamarin.Shared.targets b/msbuild/Xamarin.Shared/Xamarin.Shared.targets index b3669e04c3ab..8403e064d160 100644 --- a/msbuild/Xamarin.Shared/Xamarin.Shared.targets +++ b/msbuild/Xamarin.Shared/Xamarin.Shared.targets @@ -922,8 +922,6 @@ Copyright (C) 2018 Microsoft. All rights reserved. ProjectDir="$(MSBuildProjectDirectory)" ResourcePrefix="$(_ResourcePrefix)" SdkDevPath="$(_SdkDevPath)" - SdkBinPath="$(_SdkBinPath)" - SdkUsrPath="$(_SdkUsrPath)" SdkRoot="$(_SdkRoot)" SdkPlatform="$(_SdkPlatform)" SdkVersion="$(_SdkVersion)" @@ -1058,8 +1056,6 @@ Copyright (C) 2018 Microsoft. All rights reserved. ProjectDir="$(MSBuildProjectDirectory)" ResourcePrefix="$(_ResourcePrefix)" SdkDevPath="$(_SdkDevPath)" - SdkBinPath="$(_SdkBinPath)" - SdkUsrPath="$(_SdkUsrPath)" SdkPlatform="$(_SdkPlatform)" SdkVersion="$(_SdkVersion)" TargetFrameworkMoniker="$(_ComputedTargetFrameworkMoniker)" @@ -1471,9 +1467,7 @@ Copyright (C) 2018 Microsoft. All rights reserved. IntermediateOutputPath="$(DeviceSpecificIntermediateOutputPath)" ProjectDir="$(MSBuildProjectDirectory)" ResourcePrefix="$(_ResourcePrefix)" - SdkDevPath="$(_SdkDevPath)" - SdkBinPath="$(_SdkBinPath)" - SdkUsrPath="$(_SdkUsrPath)"> + SdkDevPath="$(_SdkDevPath)"> @@ -2089,20 +2083,17 @@ Copyright (C) 2018 Microsoft. All rights reserved. - - - diff --git a/tests/msbuild/Xamarin.MacDev.Tasks.Tests/TaskTests/ACToolTaskTest.cs b/tests/msbuild/Xamarin.MacDev.Tasks.Tests/TaskTests/ACToolTaskTest.cs index 2a6b2e271cbf..75f52139b7af 100644 --- a/tests/msbuild/Xamarin.MacDev.Tasks.Tests/TaskTests/ACToolTaskTest.cs +++ b/tests/msbuild/Xamarin.MacDev.Tasks.Tests/TaskTests/ACToolTaskTest.cs @@ -25,8 +25,6 @@ ACTool CreateACToolTask (ApplePlatform platform, string projectDir, out string i var sdk = Sdks.GetAppleSdk (platform); var version = AppleSdkVersion.UseDefault.ToString (); var root = sdk.GetSdkPath (version, false); - var usr = Path.Combine (sdk.DeveloperRoot, "usr"); - var bin = Path.Combine (usr, "bin"); string sdkPlatform; var uiDeviceFamily = ""; @@ -66,8 +64,6 @@ ACTool CreateACToolTask (ApplePlatform platform, string projectDir, out string i task.SdkDevPath = Configuration.xcode_root; task.SdkPlatform = sdkPlatform; task.SdkVersion = version.ToString (); - task.SdkUsrPath = usr; - task.SdkBinPath = bin; task.TargetFrameworkMoniker = TargetFramework.GetTargetFramework (platform).ToString (); task.UIDeviceFamily = uiDeviceFamily; return task; diff --git a/tests/msbuild/Xamarin.MacDev.Tasks.Tests/TaskTests/IBToolTaskTests.cs b/tests/msbuild/Xamarin.MacDev.Tasks.Tests/TaskTests/IBToolTaskTests.cs index e419c6de6cca..8c301b35e3c8 100644 --- a/tests/msbuild/Xamarin.MacDev.Tasks.Tests/TaskTests/IBToolTaskTests.cs +++ b/tests/msbuild/Xamarin.MacDev.Tasks.Tests/TaskTests/IBToolTaskTests.cs @@ -22,8 +22,6 @@ IBTool CreateIBToolTask (ApplePlatform framework, string projectDir, string inte var sdk = Sdks.GetSdk (framework); var version = AppleSdkVersion.GetDefault (sdk, false); var root = sdk.GetSdkPath (version, false); - var usr = Path.Combine (sdk.DeveloperRoot, "usr"); - var bin = Path.Combine (usr, "bin"); string platform; switch (framework) { @@ -50,8 +48,6 @@ IBTool CreateIBToolTask (ApplePlatform framework, string projectDir, string inte task.SdkDevPath = Configuration.xcode_root; task.SdkPlatform = platform; task.SdkVersion = version.ToString (); - task.SdkUsrPath = usr; - task.SdkBinPath = bin; task.SdkRoot = root; task.TargetFrameworkMoniker = TargetFramework.DotNet_iOS_String; return task; From 3f85b2ab382ed34f82ec89a776663b82253f3aa1 Mon Sep 17 00:00:00 2001 From: Rolf Bjarne Kvinge Date: Thu, 6 Nov 2025 13:57:35 +0100 Subject: [PATCH 16/23] [msbuild] Add support for CoreMLCompilerPath --- msbuild/Xamarin.MacDev.Tasks/Tasks/CoreMLCompiler.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msbuild/Xamarin.MacDev.Tasks/Tasks/CoreMLCompiler.cs b/msbuild/Xamarin.MacDev.Tasks/Tasks/CoreMLCompiler.cs index a86b89278332..1ccbaff6f2ec 100644 --- a/msbuild/Xamarin.MacDev.Tasks/Tasks/CoreMLCompiler.cs +++ b/msbuild/Xamarin.MacDev.Tasks/Tasks/CoreMLCompiler.cs @@ -55,7 +55,7 @@ int Compile (ITaskItem item, string outputDir, string log, string partialPlist) args.Add (partialPlist); var executable = GetExecutable (args, ToolName, CoreMlcPath); - var rv = ExecuteAsync (executable, args, sdkDevPath, mergeOutput: false).Result; + var rv = ExecuteAsync (executable, args, mergeOutput: false).Result; var exitCode = rv.ExitCode; var output = rv.StandardOutput!.ToString (); File.WriteAllText (log, output); From 1c7fa7fbe35446253edfcfbcb928b791a73b712b Mon Sep 17 00:00:00 2001 From: Rolf Bjarne Kvinge Date: Thu, 6 Nov 2025 08:44:43 +0100 Subject: [PATCH 17/23] wip --- external/Xamarin.MacDev | 2 +- msbuild/Xamarin.MacDev.Tasks/Sdks.cs | 41 +++---------------- .../Tasks/CompileAppManifest.cs | 15 ++++--- .../Tasks/CompileEntitlements.cs | 2 +- .../Tasks/DetectSdkLocation.cs | 22 ++++++---- .../Tasks/DetectSigningIdentity.cs | 2 +- .../Tasks/ReadAppManifest.cs | 2 +- .../Xamarin.MacDev.Tasks/Tasks/XamarinTask.cs | 17 ++++++++ msbuild/Xamarin.Shared/Xamarin.Shared.targets | 2 + .../TaskTests/ACToolTaskTest.cs | 5 ++- .../TaskTests/CompileAppManifestTaskTests.cs | 2 +- .../GeneratePlistTaskTests_iOS.cs | 2 +- .../GeneratePlistTaskTests_tvOS.cs | 2 +- .../TaskTests/IBToolTaskTests.cs | 7 ++-- .../TestHelpers/TestBase.cs | 2 + 15 files changed, 65 insertions(+), 60 deletions(-) diff --git a/external/Xamarin.MacDev b/external/Xamarin.MacDev index 757b4f5b7e8e..464076f830ed 160000 --- a/external/Xamarin.MacDev +++ b/external/Xamarin.MacDev @@ -1 +1 @@ -Subproject commit 757b4f5b7e8e2f60ecbea6de3967158cc4f77069 +Subproject commit 464076f830ed30aad405fc36d7f29bca331d138e diff --git a/msbuild/Xamarin.MacDev.Tasks/Sdks.cs b/msbuild/Xamarin.MacDev.Tasks/Sdks.cs index ca04c9c665f1..17b7c0c04143 100644 --- a/msbuild/Xamarin.MacDev.Tasks/Sdks.cs +++ b/msbuild/Xamarin.MacDev.Tasks/Sdks.cs @@ -9,53 +9,24 @@ namespace Xamarin.MacDev { public static class Sdks { - public static AppleIPhoneSdk IOS { get; private set; } - public static MacOSXSdk MacOS { get; private set; } - public static AppleTVOSSdk TVOS { get; private set; } - - static Sdks () - { - IOS = new AppleIPhoneSdk (AppleSdkSettings.DeveloperRoot, AppleSdkSettings.DeveloperRootVersionPlist); - TVOS = new AppleTVOSSdk (AppleSdkSettings.DeveloperRoot, AppleSdkSettings.DeveloperRootVersionPlist); - MacOS = new MacOSXSdk (AppleSdkSettings.DeveloperRoot, AppleSdkSettings.DeveloperRootVersionPlist); - } - - public static AppleSdk GetSdk (ApplePlatform framework) + public static IAppleSdk GetAppleSdk (ApplePlatform framework, XcodeLocator appleSdk) { switch (framework) { case ApplePlatform.iOS: - return IOS; + return new AppleIPhoneSdk (appleSdk.DeveloperRoot, appleSdk.DeveloperRootVersionPlist); case ApplePlatform.TVOS: - return TVOS; - default: - throw new InvalidOperationException (string.Format (MSBStrings.InvalidFramework, framework)); - } - } - - public static AppleSdk GetSdk (string targetFrameworkMoniker) - { - return GetSdk (PlatformFrameworkHelper.GetFramework (targetFrameworkMoniker)); - } - - public static IAppleSdk GetAppleSdk (ApplePlatform framework) - { - switch (framework) { - case ApplePlatform.iOS: - return IOS; - case ApplePlatform.TVOS: - return TVOS; + return new AppleTVOSSdk (appleSdk.DeveloperRoot, appleSdk.DeveloperRootVersionPlist); case ApplePlatform.MacCatalyst: case ApplePlatform.MacOSX: - return MacOS; + return new MacOSXSdk (appleSdk.DeveloperRoot, appleSdk.DeveloperRootVersionPlist); default: throw new InvalidOperationException (string.Format (MSBStrings.InvalidFramework, framework)); } } - public static IAppleSdk GetAppleSdk (string targetFrameworkMoniker) + public static IAppleSdk GetAppleSdk (string targetFrameworkMoniker, XcodeLocator appleSdk) { - return GetAppleSdk (PlatformFrameworkHelper.GetFramework (targetFrameworkMoniker)); + return GetAppleSdk (PlatformFrameworkHelper.GetFramework (targetFrameworkMoniker), appleSdk); } - } } diff --git a/msbuild/Xamarin.MacDev.Tasks/Tasks/CompileAppManifest.cs b/msbuild/Xamarin.MacDev.Tasks/Tasks/CompileAppManifest.cs index f4201d361ff1..0c9ef6888ec0 100644 --- a/msbuild/Xamarin.MacDev.Tasks/Tasks/CompileAppManifest.cs +++ b/msbuild/Xamarin.MacDev.Tasks/Tasks/CompileAppManifest.cs @@ -252,7 +252,7 @@ bool SetMinimumOSVersion (PDictionary plist) if (Platform == ApplePlatform.MacCatalyst && !string.IsNullOrEmpty (SupportedOSPlatformVersion)) { // SupportedOSPlatformVersion is the iOS version for Mac Catalyst. // But we need to store the macOS version in the app manifest, so convert it to the macOS version here. - if (!MacCatalystSupport.TryGetMacOSVersion (Sdks.GetAppleSdk (Platform).GetSdkPath (SdkVersion), SupportedOSPlatformVersion, out var convertedVersion, out var knowniOSVersions)) { + if (!MacCatalystSupport.TryGetMacOSVersion (GetSdk ().GetSdkPath (SdkVersion), SupportedOSPlatformVersion, out var convertedVersion, out var knowniOSVersions)) { Log.LogError (MSBStrings.E0188, SupportedOSPlatformVersion, string.Join (", ", knowniOSVersions.OrderBy (v => v))); return false; } @@ -266,7 +266,7 @@ bool SetMinimumOSVersion (PDictionary plist) var minimumiOSVersionInManifest = plist.Get (ManifestKeys.MinimumOSVersion)?.Value; if (!string.IsNullOrEmpty (minimumiOSVersionInManifest)) { // Convert to the macOS version - if (!MacCatalystSupport.TryGetMacOSVersion (Sdks.GetAppleSdk (Platform).GetSdkPath (SdkVersion), minimumiOSVersionInManifest!, out var convertedVersion, out var knowniOSVersions)) { + if (!MacCatalystSupport.TryGetMacOSVersion (GetSdk ().GetSdkPath (SdkVersion), minimumiOSVersionInManifest!, out var convertedVersion, out var knowniOSVersions)) { Log.LogError (MSBStrings.E0188, minimumiOSVersionInManifest, string.Join (", ", knowniOSVersions.OrderBy (v => v))); return false; } @@ -325,7 +325,7 @@ bool Compile (PDictionary plist) return false; } - var currentSDK = Sdks.GetAppleSdk (Platform); + var currentSDK = GetSdk (); sdkVersion = AppleSdkVersion.Parse (DefaultSdkVersion); if (!currentSDK.SdkIsInstalled (sdkVersion, SdkIsSimulator)) { @@ -424,6 +424,11 @@ protected void MergePartialPlistTemplates (PDictionary plist) MergePartialPLists (this, plist, PartialAppManifests); } + IAppleSdk GetSdk () + { + return Sdks.GetAppleSdk (Platform, GetXcodeLocator ()); + } + void Validation (PDictionary plist) { if (!Validate) @@ -440,7 +445,7 @@ void Validation (PDictionary plist) GetMinimumOSVersion (plist, out var minimumOSVersion); if (minimumOSVersion < new Version (11, 0)) { string miniOSVersion = "?"; - if (MacCatalystSupport.TryGetiOSVersion (Sdks.GetAppleSdk (Platform).GetSdkPath (SdkVersion), minimumOSVersion, out var iOSVersion, out var _)) + if (MacCatalystSupport.TryGetiOSVersion (GetSdk ().GetSdkPath (SdkVersion), minimumOSVersion, out var iOSVersion, out var _)) miniOSVersion = iOSVersion?.ToString () ?? "?"; LogAppManifestError (MSBStrings.E7099 /* The UIDeviceFamily value '6' requires macOS 11.0. Please set the 'SupportedOSPlatformVersion' in the project file to at least 14.0 (the Mac Catalyst version equivalent of macOS 11.0). The current value is {0} (equivalent to macOS {1}). */, miniOSVersion, minimumOSVersion); } @@ -534,7 +539,7 @@ void SetXcodeValues (PDictionary plist, IAppleSdk currentSDK) SetValueIfNotNull (plist, "DTPlatformName", PlatformUtils.GetTargetPlatform (SdkPlatform, IsWatchApp)); SetValueIfNotNull (plist, "DTPlatformVersion", dtSettings.DTPlatformVersion); SetValueIfNotNull (plist, "DTSDKName", sdkSettings.CanonicalName); - SetValueIfNotNull (plist, "DTXcode", AppleSdkSettings.DTXcode); + SetValueIfNotNull (plist, "DTXcode", GetXcodeLocator ().DTXcode); SetValueIfNotNull (plist, "DTXcodeBuild", dtSettings.DTXcodeBuild); } diff --git a/msbuild/Xamarin.MacDev.Tasks/Tasks/CompileEntitlements.cs b/msbuild/Xamarin.MacDev.Tasks/Tasks/CompileEntitlements.cs index 4287190635c9..a55cd3ef31c2 100644 --- a/msbuild/Xamarin.MacDev.Tasks/Tasks/CompileEntitlements.cs +++ b/msbuild/Xamarin.MacDev.Tasks/Tasks/CompileEntitlements.cs @@ -117,7 +117,7 @@ string DefaultEntitlementsPath { return "Entitlements.plist"; } - return Path.Combine (Sdks.GetAppleSdk (TargetFrameworkMoniker).GetSdkPath (SdkVersion, false), "Entitlements.plist"); + return Path.Combine (Sdks.GetAppleSdk (TargetFrameworkMoniker, GetXcodeLocator ()).GetSdkPath (SdkVersion, false), "Entitlements.plist"); } } diff --git a/msbuild/Xamarin.MacDev.Tasks/Tasks/DetectSdkLocation.cs b/msbuild/Xamarin.MacDev.Tasks/Tasks/DetectSdkLocation.cs index ea83dee857c6..88f0de63cc1d 100644 --- a/msbuild/Xamarin.MacDev.Tasks/Tasks/DetectSdkLocation.cs +++ b/msbuild/Xamarin.MacDev.Tasks/Tasks/DetectSdkLocation.cs @@ -28,17 +28,19 @@ public string SdkRoot { get; set; } = ""; + // this is input too [Output] public new string SdkDevPath { - get; set; - } = ""; - + get => base.SdkDevPath; + set => base.SdkDevPath = value; + } [Output] public bool SdkIsSimulator { get; set; } + [Output] public string SdkPlatform { get; set; } = ""; @@ -64,10 +66,12 @@ public string XcodeVersion { protected IAppleSdk CurrentSdk { get { - return Sdks.GetAppleSdk (Platform); + return Sdks.GetAppleSdk (Platform, GetXcodeLocator ()); } } + XcodeLocator? appleSdkSettings; + IAppleSdkVersion GetDefaultSdkVersion () { switch (Platform) { @@ -148,14 +152,16 @@ bool ExecuteImpl () return ExecuteRemotely (); } - AppleSdkSettings.Init (); + appleSdkSettings = GetXcodeLocator (initialDiscovery: true); + SdkDevPath = appleSdkSettings.DeveloperRoot; + XcodeVersion = appleSdkSettings.XcodeVersion.ToString (); + if (Log.HasLoggedErrors) + return false; if (EnsureAppleSdkRoot ()) EnsureSdkPath (); EnsureXamarinSdkRoot (); - XcodeVersion = AppleSdkSettings.XcodeVersion.ToString (); - return !Log.HasLoggedErrors; } @@ -163,7 +169,7 @@ protected bool EnsureAppleSdkRoot () { var currentSdk = CurrentSdk; if (!currentSdk.IsInstalled) { - Log.LogError (MSBStrings.E0044v2 /* Could not find a valid Xcode app bundle at '{0}'. Please verify that 'xcode-select -p' points to your Xcode installation. For more information see https://aka.ms/macios-missing-xcode. */, AppleSdkSettings.InvalidDeveloperRoot); + Log.LogError (MSBStrings.E0044v2 /* Could not find a valid Xcode app bundle at '{0}'. Please verify that 'xcode-select -p' points to your Xcode installation. For more information see https://aka.ms/macios-missing-xcode. */, appleSdkSettings?.XcodeLocation); return false; } Log.LogMessage (MessageImportance.Low, "DeveloperRoot: {0}", currentSdk.DeveloperRoot); diff --git a/msbuild/Xamarin.MacDev.Tasks/Tasks/DetectSigningIdentity.cs b/msbuild/Xamarin.MacDev.Tasks/Tasks/DetectSigningIdentity.cs index f3797f0c3bca..a41f7b717115 100644 --- a/msbuild/Xamarin.MacDev.Tasks/Tasks/DetectSigningIdentity.cs +++ b/msbuild/Xamarin.MacDev.Tasks/Tasks/DetectSigningIdentity.cs @@ -31,7 +31,7 @@ public class DetectSigningIdentity : XamarinTask, ITaskCallback, ICancelableTask protected string DeveloperRoot { get { - return Sdks.GetAppleSdk (TargetFrameworkMoniker).DeveloperRoot; + return Sdks.GetAppleSdk (TargetFrameworkMoniker, GetXcodeLocator ()).DeveloperRoot; } } diff --git a/msbuild/Xamarin.MacDev.Tasks/Tasks/ReadAppManifest.cs b/msbuild/Xamarin.MacDev.Tasks/Tasks/ReadAppManifest.cs index 4a18efd376ea..effa19dda461 100644 --- a/msbuild/Xamarin.MacDev.Tasks/Tasks/ReadAppManifest.cs +++ b/msbuild/Xamarin.MacDev.Tasks/Tasks/ReadAppManifest.cs @@ -73,7 +73,7 @@ public override bool Execute () if (Platform == ApplePlatform.MacCatalyst) { // The minimum version in the Info.plist is the macOS version. However, the rest of our tooling // expects the iOS version, so expose that. - if (!MacCatalystSupport.TryGetiOSVersion (Sdks.GetAppleSdk (Platform).GetSdkPath (), MinimumOSVersion!, out var convertedVersion, out var knownMacOSVersions)) + if (!MacCatalystSupport.TryGetiOSVersion (Sdks.GetAppleSdk (Platform, GetXcodeLocator ()).GetSdkPath (), MinimumOSVersion!, out var convertedVersion, out var knownMacOSVersions)) Log.LogError (MSBStrings.E0187, MinimumOSVersion, string.Join (", ", knownMacOSVersions.OrderBy (v => v))); MinimumOSVersion = convertedVersion; } diff --git a/msbuild/Xamarin.MacDev.Tasks/Tasks/XamarinTask.cs b/msbuild/Xamarin.MacDev.Tasks/Tasks/XamarinTask.cs index b1926ee6ceec..fec6792c7855 100644 --- a/msbuild/Xamarin.MacDev.Tasks/Tasks/XamarinTask.cs +++ b/msbuild/Xamarin.MacDev.Tasks/Tasks/XamarinTask.cs @@ -25,6 +25,23 @@ public abstract class XamarinTask : Task, IHasSessionId, ICustomLogger { public string SdkDevPath { get; set; } = string.Empty; + XcodeLocator? xcodeLocator = null; + public XcodeLocator GetXcodeLocator (bool initialDiscovery = false) + { + if (xcodeLocator is null) { + if (!initialDiscovery && string.IsNullOrEmpty (SdkDevPath)) { + // Log.LogError (MSBStrings.E7164 /* The task '{0}' is trying to call an external process, but a path to Xcode has not been provided. Please file an issue at https://github.com/dotnet/macios/issues/new/choose. */, task.GetType ().Name); + Log.LogError ("The task '{0}' requires SdkDevPath to be set.\n{1}", GetType ().Name, Environment.StackTrace); + } + + var xcodeLocator = new XcodeLocator (this); + if (!xcodeLocator.TryLocatingXcode (SdkDevPath)) + Log.LogError (MSBStrings.E0086 /* Could not find a valid Xcode developer path */); + this.xcodeLocator = xcodeLocator; + } + return xcodeLocator; + } + void VerifyTargetFrameworkMoniker () { if (!string.IsNullOrEmpty (TargetFrameworkMoniker)) diff --git a/msbuild/Xamarin.Shared/Xamarin.Shared.targets b/msbuild/Xamarin.Shared/Xamarin.Shared.targets index 8403e064d160..571f96839ae4 100644 --- a/msbuild/Xamarin.Shared/Xamarin.Shared.targets +++ b/msbuild/Xamarin.Shared/Xamarin.Shared.targets @@ -697,6 +697,7 @@ Copyright (C) 2018 Microsoft. All rights reserved. ProjectDir="$(MSBuildProjectDirectory)" ResourcePrefix="$(_ResourcePrefix)" ResourceRules="$(_PreparedResourceRules)" + SdkDevPath="$(_SdkDevPath)" SdkIsSimulator="$(_SdkIsSimulator)" SdkVersion="$(_SdkVersion)" SupportedOSPlatformVersion="$(SupportedOSPlatformVersion)" @@ -2062,6 +2063,7 @@ Copyright (C) 2018 Microsoft. All rights reserved. SdkPlatform="$(_SdkPlatform)" ProvisioningProfile="$(CodesignProvision)" SigningKey="$(_SpecifiedCodesignKey)" + SdkDevPath="$(_SdkDevPath)" DetectedCodeSigningKey="$(_CodeSigningKey)" TargetFrameworkMoniker="$(_ComputedTargetFrameworkMoniker)" > diff --git a/tests/msbuild/Xamarin.MacDev.Tasks.Tests/TaskTests/ACToolTaskTest.cs b/tests/msbuild/Xamarin.MacDev.Tasks.Tests/TaskTests/ACToolTaskTest.cs index 75f52139b7af..3d29841fa700 100644 --- a/tests/msbuild/Xamarin.MacDev.Tasks.Tests/TaskTests/ACToolTaskTest.cs +++ b/tests/msbuild/Xamarin.MacDev.Tasks.Tests/TaskTests/ACToolTaskTest.cs @@ -22,7 +22,9 @@ ACTool CreateACToolTask (ApplePlatform platform, string projectDir, out string i intermediateOutputPath = Cache.CreateTemporaryDirectory (); - var sdk = Sdks.GetAppleSdk (platform); + var task = CreateTask (); + + var sdk = Sdks.GetAppleSdk (platform, task.GetXcodeLocator (initialDiscovery: true)); var version = AppleSdkVersion.UseDefault.ToString (); var root = sdk.GetSdkPath (version, false); string sdkPlatform; @@ -47,7 +49,6 @@ ACTool CreateACToolTask (ApplePlatform platform, string projectDir, out string i throw new NotImplementedException (platform.ToString ()); } - var task = CreateTask (); task.ImageAssets = imageAssets .Select (v => { var spl = v.Split ('|'); diff --git a/tests/msbuild/Xamarin.MacDev.Tasks.Tests/TaskTests/CompileAppManifestTaskTests.cs b/tests/msbuild/Xamarin.MacDev.Tasks.Tests/TaskTests/CompileAppManifestTaskTests.cs index 61894f0d0835..a7224781c95e 100644 --- a/tests/msbuild/Xamarin.MacDev.Tasks.Tests/TaskTests/CompileAppManifestTaskTests.cs +++ b/tests/msbuild/Xamarin.MacDev.Tasks.Tests/TaskTests/CompileAppManifestTaskTests.cs @@ -21,7 +21,7 @@ CompileAppManifest CreateTask (string? tmpdir = null, ApplePlatform platform = A task.AssemblyName = "AssemblyName"; task.AppBundleName = "AppBundleName"; task.CompiledAppManifest = new TaskItem (Path.Combine (tmpdir, "TemporaryAppManifest.plist")); - task.DefaultSdkVersion = Sdks.GetAppleSdk (platform).GetInstalledSdkVersions (false).First ().ToString ()!; + task.DefaultSdkVersion = Sdks.GetAppleSdk (platform, task.GetXcodeLocator (initialDiscovery: true)).GetInstalledSdkVersions (false).First ().ToString ()!; task.MinSupportedOSPlatformVersion = "10.0"; task.SupportedOSPlatformVersion = "15.0"; task.SdkVersion = task.DefaultSdkVersion ?? string.Empty; diff --git a/tests/msbuild/Xamarin.MacDev.Tasks.Tests/TaskTests/GeneratePlistTaskTests/GeneratePlistTaskTests_iOS.cs b/tests/msbuild/Xamarin.MacDev.Tasks.Tests/TaskTests/GeneratePlistTaskTests/GeneratePlistTaskTests_iOS.cs index 9d094f066a94..ef2fc666b041 100644 --- a/tests/msbuild/Xamarin.MacDev.Tasks.Tests/TaskTests/GeneratePlistTaskTests/GeneratePlistTaskTests_iOS.cs +++ b/tests/msbuild/Xamarin.MacDev.Tasks.Tests/TaskTests/GeneratePlistTaskTests/GeneratePlistTaskTests_iOS.cs @@ -15,7 +15,7 @@ protected override void ConfigureTask () Configuration.IgnoreIfIgnoredPlatform (ApplePlatform.iOS); base.ConfigureTask (); - Task.DefaultSdkVersion = Sdks.IOS.GetClosestInstalledSdk (AppleSdkVersion.V6_1, true).ToString (); + Task.DefaultSdkVersion = Sdks.GetAppleSdk (Platform, Task.GetXcodeLocator (initialDiscovery: true)).GetClosestInstalledSdk (AppleSdkVersion.V6_1, true).ToString (); Task.TargetFrameworkMoniker = TargetFramework.DotNet_iOS_String; Task.TargetArchitectures = "ARM64"; } diff --git a/tests/msbuild/Xamarin.MacDev.Tasks.Tests/TaskTests/GeneratePlistTaskTests/GeneratePlistTaskTests_tvOS.cs b/tests/msbuild/Xamarin.MacDev.Tasks.Tests/TaskTests/GeneratePlistTaskTests/GeneratePlistTaskTests_tvOS.cs index b77904722891..63a1564ffd33 100644 --- a/tests/msbuild/Xamarin.MacDev.Tasks.Tests/TaskTests/GeneratePlistTaskTests/GeneratePlistTaskTests_tvOS.cs +++ b/tests/msbuild/Xamarin.MacDev.Tasks.Tests/TaskTests/GeneratePlistTaskTests/GeneratePlistTaskTests_tvOS.cs @@ -14,7 +14,7 @@ protected override void ConfigureTask () Configuration.IgnoreIfIgnoredPlatform (ApplePlatform.TVOS); base.ConfigureTask (); - Task.DefaultSdkVersion = Sdks.TVOS.GetClosestInstalledSdk (AppleSdkVersion.V9_0, true).ToString (); + Task.DefaultSdkVersion = Sdks.GetAppleSdk (Platform, Task.GetXcodeLocator (initialDiscovery: true)).GetClosestInstalledSdk (AppleSdkVersion.V9_0, true).ToString (); Task.TargetFrameworkMoniker = TargetFramework.DotNet_tvOS_String; } } diff --git a/tests/msbuild/Xamarin.MacDev.Tasks.Tests/TaskTests/IBToolTaskTests.cs b/tests/msbuild/Xamarin.MacDev.Tasks.Tests/TaskTests/IBToolTaskTests.cs index 8c301b35e3c8..304a4931674d 100644 --- a/tests/msbuild/Xamarin.MacDev.Tasks.Tests/TaskTests/IBToolTaskTests.cs +++ b/tests/msbuild/Xamarin.MacDev.Tasks.Tests/TaskTests/IBToolTaskTests.cs @@ -18,9 +18,11 @@ namespace Xamarin.MacDev.Tasks { public class IBToolTaskTests : TestBase { IBTool CreateIBToolTask (ApplePlatform framework, string projectDir, string intermediateOutputPath) { + var task = CreateTask (); + var interfaceDefinitions = new List (); - var sdk = Sdks.GetSdk (framework); - var version = AppleSdkVersion.GetDefault (sdk, false); + var sdk = Sdks.GetAppleSdk (framework, task.GetXcodeLocator (initialDiscovery: true)); + var version = AppleSdkVersion.UseDefault.ToString (); var root = sdk.GetSdkPath (version, false); string platform; @@ -39,7 +41,6 @@ IBTool CreateIBToolTask (ApplePlatform framework, string projectDir, string inte foreach (var item in Directory.EnumerateFiles (projectDir, "*.xib", SearchOption.AllDirectories)) interfaceDefinitions.Add (new TaskItem (item)); - var task = CreateTask (); task.InterfaceDefinitions = interfaceDefinitions.ToArray (); task.IntermediateOutputPath = intermediateOutputPath; task.MinimumOSVersion = PDictionary.FromFile (Path.Combine (projectDir, "Info.plist")).GetMinimumOSVersion (); diff --git a/tests/msbuild/Xamarin.MacDev.Tasks.Tests/TestHelpers/TestBase.cs b/tests/msbuild/Xamarin.MacDev.Tasks.Tests/TestHelpers/TestBase.cs index 8f38b34b0225..3856dc0dc097 100644 --- a/tests/msbuild/Xamarin.MacDev.Tasks.Tests/TestHelpers/TestBase.cs +++ b/tests/msbuild/Xamarin.MacDev.Tasks.Tests/TestHelpers/TestBase.cs @@ -53,6 +53,8 @@ public virtual void Setup () { var t = new T (); t.BuildEngine = Engine; + if (t is XamarinTask xt) + xt.SdkDevPath = Configuration.xcode_root; return t; } From 569eb19d189aee08b028e4879aa7abedac61b43b Mon Sep 17 00:00:00 2001 From: Rolf Bjarne Kvinge Date: Mon, 10 Nov 2025 10:34:05 +0100 Subject: [PATCH 18/23] A few more! --- msbuild/Xamarin.Shared/Xamarin.Shared.targets | 2 ++ 1 file changed, 2 insertions(+) diff --git a/msbuild/Xamarin.Shared/Xamarin.Shared.targets b/msbuild/Xamarin.Shared/Xamarin.Shared.targets index 571f96839ae4..4fbd365f5829 100644 --- a/msbuild/Xamarin.Shared/Xamarin.Shared.targets +++ b/msbuild/Xamarin.Shared/Xamarin.Shared.targets @@ -724,6 +724,7 @@ Copyright (C) 2018 Microsoft. All rights reserved. Condition="'$(IsMacEnabled)' == 'true' And '$(_BundleOriginalResources)' != 'true'" SessionId="$(BuildSessionId)" AppManifest="$(_TemporaryAppManifest)" + SdkDevPath="$(_SdkDevPath)" TargetFrameworkMoniker="$(_ComputedTargetFrameworkMoniker)" > @@ -811,6 +812,7 @@ Copyright (C) 2018 Microsoft. All rights reserved. Entitlements="$(CodesignEntitlements)" CompiledEntitlements="$(_CompiledEntitlementsPath)" ProvisioningProfile="$(_ProvisioningProfile)" + SdkDevPath="$(_SdkDevPath)" SdkIsSimulator="$(_SdkIsSimulator)" SdkPlatform="$(_SdkPlatform)" SdkVersion="$(_SdkVersion)" From b52339eb9fc1250622d9ce160a92bb481ef0bab8 Mon Sep 17 00:00:00 2001 From: Rolf Bjarne Kvinge Date: Mon, 10 Nov 2025 15:51:02 +0100 Subject: [PATCH 19/23] fixes --- msbuild/Xamarin.Shared/Xamarin.Shared.targets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msbuild/Xamarin.Shared/Xamarin.Shared.targets b/msbuild/Xamarin.Shared/Xamarin.Shared.targets index 4fbd365f5829..10f608448097 100644 --- a/msbuild/Xamarin.Shared/Xamarin.Shared.targets +++ b/msbuild/Xamarin.Shared/Xamarin.Shared.targets @@ -1149,7 +1149,7 @@ Copyright (C) 2018 Microsoft. All rights reserved. + DependsOnTargets="_BeforeCoreCompileSceneKitAssets;_GenerateBundleName;_ComputeTargetFrameworkMoniker;_SetResourceMetadata;_DetectSdkLocations"> Date: Tue, 11 Nov 2025 18:56:44 +0100 Subject: [PATCH 20/23] tweaks --- .../MSBStrings.resx | 20 +++++++++++++++++ .../Tasks/DetectSdkLocation.cs | 22 ++++++++++++++++++- .../Xamarin.MacDev.Tasks/Tasks/XamarinTask.cs | 8 +++---- 3 files changed, 45 insertions(+), 5 deletions(-) diff --git a/msbuild/Xamarin.Localization.MSBuild/MSBStrings.resx b/msbuild/Xamarin.Localization.MSBuild/MSBStrings.resx index a3e08d454caf..90577f75ac2b 100644 --- a/msbuild/Xamarin.Localization.MSBuild/MSBStrings.resx +++ b/msbuild/Xamarin.Localization.MSBuild/MSBStrings.resx @@ -1633,4 +1633,24 @@ The task '{0}' is trying to call an external process, but a path to Xcode has not been provided. Please file an issue at https://github.com/dotnet/macios/issues/new/choose. + + + The environment variable '{0}' is deprecated, and will be ignored in .NET 11+. Please set use the 'DEVELOPER_DIR' environment variable or the 'XcodeLocation' MSBuild property to choose which Xcode to use. + + + + The environment variable '{0}' is deprecated, and will be ignored. Please set use the 'DEVELOPER_DIR' environment variable or the 'XcodeLocation' MSBuild property to choose which Xcode to use. + + + + The settings file '{0}' is deprecated, and will be ignored in .NET 11+. Please set use the 'DEVELOPER_DIR' environment variable or the 'XcodeLocation' MSBuild property to choose which Xcode to use. + + + + The settings file '{0}' is deprecated, and will be ignored. Please set use the 'DEVELOPER_DIR' environment variable or the 'XcodeLocation' MSBuild property to choose which Xcode to use. + + + + The task '{0}' requires the property '{1}' to be set. Please file an issue at https://github.com/dotnet/macios/issues/new/choose. + diff --git a/msbuild/Xamarin.MacDev.Tasks/Tasks/DetectSdkLocation.cs b/msbuild/Xamarin.MacDev.Tasks/Tasks/DetectSdkLocation.cs index 88f0de63cc1d..5835d545e18f 100644 --- a/msbuild/Xamarin.MacDev.Tasks/Tasks/DetectSdkLocation.cs +++ b/msbuild/Xamarin.MacDev.Tasks/Tasks/DetectSdkLocation.cs @@ -152,9 +152,29 @@ bool ExecuteImpl () return ExecuteRemotely (); } - appleSdkSettings = GetXcodeLocator (initialDiscovery: true); + var isNet11OrNewer = TargetFramework.Version.Major >= 11; + appleSdkSettings = GetXcodeLocator (initialDiscovery: true, (locator) => { + locator.SupportEnvironmentVariableLookup = !isNet11OrNewer; + locator.SupportSettingsFileLookup = !isNet11OrNewer; + }); SdkDevPath = appleSdkSettings.DeveloperRoot; XcodeVersion = appleSdkSettings.XcodeVersion.ToString (); + + if (appleSdkSettings.SystemHasEnvironmentVariable) { + if (isNet11OrNewer) { + Log.LogError (MSBStrings.W7166 /* The environment variable '{0}' is deprecated, and will be ignored. Please set use the 'DEVELOPER_DIR' environment variable or the 'XcodeLocation' MSBuild property to choose which Xcode to use. */, XcodeLocator.EnvironmentVariableName); + } else { + Log.LogError (MSBStrings.W7165 /* The environment variable '{0}' is deprecated, and will be ignored in .NET 11+. Please set use the 'DEVELOPER_DIR' environment variable or the 'XcodeLocation' MSBuild property to choose which Xcode to use. */, XcodeLocator.EnvironmentVariableName); + } + } + foreach (var file in appleSdkSettings.SystemExistingSettingsFiles) { + if (isNet11OrNewer) { + Log.LogError (MSBStrings.W7168 /* The settings file '{0}' is deprecated, and will be ignored. Please set use the 'DEVELOPER_DIR' environment variable or the 'XcodeLocation' MSBuild property to choose which Xcode to use. */, file); + } else { + Log.LogWarning (MSBStrings.W7167 /* The settings file '{0}' is deprecated, and will be ignored in .NET 11+. Please set use the 'DEVELOPER_DIR' environment variable or the 'XcodeLocation' MSBuild property to choose which Xcode to use. */, file); + } + } + if (Log.HasLoggedErrors) return false; diff --git a/msbuild/Xamarin.MacDev.Tasks/Tasks/XamarinTask.cs b/msbuild/Xamarin.MacDev.Tasks/Tasks/XamarinTask.cs index fec6792c7855..3e6e0087a0d6 100644 --- a/msbuild/Xamarin.MacDev.Tasks/Tasks/XamarinTask.cs +++ b/msbuild/Xamarin.MacDev.Tasks/Tasks/XamarinTask.cs @@ -26,15 +26,15 @@ public abstract class XamarinTask : Task, IHasSessionId, ICustomLogger { public string SdkDevPath { get; set; } = string.Empty; XcodeLocator? xcodeLocator = null; - public XcodeLocator GetXcodeLocator (bool initialDiscovery = false) + public XcodeLocator GetXcodeLocator (bool initialDiscovery = false, Action? preprocess = null) { if (xcodeLocator is null) { if (!initialDiscovery && string.IsNullOrEmpty (SdkDevPath)) { - // Log.LogError (MSBStrings.E7164 /* The task '{0}' is trying to call an external process, but a path to Xcode has not been provided. Please file an issue at https://github.com/dotnet/macios/issues/new/choose. */, task.GetType ().Name); - Log.LogError ("The task '{0}' requires SdkDevPath to be set.\n{1}", GetType ().Name, Environment.StackTrace); + Log.LogError (MSBStrings.E7169, /* The task '{0}' requires the property '{1}' to be set. Please file an issue at https://github.com/dotnet/macios/issues/new/choose. */ GetType ().Name, "SdkDevPath"); } var xcodeLocator = new XcodeLocator (this); + preprocess?.Invoke (xcodeLocator); if (!xcodeLocator.TryLocatingXcode (SdkDevPath)) Log.LogError (MSBStrings.E0086 /* Could not find a valid Xcode developer path */); this.xcodeLocator = xcodeLocator; @@ -46,7 +46,7 @@ void VerifyTargetFrameworkMoniker () { if (!string.IsNullOrEmpty (TargetFrameworkMoniker)) return; - Log.LogError ($"The task {GetType ().Name} requires TargetFrameworkMoniker to be set."); + Log.LogError (MSBStrings.E7169, /* The task '{0}' requires the property '{1}' to be set. Please file an issue at https://github.com/dotnet/macios/issues/new/choose. */ GetType ().Name, "TargetFrameworkMoniker"); } public string Product { From 83c44f7e5f77074319cff6dc41cb53d66e08f0b7 Mon Sep 17 00:00:00 2001 From: Rolf Bjarne Kvinge Date: Tue, 11 Nov 2025 19:14:01 +0100 Subject: [PATCH 21/23] Bump --- external/Xamarin.MacDev | 2 +- msbuild/Xamarin.MacDev.Tasks/Tasks/DetectSdkLocation.cs | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/external/Xamarin.MacDev b/external/Xamarin.MacDev index 464076f830ed..3b04d3c757c5 160000 --- a/external/Xamarin.MacDev +++ b/external/Xamarin.MacDev @@ -1 +1 @@ -Subproject commit 464076f830ed30aad405fc36d7f29bca331d138e +Subproject commit 3b04d3c757c53cd404c2e88eeb48bf7c4c1131eb diff --git a/msbuild/Xamarin.MacDev.Tasks/Tasks/DetectSdkLocation.cs b/msbuild/Xamarin.MacDev.Tasks/Tasks/DetectSdkLocation.cs index 5835d545e18f..ad0dcc9254f0 100644 --- a/msbuild/Xamarin.MacDev.Tasks/Tasks/DetectSdkLocation.cs +++ b/msbuild/Xamarin.MacDev.Tasks/Tasks/DetectSdkLocation.cs @@ -162,14 +162,14 @@ bool ExecuteImpl () if (appleSdkSettings.SystemHasEnvironmentVariable) { if (isNet11OrNewer) { - Log.LogError (MSBStrings.W7166 /* The environment variable '{0}' is deprecated, and will be ignored. Please set use the 'DEVELOPER_DIR' environment variable or the 'XcodeLocation' MSBuild property to choose which Xcode to use. */, XcodeLocator.EnvironmentVariableName); + Log.LogWarning (MSBStrings.W7166 /* The environment variable '{0}' is deprecated, and will be ignored. Please set use the 'DEVELOPER_DIR' environment variable or the 'XcodeLocation' MSBuild property to choose which Xcode to use. */, XcodeLocator.EnvironmentVariableName); } else { - Log.LogError (MSBStrings.W7165 /* The environment variable '{0}' is deprecated, and will be ignored in .NET 11+. Please set use the 'DEVELOPER_DIR' environment variable or the 'XcodeLocation' MSBuild property to choose which Xcode to use. */, XcodeLocator.EnvironmentVariableName); + Log.LogWarning (MSBStrings.W7165 /* The environment variable '{0}' is deprecated, and will be ignored in .NET 11+. Please set use the 'DEVELOPER_DIR' environment variable or the 'XcodeLocation' MSBuild property to choose which Xcode to use. */, XcodeLocator.EnvironmentVariableName); } } foreach (var file in appleSdkSettings.SystemExistingSettingsFiles) { if (isNet11OrNewer) { - Log.LogError (MSBStrings.W7168 /* The settings file '{0}' is deprecated, and will be ignored. Please set use the 'DEVELOPER_DIR' environment variable or the 'XcodeLocation' MSBuild property to choose which Xcode to use. */, file); + Log.LogWarning (MSBStrings.W7168 /* The settings file '{0}' is deprecated, and will be ignored. Please set use the 'DEVELOPER_DIR' environment variable or the 'XcodeLocation' MSBuild property to choose which Xcode to use. */, file); } else { Log.LogWarning (MSBStrings.W7167 /* The settings file '{0}' is deprecated, and will be ignored in .NET 11+. Please set use the 'DEVELOPER_DIR' environment variable or the 'XcodeLocation' MSBuild property to choose which Xcode to use. */, file); } From 0122a1609baab8c9d9dffdf32dd99b5ac5e3a6b2 Mon Sep 17 00:00:00 2001 From: Rolf Bjarne Kvinge Date: Wed, 12 Nov 2025 19:02:41 +0100 Subject: [PATCH 22/23] No more MD_APPLE_SDK_ROOT. Nor warnings about settings files. --- Make.config | 1 - tests/common/BinLog.cs | 3 +++ tests/common/Configuration.cs | 2 +- tests/dotnet/UnitTests/XcodeVersionTest.cs | 6 +++--- tests/msbuild/Xamarin.MacDev.Tasks.Tests/AssemblySetup.cs | 2 +- tests/package-mac-tests.sh | 2 +- tests/xharness/Jenkins/TestTasks/AppleTestTask.cs | 2 +- 7 files changed, 10 insertions(+), 8 deletions(-) diff --git a/Make.config b/Make.config index 701b297e8dd2..d584f1d752b7 100644 --- a/Make.config +++ b/Make.config @@ -223,7 +223,6 @@ endif # Tell both Xcode and our build logic which Xcode we're using. export DEVELOPER_DIR=$(XCODE_DEVELOPER_ROOT) -export MD_APPLE_SDK_ROOT=$(abspath $(XCODE_DEVELOPER_ROOT)/../..) # We don't need to be told there are workload updates export DOTNET_CLI_WORKLOAD_UPDATE_NOTIFY_DISABLE=true diff --git a/tests/common/BinLog.cs b/tests/common/BinLog.cs index f02f5123bfec..e8afbc729d96 100644 --- a/tests/common/BinLog.cs +++ b/tests/common/BinLog.cs @@ -210,6 +210,9 @@ public static IEnumerable GetBuildLogWarnings (string path) .Where (v => v.Type == BuildLogEventType.Warning) // We're often referencing earlier .NET projects (Touch.Unit/MonoTouch.Dialog), so ignore any out-of-support warnings. .Where (v => v.Message?.Contains ("is out of support and will not receive security updates in the future") != true) + // Ignore any messages about the settings files, we get *a lot* of those + .Where (v => !(v.Message?.Contains ("The settings file '/Users/") == true && v.Message?.Contains ("/Library/Preferences/maui/Settings.plist' is deprecated, and will be ignored in .NET 11+. ") == true)) + .Where (v => !(v.Message?.Contains ("The settings file '/Users/") == true && v.Message?.Contains ("/Library/Preferences/Xamarin/Settings.plist' is deprecated, and will be ignored in .NET 11+. ") == true)) ; } diff --git a/tests/common/Configuration.cs b/tests/common/Configuration.cs index 2ce50b89c87f..9ee53f61f1f9 100644 --- a/tests/common/Configuration.cs +++ b/tests/common/Configuration.cs @@ -697,7 +697,7 @@ public static void SetBuildVariables (ApplePlatform platform, ref Dictionary (); - environment ["MD_APPLE_SDK_ROOT"] = Path.GetDirectoryName (Path.GetDirectoryName (xcode_root)); + environment ["DEVELOPER_DIR"] = Path.GetDirectoryName (Path.GetDirectoryName (xcode_root)); // This is set by `dotnet test` and can cause building legacy projects to fail to build with: // Microsoft.NET.Build.Extensions.ConflictResolution.targets(30,5): diff --git a/tests/dotnet/UnitTests/XcodeVersionTest.cs b/tests/dotnet/UnitTests/XcodeVersionTest.cs index a365af92f75e..27829f8442aa 100644 --- a/tests/dotnet/UnitTests/XcodeVersionTest.cs +++ b/tests/dotnet/UnitTests/XcodeVersionTest.cs @@ -36,14 +36,14 @@ public void Test (ApplePlatform platform, string xcodePath, Version xcodeVersion var properties = GetDefaultProperties (runtimeIdentifiers); properties ["BundleOriginalResources"] = "true"; // this prevents a different and unrelated error message from failing to build library projects - var existingDeveloperDir = Environment.GetEnvironmentVariable ("MD_APPLE_SDK_ROOT"); + var existingDeveloperDir = Environment.GetEnvironmentVariable ("DEVELOPER_DIR"); try { - Environment.SetEnvironmentVariable ("MD_APPLE_SDK_ROOT", Path.GetDirectoryName (Path.GetDirectoryName (xcodePath))); + Environment.SetEnvironmentVariable ("DEVELOPER_DIR", Path.GetDirectoryName (Path.GetDirectoryName (xcodePath))); var rv = DotNet.AssertBuildFailure (project_path, properties); var errors = BinLog.GetBuildLogErrors (rv.BinLogPath).ToArray (); AssertErrorMessages (errors, $"This version of .NET for {platform.AsString ()} ({Configuration.GetNuGetVersionNoMetadata (platform)}) requires Xcode {Configuration.XcodeVersion}. The current version of Xcode is {xcodeVersion}. Either install Xcode {Configuration.XcodeVersion}, or use a different version of .NET for {platform.AsString ()}. See https://aka.ms/xcode-requirement for more information."); } finally { - Environment.SetEnvironmentVariable ("MD_APPLE_SDK_ROOT", existingDeveloperDir); + Environment.SetEnvironmentVariable ("DEVELOPER_DIR", existingDeveloperDir); } } } diff --git a/tests/msbuild/Xamarin.MacDev.Tasks.Tests/AssemblySetup.cs b/tests/msbuild/Xamarin.MacDev.Tasks.Tests/AssemblySetup.cs index 4c485e135bee..ebe462f05921 100644 --- a/tests/msbuild/Xamarin.MacDev.Tasks.Tests/AssemblySetup.cs +++ b/tests/msbuild/Xamarin.MacDev.Tasks.Tests/AssemblySetup.cs @@ -17,7 +17,7 @@ public void AssemblyInitialization () const string msbuild_exe_path = "/Library/Frameworks/Mono.framework/Versions/Current/lib/mono/msbuild/15.0/bin/MSBuild.dll"; if (is_in_vsmac) { var env = new Dictionary { - { "MD_APPLE_SDK_ROOT", Path.GetDirectoryName (Path.GetDirectoryName (Configuration.xcode_root)) }, + { "DEVELOPER_DIR", Path.GetDirectoryName (Path.GetDirectoryName (Configuration.xcode_root)) }, { "MSBUILD_EXE_PATH", msbuild_exe_path }, }; diff --git a/tests/package-mac-tests.sh b/tests/package-mac-tests.sh index b114e3de4fe3..99fe73178e34 100755 --- a/tests/package-mac-tests.sh +++ b/tests/package-mac-tests.sh @@ -19,7 +19,7 @@ cat test.config INCLUDE_MAC=$(grep ^INCLUDE_MAC= test.config | sed 's/.*=//') INCLUDE_MACCATALYST=$(grep ^INCLUDE_MACCATALYST= test.config | sed 's/.*=//') XCODE_DEVELOPER_ROOT=$(grep ^XCODE_DEVELOPER_ROOT= test.config | sed 's/.*=//') -export MD_APPLE_SDK_ROOT="$(dirname "$(dirname "$XCODE_DEVELOPER_ROOT")")" +export DEVELOPER_DIR="$(dirname "$(dirname "$XCODE_DEVELOPER_ROOT")")" export RootTestsDirectory="$(pwd)" make diff --git a/tests/xharness/Jenkins/TestTasks/AppleTestTask.cs b/tests/xharness/Jenkins/TestTasks/AppleTestTask.cs index b8e47819e90f..386eab0fbc09 100644 --- a/tests/xharness/Jenkins/TestTasks/AppleTestTask.cs +++ b/tests/xharness/Jenkins/TestTasks/AppleTestTask.cs @@ -35,7 +35,7 @@ public override void SetEnvironmentVariables (Process process) var xcodeRoot = Jenkins.Harness.XcodeRoot; process.StartInfo.EnvironmentVariables ["RootTestsDirectory"] = HarnessConfiguration.RootDirectory; - process.StartInfo.EnvironmentVariables ["MD_APPLE_SDK_ROOT"] = xcodeRoot; + process.StartInfo.EnvironmentVariables ["DEVELOPER_DIR"] = xcodeRoot; foreach (var kvp in Environment) { if (kvp.Value is null) { From 0d98831ad72e213dcaf51e6f6169cf5ab0441427 Mon Sep 17 00:00:00 2001 From: Rolf Bjarne Kvinge Date: Sat, 15 Nov 2025 00:08:42 +0100 Subject: [PATCH 23/23] Tweaks --- external/Xamarin.MacDev | 2 +- .../Xamarin.MacDev.Tasks/Tasks/DetectSdkLocation.cs | 10 +--------- msbuild/Xamarin.Shared/Xamarin.Shared.targets | 2 +- tests/dotnet/UnitTests/XcodeVersionTest.cs | 13 ++++--------- 4 files changed, 7 insertions(+), 20 deletions(-) diff --git a/external/Xamarin.MacDev b/external/Xamarin.MacDev index 3b04d3c757c5..8d6495b42028 160000 --- a/external/Xamarin.MacDev +++ b/external/Xamarin.MacDev @@ -1 +1 @@ -Subproject commit 3b04d3c757c53cd404c2e88eeb48bf7c4c1131eb +Subproject commit 8d6495b4202877a8f849311fba290d7c4e345489 diff --git a/msbuild/Xamarin.MacDev.Tasks/Tasks/DetectSdkLocation.cs b/msbuild/Xamarin.MacDev.Tasks/Tasks/DetectSdkLocation.cs index ad0dcc9254f0..1839138f8e06 100644 --- a/msbuild/Xamarin.MacDev.Tasks/Tasks/DetectSdkLocation.cs +++ b/msbuild/Xamarin.MacDev.Tasks/Tasks/DetectSdkLocation.cs @@ -13,14 +13,6 @@ namespace Xamarin.MacDev.Tasks { public class DetectSdkLocations : XamarinTask, ICancelableTask { const string SdkVersionDefaultValue = "default"; - #region Inputs - - public string XcodeLocation { - get; set; - } = ""; - - #endregion Inputs - #region Outputs [Output] @@ -28,7 +20,7 @@ public string SdkRoot { get; set; } = ""; - // this is input too + // this is input too (the variable 'XcodeLocation') [Output] public new string SdkDevPath { get => base.SdkDevPath; diff --git a/msbuild/Xamarin.Shared/Xamarin.Shared.targets b/msbuild/Xamarin.Shared/Xamarin.Shared.targets index 10f608448097..a660e6fc9bc1 100644 --- a/msbuild/Xamarin.Shared/Xamarin.Shared.targets +++ b/msbuild/Xamarin.Shared/Xamarin.Shared.targets @@ -2087,11 +2087,11 @@ Copyright (C) 2018 Microsoft. All rights reserved. diff --git a/tests/dotnet/UnitTests/XcodeVersionTest.cs b/tests/dotnet/UnitTests/XcodeVersionTest.cs index 27829f8442aa..301eb5e57fe0 100644 --- a/tests/dotnet/UnitTests/XcodeVersionTest.cs +++ b/tests/dotnet/UnitTests/XcodeVersionTest.cs @@ -35,16 +35,11 @@ public void Test (ApplePlatform platform, string xcodePath, Version xcodeVersion Clean (project_path); var properties = GetDefaultProperties (runtimeIdentifiers); properties ["BundleOriginalResources"] = "true"; // this prevents a different and unrelated error message from failing to build library projects + properties ["XcodeLocation"] = xcodePath; - var existingDeveloperDir = Environment.GetEnvironmentVariable ("DEVELOPER_DIR"); - try { - Environment.SetEnvironmentVariable ("DEVELOPER_DIR", Path.GetDirectoryName (Path.GetDirectoryName (xcodePath))); - var rv = DotNet.AssertBuildFailure (project_path, properties); - var errors = BinLog.GetBuildLogErrors (rv.BinLogPath).ToArray (); - AssertErrorMessages (errors, $"This version of .NET for {platform.AsString ()} ({Configuration.GetNuGetVersionNoMetadata (platform)}) requires Xcode {Configuration.XcodeVersion}. The current version of Xcode is {xcodeVersion}. Either install Xcode {Configuration.XcodeVersion}, or use a different version of .NET for {platform.AsString ()}. See https://aka.ms/xcode-requirement for more information."); - } finally { - Environment.SetEnvironmentVariable ("DEVELOPER_DIR", existingDeveloperDir); - } + var rv = DotNet.AssertBuildFailure (project_path, properties); + var errors = BinLog.GetBuildLogErrors (rv.BinLogPath).ToArray (); + AssertErrorMessages (errors, $"This version of .NET for {platform.AsString ()} ({Configuration.GetNuGetVersionNoMetadata (platform)}) requires Xcode {Configuration.XcodeVersion}. The current version of Xcode is {xcodeVersion}. Either install Xcode {Configuration.XcodeVersion}, or use a different version of .NET for {platform.AsString ()}. See https://aka.ms/xcode-requirement for more information."); } } }