From 4f78bb61fff66d77925b5ade02c30c6750702e33 Mon Sep 17 00:00:00 2001 From: Peter Collins Date: Wed, 15 May 2024 12:44:13 -0700 Subject: [PATCH] [macios] Add `@(XcodeProjectReference)` Introduces a new `@(XcodeProjectReference)` item to help simplify the content that needs to be added to the binding .csproj file. This item will translate relevant metadata to the `@(NativeReference)` item that is automatically added to the project after the xcode project is built. Build task wrappers for `xcodebuild` and `sharpie` have been added to improve msbuild output and error logging when a tool invocation fails. --- .gitignore | 1 + eng/Common.macios.targets | 204 ++++++++++-------- .../MSBuildExtensions.cs | 16 ++ .../Tasks/BindingToolTask.cs | 3 +- .../Tasks/Gradle.cs | 7 +- .../Tasks/Sharpie.cs | 48 +++++ .../Tasks/XcodeBuild.cs | 43 ++++ .../Facebook.MaciOS.Binding.csproj | 37 ++-- .../Firebase.MaciOS.Binding.csproj | 40 ++-- .../GoogleCast.Binding.csproj | 64 +++--- 10 files changed, 301 insertions(+), 162 deletions(-) create mode 100644 eng/src/Microsoft.Maui.BindingExtensions.Build.Tasks/Tasks/Sharpie.cs create mode 100644 eng/src/Microsoft.Maui.BindingExtensions.Build.Tasks/Tasks/XcodeBuild.cs diff --git a/.gitignore b/.gitignore index 3fb3d9b..42e658b 100644 --- a/.gitignore +++ b/.gitignore @@ -403,6 +403,7 @@ FodyWeavers.xsd xcuserdata/ +build/ .build/ *.xcframework Pods/ diff --git a/eng/Common.macios.targets b/eng/Common.macios.targets index 559b305..b4a3aec 100644 --- a/eng/Common.macios.targets +++ b/eng/Common.macios.targets @@ -1,94 +1,118 @@ - - Release - - .build - $(XcodeDefaultBuildDir) - - <_XcodeProjectFullPath>$([System.IO.Path]::GetFullPath($(XcodeProject))) - - $([System.IO.Path]::GetFilenameWithoutExtension($(XcodeProject))) - - $([System.IO.Path]::GetDirectoryName($(_XcodeProjectFullPath))) - $([System.IO.Path]::Combine($(XcodeProjectDir), $(XcodeBuildDirName))) - - True - - True - True - True - - <_XcodeBuildDirFullPath>$([System.IO.Path]::GetFullPath($(XcodeBuildDir))) - <_XcodeProjectDirFullPath>$([System.IO.Path]::GetFullPath($(XcodeProjectDir))) - - <_XcArchiveiOSFullPath>$([System.IO.Path]::Combine($(_XcodeBuildDirFullPath), $(XcodeScheme)-ios.xcarchive)) - <_XcArchiveiOSSimulatorFullPath>$([System.IO.Path]::Combine($(_XcodeBuildDirFullPath), $(XcodeScheme)-iossimulator.xcarchive)) - <_XcArchiveMacCatalystFullPath>$([System.IO.Path]::Combine($(_XcodeBuildDirFullPath), $(XcodeScheme)-maccatalyst.xcarchive)) - <_XcArchiveExtraArgs>ENABLE_BITCODE=NO SKIP_INSTALL=NO SWIFT_INSTALL_OBJC_HEADER=YES BUILD_LIBRARY_FOR_DISTRIBUTION=YES OTHER_LDFLAGS='-ObjC' OTHER_SWIFT_FLAGS='-no-verify-emitted-module-interface' OBJC_CFLAGS='-fno-objc-msgsend-selector-stubs -ObjC' - - <_XcFrameworkFullPath>$([System.IO.Path]::Combine($(_XcodeBuildDirFullPath), $(XcodeScheme).xcframework)) - - - - <_XcodeProjectInputs Include="$(_XcodeProjectDirFullPath)/**/*.swift" Exclude="$(_XcodeBuildDirFullPath)/**" /> - <_XcodeProjectInputs Include="$(_XcodeProjectDirFullPath)/**/*.h" Exclude="$(_XcodeBuildDirFullPath)/**" /> - <_XcodeProjectInputs Include="$(_XcodeProjectFullPath)/*.pbxproj" /> - <_XcodeProjectInputs Include="$(_XcodeProjectFullPath)/*.xcworkspace" /> - - - - <_GenerateBindingsDependsOn> - BuildXCFramework; - ObjSharpieBind; - $(_GenerateBindingsDependsOn); - - - - - - - - - - - - <_CreateXcFxArgs Include="-create-xcframework" /> - <_CreateXcFxArgs Condition=" '$(XcodeBuildiOS)' == 'True' " Include="-archive $(_XcArchiveiOSFullPath) -framework $(XcodeScheme).framework" /> - <_CreateXcFxArgs Condition=" '$(XcodeBuildiOSSimulator)' == 'True' " Include="-archive $(_XcArchiveiOSSimulatorFullPath) -framework $(XcodeScheme).framework" /> - <_CreateXcFxArgs Condition=" '$(XcodeBuildMacCatalyst)' == 'True' " Include="-archive $(_XcArchiveMacCatalystFullPath) -framework $(XcodeScheme).framework" /> - <_CreateXcFxArgs Include="-output $(_XcFrameworkFullPath)" /> - - - - - - - - True - $(_XcodeBuildDirFullPath)/Binding - $(_XcArchiveiOSFullPath)/Products/Library/Frameworks/$(XcodeScheme).framework/Headers/$(XcodeScheme)-Swift.h - - - - - <_ObjSharpieInputs Include="$(ObjSharpieSourceHeader)" /> - - - - - <_ObjSharpieArgs Include="--output=$(ObjSharpieBindOutputDir)" /> - <_ObjSharpieArgs Include="--namespace=$(ObjSharpieBindNamespace)" /> - <_ObjSharpieArgs Include="--framework $(_XcArchiveiOSFullPath)/Products/Library/Frameworks/$(XcodeScheme).framework" /> - - - + + + + + + + Release + true + true + true + false + + <_XcArchiveExtraArgs>$(_XcArchiveExtraArgs) ENABLE_BITCODE=NO SKIP_INSTALL=NO SWIFT_INSTALL_OBJC_HEADER=YES BUILD_LIBRARY_FOR_DISTRIBUTION=YES + <_XcArchiveExtraArgs>$(_XcArchiveExtraArgs) OTHER_LDFLAGS="-ObjC" OTHER_SWIFT_FLAGS="-no-verify-emitted-module-interface" OBJC_CFLAGS="-fno-objc-msgsend-selector-stubs -ObjC" + + + + <_GenerateBindingsDependsOn> + _BuildXcodeProjects; + _SharpieBindXcodeProjects; + $(_GenerateBindingsDependsOn); + + + + + + Framework + true + + + + + + + <_XcbInputs Include="@(XcodeProjectReference->'%(RootDir)%(Directory)**/*.swift')" /> + <_XcbInputs Include="@(XcodeProjectReference->'%(RootDir)%(Directory)**/*.h')" /> + <_XcbInputs Include="@(XcodeProjectReference->'%(RootDir)%(Directory)**/*.pbxproj')" /> + <_XcbInputs Include="@(XcodeProjectReference->'%(RootDir)%(Directory)**/*.xcworkspace')"/> + <_XcbInputs Remove="@(XcodeProjectReference->'%(RootDir)%(Directory)%(SchemeName)/build/**/*')" /> + + + + + + + + + + + + + + + + + + <_CreateXcFxArgs Include="-create-xcframework" /> + <_CreateXcFxArgs Condition=" '$(XcodeBuildiOS)' == 'true' " Include="@(XcodeProjectReference->'-archive %(RootDir)%(Directory)%(SchemeName)/build/%(SchemeName)-ios.xcarchive')" /> + <_CreateXcFxArgs Condition=" '$(XcodeBuildiOS)' == 'true' " Include="-framework %(XcodeProjectReference.SchemeName).framework" /> + <_CreateXcFxArgs Condition=" '$(XcodeBuildiOSSimulator)' == 'true' " Include="@(XcodeProjectReference->'-archive %(RootDir)%(Directory)%(SchemeName)/build/%(SchemeName)-iossimulator.xcarchive')" /> + <_CreateXcFxArgs Condition=" '$(XcodeBuildiOSSimulator)' == 'true' " Include="-framework %(XcodeProjectReference.SchemeName).framework" /> + <_CreateXcFxArgs Condition=" '$(XcodeBuildMacCatalyst)' == 'true' " Include="@(XcodeProjectReference->'-archive %(RootDir)%(Directory)%(SchemeName)/build/%(SchemeName)-maccatalyst.xcarchive')" /> + <_CreateXcFxArgs Condition=" '$(XcodeBuildMacCatalyst)' == 'true' " Include="-framework %(XcodeProjectReference.SchemeName).framework" /> + <_CreateXcFxArgs Include="@(XcodeProjectReference->'-output %(RootDir)%(Directory)%(SchemeName)/build/%(SchemeName).xcframework')" /> + + + + + + + + + + %(XcodeProjectReference.Kind) + %(XcodeProjectReference.SmartLink) + + + + + + + + + + + <_SharpieInputs Include="@(XcodeProjectReference->'%(RootDir)%(Directory)%(SchemeName)/build/%(SchemeName)-ios.xcarchive/Products/Library/Frameworks/%(SchemeName).framework')" /> + + + + + + + <_ObjSharpieArgs Include="@(XcodeProjectReference->'--output=%(RootDir)%(Directory)%(SchemeName)/build/sharpie')" /> + <_ObjSharpieArgs Include="--namespace=%(XcodeProjectReference.SharpieNamespace)" /> + <_ObjSharpieArgs Include="@(XcodeProjectReference->'--framework %(RootDir)%(Directory)%(SchemeName)/build/%(SchemeName)-ios.xcarchive/Products/Library/Frameworks/%(SchemeName).framework')" /> + + + + diff --git a/eng/src/Microsoft.Maui.BindingExtensions.Build.Tasks/MSBuildExtensions.cs b/eng/src/Microsoft.Maui.BindingExtensions.Build.Tasks/MSBuildExtensions.cs index d6e481b..9827379 100644 --- a/eng/src/Microsoft.Maui.BindingExtensions.Build.Tasks/MSBuildExtensions.cs +++ b/eng/src/Microsoft.Maui.BindingExtensions.Build.Tasks/MSBuildExtensions.cs @@ -18,5 +18,21 @@ public static void LogCodedError(this TaskLoggingHelper log, string code, string message: message, messageArgs: messageArgs); } + + public static void LogCodedWarning(this TaskLoggingHelper log, string code, string message, params object [] messageArgs) + { + log.LogWarning( + subcategory: string.Empty, + warningCode: code, + helpKeyword: string.Empty, + file: string.Empty, + lineNumber: 0, + columnNumber: 0, + endLineNumber: 0, + endColumnNumber: 0, + message: message, + messageArgs: messageArgs); + } + } } diff --git a/eng/src/Microsoft.Maui.BindingExtensions.Build.Tasks/Tasks/BindingToolTask.cs b/eng/src/Microsoft.Maui.BindingExtensions.Build.Tasks/Tasks/BindingToolTask.cs index fbf2e23..94a4779 100644 --- a/eng/src/Microsoft.Maui.BindingExtensions.Build.Tasks/Tasks/BindingToolTask.cs +++ b/eng/src/Microsoft.Maui.BindingExtensions.Build.Tasks/Tasks/BindingToolTask.cs @@ -1,4 +1,5 @@ using System.Text; + using Microsoft.Build.Framework; using Microsoft.Build.Utilities; @@ -31,7 +32,7 @@ public override bool Execute() } catch (Exception ex) { - Log.LogCodedError($"{TaskPrefix}0001", ex.ToString()); + Log.LogCodedError($"{TaskPrefix}0100", ex.ToString()); return false; } } diff --git a/eng/src/Microsoft.Maui.BindingExtensions.Build.Tasks/Tasks/Gradle.cs b/eng/src/Microsoft.Maui.BindingExtensions.Build.Tasks/Tasks/Gradle.cs index 88f2a5c..844e4ad 100644 --- a/eng/src/Microsoft.Maui.BindingExtensions.Build.Tasks/Tasks/Gradle.cs +++ b/eng/src/Microsoft.Maui.BindingExtensions.Build.Tasks/Tasks/Gradle.cs @@ -1,13 +1,14 @@ -using Microsoft.Build.Framework; -using System; +using System; using System.Diagnostics; using System.Runtime.InteropServices; +using Microsoft.Build.Framework; + namespace Microsoft.Maui.BindingExtensions.Build.Tasks { public class Gradle : BindingToolTask { - public override string TaskPrefix => "GDL"; + public override string TaskPrefix => "GRDL"; protected override string ToolName => RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "gradlew.bat" : "gradlew"; diff --git a/eng/src/Microsoft.Maui.BindingExtensions.Build.Tasks/Tasks/Sharpie.cs b/eng/src/Microsoft.Maui.BindingExtensions.Build.Tasks/Tasks/Sharpie.cs new file mode 100644 index 0000000..df7ba7f --- /dev/null +++ b/eng/src/Microsoft.Maui.BindingExtensions.Build.Tasks/Tasks/Sharpie.cs @@ -0,0 +1,48 @@ +using System; +using System.Runtime.InteropServices; + +using Microsoft.Build.Framework; + +namespace Microsoft.Maui.BindingExtensions.Build.Tasks +{ + public class Sharpie : BindingToolTask + { + public override string TaskPrefix => "SHRP"; + + protected override string ToolName => "sharpie"; + + + public string Arguments { get; set; } = string.Empty; + + + public Sharpie() + { + } + + protected override string GenerateFullPathToTool() + { + return Path.Combine("/usr", "local", "bin", ToolExe); + } + + protected override string GenerateCommandLineCommands() => Arguments; + + public override bool RunTask() + { + if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) + { + if (!File.Exists (GenerateFullPathToTool ())) { + Log.LogCodedWarning($"{TaskPrefix}1000", "Unable to locate `sharpie`, please install https://aka.ms/objective-sharpie."); + return false; + } + + return base.RunTask(); + } + else + { + Log.LogCodedWarning($"{TaskPrefix}1000", "sharpie is not currently supported on this platform. Please build this project on a macOS machine."); + return false; + } + } + + } +} diff --git a/eng/src/Microsoft.Maui.BindingExtensions.Build.Tasks/Tasks/XcodeBuild.cs b/eng/src/Microsoft.Maui.BindingExtensions.Build.Tasks/Tasks/XcodeBuild.cs new file mode 100644 index 0000000..05d3a5c --- /dev/null +++ b/eng/src/Microsoft.Maui.BindingExtensions.Build.Tasks/Tasks/XcodeBuild.cs @@ -0,0 +1,43 @@ +using System; +using System.Runtime.InteropServices; + +using Microsoft.Build.Framework; + +namespace Microsoft.Maui.BindingExtensions.Build.Tasks +{ + public class XcodeBuild : BindingToolTask + { + public override string TaskPrefix => "XCBD"; + + protected override string ToolName => "xcodebuild"; + + + public string Arguments { get; set; } = string.Empty; + + + public XcodeBuild() + { + } + + protected override string GenerateFullPathToTool() + { + return Path.Combine("/usr", "bin", ToolExe); + } + + protected override string GenerateCommandLineCommands() => Arguments; + + public override bool RunTask() + { + if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) + { + return base.RunTask(); + } + else + { + Log.LogCodedWarning($"{TaskPrefix}1000", "xcodebuild is not currently supported on this platform. Please build this project on a macOS machine."); + return false; + } + } + + } +} diff --git a/facebook/macios/Facebook.MaciOS.Binding/Facebook.MaciOS.Binding.csproj b/facebook/macios/Facebook.MaciOS.Binding/Facebook.MaciOS.Binding.csproj index 9badedf..9a6b3c8 100644 --- a/facebook/macios/Facebook.MaciOS.Binding/Facebook.MaciOS.Binding.csproj +++ b/facebook/macios/Facebook.MaciOS.Binding/Facebook.MaciOS.Binding.csproj @@ -1,22 +1,25 @@ - - net8.0-ios - enable - true - true + + net8.0-ios + enable + true + true + - $(MSBuildThisFileDirectory)../native/MauiFacebook.xcodeproj - Facebook - + + + - - - - - Framework - true - - + + + MauiFacebook + Facebook + true + + Framework + true + + - + diff --git a/firebase/macios/Firebase.MaciOS.Binding/Firebase.MaciOS.Binding.csproj b/firebase/macios/Firebase.MaciOS.Binding/Firebase.MaciOS.Binding.csproj index 3dd9f3c..14367b1 100644 --- a/firebase/macios/Firebase.MaciOS.Binding/Firebase.MaciOS.Binding.csproj +++ b/firebase/macios/Firebase.MaciOS.Binding/Firebase.MaciOS.Binding.csproj @@ -1,24 +1,26 @@ - - net8.0-ios;net8.0-maccatalyst - enable - true - true - true + + net8.0-ios;net8.0-maccatalyst + enable + true + true + true + - $(MSBuildThisFileDirectory)../native/MauiFirebase.xcodeproj - true - true - Firebase - + + + - - - - Framework - true - - + + + MauiFirebase + Firebase + true + + Framework + true + + - + diff --git a/googlecast/macios/GoogleCast.Binding/GoogleCast.Binding.csproj b/googlecast/macios/GoogleCast.Binding/GoogleCast.Binding.csproj index c0ab311..fabfa1d 100644 --- a/googlecast/macios/GoogleCast.Binding/GoogleCast.Binding.csproj +++ b/googlecast/macios/GoogleCast.Binding/GoogleCast.Binding.csproj @@ -1,41 +1,41 @@ - - net8.0-ios - enable - true - true - + + net8.0-ios + enable + true + true + + False + $(BuildXcodeProjectsDependsOnTargets);NativeDependencies + - - - - - Framework - True - - + + + + + + MauiGoogleCast + GoogleCast + true + + Framework + true + + + + - False - $(MSBuildThisFileDirectory)../native/MauiGoogleCast.xcodeproj - true - False - GoogleCast - $(BuildXCFrameworkDependsOnTargets);NativeDependencies + 4.8.0 + https://dl.google.com/dl/chromecast/sdk/ios/GoogleCastSDK-ios-$(GoogleCastiOSSdkVersion)_dynamic_xcframework.zip - - - 4.8.0 - https://dl.google.com/dl/chromecast/sdk/ios/GoogleCastSDK-ios-$(GoogleCastiOSSdkVersion)_dynamic_xcframework.zip - - - - - + + + - - + + - +