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

Feature request: conditionally merge duplicated members #215

Closed
wmjordan opened this issue Jan 2, 2018 · 19 comments
Closed

Feature request: conditionally merge duplicated members #215

wmjordan opened this issue Jan 2, 2018 · 19 comments

Comments

@wmjordan
Copy link
Contributor

wmjordan commented Jan 2, 2018

Is it possible to remove some members during the repack?
For instance, I'd like to remove some members marked with a specific attribute, or given full names.

@gluck
Copy link
Owner

gluck commented Jan 2, 2018

No this feature isn't available, not sure it makes sense for the tool, though there's already options for flagging types as intern, what's your use case for removing these members ?

@wmjordan
Copy link
Contributor Author

wmjordan commented Jan 2, 2018

I am attempting to merge two assemblies compiled from different projects.
One from C#, the other one from a dynamically generated assembly, or IL.
The projects contain dummy types to keep them from cross-referencing each other.
If the remove members function is ready, it is possible to merge members from those two assemblies into a single type.

@deniszykov
Copy link
Contributor

I think it is easier for you to write custom merge tool with Mono.Cecil

@gluck
Copy link
Owner

gluck commented Jan 2, 2018

You mean you are using allowdup/union to merge these types with same name into one ?
And getting rejects because they have members with same name/signature ?

@gluck
Copy link
Owner

gluck commented Jan 2, 2018

(actually ILRepack ignores duplicated members, so if your "true" members are in the same assembly, providing it first in the command line should work)

@wmjordan
Copy link
Contributor Author

wmjordan commented Jan 3, 2018

@gluck Thanks for replying.
You are right, I am using /allowdup to merge types with same name into one.
Rather than relying on the order of assemblies, is it possible to specify
[System.Runtime.CompilerServices.MethodImpl( System.Runtime.CompilerServices.MethodImplOptions.ForwardRef)]
on the method to tell ILRepack that the annotated method is the "fake" one?

@wmjordan
Copy link
Contributor Author

wmjordan commented Jan 3, 2018

so if your "true" members are in the same assembly, providing it first in the command line should work

When I was trying to use this approach, I met with a problem about the AssemblyVersion.

My primary assembly named A needed to be merged with another assembly named B.
In A, there were several methods which should be overridden by their counterparts in B.

If I specify B first, followed by A, then A and B got merged together, however, the AssemblyVersion was the one in B, no longer the on in the primary assembly, A, even if I have specified /attr:A.dll in the command line.
If I specify A first, then members in B could not be merged into A.

@wmjordan
Copy link
Contributor Author

wmjordan commented Jan 3, 2018

Well, I solved the above problem by specifying /ver:$(AssemblyVersion) in the csproj file which called ILRepack.

@gluck
Copy link
Owner

gluck commented Jan 3, 2018

lots of topics there ! Here's my take:

  • /attr should ignore what you have in any assembly, so the custom attributes (incl. version) are likely correct, but the IL assembly version hasn't been corrected from the attributes (bug I'd say, as they should stay in sync)
  • ForwardRef support sounds interesting, so that if there's a duplicate member, the one w/o the attribute will take precedence 👍

@wmjordan wmjordan changed the title Feature request: Remove members Feature request: conditionally merge duplicated members Jan 4, 2018
@wmjordan
Copy link
Contributor Author

wmjordan commented Feb 4, 2018

The problem of ForwardRef is that it can be applied to methods only.

Maybe it is possible to take advantage of the [ObfuscationAttribute] to instruct ILRepack to merge duplicated members, for that attribute can be applied to all members, and if possible, we can even centralize the merging of duplicate members in the Property\AssemblyInfo.cs file.
After repacking, the relative [Obfuscation] attributes can be stripped out.

@gluck
Copy link
Owner

gluck commented Feb 5, 2018

I'd rather support an attribute by name only (like mono-linker [Preserve] attribute) rather than abuse the obfuscation one (unrelated IMO).
E.g. we could support [ForwardRef] by name, if the official one works for you, use it, if it doesn't, create your own.

Or we could support another by-name-attributes, like RepackDrop that would ignore the member during repack.

@wmjordan
Copy link
Contributor Author

wmjordan commented Feb 6, 2018

OK. I am looking forward to it.

@wmjordan
Copy link
Contributor Author

wmjordan commented Mar 1, 2018

How are you doing @gluck ? Any progress on this?

@gluck
Copy link
Owner

gluck commented Mar 1, 2018

Hello, sorry if I let you think otherwise, but I have no plan to implement this myself.
I'd welcome a PR along the lines of what we discussed though if you need that feature !

Let me know.

@wmjordan
Copy link
Contributor Author

wmjordan commented Mar 1, 2018

I found the "RepackDrop" annotation support was quite easy to implement. I took several minutes and I got it up and running.
Since there was only one file which needed to be changed. I uploaded the source code here.
Please take it if it is appropriated.
RepackImporter.zip

@wmjordan
Copy link
Contributor Author

wmjordan commented Mar 1, 2018

Simply add a method and use it in the Import method, things are done.

private bool CanInclude<TMember> (TMember member)
	where TMember : ICustomAttributeProvider, IMemberDefinition {
	// skip members marked with a custom attribute named "RepackDrop"
	var marked = member.HasCustomAttributes
		&& member.CustomAttributes.FirstOrDefault(attr => attr.AttributeType.Name == "RepackDropAttribute") != null;
	if (marked) {
		_logger.Log("Repack dropped " + member.FullName);
	}
	return marked == false;
}

@wmjordan
Copy link
Contributor Author

wmjordan commented Mar 1, 2018

Usage:

  1. Manually define an attribute named RepackDropAttribute, and use it on the member we need to exclude from repacking.
  2. Run ILRepack as usual.

@wmjordan
Copy link
Contributor Author

wmjordan commented Mar 2, 2018

The PR added option support for the RepackDrop attribute name (by default, RepackDropAttribute)

gluck added a commit that referenced this issue Mar 12, 2018
@wmjordan
Copy link
Contributor Author

Implemented via #221

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants