Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[msbuild] Add support for .xcframework #10046

Merged
merged 24 commits into from Nov 30, 2020
Merged

Conversation

spouliot
Copy link
Contributor

@spouliot spouliot commented Nov 4, 2020

This is done early so we can resolve the inner framework, inside the
xcframework, and let the existing framework support do most of the
work.

The resolving code has unit tests. Custom projects for "NoEmbedding"
exists for all supported platforms and executed by xharness.

A sample xcframework with tests projects is also available here.

Work in progress

  • add XM support and tests
  • add/confirm correct .dSYM support

This is done early so we can resolve the inner framework, inside the
xcframework, and let the existing framework support do most of the
work.

Xamarin.Mac builds are disabled. Support for XM will come in a later
pull-request, possibly on `xcode12.2`. There's more code for handling
_normal_ frameworks inside `mtouch` and XI msbuild than in XM so it
might require more work.

The resolving code has unit tests. A sample `xcframework` with
tests projects is also available [here](https://github.com/spouliot/xcframework).

**Work in progress** More, integrated project-level, tests are coming
@spouliot spouliot added enhancement The issue or pull request is an enhancement do-not-merge Do not merge this pull request labels Nov 4, 2020
@monojenkins
Copy link
Collaborator

Build failure
Provisioning succeeded
Build succeeded
API Diff (from stable)
API Diff (from PR only) (no change)
Generator Diff (no change)
🔥 Test run failed 🔥

Test results

1 tests failed, 66 tests passed.

Failed tests

  • MSBuild tests/iOS (tasks): Failed (Execution failed with exit code 11)

msbuild/Xamarin.iOS.Tasks.Core/Tasks/MTouchTaskBase.cs Outdated Show resolved Hide resolved

// existing (as of this commit) IDE versions will add a `.xcframework` directorty as a `Static` native reference
if ((kind == NativeReferenceKind.Static) && (Path.GetExtension (libName) == ".xcframework"))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thinking about dotnet support, I think it would be easier if the xcframework -> framework resolution was put into a new MSBuild target that ran before the _CompileToNative target, and rewrote the NativeReference item groups to be Frameworks pointing to the right path instead. This new target could then be re-used as-is in the dotnet code.

The end result is that there would be no changes to MTouchTaskBase (nor MmpTaskBase) classes, they would work as-is.

Copy link
Member

@dalexsoto dalexsoto Nov 5, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about dSYM files included in xcframeworks should we take this into account to put them in the output folder? here is an example of the structure of one xcframework with dSYM files included

unknown

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dalexsoto bad example as it is not the normal structure. That's how Xcode do them: https://github.com/spouliot/xcframework#tree

and PSPDFKit tweaks them https://pspdfkit.com/blog/2020/supporting-xcframeworks/#bcsymbolmaps-and-dsyms

The idea is to make them them (xcframework) transparent to the down-level tooling. It might be easy to deal with custom dSYM or not, but it's not a top priority.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting, I guess you need to enable it on demand since Xcode 12.0 release notes state the following

XCFrameworks can now include .dSYM and .bcsymbolmap debugging symbol files in your library bundle with the -debug-symbols flag. Run the command xcodebuild -create-xcframework -help for additional usage information. (64910707)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

interesting, I'll update my repo-sample to add the flag and see how it affects the files inside the xcframework

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added spouliot/xcframework@9fe2052
it does make it clear / well-defined (inside the .plist) where the dSYM can be found

Sebastien Pouliot added 2 commits November 11, 2020 13:17
This is based on Rolf's earlier/partial implementation.
rolfbjarne@xcframework

Thing to note:

Do not rename a framework (like XTest) to use it in an xcframework
(like XCTest). That will fail at codesign but won't give anything
useful. You might think signing the framework (instead of the inner
binary) would solve it. It does, as it codesign, but then the app
crash at startup. At some point you realize some symbols are still
using XTest (not XCTest) and then you can delete several other weird
workarounds (like for `ld`) because all of it was cause by this
never identified rename.
@monojenkins
Copy link
Collaborator

Build success
Provisioning succeeded
Build succeeded
API Diff (from stable)
API Diff (from PR only) (no change)
Generator Diff (no change)
Test run succeeded

@monojenkins
Copy link
Collaborator

Build failure
Provisioning succeeded
Build succeeded
API Diff (from stable)
API Diff (from PR only) (no change)
Generator Diff (no change)
🔥 Test run failed 🔥

Test results

3 tests failed, 71 tests passed.

Failed tests

  • framework-test/iOS Unified 64-bits - simulator/Debug: BuildFailure
  • framework-test/tvOS - simulator/Debug: BuildFailure
  • MSBuild tests/iOS (integration): Failed (Execution failed with exit code 5)

@monojenkins
Copy link
Collaborator

Build failure
Provisioning succeeded
Build succeeded
API Diff (from stable)
API Diff (from PR only) (no change)
Generator Diff (no change)
🔥 Test run failed 🔥

Test results

4 tests failed, 70 tests passed.

Failed tests

  • xcframework-test/iOS Unified 64-bits - simulator/Debug: BuildFailure
  • xcframework-test/tvOS - simulator/Debug: BuildFailure
  • MSBuild tests/iOS (tasks): Failed (Execution failed with exit code 3)
  • MSBuild tests/iOS (integration): Failed (Execution failed with exit code 2)

@monojenkins
Copy link
Collaborator

Build failure
Provisioning succeeded
Build succeeded
API Diff (from stable)
API Diff (from PR only) (no change)
Generator Diff (no change)
🔥 Test run failed 🔥

Test results

3 tests failed, 71 tests passed.

Failed tests

  • xcframework-test/iOS Unified 64-bits - simulator/Debug: BuildFailure
  • xcframework-test/tvOS - simulator/Debug: BuildFailure
  • MSBuild tests/iOS (integration): Failed (Execution failed with exit code 2)

@monojenkins
Copy link
Collaborator

Build failure
Provisioning succeeded
Build succeeded
API Diff (from stable)
API Diff (from PR only) (no change)
Generator Diff (no change)
🔥 Test run failed 🔥

Test results

3 tests failed, 88 tests passed.

Failed tests

  • xammac tests/Mac Modern/Release: Failed (Tests run: 2175 Passed: 2041 Inconclusive: 7 Failed: 3 Ignored: 131)
  • xcframework-test/watchOS 32-bits - simulator/Debug: BuildFailure
  • MSBuild tests/iOS (integration): Failed (Execution failed with exit code 2)

@monojenkins
Copy link
Collaborator

Build failure
Provisioning succeeded
Build succeeded
API Diff (from stable)
API Diff (from PR only) (no change)
Generator Diff (no change)
🔥 Test run failed 🔥

Test results

26 tests failed, 65 tests passed.

Failed tests

  • xammac tests/Mac Modern/Debug: Failed (Tests run: 2175 Passed: 2049 Inconclusive: 11 Failed: 2 Ignored: 124)
  • xammac tests/Mac Modern/Release: Failed (Tests run: 2175 Passed: 2049 Inconclusive: 11 Failed: 2 Ignored: 124)
  • xammac tests/Mac Modern/Release (all optimizations): Failed (Tests run: 1830 Passed: 1742 Inconclusive: 7 Failed: 2 Ignored: 86)
  • monotouch-test/iOS Unified 64-bits - simulator/Debug: BuildFailure
  • monotouch-test/iOS Unified 64-bits - simulator/Debug [dotnet]: BuildFailure
  • monotouch-test/iOS Unified 64-bits - simulator/Debug (LinkSdk): BuildFailure
  • monotouch-test/iOS Unified 64-bits - simulator/Debug (static registrar): BuildFailure
  • monotouch-test/iOS Unified 64-bits - simulator/Release (all optimizations): BuildFailure
  • monotouch-test/iOS Unified 64-bits - simulator/Debug (LinkSdk) [dotnet]: BuildFailure
  • monotouch-test/iOS Unified 64-bits - simulator/Debug (static registrar) [dotnet]: BuildFailure
  • monotouch-test/iOS Unified 64-bits - simulator/Release (all optimizations) [dotnet]: BuildFailure
  • monotouch-test/tvOS - simulator/Debug: BuildFailure
  • monotouch-test/tvOS - simulator/Debug (LinkSdk): BuildFailure
  • monotouch-test/tvOS - simulator/Debug (static registrar): BuildFailure
  • monotouch-test/tvOS - simulator/Release (all optimizations): BuildFailure
  • monotouch-test/watchOS 32-bits - simulator/Debug: BuildFailure
  • monotouch-test/watchOS 32-bits - simulator/Debug (LinkSdk): BuildFailure
  • monotouch-test/watchOS 32-bits - simulator/Debug (static registrar): BuildFailure
  • monotouch-test/watchOS 32-bits - simulator/Release (all optimizations): BuildFailure
  • framework-test/iOS Unified 64-bits - simulator/Debug: BuildFailure
  • framework-test/tvOS - simulator/Debug: BuildFailure
  • framework-test/watchOS 32-bits - simulator/Debug: BuildFailure
  • xcframework-test/iOS Unified 64-bits - simulator/Debug: BuildFailure
  • xcframework-test/tvOS - simulator/Debug: BuildFailure
  • xcframework-test/watchOS 32-bits - simulator/Debug: BuildFailure
  • MSBuild tests/iOS (integration): Failed (Execution failed with exit code 16)

@spouliot
Copy link
Contributor Author

build

@monojenkins
Copy link
Collaborator

Build failure
Provisioning succeeded
Build succeeded
API Diff (from stable)
API Diff (from PR only) (no change)
Generator Diff (no change)
🔥 Test run failed 🔥

Test results

1 tests failed, 90 tests passed.

Failed tests

  • MSBuild tests/iOS (integration): Failed (Execution failed with exit code 2)

@monojenkins
Copy link
Collaborator

Build failure
Provisioning succeeded
Build succeeded
API Diff (from stable)
API Diff (from PR only) (no change)
Generator Diff (no change)
🔥 Test run failed 🔥

Test results

1 tests failed, 90 tests passed.

Failed tests

  • MSBuild tests/iOS (integration): Failed (Execution failed with exit code 1)

@monojenkins
Copy link
Collaborator

Build failure
Provisioning succeeded
Build succeeded
API Diff (from stable)
API Diff (from PR only) (no change)
Generator Diff (no change)
🔥 Test run failed 🔥

Test results

1 tests failed, 90 tests passed.

Failed tests

  • MSBuild tests/iOS (integration): Failed (Execution failed with exit code 1)

@monojenkins
Copy link
Collaborator

Build failure
Provisioning succeeded
Build succeeded
API Diff (from stable)
API Diff (from PR only) (no change)
Generator Diff (no change)
🔥 Test run failed 🔥

Test results

2 tests failed, 90 tests passed.

Failed tests

  • framework-test/tvOS - simulator/Debug: BuildFailure (Harness exception for 'framework-test': System.IO.DirectoryNotFoundException: Could not find a part of the path "/Users/builder/jenkins/workspace/xamarin-macios-pr-builder/tests/bindings-framework-test/generated-projects/tvos/bindings-framework-test-tvos.csproj".
    at System.IO.FileStream..ctor (System.String path, System.IO.FileMode mode, System.IO.FileAccess access, System.IO.FileShare share, System.Int32 bufferSize, System.Boolean anonymous, System.IO.FileOptions options) [0x0015e] in /Users/builder/jenkins/workspace/build-package-osx-mono/2020-02/external/bockbuild/builds/mono-x64/mcs/class/corlib/System.IO/FileStream.cs:223
    at System.IO.FileStream..ctor (System.String path, System.IO.FileMode mode, System.IO.FileAccess access, System.IO.FileShare share, System.Int32 bufferSize, System.Boolean isAsync, System.Boolean anonymous) [0x00000] in /Users/builder/jenkins/workspace/build-package-osx-mono/2020-02/external/bockbuild/builds/mono-x64/mcs/class/corlib/System.IO/FileStream.cs:149
    at System.IO.FileStream..ctor (System.String path, System.IO.FileMode mode, System.IO.FileAccess access) [0x00000] in /Users/builder/jenkins/workspace/build-package-osx-mono/2020-02/external/bockbuild/builds/mono-x64/mcs/class/corlib/System.IO/FileStream.cs:86
    at (wrapper remoting-invoke-with-check) System.IO.FileStream..ctor(string,System.IO.FileMode,System.IO.FileAccess)
    at Microsoft.DotNet.XHarness.iOS.Shared.Utilities.PListExtensions.LoadWithoutNetworkAccess (System.Xml.XmlDocument doc, System.String filename) [0x00000] in /_/src/Microsoft.DotNet.XHarness.iOS.Shared/Utilities/PlistExtensions.cs:28
    at Xharness.TestProject.CreateCopyAsync (Microsoft.DotNet.XHarness.Common.Logging.ILog log, Microsoft.DotNet.XHarness.Common.Execution.IProcessManager processManager, Xharness.Jenkins.TestTasks.ITestTask test, System.String rootDirectory, System.Collections.Generic.Dictionary2[TKey,TValue] allProjectReferences) [0x0010c] in /Users/builder/jenkins/workspace/xamarin-macios-pr-builder/tests/xharness/TestProject.cs:97 at Xharness.TestProject.CreateCopyAsync (Microsoft.DotNet.XHarness.Common.Logging.ILog log, Microsoft.DotNet.XHarness.Common.Execution.IProcessManager processManager, Xharness.Jenkins.TestTasks.ITestTask test, System.String rootDirectory, System.Collections.Generic.Dictionary2[TKey,TValue] allProjectReferences) [0x008dd] in /Users/builder/jenkins/workspace/xamarin-macios-pr-builder/tests/xharness/TestProject.cs:189
    at Xharness.Jenkins.TestTasks.TestTasks.RunInternalAsync () [0x00117] in /Users/builder/jenkins/workspace/xamarin-macios-pr-builder/tests/xharness/Jenkins/TestTasks/TestTask.cs:274 )
  • framework-test/watchOS 32-bits - simulator/Debug: BuildFailure (Harness exception for 'framework-test': System.IO.DirectoryNotFoundException: Could not find a part of the path "/Users/builder/jenkins/workspace/xamarin-macios-pr-builder/tests/bindings-framework-test/generated-projects/watchos/bindings-framework-test-watchos.csproj".
    at System.IO.FileStream..ctor (System.String path, System.IO.FileMode mode, System.IO.FileAccess access, System.IO.FileShare share, System.Int32 bufferSize, System.Boolean anonymous, System.IO.FileOptions options) [0x0015e] in /Users/builder/jenkins/workspace/build-package-osx-mono/2020-02/external/bockbuild/builds/mono-x64/mcs/class/corlib/System.IO/FileStream.cs:223
    at System.IO.FileStream..ctor (System.String path, System.IO.FileMode mode, System.IO.FileAccess access, System.IO.FileShare share, System.Int32 bufferSize, System.Boolean isAsync, System.Boolean anonymous) [0x00000] in /Users/builder/jenkins/workspace/build-package-osx-mono/2020-02/external/bockbuild/builds/mono-x64/mcs/class/corlib/System.IO/FileStream.cs:149
    at System.IO.FileStream..ctor (System.String path, System.IO.FileMode mode, System.IO.FileAccess access) [0x00000] in /Users/builder/jenkins/workspace/build-package-osx-mono/2020-02/external/bockbuild/builds/mono-x64/mcs/class/corlib/System.IO/FileStream.cs:86
    at (wrapper remoting-invoke-with-check) System.IO.FileStream..ctor(string,System.IO.FileMode,System.IO.FileAccess)
    at Microsoft.DotNet.XHarness.iOS.Shared.Utilities.PListExtensions.LoadWithoutNetworkAccess (System.Xml.XmlDocument doc, System.String filename) [0x00000] in /_/src/Microsoft.DotNet.XHarness.iOS.Shared/Utilities/PlistExtensions.cs:28
    at Xharness.TestProject.CreateCopyAsync (Microsoft.DotNet.XHarness.Common.Logging.ILog log, Microsoft.DotNet.XHarness.Common.Execution.IProcessManager processManager, Xharness.Jenkins.TestTasks.ITestTask test, System.String rootDirectory, System.Collections.Generic.Dictionary2[TKey,TValue] allProjectReferences) [0x0010c] in /Users/builder/jenkins/workspace/xamarin-macios-pr-builder/tests/xharness/TestProject.cs:97 at Xharness.TestProject.CreateCopyAsync (Microsoft.DotNet.XHarness.Common.Logging.ILog log, Microsoft.DotNet.XHarness.Common.Execution.IProcessManager processManager, Xharness.Jenkins.TestTasks.ITestTask test, System.String rootDirectory, System.Collections.Generic.Dictionary2[TKey,TValue] allProjectReferences) [0x008dd] in /Users/builder/jenkins/workspace/xamarin-macios-pr-builder/tests/xharness/TestProject.cs:189
    at Xharness.TestProject.CreateCopyAsync (Microsoft.DotNet.XHarness.Common.Logging.ILog log, Microsoft.DotNet.XHarness.Common.Execution.IProcessManager processManager, Xharness.Jenkins.TestTasks.ITestTask test, System.String rootDirectory, System.Collections.Generic.Dictionary2[TKey,TValue] allProjectReferences) [0x008dd] in /Users/builder/jenkins/workspace/xamarin-macios-pr-builder/tests/xharness/TestProject.cs:189 at Xharness.TestProject.CreateCopyAsync (Microsoft.DotNet.XHarness.Common.Logging.ILog log, Microsoft.DotNet.XHarness.Common.Execution.IProcessManager processManager, Xharness.Jenkins.TestTasks.ITestTask test, System.String rootDirectory, System.Collections.Generic.Dictionary2[TKey,TValue] allProjectReferences) [0x008dd] in /Users/builder/jenkins/workspace/xamarin-macios-pr-builder/tests/xharness/TestProject.cs:189
    at Xharness.Jenkins.TestTasks.TestTasks.RunInternalAsync () [0x00117] in /Users/builder/jenkins/workspace/xamarin-macios-pr-builder/tests/xharness/Jenkins/TestTasks/TestTask.cs:274 )

@spouliot spouliot marked this pull request as ready for review November 26, 2020 19:29
@spouliot spouliot removed the do-not-merge Do not merge this pull request label Nov 26, 2020
@monojenkins
Copy link
Collaborator

Build failure
Build failed or was aborted

Provisioning succeeded
Build succeeded
API Diff (from stable)
API Diff (from PR only) (no change)
Generator Diff (no change)

@monojenkins
Copy link
Collaborator

Build failure
Provisioning succeeded
Build succeeded
API Diff (from stable)
API Diff (from PR only) (no change)
Generator Diff (no change)
🔥 Test run failed 🔥

Test results

1 tests failed, 92 tests passed.

Failed tests

  • mmptest/macOS/Debug: Failed (Execution failed with exit code 6)

@@ -191,6 +191,39 @@ $(eval $(call FatFrameworkTemplate,ios-fat,iphoneos,iphonesimulator))
$(eval $(call FatFrameworkTemplate,tvos-fat,tvos,tvsimulator))
$(eval $(call FatFrameworkTemplate,watchos-fat,watchos,watchsimulator))

define XCTemplate
.libs/by-platform/$(1)/XTest.framework/XTest: $(foreach arch,$(3),.libs/$(2)/libtest$(4).$(arch).dylib) | .libs/by-platform/$(1)/XTest.framework
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any reason you can't use the existing XTest.frameworks?

$ ls -lad tests/test-libraries/.libs/*/XTest.framework
drwxr-xr-x  4 rolf  wheel  128 Nov 24 08:20 tests/test-libraries/.libs/ios-fat/XTest.framework
drwxr-xr-x  4 rolf  wheel  128 Nov 24 08:20 tests/test-libraries/.libs/iphoneos/XTest.framework
drwxr-xr-x  4 rolf  wheel  128 Nov 24 08:20 tests/test-libraries/.libs/iphonesimulator/XTest.framework
drwxr-xr-x  4 rolf  wheel  128 Nov 24 08:20 tests/test-libraries/.libs/macos/XTest.framework
drwxr-xr-x  4 rolf  wheel  128 Nov 24 08:20 tests/test-libraries/.libs/tvos-fat/XTest.framework
drwxr-xr-x  4 rolf  wheel  128 Nov 24 08:20 tests/test-libraries/.libs/tvos/XTest.framework
drwxr-xr-x  4 rolf  wheel  128 Nov 24 08:20 tests/test-libraries/.libs/tvsimulator/XTest.framework
drwxr-xr-x  4 rolf  wheel  128 Nov 24 08:20 tests/test-libraries/.libs/watchos-fat/XTest.framework
drwxr-xr-x  4 rolf  wheel  128 Nov 24 08:20 tests/test-libraries/.libs/watchos/XTest.framework
drwxr-xr-x  4 rolf  wheel  128 Nov 24 08:20 tests/test-libraries/.libs/watchsimulator/XTest.framework

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That should work, it came from rolfbjarne@xcframework#diff-c0db661233e8bd837a40c8de3bdbb802b63d5edb88fa262a82d9799ee39e50ebR155 , but then I renamed it XTest since XCTest is the Apple framework for Xcode unit tests and something (linking or codesigning) did not appreciate the renaming.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh I see what happened here. My point was that this code is more complicated than it needs to be; in any case I fixed it and pushed the fix.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks, even simpler of the changes I made locally

@@ -133,6 +133,7 @@ Copyright (C) 2020 Microsoft. All rights reserved.
<!-- The default architecture for Xamarin.Mac is x86_64 -->
<TargetArchitectures Condition="'$(TargetArchitectures)' == '' And '$(_PlatformName)' == 'macOS'">x86_64</TargetArchitectures>
<!-- There should always be an MtouchArch value in newer projects, but for older projects default to old values -->
<TargetArchitectures Condition="'$(TargetArchitectures)' == '' And '$(_PlatformName)' == 'tvOS' And '$(ComputedPlatform)' == 'iPhoneSimulator'">x86_64</TargetArchitectures>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This shouldn't be necessary, all tvOS projects should have an MtouchArch value.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll try again but I'm pretty sure it did not work. However it might just be the xharness created/cloned projects that are missing the value.

@monojenkins
Copy link
Collaborator

Build failure
Build failed or was aborted

Provisioning succeeded
🔥 Build failed 🔥

@spouliot
Copy link
Contributor Author

make[1]: *** [downloads/dotnet-sdk-6.0.100-alpha.1.20562.2-osx-x64.tar.gz] Error 56

@monojenkins
Copy link
Collaborator

Build success
Provisioning succeeded
Build succeeded
API Diff (from stable)
API Diff (from PR only) (no change)
Generator Diff (no change)
Test run succeeded

@spouliot spouliot merged commit 3bd14c3 into xamarin:main Nov 30, 2020
@spouliot spouliot deleted the xcframework branch November 30, 2020 18:44
@nesevis
Copy link

nesevis commented Mar 1, 2021

There may have been some sort of regression here, as even @spouliot's test project referenced in the PR fails to build with the newest version of Xamarin.

@Atamanam
Copy link

This is done early so we can resolve the inner framework, inside the xcframework, and let the existing framework support do most of the work.

The resolving code has unit tests. Custom projects for "NoEmbedding" exists for all supported platforms and executed by xharness.

A sample xcframework with tests projects is also available here.

Work in progress

  • add XM support and tests
  • add/confirm correct .dSYM support

I hv downloaded the same project but when I tried to run I get this error
Screen Shot 2021-10-26 at 10 18 49 AM

=== Visual Studio Community 2019 for Mac ===
Version 8.10.11 (build 8)
Installation UUID: 33921847-3b42-4e35-8fde-c091797f5fdf
GTK+ 2.24.23 (Raleigh theme)
Xamarin.Mac 6.18.0.23 (d16-6 / 088c736)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement The issue or pull request is an enhancement
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

8 participants