Stop requiring a LinkWith attribute in an assembly in order to keep any Objective-C
types within. There are many ways to include a native library in a build nowadays,
and more and more often they don't need any LinkWith attributes to specify custom
linker behavior (in particular for frameworks, which can typically be included as-is).
The result of not searching such assemblies for Objective-C types would be that the
native linker would strip them away, and that would mean incorrect behavior at runtime.
However, this is a rather invasive change, especially for a minor release, so I'm
adding two things to make it better:
1. An opt-out MSBuild property: `RequireLinkWithAttributeForObjectiveCClassSearch`.
Set to 'true' to opt-out (default is 'false').
2. Improve handling of native symbols with regards to the native linker.
Add a new item group, ReferenceNativeSymbol, that contains native symbols
we handle in some way - either to be ignored or we ask the native linker
to keep it (by passing it as '-u ...' or in a symbol list file).
There are two supported types of metadata:
* SymbolType: either 'ObjectiveCClass', 'Function' or 'Field'. Used to
compute the complete native name of a symbol (for instance, the native
symbol for the Objective-C class "MyClass" is `_OBJC_CLASS_$_MyClass`,
while for a function "MyFunction" it's just `_MyFunction`.
* SymbolMode: either 'Ignore' or 'Default'. "Ignore" means to not pass the given
symbol to the native linker, the default is to do so.
SymbolType is required, while SymbolMode isn't.
Example symbol to keep:
```xml
<ItemGroup>
<ReferenceNativeSymbol Include="MyClass" SymbolType="ObjectiveCClass" />
</ItemGroup>
```
Example symbol to ignore:
```xml
<ItemGroup>
<ReferenceNativeSymbol Include="MyClass" SymbolType="ObjectiveCClass" SymbolMode="Ignore" />
</ItemGroup>
```
Finally use the latter solution to work around an issue that arouse with monotouch-test:
we reference an Objective-C class that doesn't exist in monotouch-test. This worked
because the referencing assembly didn't have a LinkWith attribute (and thus the reference
was ignored), but now that the reference isn't ignored anymore, we need to explicitly
ignore the Objective-C class.
Make the live of the mantianers better by using inheritance for the
build pipelines. This later will make the move to the 1ES template
easier since we refactored the yaml of the pipelines to be as small as
possible.
If the project in question needs a custom NuGet.config, this NuGet.config file
will be in a base directory of where the .NET executable is located. I'm not
certain what the current directory is when executing `dotnet` in this task, so
make it explicit in case it's a different path.
This in particular might affect us for remote tests using .NET previews:
/Users/builder/Library/Caches/Xamarin/mtbs/builds/bindingsframeworktest/8b36a8b30efab69178e7774426ff34b9aded7e20a789eb18f485be2f81a2dccd/obj/Debug/net9.0-ios/ComputeRemoteGeneratorProperties/ComputeRemoteGeneratorProperties.csproj : error NU1102: Unable to find package Microsoft.NET.ILLink.Tasks with version (>= 9.0.0-preview.4.24223.11)
/Users/builder/Library/Caches/Xamarin/mtbs/builds/bindingsframeworktest/8b36a8b30efab69178e7774426ff34b9aded7e20a789eb18f485be2f81a2dccd/obj/Debug/net9.0-ios/ComputeRemoteGeneratorProperties/ComputeRemoteGeneratorProperties.csproj : error NU1102: - Found 21 version(s) in nuget.org [ Nearest version: 9.0.0-preview.3.24172.9 ]
Failed to restore /Users/builder/Library/Caches/Xamarin/mtbs/builds/bindingsframeworktest/8b36a8b30efab69178e7774426ff34b9aded7e20a789eb18f485be2f81a2dccd/obj/Debug/net9.0-ios/ComputeRemoteGeneratorProperties/ComputeRemoteGeneratorProperties.csproj (in 424 ms).
1Es is problematic and has a lot of issues on how we use the matrix
strategies. We have two options, either wait for 1ES to implement the
needed changes or move all the tests out to two different pipelines that
won't need to be 1ES complient.
In the long run moving out of the build piepline is going to give us
more flexibility and will move the project away from depending on a
thridparty to fix the yaml issues.
Even when landing this PR we will not have the tests removed, we will do
that after we have been able to test that things work as expected.
This was complicated a bit because it uses a non-blittable struct we can't
change because it's public API. So introduce an internal temporary blittable
struct.
Contributes towards #15684.
The generator needs a library name for the generated `_domain` field.
Here's an example for the generated `ARErrorCodeExtensions` class ("ARKit" is
the library name):
```cs
[Field ("ARErrorDomain", "ARKit")]
static NSString? _domain;
```
In order to find the library name, the generator would look at the first enum
field with a `[Field]` attribute, and get the `LibraryName` property from that
`[Field]` attribute. Unfortunately error enums don't necessarily have `[Field]`
attributes on their enum fields. This works fine for our own bindings, because
the generator will fall back to the enum's namespace, but for third-party
bindings this would be the result:
> error BI1042: bgen: Missing '[Field (LibraryName=value)]' for ErrorDomainNS.EWithDomain. (e.g."__Internal")
Note that the error message is rather confusing: it's trying to report a
missing `LibraryName` property for a `[Field]` attribute, but there's no `[Field]`
attribute anywhere in the enum in question.
So fix this by:
* Adding the `LibraryName` property on the `[ErrorDomain]` attribute.
* Implement support for looking at this new property in the generator.
* Report a better error if it's not there.
Note that this document is currently not published on our documentation web site.
* Consolidate on a single way to specify message arguments (* instead of {...}).
* Mark messages that will only be show in legacy as such (but keep them)
* Escape star characters in headers.
* Remove mentions of Xamarin.
* Misc other updates.
* Unpack into a per-assembly directory. This way identically named resources from
different assemblies won't overwrite eachother.
* Remove logic to detect overwriting of existing bundle resources, because it's broken.
In particular this piece of code is missing a single character (there should be a `!` in the condition):
```cs
if (string.IsNullOrEmpty (logicalName))
ignore.Add (logicalName);
```
This means we're only ignoring bundle resources without LogicalName, which shouldn't
happen. So just remove the code, since it doesn't do anything useful. A proper fix
for resource collision is in progress and will come in a separate pull request.
* Fix task to work for incremental builds. Previously we'd detect that any resources
had been extracted and not re-extract, but we wouldn't add those extracted resources
to the `_BundleResourceWithLogicalName` item group. The end result would be that
on incremental builds, any bundled resources wouldn't be picked up at all. Typically
this wouldn't be a problem (because the resources would be in the resulting app
bundle), but doing anything out of the ordinary could cause problems. The fix is
to write the unpacked items + their metadata to a file, and load those when we
detect that no re-extraction is necessary (this file also does double duty as a
stamp file in the code).
* Augment `WriteItemsToFile` to make its `Write` method accessible from different classes.
* Improve logging a bit.
By default we limit the error message to 1024 characters in case the native
linker fails. The problem is that the native linker may show a lot of warnings
in the beginning, so if that happened, the error output would show only a list
of warnings and nothing else, which is rather confusing.
So change the output slightly when reporting an error in the native linker:
* Try to filter out warnings.
* Show a max of 25 lines of errors (as opposed to 1024 characters, which tended to be 3-4 lines).
So now instead of this error:
[...]/targets/Xamarin.Shared.Sdk.targets(1623,3): clang++ exited with code 1:
ld: warning: object file ([...]/packs/Microsoft.NETCore.App.Runtime.Mono.maccatalyst-arm64/8.0.3/runtimes/maccatalyst-arm64/native/libSystem.Globalization.Native.a(pal_calendarData.c.o)) was built for newer Mac Catalyst version (14.2) than being linked (14.0)
ld: warning: object file ([...]/packs/Microsoft.NETCore.App.Runtime.Mono.maccatalyst-arm64/8.0.3/runtimes/maccatalyst-arm64/native/libSystem.IO.Compression.Native.a(pal_zlib.c.o)) was built for newer Mac Catalyst version (14.2) than being linked (14.0)
ld: warning: object file ([...]/packs/Microsoft.NETCore.App.Runtime.Mono.maccatalyst-arm64/8.0.3/runtimes/maccatalyst-arm64/native/libSystem.IO.Compression.Native.a(constants.c.o)) was built for newer Mac Catalyst versio
we get:
[...]/targets/Xamarin.Shared.Sdk.targets(1623,3): clang++ exited with code 1:
Undefined symbols for architecture arm64:
"__swift_FORCE_LOAD_$_swiftCompatibility56", referenced from:
__swift_FORCE_LOAD_$_swiftCompatibility56_$_main in libSwiftTest.a(libSwiftTest.arm64.o)
(maybe you meant: __swift_FORCE_LOAD_$_swiftCompatibility56_$_main)
"__swift_FORCE_LOAD_$_swiftCompatibilityConcurrency", referenced from:
__swift_FORCE_LOAD_$_swiftCompatibilityConcurrency_$_main in libSwiftTest.a(libSwiftTest.arm64.o)
(maybe you meant: __swift_FORCE_LOAD_$_swiftCompatibilityConcurrency_$_main)
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
which makes much more sense for an error.
The full linker output is still available in the build log if needed.
Make sure Microsoft.\<platform\>.Sdk.DefaultItems.props is rebuilt if the
current hash changes.
This fixes a local rebuild issue, where we'd rebuild
Microsoft.\<platform\>.Sdk.Versions.props, but not
Microsoft.\<platform\>.Sdk.DefaultItems.props.
A build failure like this would thus result:
tools/msbuild/iOS/Xamarin.Shared.targets(606,3): error : A bundle identifier is required. Either add an 'ApplicationId' property in the project file, or add a 'CFBundleIdentifier' entry in the project's Info.plist file.
because:
* We store the current git hash in both of the files mentioned above.
* We only include default items in a build if the git hashes match.
* Since the files weren't both rebuilt, they'd contain different hashes, and
thus we wouldn't include Info.plist in the build, leading to the build
error.
It's been a few years since we've synchronized the documentation here with the
documentation in the documentation repository
(https://github.com/MicrosoftDocs/xamarin-docs-pr/), so bring all updates done
there over here.
This PR is probably best reviewed commit-by-commit.
The GKHybridStrategist type doesn't exist in iOS. This was probably a type
initially introduced in a beta version, and then removed in a later beta
version, and then we didn't notice.
Stop using the term 'Xamarin' in our error messages.
🙈🙊🙉
Note: this may not be complete, since we compute error messages in numerous
places, and those aren't fixed here (if there are any that still says
'Xamarin' in any way).
---------
Co-authored-by: Michael Cummings (MSFT) <mcumming@microsoft.com>
By adding the 'LinkWithSwiftSystemLibraries=true' property in a project file, we'll
now add the location of Swift's system libraries to the linker arguments.
Fixes https://github.com/xamarin/xamarin-macios/issues/18848.