From d6904081a731809da1ef20318cfee330f08fecb6 Mon Sep 17 00:00:00 2001 From: Rolf Bjarne Kvinge Date: Wed, 16 Oct 2024 11:36:52 +0200 Subject: [PATCH 1/4] [msbuild] Port the BTouch task to subclass XamarinTask. This has a few advantages: * We simplify and unify more of our code. * We have more control over the error reporting / logging behavior. Additionally: * Rename to 'BGen', since that's what the .NET version of the tool is called, and update properties and item groups accordingly. * Allow for overriding the path to the command-line tool in question. * Add support for cancellation. * Fix nullability. * Add documentation for the relevant properties and item groups. --- docs/build-apps/build-items.md | 7 + docs/build-apps/build-properties.md | 22 +++ dotnet/targets/Xamarin.Shared.Sdk.targets | 4 +- .../CommandLineArgumentBuilder.cs | 26 +++ .../Tasks/{BTouch.cs => BGen.cs} | 162 ++++++++---------- .../Tasks/ComputeRemoteGeneratorProperties.cs | 12 +- msbuild/Xamarin.Shared/Xamarin.Shared.props | 6 - msbuild/Xamarin.Shared/Xamarin.Shared.targets | 39 +++-- .../{BTouchTaskTest.cs => BGenTaskTest.cs} | 20 +-- 9 files changed, 165 insertions(+), 133 deletions(-) rename msbuild/Xamarin.MacDev.Tasks/Tasks/{BTouch.cs => BGen.cs} (63%) rename tests/msbuild/Xamarin.MacDev.Tasks.Tests/TaskTests/{BTouchTaskTest.cs => BGenTaskTest.cs} (75%) diff --git a/docs/build-apps/build-items.md b/docs/build-apps/build-items.md index ca29996cd0a2..2c5b8b1244ae 100644 --- a/docs/build-apps/build-items.md +++ b/docs/build-apps/build-items.md @@ -30,6 +30,13 @@ See also: * The [AppIcon](build-properties.md#AppIcon) property. * The [IncludeAllAppIcons](build-properties.md#IncludeAllAppIcons) property. +## BGenReferencePath + +The list of assembly references to pass to the `bgen` tool (binding generator). + +Typically this is handled automatically by adding references as +`ProjectReference` or `PackageReference` items instead. + ## PartialAppManifest `PartialAppManifest` can be used to add additional partial app manifests that diff --git a/docs/build-apps/build-properties.md b/docs/build-apps/build-properties.md index b405f6b4833b..178b46b9612e 100644 --- a/docs/build-apps/build-properties.md +++ b/docs/build-apps/build-properties.md @@ -33,6 +33,28 @@ See also: * The [AlternateAppIcon](build-items.md#AlternateAppIcon) item group. * The [IncludeAllAppIcons](#IncludeAllAppIcons) property. +### BGenEmitDebugInformation + +Whether the `bgen` tool (the binding generator) should emit debug information or not. + +The default behavior is `true` when the `Debug` property is set to `true`. + +## BGenExtraArgs + +Any extra arguments to the `bgen` tool (the binding generator). + +## BGenToolPath + +The name of the `bgen` executable (a tool used by binding projects to generate bindings). + +The default behavior is to use the `bgen` tool shipped with our workload. + +## BGenToolPath + +The directory to where the `bgen` ([BGenToolExe](#BGenToolExe)) is located. + +The default behavior is to use the `bgen` tool shipped with our workload. + ## DittoPath The full path to the `ditto` executable. diff --git a/dotnet/targets/Xamarin.Shared.Sdk.targets b/dotnet/targets/Xamarin.Shared.Sdk.targets index f7329f9b6ba1..1504cb8c6a9f 100644 --- a/dotnet/targets/Xamarin.Shared.Sdk.targets +++ b/dotnet/targets/Xamarin.Shared.Sdk.targets @@ -1416,8 +1416,8 @@ - bgen.dll - $(_XamarinSdkRootDirectory)\tools\lib\bgen + bgen.dll + $(_XamarinSdkRootDirectory)\tools\lib\bgen $(_XamarinRefAssemblyPath) <_GeneratorAttributeAssembly>$(_XamarinSdkRootDirectory)/tools/lib/Xamarin.Apple.BindingAttributes.dll <_DotNetCscCompiler>$(RoslynTargetsPath)\bincore\csc.dll diff --git a/msbuild/Xamarin.MacDev.Tasks/CommandLineArgumentBuilder.cs b/msbuild/Xamarin.MacDev.Tasks/CommandLineArgumentBuilder.cs index 9d13fcc21f96..ea81b10f80ed 100644 --- a/msbuild/Xamarin.MacDev.Tasks/CommandLineArgumentBuilder.cs +++ b/msbuild/Xamarin.MacDev.Tasks/CommandLineArgumentBuilder.cs @@ -229,5 +229,31 @@ public string CreateResponseFile (Task task, string responseFilePath, IList CreateResponseFile (Task task, string responseFilePath, IList responseArguments, IList nonResponseArguments) + { + // Generate a response file + var responseFile = Path.GetFullPath (responseFilePath); + + if (File.Exists (responseFile)) + File.Delete (responseFile); + + try { + File.WriteAllLines (responseFile, responseArguments); + } catch (Exception ex) { + task.Log.LogWarning ("Failed to create response file '{0}': {1}", responseFile, ex); + } + + // Some arguments can not safely go in the response file and are + // added separately. They must go _after_ the response file + // as they may override options passed in the response file + var actualArgs = new List (); + + actualArgs.Add ($"@{responseFile}"); + actualArgs.AddRange (nonResponseArguments); + + // Generate the command line + return actualArgs; + } } } diff --git a/msbuild/Xamarin.MacDev.Tasks/Tasks/BTouch.cs b/msbuild/Xamarin.MacDev.Tasks/Tasks/BGen.cs similarity index 63% rename from msbuild/Xamarin.MacDev.Tasks/Tasks/BTouch.cs rename to msbuild/Xamarin.MacDev.Tasks/Tasks/BGen.cs index 48ba271c855e..512a261c1dbb 100644 --- a/msbuild/Xamarin.MacDev.Tasks/Tasks/BTouch.cs +++ b/msbuild/Xamarin.MacDev.Tasks/Tasks/BGen.cs @@ -5,6 +5,8 @@ using System.Collections.Generic; using System.Linq; using System.Text; +using System.Threading; +using System.Threading.Tasks; using Microsoft.Build.Framework; using Microsoft.Build.Utilities; @@ -15,123 +17,102 @@ using Xamarin.Messaging; using Xamarin.Messaging.Build.Client; -// Disable until we get around to enable + fix any issues. -#nullable disable +#nullable enable namespace Xamarin.MacDev.Tasks { - public class BTouch : XamarinToolTask, ITaskCallback { + public class BGen : XamarinTask, ICancelableTask { + CancellationTokenSource? cancellationTokenSource; - public string OutputPath { get; set; } + public string OutputPath { get; set; } = string.Empty; [Required] - public string BTouchToolPath { get; set; } + public string BGenToolPath { get; set; } = string.Empty; [Required] - public string BTouchToolExe { get; set; } + public string BGenToolExe { get; set; } = string.Empty; - public ITaskItem [] ObjectiveCLibraries { get; set; } + public ITaskItem [] ObjectiveCLibraries { get; set; } = Array.Empty (); - public ITaskItem [] AdditionalLibPaths { get; set; } + public ITaskItem [] AdditionalLibPaths { get; set; } = Array.Empty (); public bool AllowUnsafeBlocks { get; set; } [Required] - public string BaseLibDll { get; set; } + public string BaseLibDll { get; set; } = string.Empty; [Required] - public ITaskItem [] ApiDefinitions { get; set; } + public ITaskItem [] ApiDefinitions { get; set; } = Array.Empty (); - public string AttributeAssembly { get; set; } + public string AttributeAssembly { get; set; } = string.Empty; - public ITaskItem CompiledApiDefinitionAssembly { get; set; } + public ITaskItem? CompiledApiDefinitionAssembly { get; set; } - public ITaskItem [] CoreSources { get; set; } + public ITaskItem [] CoreSources { get; set; } = Array.Empty (); - public string DefineConstants { get; set; } + public string DefineConstants { get; set; } = string.Empty; public bool EmitDebugInformation { get; set; } - public string ExtraArgs { get; set; } + public string ExtraArgs { get; set; } = string.Empty; public int Verbosity { get; set; } - public string GeneratedSourcesDir { get; set; } + public string GeneratedSourcesDir { get; set; } = string.Empty; - public string GeneratedSourcesFileList { get; set; } + public string GeneratedSourcesFileList { get; set; } = string.Empty; - public string Namespace { get; set; } + public string Namespace { get; set; } = string.Empty; public bool NoNFloatUsing { get; set; } - public ITaskItem [] NativeLibraries { get; set; } + public ITaskItem [] NativeLibraries { get; set; } = Array.Empty (); - public string OutputAssembly { get; set; } + public string OutputAssembly { get; set; } = string.Empty; public bool ProcessEnums { get; set; } [Required] - public string ProjectDir { get; set; } + public string ProjectDir { get; set; } = string.Empty; - public ITaskItem [] References { get; set; } + public ITaskItem [] References { get; set; } = Array.Empty (); - public ITaskItem [] Resources { get; set; } + public ITaskItem [] Resources { get; set; } = Array.Empty (); - public ITaskItem [] Sources { get; set; } + public ITaskItem [] Sources { get; set; } = Array.Empty (); [Required] - public string ResponseFilePath { get; set; } + public string ResponseFilePath { get; set; } = string.Empty; - protected override string ToolName { - get { - if (IsDotNet) - return Path.GetFileName (this.GetDotNetPath ()); - - return Path.GetFileNameWithoutExtension (ToolExe); - } - } - - protected override string GenerateFullPathToTool () - { - // If we're building a .NET app, executing bgen using the same - // dotnet binary as we're executed with, instead of using the - // wrapper bgen script, because that script will try to use the - // system dotnet, which might not exist or not have the version we - // need. - if (IsDotNet) - return this.GetDotNetPath (); - - return Path.Combine (ToolPath, ToolExe); - } - - protected virtual void HandleReferences (CommandLineArgumentBuilder cmd) + protected virtual void HandleReferences (List cmd) { if (References is not null) { foreach (var item in References) - cmd.AddQuoted ("-r:" + Path.GetFullPath (item.ItemSpec)); + cmd.Add ($"-r:{Path.GetFullPath (item.ItemSpec)}"); } } - protected override string GenerateCommandLineCommands () + public virtual List GenerateCommandLineArguments () { - var cmd = new CommandLineArgumentBuilder (); + var cmd = new List (); #if DEBUG cmd.Add ("/v"); #endif if (CompiledApiDefinitionAssembly is not null) - cmd.AddQuotedSwitchIfNotNull ("/compiled-api-definition-assembly:", CompiledApiDefinitionAssembly.ItemSpec); + cmd.Add ($"/compiled-api-definition-assembly:{CompiledApiDefinitionAssembly.ItemSpec}"); cmd.Add ("/nostdlib"); - cmd.AddQuotedSwitchIfNotNull ("/baselib:", BaseLibDll); - cmd.AddQuotedSwitchIfNotNull ("/out:", OutputAssembly); + if (!string.IsNullOrEmpty (BaseLibDll)) + cmd.Add ($"/baselib:{BaseLibDll}"); + if (!string.IsNullOrEmpty (OutputAssembly)) + cmd.Add ($"/out:{OutputAssembly}"); - cmd.AddQuotedSwitchIfNotNull ("/attributelib:", AttributeAssembly); + cmd.Add ($"/attributelib:{AttributeAssembly}"); - string dir; if (!string.IsNullOrEmpty (BaseLibDll)) { - dir = Path.GetDirectoryName (BaseLibDll); - cmd.AddQuotedSwitchIfNotNull ("/lib:", dir); + var dir = Path.GetDirectoryName (BaseLibDll); + cmd.Add ($"/lib:{dir}"); } if (ProcessEnums) @@ -143,7 +124,7 @@ protected override string GenerateCommandLineCommands () if (AllowUnsafeBlocks) cmd.Add ("/unsafe"); - cmd.AddQuotedSwitchIfNotNull ("/ns:", Namespace); + cmd.Add ($"/ns:{Namespace}"); if (NoNFloatUsing) cmd.Add ("/no-nfloat-using:true"); @@ -151,27 +132,27 @@ protected override string GenerateCommandLineCommands () if (!string.IsNullOrEmpty (DefineConstants)) { var strv = DefineConstants.Split (new [] { ';' }, StringSplitOptions.RemoveEmptyEntries); foreach (var str in strv) - cmd.AddQuoted ("/d:" + str); + cmd.Add ($"/d:{str}"); } //cmd.AppendSwitch ("/e"); foreach (var item in ApiDefinitions) - cmd.AddQuoted (Path.GetFullPath (item.ItemSpec)); + cmd.Add (Path.GetFullPath (item.ItemSpec)); if (CoreSources is not null) { foreach (var item in CoreSources) - cmd.AddQuoted ("/s:" + Path.GetFullPath (item.ItemSpec)); + cmd.Add ($"/s:{Path.GetFullPath (item.ItemSpec)}"); } if (Sources is not null) { foreach (var item in Sources) - cmd.AddQuoted ("/x:" + Path.GetFullPath (item.ItemSpec)); + cmd.Add ($"/x:{Path.GetFullPath (item.ItemSpec)}"); } if (AdditionalLibPaths is not null) { foreach (var item in AdditionalLibPaths) - cmd.AddQuoted ("/lib:" + Path.GetFullPath (item.ItemSpec)); + cmd.Add ($"/lib:{Path.GetFullPath (item.ItemSpec)}"); } HandleReferences (cmd); @@ -183,7 +164,7 @@ protected override string GenerateCommandLineCommands () if (!string.IsNullOrEmpty (id)) argument += "," + id; - cmd.AddQuoted ("/res:" + argument); + cmd.Add ($"/res:{argument}"); } } @@ -194,15 +175,15 @@ protected override string GenerateCommandLineCommands () if (string.IsNullOrEmpty (id)) id = Path.GetFileName (argument); - cmd.AddQuoted ("/res:" + argument + "," + id); + cmd.Add ($"/res:{argument},{id}"); } } if (GeneratedSourcesDir is not null) - cmd.AddQuoted ("/tmpdir:" + Path.GetFullPath (GeneratedSourcesDir)); + cmd.Add ($"/tmpdir:{Path.GetFullPath (GeneratedSourcesDir)}"); if (GeneratedSourcesFileList is not null) - cmd.AddQuoted ("/sourceonly:" + Path.GetFullPath (GeneratedSourcesFileList)); + cmd.Add ($"/sourceonly:{Path.GetFullPath (GeneratedSourcesFileList)}"); cmd.Add ($"/target-framework={TargetFrameworkMoniker}"); @@ -242,20 +223,16 @@ protected override string GenerateCommandLineCommands () } } - cmd.Add (VerbosityUtils.Merge (ExtraArgs, (LoggerVerbosity) Verbosity)); + cmd.AddRange (VerbosityUtils.Merge (ExtraArgs, (LoggerVerbosity) Verbosity)); - var commandLine = cmd.CreateResponseFile (this, ResponseFilePath, null); - if (IsDotNet) - commandLine = StringUtils.Quote (Path.Combine (BTouchToolPath, BTouchToolExe)) + " " + commandLine; - - return commandLine.ToString (); + return CommandLineArgumentBuilder.CreateResponseFile (this, ResponseFilePath, cmd, null); } public override bool Execute () { if (ShouldExecuteRemotely ()) { try { - BTouchToolPath = PlatformPath.GetPathForCurrentPlatform (BTouchToolPath); + BGenToolPath = PlatformPath.GetPathForCurrentPlatform (BGenToolPath); BaseLibDll = PlatformPath.GetPathForCurrentPlatform (BaseLibDll); TaskItemFixer.FixFrameworkItemSpecs (Log, item => OutputPath, TargetFramework.Identifier, References.Where (x => x.IsFrameworkItem ()).ToArray ()); @@ -277,18 +254,11 @@ public override bool Execute () AttributeAssembly = PathUtils.ConvertToMacPath (AttributeAssembly); BaseLibDll = PathUtils.ConvertToMacPath (BaseLibDll); - BTouchToolExe = PathUtils.ConvertToMacPath (BTouchToolExe); - BTouchToolPath = PathUtils.ConvertToMacPath (BTouchToolPath); - - if (IsDotNet) { - var customHome = Environment.GetEnvironmentVariable ("DOTNET_CUSTOM_HOME"); - if (!string.IsNullOrEmpty (customHome)) { - EnvironmentVariables = EnvironmentVariables.CopyAndAdd ($"HOME={customHome}"); - } - } else { - ToolExe = BTouchToolExe; - ToolPath = BTouchToolPath; + var customHome = Environment.GetEnvironmentVariable ("DOTNET_CUSTOM_HOME"); + var env = new Dictionary (); + if (!string.IsNullOrEmpty (customHome)) { + env ["HOME"] = customHome; } if (!string.IsNullOrEmpty (SessionId) && @@ -302,7 +272,16 @@ public override bool Execute () return false; } - return base.Execute (); + var executablePath = PathUtils.ConvertToMacPath (BGenToolPath); + var executableExe = PathUtils.ConvertToMacPath (BGenToolExe); + var executable = Path.Combine (executablePath, executableExe); + var args = GenerateCommandLineArguments (); + if (Log.HasLoggedErrors) + return false; + + cancellationTokenSource = new CancellationTokenSource (); + ExecuteAsync (Log, executable, args, environment: env, cancellationToken: cancellationTokenSource.Token).Wait (); + return !Log.HasLoggedErrors; } public bool ShouldCopyToBuildServer (ITaskItem item) => !item.IsFrameworkItem (); @@ -320,12 +299,13 @@ public IEnumerable GetAdditionalItemsToBeCopied () }).ToArray (); } - public override void Cancel () + public void Cancel () { - base.Cancel (); - - if (!string.IsNullOrEmpty (SessionId)) + if (ShouldExecuteRemotely ()) { BuildConnection.CancelAsync (BuildEngine4).Wait (); + } else { + cancellationTokenSource?.Cancel (); + } } async System.Threading.Tasks.Task GetGeneratedSourcesAsync (TaskRunner taskRunner) diff --git a/msbuild/Xamarin.MacDev.Tasks/Tasks/ComputeRemoteGeneratorProperties.cs b/msbuild/Xamarin.MacDev.Tasks/Tasks/ComputeRemoteGeneratorProperties.cs index 745da29e5f86..bbd2f68a4560 100644 --- a/msbuild/Xamarin.MacDev.Tasks/Tasks/ComputeRemoteGeneratorProperties.cs +++ b/msbuild/Xamarin.MacDev.Tasks/Tasks/ComputeRemoteGeneratorProperties.cs @@ -26,10 +26,10 @@ public class ComputeRemoteGeneratorProperties : XamarinTask, ITaskCallback, ICan public string BaseLibDllPath { get; set; } = string.Empty; [Output] - public string BTouchToolExe { get; set; } = string.Empty; + public string BGenToolExe { get; set; } = string.Empty; [Output] - public string BTouchToolPath { get; set; } = string.Empty; + public string BGenToolPath { get; set; } = string.Empty; [Output] public string DotNetCscCompiler { get; set; } = string.Empty; @@ -139,11 +139,11 @@ void ComputeProperties () case "BaseLibDllPath": BaseLibDllPath = value; break; - case "BTouchToolExe": - BTouchToolExe = value; + case "BGenToolExe": + BGenToolExe = value; break; - case "BTouchToolPath": - BTouchToolPath = value; + case "BGenToolPath": + BGenToolPath = value; break; case "_DotNetCscCompiler": DotNetCscCompiler = value; diff --git a/msbuild/Xamarin.Shared/Xamarin.Shared.props b/msbuild/Xamarin.Shared/Xamarin.Shared.props index 79045a9f800e..de3df76b9fa5 100644 --- a/msbuild/Xamarin.Shared/Xamarin.Shared.props +++ b/msbuild/Xamarin.Shared/Xamarin.Shared.props @@ -315,12 +315,6 @@ Copyright (C) 2020 Microsoft. All rights reserved. $(_XamarinPlatformAssemblyPath) - $(_XamarinSdkRoot)/bin/ - $(MSBuildExtensionsPath)\Xamarin\iOS\ - - bgen - bgen.exe - $(IntermediateOutputPath)$(_PlatformName) $(GeneratedSourcesDir)\ <_GeneratedSourcesFileList>$(GeneratedSourcesDir)sources.list diff --git a/msbuild/Xamarin.Shared/Xamarin.Shared.targets b/msbuild/Xamarin.Shared/Xamarin.Shared.targets index 25fc2af375c8..cd748c94a7ba 100644 --- a/msbuild/Xamarin.Shared/Xamarin.Shared.targets +++ b/msbuild/Xamarin.Shared/Xamarin.Shared.targets @@ -39,7 +39,7 @@ Copyright (C) 2018 Microsoft. All rights reserved. - + @@ -1716,8 +1716,8 @@ Copyright (C) 2018 Microsoft. All rights reserved. <_ComputedRemoteGeneratorProperties Include="BaseLibDllPath=$(BaseLibDllPath)" /> - <_ComputedRemoteGeneratorProperties Include="BTouchToolExe=$(BTouchToolExe)" /> - <_ComputedRemoteGeneratorProperties Include="BTouchToolPath=$(BTouchToolPath)" /> + <_ComputedRemoteGeneratorProperties Include="BGenToolExe=$(BGenToolExe)" /> + <_ComputedRemoteGeneratorProperties Include="BGenToolPath=$(BGenToolPath)" /> <_ComputedRemoteGeneratorProperties Include="_DotNetCscCompiler=$(_DotNetCscCompiler)" /> <_ComputedRemoteGeneratorProperties Include="_GeneratorAttributeAssembly=$(_GeneratorAttributeAssembly)" /> @@ -1733,7 +1733,7 @@ Copyright (C) 2018 Microsoft. All rights reserved. - + @@ -1754,7 +1754,7 @@ Copyright (C) 2018 Microsoft. All rights reserved. <_CompiledApiDefinitionReferences Include="$(_GeneratorAttributeAssembly)" /> <_CompiledApiDefinitionReferences Include="@(ReferencePath)" /> - <_CompiledApiDefinitionReferences Include="@(BTouchReferencePath)" /> + <_CompiledApiDefinitionReferences Include="@(BGenReferencePath)" /> <_CompiledApiDefinitionsCompile Include="@(ObjcBindingApiDefinition)" /> <_CompiledApiDefinitionsCompile Include="@(ObjcBindingCoreSource)" /> @@ -1817,10 +1817,17 @@ Copyright (C) 2018 Microsoft. All rights reserved. - false - true + $(BTouchEmitDebugInformation) + true + false + + $(BTouchExtraArgs) + + + + @@ -1831,13 +1838,13 @@ Copyright (C) 2018 Microsoft. All rights reserved. TargetFrameworkMoniker="$(_ComputedTargetFrameworkMoniker)" > - - + + - - + (); + var task = CreateTask (); task.ApiDefinitions = new [] { new TaskItem ("apidefinition.cs") }; task.References = new [] { new TaskItem ("a.dll"), new TaskItem ("b.dll"), new TaskItem ("c.dll") }; task.ResponseFilePath = Path.Combine (Cache.CreateTemporaryDirectory (), "response-file.txt"); - var args = task.GetCommandLineCommands () + " " + File.ReadAllText (task.ResponseFilePath); + var args = task.GenerateCommandLineArguments (); + args.AddRange (File.ReadAllLines (task.ResponseFilePath)); Assert.That (args, Does.Contain ("-r:" + Path.Combine (Environment.CurrentDirectory, "a.dll")), "#1a"); Assert.That (args, Does.Contain ("-r:" + Path.Combine (Environment.CurrentDirectory, "b.dll")), "#1b"); Assert.That (args, Does.Contain ("-r:" + Path.Combine (Environment.CurrentDirectory, "c.dll")), "#1c"); @@ -33,7 +28,7 @@ public void StandardCommandline () [Test] public void Bug656983 () { - var task = CreateTask (); + var task = CreateTask (); task.ApiDefinitions = new [] { new TaskItem ("apidefinition.cs") }; task.References = new [] { new TaskItem ("a.dll"), new TaskItem ("b.dll"), new TaskItem ("c.dll") }; @@ -42,7 +37,8 @@ public void Bug656983 () task.OutputAssembly = null; // default, but important for the bug (in case that default changes) task.ExtraArgs = "-invalid"; - var args = task.GetCommandLineCommands () + " " + File.ReadAllText (task.ResponseFilePath); + var args = task.GenerateCommandLineArguments (); + args.AddRange (File.ReadAllLines (task.ResponseFilePath)); Assert.That (args.Contains (" -invalid"), "incorrect ExtraArg not causing an exception"); } } From 4409dd8582c225fed873047983cb0d49d3711c31 Mon Sep 17 00:00:00 2001 From: Rolf Bjarne Kvinge Date: Fri, 15 Nov 2024 07:58:12 -0800 Subject: [PATCH 2/4] Fixes --- docs/build-apps/build-properties.md | 2 +- msbuild/Xamarin.Shared/Xamarin.Shared.targets | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/build-apps/build-properties.md b/docs/build-apps/build-properties.md index 178b46b9612e..5464bc38b226 100644 --- a/docs/build-apps/build-properties.md +++ b/docs/build-apps/build-properties.md @@ -43,7 +43,7 @@ The default behavior is `true` when the `Debug` property is set to `true`. Any extra arguments to the `bgen` tool (the binding generator). -## BGenToolPath +## BGenToolExe The name of the `bgen` executable (a tool used by binding projects to generate bindings). diff --git a/msbuild/Xamarin.Shared/Xamarin.Shared.targets b/msbuild/Xamarin.Shared/Xamarin.Shared.targets index cd748c94a7ba..09e89e23f4db 100644 --- a/msbuild/Xamarin.Shared/Xamarin.Shared.targets +++ b/msbuild/Xamarin.Shared/Xamarin.Shared.targets @@ -1871,7 +1871,6 @@ Copyright (C) 2018 Microsoft. All rights reserved. TargetFrameworkMoniker="$(_ComputedTargetFrameworkMoniker)" BGenToolPath="$(BGenToolPath)" BGenToolExe="$(BGenToolExe)" - StandardOutputImportance="High" > From a5b9f8676fa679184b7a3a98523955ed2280e232 Mon Sep 17 00:00:00 2001 From: Rolf Bjarne Kvinge Date: Tue, 19 Nov 2024 12:32:28 +0100 Subject: [PATCH 3/4] Fixes --- .../CommandLineArgumentBuilder.cs | 3 ++- msbuild/Xamarin.MacDev.Tasks/Tasks/BGen.cs | 26 ++++++++++++------- .../TaskTests/BGenTaskTest.cs | 2 +- 3 files changed, 20 insertions(+), 11 deletions(-) diff --git a/msbuild/Xamarin.MacDev.Tasks/CommandLineArgumentBuilder.cs b/msbuild/Xamarin.MacDev.Tasks/CommandLineArgumentBuilder.cs index ea81b10f80ed..a903ce2d9d46 100644 --- a/msbuild/Xamarin.MacDev.Tasks/CommandLineArgumentBuilder.cs +++ b/msbuild/Xamarin.MacDev.Tasks/CommandLineArgumentBuilder.cs @@ -250,7 +250,8 @@ public static List CreateResponseFile (Task task, string responseFilePat var actualArgs = new List (); actualArgs.Add ($"@{responseFile}"); - actualArgs.AddRange (nonResponseArguments); + if (nonResponseArguments is not null) + actualArgs.AddRange (nonResponseArguments); // Generate the command line return actualArgs; diff --git a/msbuild/Xamarin.MacDev.Tasks/Tasks/BGen.cs b/msbuild/Xamarin.MacDev.Tasks/Tasks/BGen.cs index 512a261c1dbb..d10948aba353 100644 --- a/msbuild/Xamarin.MacDev.Tasks/Tasks/BGen.cs +++ b/msbuild/Xamarin.MacDev.Tasks/Tasks/BGen.cs @@ -99,8 +99,13 @@ public virtual List GenerateCommandLineArguments () cmd.Add ("/v"); #endif - if (CompiledApiDefinitionAssembly is not null) - cmd.Add ($"/compiled-api-definition-assembly:{CompiledApiDefinitionAssembly.ItemSpec}"); + var compiledApiDefinitionAssembly = CompiledApiDefinitionAssembly?.ItemSpec; +#if NET + if (!string.IsNullOrEmpty (compiledApiDefinitionAssembly)) +#else + if (compiledApiDefinitionAssembly is not null && !string.IsNullOrEmpty (compiledApiDefinitionAssembly)) +#endif + cmd.Add ($"/compiled-api-definition-assembly:{compiledApiDefinitionAssembly}"); cmd.Add ("/nostdlib"); if (!string.IsNullOrEmpty (BaseLibDll)) @@ -124,7 +129,8 @@ public virtual List GenerateCommandLineArguments () if (AllowUnsafeBlocks) cmd.Add ("/unsafe"); - cmd.Add ($"/ns:{Namespace}"); + if (!string.IsNullOrEmpty (Namespace)) + cmd.Add ($"/ns:{Namespace}"); if (NoNFloatUsing) cmd.Add ("/no-nfloat-using:true"); @@ -179,10 +185,10 @@ public virtual List GenerateCommandLineArguments () } } - if (GeneratedSourcesDir is not null) + if (!string.IsNullOrEmpty (GeneratedSourcesDir)) cmd.Add ($"/tmpdir:{Path.GetFullPath (GeneratedSourcesDir)}"); - if (GeneratedSourcesFileList is not null) + if (!string.IsNullOrEmpty (GeneratedSourcesFileList)) cmd.Add ($"/sourceonly:{Path.GetFullPath (GeneratedSourcesFileList)}"); cmd.Add ($"/target-framework={TargetFrameworkMoniker}"); @@ -208,7 +214,7 @@ public virtual List GenerateCommandLineArguments () // { "solutiondir", proj.ParentSolution is not null ? proj.ParentSolution.BaseDirectory : proj.BaseDirectory }, }; // OutputAssembly is optional so it can be null - if (target is not null) { + if (!string.IsNullOrEmpty (target)) { var d = Path.GetDirectoryName (target); var n = Path.GetFileName (target); customTags.Add ("targetpath", Path.Combine (d, n)); @@ -272,10 +278,12 @@ public override bool Execute () return false; } - var executablePath = PathUtils.ConvertToMacPath (BGenToolPath); - var executableExe = PathUtils.ConvertToMacPath (BGenToolExe); - var executable = Path.Combine (executablePath, executableExe); + var bgenPath = PathUtils.ConvertToMacPath (BGenToolPath); + var bgenExe = PathUtils.ConvertToMacPath (BGenToolExe); + var bgen = Path.Combine (bgenPath, bgenExe); var args = GenerateCommandLineArguments (); + args.Insert (0, bgen); + var executable = this.GetDotNetPath (); if (Log.HasLoggedErrors) return false; diff --git a/tests/msbuild/Xamarin.MacDev.Tasks.Tests/TaskTests/BGenTaskTest.cs b/tests/msbuild/Xamarin.MacDev.Tasks.Tests/TaskTests/BGenTaskTest.cs index dc5e3dc3c026..2ad583c129b5 100644 --- a/tests/msbuild/Xamarin.MacDev.Tasks.Tests/TaskTests/BGenTaskTest.cs +++ b/tests/msbuild/Xamarin.MacDev.Tasks.Tests/TaskTests/BGenTaskTest.cs @@ -39,7 +39,7 @@ public void Bug656983 () task.ExtraArgs = "-invalid"; var args = task.GenerateCommandLineArguments (); args.AddRange (File.ReadAllLines (task.ResponseFilePath)); - Assert.That (args.Contains (" -invalid"), "incorrect ExtraArg not causing an exception"); + Assert.That (args.Contains ("-invalid"), "incorrect ExtraArg not causing an exception"); } } } From beeb56b235d4913157a17363eabc29d3621a69f2 Mon Sep 17 00:00:00 2001 From: Rolf Bjarne Kvinge Date: Wed, 20 Nov 2024 09:07:13 +0100 Subject: [PATCH 4/4] Quote --- msbuild/Xamarin.MacDev.Tasks/CommandLineArgumentBuilder.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/msbuild/Xamarin.MacDev.Tasks/CommandLineArgumentBuilder.cs b/msbuild/Xamarin.MacDev.Tasks/CommandLineArgumentBuilder.cs index a903ce2d9d46..1b76873c86d7 100644 --- a/msbuild/Xamarin.MacDev.Tasks/CommandLineArgumentBuilder.cs +++ b/msbuild/Xamarin.MacDev.Tasks/CommandLineArgumentBuilder.cs @@ -1,5 +1,6 @@ using System; using System.IO; +using System.Linq; using System.Text; using System.Collections.Generic; @@ -239,7 +240,7 @@ public static List CreateResponseFile (Task task, string responseFilePat File.Delete (responseFile); try { - File.WriteAllLines (responseFile, responseArguments); + File.WriteAllLines (responseFile, StringUtils.Quote (responseArguments.ToArray ())); } catch (Exception ex) { task.Log.LogWarning ("Failed to create response file '{0}': {1}", responseFile, ex); }