Generating a Portable Class Library through Reflection.Emit
.net, portable-class-library, reflection.emit
Solution
All right, I'll answer my own question.
I've found no evidence that the `System.Reflection.Emit` APIs can generate assemblies referencing another version of `mscorlib` than the one used used by the current process. Indeed, the APIs that take `System.Type` parameters and other reflection objects presumably add a reference to the result of querying their `Type.Assembly` property, which corresponds to the version of `mscorlib` in use.
However, portable class libraries aren't that different from what `System.Reflection.Emit` generates, so it is possible to patch the assemblies after the fact to "make them portable". Disclaimer: this requires familiarity with the PE file format and might have unforeseen side-effects, but it works for me:
When generating the assembly, use `AssemblyBuilder.SetCustomAttribute` to add this attribute to the assembly:
[System.Runtime.Versioning.TargetFrameworkAttribute(".NETPortable,Version=v4.0,Profile=Profile136", FrameworkDisplayName = ".NET Portable Subset")]
This is where it gets sketchy: after having called `AssemblyBuilder.Save`, open a read/write file stream to the generated assembly, walk through the PE, COFF, COM, CLI and metadata table headers to locate the `AssemblyRef` table row for `mscorlib`. Modify the referenced version of `mscorlib` to `2.0.5.0`, add `0x100` to its flags ("retargetable") and update its public key token blob to `0x7CEC85D7BEA7798E`.
Note that if you use other framework assemblies, you might need to patch their references as well (I haven't tested this). Otherwise, voilà! The assembly is now portable and can be used, for example, in a Windows Phone project.
(... or just use `Mono.Cecil`/`IKVM.Reflection` ...)
Edit: The code I used can be found on github. This is a huge hack so the usual disclaimers apply, use at your own risks.
Problem
I am writing a compiler which generates on-disk .NET assemblies using the `System.Reflection.Emit` API. The compiler itself is built against .NET 4.5, but the generated code only references types from Portable Class Libraries. However, when trying to reference a generated assembly from a Windows Phone 8 project, Visual Studio complains that `A reference to a higher version or incompatible assembly cannot be added to the project`. When opening the generated assembly in a decompiler, I can see that it references two PCLs plus `mscorlib 4.0.0.0`, whereas I understand that PCLs are supposed to reference `mscorlib 2.0.5.0`. Is there a way to make make the `System.Reflection.Emit` API generate PCLs, or is my only option to migrate to `Mono.Cecil`?