Skip to content

[msbuild] Simplify resolving xcframeworks - #10376

Merged
spouliot merged 2 commits into
dotnet:mainfrom
spouliot:xcframework-update
Jan 12, 2021
Merged

[msbuild] Simplify resolving xcframeworks#10376
spouliot merged 2 commits into
dotnet:mainfrom
spouliot:xcframework-update

Conversation

@spouliot

@spouliot spouliot commented Jan 11, 2021

Copy link
Copy Markdown
Contributor

TD&LR: This PR simplifies how we refer to user frameworks and fixes both
warnings and non-optimal (app) output.

Much longer story:

Additional testing on macOS showed some build-time warnings and an
extra (dupe) file.

Logs shows that we referred to the xcframework several times, where once
should have been enough.

/native-reference:/Users/poupou/git/spouliot/xcframework/Universal.xcframework
/native-reference:/Users/poupou/git/spouliot/xcframework/Universal.xcframework/macos-arm64_x86_64/Universal.framework
/native-reference:/Users/poupou/git/spouliot/xcframework/Universal.xcframework/macos-arm64_x86_64/Universal.framework/Universal

The first /native-reference line produced a warning like:

MMP warning MM2006: Native library 'Universal.xcframework' was referenced but could not be found.

which makes sense as the tools (both mmp and mtouch) are not, by
design, aware of (unresolved) xcframeworks.

Removing {NativeReference} from Xamarin.Mac.Common.targets (and
Xamarin.iOS.Common.targets) as it has already been processed by
_ExpandNativeReferences solves this.

The other part of the issue (next two lines) is because msbuild does
not track changes to directories like it does for files - and the
workaround (in _ExpandNativeReferences) had to be copied in other
places (both XI and XM _CompileToNative) and that was not enough (and
would eventually need to be duplicated again and again).

This could lead to duplicate entries (i msbuild logs) like

NativeReferences
../../Universal.xcframework/macos-arm64_x86_64/Universal.framework
../../Universal.xcframework/macos-arm64_x86_64/Universal.framework/Univeral

which maps to our extra entries.

In order to simplify things we make the _ExpandNativeReferences resolve
the full path to the library name (not the .framework directory) which
simplifies both _CompileToNative and ensure a single way (at least for
msbuild) to provide this data to the tools (mmp and mtouch).

Using a file, instead of a directory, is also more consistent for the
existing -framework option, e.g. we provide the names like:

--framework=CoreLocation
--framework=ModelIO

So adding a full path that include the name is more appropriate, e.g.

--framework=/Users/poupou/git/master/xamarin-macios/tests/xharness/tmp-test-dir/xcframework-test760/bin/AnyCPU/Debug/bindings-xcframework-test.resources/XTest.xcframework/ios-i386_x86_64-simulator/XTest.framework/XTest

Finally for macOS applications it turns out we were embedding yet another
copy of the framework's library inside the MonoBundle, which is clearly
wrong, because of the last entry.

$ l bin/Release/xcf-mac.app/Contents/MonoBundle/Universal
-rwxr-xr-x  1 poupou  staff  167152  2 Dec 16:16 bin/Release/xcf-mac.app/Contents/MonoBundle/Universal

The tool now checks if a provided library is inside a framework (or not)
which is a good validation to have anyway when it gets called directly,
i.e. not thru msbuild.

TD&LR: This PR simplifies how we refer to user frameworks and fixes both
warnings and non-optimal (app) output.

Much longer story:

