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

[linker/trimmer] Add opt-in support for not marking NSObjects in user assemblies. Fixes #15723. #17949

Merged
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions dotnet/targets/Xamarin.Shared.Sdk.targets
Original file line number Diff line number Diff line change
Expand Up @@ -507,6 +507,7 @@
SdkDevPath=$(_SdkDevPath)
SdkRootDirectory=$(_XamarinSdkRootDirectory)
SdkVersion=$(_SdkVersion)
SkipMarkingNSObjectsInUserAssemblies=$(_SkipMarkingNSObjectsInUserAssemblies)
TargetArchitectures=$(TargetArchitectures)
TargetFramework=$(_ComputedTargetFrameworkMoniker)
UseLlvm=$(MtouchUseLlvm)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ public abstract class ParseBundlerArgumentsTaskBase : XamarinTask {
[Output]
public string NoStrip { get; set; }

[Output]
public string SkipMarkingNSObjectsInUserAssemblies { get; set; }

[Output]
public int Verbosity { get; set; }

Expand Down Expand Up @@ -165,6 +168,9 @@ public override bool Execute ()
item.SetMetadata ("Value", value.Substring (colon + 1));
envVariables.Add (item);
break;
case "skip-marking-nsobjects-in-user-assemblies":
SkipMarkingNSObjectsInUserAssemblies = ParseBool (value) ? "false" : "true";
Copy link
Contributor

Choose a reason for hiding this comment

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

This looks weird. If the extra arg skip-marking-nsobjects-in-user-assemblies is true, we set SkipMarkingNSObjectsInUserAssemblies to false?

Copy link
Member Author

Choose a reason for hiding this comment

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

@emaf Good catch! I've now fixed this.

break;
case "xml":
if (xml == null)
xml = new List<string> ();
Expand Down
1 change: 1 addition & 0 deletions msbuild/Xamarin.Shared/Xamarin.Shared.targets
Original file line number Diff line number Diff line change
Expand Up @@ -1851,6 +1851,7 @@ Copyright (C) 2018 Microsoft. All rights reserved.
<Output TaskParameter="PackageDebugSymbols" PropertyName="PackageDebugSymbols" />
<Output TaskParameter="Registrar" PropertyName="Registrar" />
<Output TaskParameter="RequirePInvokeWrappers" PropertyName="_RequirePInvokeWrappers" />
<Output TaskParameter="SkipMarkingNSObjectsInUserAssemblies" PropertyName="_SkipMarkingNSObjectsInUserAssemblies" />
<Output TaskParameter="Verbosity" PropertyName="_BundlerVerbosity" />
<Output TaskParameter="XmlDefinitions" ItemName="_BundlerXmlDefinitions" />
<Output TaskParameter="NoStrip" PropertyName="EnableAssemblyILStripping" />
Expand Down
2 changes: 2 additions & 0 deletions tools/common/Application.cs
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,8 @@ public bool IsDefaultMarshalManagedExceptionMode {
public bool EnableMarkerOnlyBitCode { get { return BitCodeMode == BitCodeMode.MarkerOnly; } }
public bool EnableBitCode { get { return BitCodeMode != BitCodeMode.None; } }

public bool SkipMarkingNSObjectsInUserAssemblies { get; set; }

// assembly_build_targets describes what kind of native code each assembly should be compiled into for mobile targets (iOS, tvOS, watchOS).
// An assembly can be compiled into: static object (.o), dynamic library (.dylib) or a framework (.framework).
// In the case of a framework, each framework may contain the native code for multiple assemblies.
Expand Down
3 changes: 3 additions & 0 deletions tools/common/Driver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,9 @@ static bool ParseOptions (Application app, Mono.Options.OptionSet options, strin
options.Add ("require-pinvoke-wrappers:", v => {
app.RequiresPInvokeWrappers = ParseBool (v, "--require-pinvoke-wrappers");
});
options.Add ("skip-marking-nsobjects-in-user-assemblies:", "Don't mark NSObject (and any subclass of NSObject) in user assemblies in the linker. This may break your app, use at own risk.", v => {
app.SkipMarkingNSObjectsInUserAssemblies = ParseBool (v, "--skip-marking-nsobjects-in-user-assemblies");
});


// Keep the ResponseFileSource option at the end.
Expand Down
5 changes: 5 additions & 0 deletions tools/dotnet-linker/LinkerConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,11 @@ public static LinkerConfiguration GetInstance (LinkContext context, bool createI
throw new InvalidOperationException ($"Unable to parse the {key} value: {value} in {linker_file}");
SdkVersion = sdk_version;
break;
case "SkipMarkingNSObjectsInUserAssemblies":
if (!TryParseOptionalBoolean (value, out var skip_marking_nsobjects_in_user_assemblies))
throw new InvalidOperationException ($"Unable to parse the {key} value: {value} in {linker_file}");
Application.SkipMarkingNSObjectsInUserAssemblies = skip_marking_nsobjects_in_user_assemblies;
break;
case "TargetArchitectures":
if (!Enum.TryParse<Abi> (value, out var arch))
throw new InvalidOperationException ($"Unknown target architectures: {value} in {linker_file}");
Expand Down
5 changes: 4 additions & 1 deletion tools/linker/MarkNSObjects.cs
Original file line number Diff line number Diff line change
Expand Up @@ -143,8 +143,11 @@ static bool IsProductMethod (MethodDefinition method)
return (method.DeclaringType.Module.Assembly.Name.Name == ProductAssembly);
}

static bool IsProductType (TypeDefinition type)
bool IsProductType (TypeDefinition type)
{
if (LinkContext.App.SkipMarkingNSObjectsInUserAssemblies)
return true;

var name = type.Module.Assembly.Name.Name;
switch (name) {
case "Xamarin.Forms.Platform.iOS":
Expand Down