dotnet / ILMerge

ILMerge is a static linker for .NET Assemblies.
MIT License
1.23k stars 170 forks source link

Support for portable PDBs #11

Closed jnm2 closed 4 years ago

jnm2 commented 7 years ago

With the new csproj format, the default is the superior portable PDB format for all .NET projects, including traditional .NET Framework apps.

ILMerge will crash with

An exception occurred during merging:
ILMerge.Merge:        There were errors reported in ReferencedProject's metadata.
      Array dimensions exceeded supported range.
   at ILMerging.ILMerge.Merge()
   at ILMerging.ILMerge.Main(String[] args)

as demonstrated by this simple test: https://github.com/Microsoft/ILMerge/compare/master...jnm2:portable_pdb_bug

This is somewhat of a integral issue. Where should this capability be on the roadmap?

mike-barnett commented 7 years ago

Hmm, I'm guessing that a different PDB reader would have to be used instead of the one that ILMerge/CCI currently uses, which is some COM object of type CorSymBinder2. Would you know if the new reader can handle both the portable PDB format and the old format? I.e., can we just switch to the new one and use that alone?

jnm2 commented 7 years ago

I wish I knew. Would it be possible for you to cc your colleagues for a recommendation?

pharring commented 7 years ago

@tmat for comment. I don't think there's a "universal" reader. You'd have two code-paths. However, there are tools that can convert between the formats so, in theory, one could build a universal reader.

mike-barnett commented 7 years ago

I'll also take a look at how CCI2 handles this. As a more general comment, I believe the direction ILMerge should take is to remove its dependence on the System.Compiler project (which is CCI1) and instead get rewritten against CCI2. Or we just move. I've already created an initial version . But it doesn't have any of the many options that this version has.

tmat commented 7 years ago

What are the features ILMerge provides compared to Mono ILLinker?

mike-barnett commented 7 years ago

I don't know. I'd love it if there were a better tool so we could put ILMerge down for good. But I've had at least one person say they had tried some other Mono utility (could be that one) and that they preferred to stay with ILMerge. No accounting for taste... Why do you ask? Do you think ILLinker is as good or better than ILMerge? It looks from a cursory glance that they also do tree shaking, which is a nice thing.

erozenfeld commented 7 years ago

ILLink does tree shaking but doesn't merge assemblies (yet) so the two tools do different things at the moment. Another difference is that ILLink uses Cecil, while ILMerge uses CCI for reading and writing assemblies.

tmat commented 7 years ago

@mike-barnett I am asking since the tools are similar and I don't think we need both.

tmat commented 7 years ago

@erozenfeld I'm aware of the difference in implementation (Cecil vs CCI). That's kind of my point. Cecil supports Portable PDBs already.

erozenfeld commented 7 years ago

@tmat There are plans to support assembly merging in ILLink but it's not clear how soon that will happen. /cc @russellhadley @swaroop-sridhar

mike-barnett commented 7 years ago

@tmat Totally agree! Hope my question did not sound confrontational! Getting the merging to work in ILLink sounds like a great thing, but I'm afraid I don't have the time to commit to doing that. But if there are people there that are working on it, then I will definitely drop the idea of moving ILMerge onto CCI2.

tmat commented 7 years ago

@mike-barnett No worries. I just wanted to point out that rather then investing into ILMerge we could spend time on making ILLink better.

jnm2 commented 7 years ago

So in the meantime...

tmat commented 7 years ago

In the meantime you can perhaps use Pdb2Pdb: https://github.com/dotnet/symreader-converter. Package: https://dotnet.myget.org/feed/symreader-converter/package/nuget/Pdb2Pdb

poizan42 commented 5 years ago

I'm surprised no one has mentioned this - an alternative to ILMerge is ILRepack. Once it has been migrated to use Mono.Cecil 0.10 it should work with portable pdbs (see https://github.com/gluck/il-repack/issues/182, https://github.com/gluck/il-repack/issues/230, https://github.com/gluck/il-repack/pull/236)

walterlv commented 5 years ago

@poizan42 I've tested ILRepack from the master branch but the same exception happens.

image

The ILRepack has a 0.10 branch but the critical commits have never been merged to the master. So the main tool still does not support the portable pdbs. But if I checkout to the 0.10 branch, I get another exception of type InvalidOperationException.

poizan42 commented 5 years ago

@walterlv I think we are still waiting for https://github.com/gluck/il-repack/pull/236 to be merged

cathalnoonan commented 5 years ago

Hi guys, I think I found a workaround for this

Try to delete (or rename) the .pdb file in the packages folder of your project

image

After doing this, I had a problem where it couldn't merge "System.Threading.Tasks.Extensions". The error message was "Unresolved assembly reference not allowed"

After some trial and error, I copied the contents of the following directory into the Scriban package directory \packages\System.Threading.Tasks.Extensions.4.5.3\lib\portable-net45+win8+wp8+wpa81

image

The build is succeeding in Visual Studio now

sohailrazarizvi commented 4 years ago

If Portable PDBs are not required then you can select the 'Full' option for 'Debugging information:'

Steps

Compile your project and it will work.

image

BobVul commented 4 years ago

If you don't need debug symbols in your merged output, you can also use /ndebug rather than changing what is generated.

mygithub07 commented 4 years ago

I was getting similar error while using MSBuild.ILMerge.Task and I tried workaround by cathalnoonan above . That error is gone , but now I get same error for a different package. And I already have "Full" selected as mentioned by sohailrazarizvi above . What is the general solution/workaround for this , so I don't get this error for any package? The error is :

Error       ILMerge.Merge:  There were errors reported in TechTalk.SpecFlow's metadata.
    Exception of type 'System.OutOfMemoryException' was thrown. 
MaxXor commented 4 years ago

Any update on this? Or is there a workaround on how to debug merged assemblies?

mike-barnett commented 4 years ago

At this point, ILMerge will never be able to read portable PDBs. It would require moving ILMerge to work on top of CCI2, which I just don't see happening. I don't know what has happened in the meantime with the ILLink project that is mentioned above in this thread. Maybe that is now able to merge assemblies?

jnm2 commented 4 years ago

@mike-barnett Thanks for the answer. Appreciate the work you've put on on ILMerge!