Custom IL Rewriting plugin for msbuild

二次信任 提交于 2019-12-12 14:10:44

问题


I want to create a custom msbuild task that applies IL rwriting to my output assembly.

At the moment i am already using PostSharp and now try to extend the rewriting capabilities.

For some special cases i use Mono.Cecil to rewrite some proxy types into the assembly. This works fine right now.

But now i want to intercept the build process between the actual build and the PostSharp transformation in order to generate aspects on my proxy types that get implemented by PostSharp in the next step.

I already contacted the PostSharp support and got a direction:

PostSharp injects itselft into a build process by overriding the MSBuild property CompileDependsOn (more info on MSDN https://msdn.microsoft.com/en-us/library/ms366724.aspx).

You can execute your own tasks after compilation but before PostSharp by overriding the CompileDependsOn property before the PostSharp.targets import statement in your *.csproj file.PostSharp injects itselft into a build process by overriding the MSBuild property CompileDependsOn (more info on MSDN https://msdn.microsoft.com/en-us/library/ms366724.aspx).

You can execute your own tasks after compilation but before PostSharp by overriding the CompileDependsOn property before the PostSharp.targets import statement in your *.csproj file.

I already found the location in the PostSharp.targets file that contains the overrides:

<PropertyGroup Condition="'$(InjectPostSharp30)' != 'False'">
<PostSharp30DependsOn>
  $(PostSharp30DependsOn);
  PostSharp30ExtractBinaries;
  BeforePostSharpTransformation; // I added this one
  </PostSharp30DependsOn>
<PostSharpInspectDependsOn>
  $(PostSharpInspectDependsOn);
  PostSharp30InspectConstants;
  PostSharp30InspectReferences;
  PostSharp30DisablePreviousVersions
</PostSharpInspectDependsOn>
<CoreCompileDependsOn>
  PostSharpInspect;
  PostSharp30DefineConstant;
  $(CoreCompileDependsOn)
</CoreCompileDependsOn>
<CompileDependsOn>
  PostSharp30TimestampBeforeCompile;
  $(CompileDependsOn);
  PostSharp30TimestampAfterCompile;
  PostSharp30
</CompileDependsOn>
<BuildDependsOn>
  $(BuildDependsOn);
  PostSharp30Verify
</BuildDependsOn>
<CleanDependsOn>
  $(CleanDependsOn);
  PostSharp30Clean
</CleanDependsOn>

I also got my msbuild task running. It is getting invoked and also gets provided with the right path for the assembly but when the build actually gets invoked it is invoked too early and can not find the assembly because the build is not finished yet.

If i attach to the post build event PostSharp did already run but i need it to run after my custom transformations in order to implement my types using aspects.

My test task is implemented like this:

    public class RewritingTask : Task
{
    [Required]
    public string OutputAssembly { get; set; }

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

    public override bool Execute()
    {
        string preTransformDir = Path.GetDirectoryName(OutputAssembly) + "\\PreTransform\\";

        if (!Directory.Exists(preTransformDir))
        {
            Directory.CreateDirectory(preTransformDir);
        }

        if (!File.Exists(OutputAssembly))
        {
            return false;
        }

        File.Copy(OutputAssembly, preTransformDir + Path.GetFileName(OutputAssembly), true);

        return true;
    }
}

The error is a FileNotFoundException because the output assembly is missing.

Basically i need to know how i can overwrite the CompileDependsOn property using msbuild like the postsharp support described. I am not too familiar with msbuild-scripts, sorry


回答1:


The right place for the transformation target is

<CompileDependsOn>
    PostSharp30TimestampBeforeCompile;
    $(CompileDependsOn);
    HERE;
    PostSharp30TimestampAfterCompile;
    PostSharp30
</CompileDependsOn>

My solution completely decouples PostSharp from our entry point:

<!-- If PostSharp is imported, override with combined targets -->
<PropertyGroup Condition="'$(InjectPostSharp30)' == 'True'">
    <CompileDependsOn>
        PostSharp30TimestampBeforeCompile;
        $(CompileDependsOn);
        ApplyILRewriting;
        PostSharp30TimestampAfterCompile;
        PostSharp30
    </CompileDependsOn>
    <BuildDependsOn>
        $(BuildDependsOn);
        PostSharp30Verify;
        AfterILRewritingPostBuild
    </BuildDependsOn>
</PropertyGroup>

<!-- If PostSharp is not imported, override with necessary targets -->
<PropertyGroup Condition="'$(InjectPostSharp30)' != 'True'">
    <CompileDependsOn>
        $(CompileDependsOn);
        HERE
    </CompileDependsOn>
    <BuildDependsOn>
        $(BuildDependsOn);
        AfterILRewritingPostBuild
    </BuildDependsOn>
</PropertyGroup>

So my script can works for PostSharp and non PostSharp projects.



来源:https://stackoverflow.com/questions/37570219/custom-il-rewriting-plugin-for-msbuild

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!