12

Retargetable assembly references have been introduced for the .NET Compact Framework and are now used to support Portable Class Libraries.

Basically, the compiler emits the following MSIL:

.assembly extern retargetable mscorlib
{
    .publickeytoken = (7C EC 85 D7 BE A7 79 8E )                         
    .ver 2:0:5:0
}

How does the C# compiler understand it has to emit a retargetable reference, and how to force the C# compiler to emit such reference even outside of a portable class library?

Thomas Levesque
  • 286,951
  • 70
  • 623
  • 758
Gael Fraiteur
  • 6,759
  • 2
  • 24
  • 31
  • No hints from MSBuild target files? I wonder what you need to pass to the compiler from the command line. – leppie Jul 10 '12 at 07:49

3 Answers3

3

For the assembly itself, it's an assembly flag, ie [assembly: AssemblyFlags(AssemblyNameFlags.Retargetable)].

Make note that this flag is meaningless outside of platform assemblies - custom assemblies cannot be retargetable.

For references, it's copied as part of the name from the assembly being referenced.

David Kean
  • 5,722
  • 26
  • 26
  • Thank you. This is what I was looking for. I was hoping to get rid of the message `Could not load file or assembly 'PostSharp, Version=3.0.0.0, Culture=neutral, PublicKeyToken=53d2effcf2ee70dc, Retargetable=Yes' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)` when providing (through IHostAssemblyStore) another assembly than what the CLR requested, but I still get the error even with a retargetable reference. Is there any workaround to this? – Gael Fraiteur Jul 11 '12 at 05:55
  • Retargable won't let you key jump a user assembly, like I'm assuming you are attempting. It is entirely for CLR internal purposes. I'm not an expert on the hosting APIs, but I think LoadFile might allow you to do it. – David Kean Jul 11 '12 at 08:15
  • Thanks. I will try another solution: same short name, same strong-name key, but different version number. Normal binding policies should do the trick. – Gael Fraiteur Jul 11 '12 at 12:07
2

Not sure if this will help, but the following file was auto-generated and included in the build.

using System;
using System.Reflection;
[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(
   ".NETPortable,Version=v4.0,Profile=Profile4", 
   FrameworkDisplayName = ".NET Portable Subset")]

This might hint to the compiler to do some magic.

Edit:

I think above makes a library portable. From the command line I can see /nostdlib+ is used, and a portable mscorlib.dll is referenced (which I assume has the same attribute as mentioned above).

"...\Program Files\Reference Assemblies\Microsoft\Framework.NETPortable\v4.0\Profile\Profile4\mscorlib.dll"

leppie
  • 115,091
  • 17
  • 196
  • 297
  • 1
    The `TargetFrameworkAttribute` is also present for Client and Full Framework builds for v4, it isn't around for v3.5. This might be why they added the attribute. As of v4, it also offers a very easy way to determine if an assembly was built for the full framework or the client profile. – Adam Houldsworth Jul 10 '12 at 08:05
  • @AdamHouldsworth: Thanks, and I guess it is obsolete now given the client profile is gone in 4.5? ;p – leppie Jul 10 '12 at 08:07
  • Even in .NET 4 the difference between the client profile and full download was a couple of MB lol, not worth it - probably why they canned it in favour of PCL. – Adam Houldsworth Jul 10 '12 at 08:08
  • Thanks. The reference to the portable mscorlib.dll may be the point. – Gael Fraiteur Jul 10 '12 at 10:58
  • The TargetFrameworkAttribute is actually meaningless when it comes to portability. Old style portable (ie mscorlib-based), it is based on the retargetable reference to mscorlib. New style portable (ie System.Runtime-based) it soley based on the fact that System.Runtime, et al are present at runtime. – David Kean Jul 11 '12 at 04:21
  • 1
    We discuss this at depth over here: http://channel9.msdn.com/Shows/Going+Deep/NET-45-David-Kean-and-Marcea-Trofin-Portable-Libraries. – David Kean Jul 11 '12 at 04:23
  • @DavidKean: Thanks, going to check that out now :) – leppie Jul 11 '12 at 04:51
0

I've noticed by experimenting that the C# compiler would make an reference compiler as retargetable if the referenced assembly is marked as retargetable (a modifier on the .assembly section in MSIL). I did not find how the compiler decides to make the assembly retargetable, yet.

Gael Fraiteur
  • 6,759
  • 2
  • 24
  • 31