Additional testing on macOS showed some build-time warnings and an
[extra (dupe) file](spouliot/xcframework@a20f8ab#diff-54fd7d9cd5deae57f30195be0a43133eace03c1132401741a317e0ae8d5e13fdR34).

Logs shows that we referred to the xcframework several times, where once
should have been enough.

```
/native-reference:/Users/poupou/git/spouliot/xcframework/Universal.xcframework
/native-reference:/Users/poupou/git/spouliot/xcframework/Universal.xcframework/macos-arm64_x86_64/Universal.framework
/native-reference:/Users/poupou/git/spouliot/xcframework/Universal.xcframework/macos-arm64_x86_64/Universal.framework/Universal
```

The first `/native-reference` line produced a warning like:

```
MMP warning MM2006: Native library 'Universal.xcframework' was referenced but could not be found.
```

which makes sense as the tools (both `mmp` and `mtouch`) are not, by
design, aware of (unresolved) xcframeworks.

Removing `{NativeReference}` from `Xamarin.Mac.Common.targets` (and
`Xamarin.iOS.Common.targets`) as it has already been processed by
`_ExpandNativeReferences` solves this.

The other part of the issue (next two lines) is because `msbuild` does
not track changes to directories like it does for files - and the
workaround (in `_ExpandNativeReferences`) had to be copied in other
places (both XI and XM `_CompileToNative`) and that was not enough (and
would eventually need to be duplicated again and again).

This could lead to duplicate entries (i msbuild logs) like

```
NativeReferences
../../Universal.xcframework/macos-arm64_x86_64/Universal.framework
../../Universal.xcframework/macos-arm64_x86_64/Universal.framework/Univeral
```
which maps to our extra entries.

In order to simplify things we make the `_ExpandNativeReferences` resolve
the full path to the library name (not the `.framework` directory) which
simplifies both `_CompileToNative` and ensure a single way (at least for
`msbuild`) to provide this data to the tools (`mmp` and `mtouch`).

Using a file, instead of a directory, is also more consistent for the
existing `-framework` option, e.g. we provide the names like:

```
--framework=CoreLocation
--framework=ModelIO
```

So adding a full path that include the name is more appropriate, e.g.

``` --framework=/Users/poupou/git/master/xamarin-macios/tests/xharness/tmp-test-dir/xcframework-test760/bin/AnyCPU/Debug/bindings-xcframework-test.resources/XTest.xcframework/ios-i386_x86_64-simulator/XTest.framework/XTest
```

Finally for macOS applications it turns out we were embedding yet another
copy of the framework's library inside the `MonoBundle`, which is clearly
wrong, because of the last entry.

```
$ l bin/Release/xcf-mac.app/Contents/MonoBundle/Universal
-rwxr-xr-x  1 poupou  staff  167152  2 Dec 16:16 bin/Release/xcf-mac.app/Contents/MonoBundle/Universal
```

The tool now checks if a provided library is inside a framework (or not)
which is a good validation to have anyway when it gets called directly,
i.e. not thru `msbuild`.
@spouliot spouliot added the enhancement The issue or pull request is an enhancement label Jan 11, 2021
Outputs="$(_AppBundlePath)Contents\MacOS\$(_AppBundleName);$(DeviceSpecificOutputPath)bundler.stamp">

<ItemGroup>
<_FrameworkNativeReference Include="@(_FrameworkNativeReference -> '%(Identity)/%(Filename)')" Condition="'%(Extension)' == '.framework' Or '%(Extension)' == '.xcframework'" />

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Should the identical code in Xamarin.iOS.Common.targets be removed too?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

definitively!

@vs-mobiletools-engineering-service2

Copy link
Copy Markdown
Collaborator

❌ Device tests failed on Build ❌

Device tests failed on Build.

Test results

2 tests failed, 39 tests passed.

Failed tests

  • [xUnit] Mono Mac OS X BCL tests group 4/Mac Modern/Debug: Failed (No test log file was produced)
  • MTouch tests/NUnit: Failed (Execution failed with exit code 7)

Pipeline on Agent XAMBOT-1106'

@mandel-macaque

Copy link
Copy Markdown
Contributor

Test failures are unrelated: https://github.com/xamarin/maccore/issues/2357

@vs-mobiletools-engineering-service2

Copy link
Copy Markdown
Collaborator

❌ Device tests failed on Build ❌

Device tests failed on Build.

Test results

7 tests failed, 34 tests passed.

Failed tests

  • introspection/Mac Modern/Debug: BuildFailure
  • framework-test/Mac Modern/Debug: BuildFailure
  • xcframework-test/Mac Modern/Debug: BuildFailure
  • [xUnit] Mono Mac OS X BCL tests group 4/Mac Modern/Debug: Failed (No test log file was produced)
  • mmptest/macOS/Debug: Failed (Execution failed with exit code 1)
  • MSBuild tests/Integration: Failed (Execution failed with exit code 45)
  • MTouch tests/NUnit: Failed (Execution failed with exit code 14)

Pipeline on Agent XAMBOT-1099'

@monojenkins

Copy link
Copy Markdown
Contributor

Build failure
Provisioning succeeded
Build succeeded
API Diff (from stable)
🔥 Failed to compare API and create generator diff 🔥
    ** Error: Working directory isn't clean:
    HEAD detached at 549e558
    Untracked files:
    (use "git add ..." to include in what will be committed)
    tools/dotnet-linker/packages/
    
    nothing added to commit but untracked files present (use "git add" to track)
    Search for Comparing API & creating generator diff in the log to view the complete log.
Test run succeeded

@spouliot

Copy link
Copy Markdown
Contributor Author

Original failures (first build) are due to

Additional failures (2nd build) are due to

error : No valid macOS code signing keys found in keychain. You need to request a codesigning certificate from https://developer.apple.com. 

@spouliot
spouliot merged commit 734b8a7 into dotnet:main Jan 12, 2021
@spouliot
spouliot deleted the xcframework-update branch January 12, 2021 21:02
spouliot added a commit to spouliot/xamarin-macios that referenced this pull request Feb 4, 2021
TD&LR: This PR simplifies how we refer to user frameworks and fixes both
warnings and non-optimal (app) output.

Much longer story:

Additional testing on macOS showed some build-time warnings and an
[extra (dupe) file](spouliot/xcframework@a20f8ab#diff-54fd7d9cd5deae57f30195be0a43133eace03c1132401741a317e0ae8d5e13fdR34).

Logs shows that we referred to the xcframework several times, where once
should have been enough.

```
/native-reference:/Users/poupou/git/spouliot/xcframework/Universal.xcframework
/native-reference:/Users/poupou/git/spouliot/xcframework/Universal.xcframework/macos-arm64_x86_64/Universal.framework
/native-reference:/Users/poupou/git/spouliot/xcframework/Universal.xcframework/macos-arm64_x86_64/Universal.framework/Universal
```

The first `/native-reference` line produced a warning like:

```
MMP warning MM2006: Native library 'Universal.xcframework' was referenced but could not be found.
```

which makes sense as the tools (both `mmp` and `mtouch`) are not, by
design, aware of (unresolved) xcframeworks.

Removing `{NativeReference}` from `Xamarin.Mac.Common.targets` (and
`Xamarin.iOS.Common.targets`) as it has already been processed by
`_ExpandNativeReferences` solves this.

The other part of the issue (next two lines) is because `msbuild` does
not track changes to directories like it does for files - and the
workaround (in `_ExpandNativeReferences`) had to be copied in other
places (both XI and XM `_CompileToNative`) and that was not enough (and
would eventually need to be duplicated again and again).

This could lead to duplicate entries (i msbuild logs) like

```
NativeReferences
../../Universal.xcframework/macos-arm64_x86_64/Universal.framework
../../Universal.xcframework/macos-arm64_x86_64/Universal.framework/Univeral
```
which maps to our extra entries.

In order to simplify things we make the `_ExpandNativeReferences` resolve
the full path to the library name (not the `.framework` directory) which
simplifies both `_CompileToNative` and ensure a single way (at least for
`msbuild`) to provide this data to the tools (`mmp` and `mtouch`).

Using a file, instead of a directory, is also more consistent for the
existing `-framework` option, e.g. we provide the names like:

```
--framework=CoreLocation
--framework=ModelIO
```

So adding a full path that include the name is more appropriate, e.g.

``` --framework=/Users/poupou/git/master/xamarin-macios/tests/xharness/tmp-test-dir/xcframework-test760/bin/AnyCPU/Debug/bindings-xcframework-test.resources/XTest.xcframework/ios-i386_x86_64-simulator/XTest.framework/XTest
```

Finally for macOS applications it turns out we were embedding yet another
copy of the framework's library inside the `MonoBundle`, which is clearly
wrong, because of the last entry.

```
$ l bin/Release/xcf-mac.app/Contents/MonoBundle/Universal
-rwxr-xr-x  1 poupou  staff  167152  2 Dec 16:16 bin/Release/xcf-mac.app/Contents/MonoBundle/Universal
```

The tool now checks if a provided library is inside a framework (or not)
which is a good validation to have anyway when it gets called directly,
i.e. not thru `msbuild`.
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.

8 participants