Add a target to get native resources from another DLL to ILProj SDK (#23117)
authorEric StJohn <ericstj@microsoft.com>
Mon, 11 Mar 2019 15:53:46 +0000 (08:53 -0700)
committerGitHub <noreply@github.com>
Mon, 11 Mar 2019 15:53:46 +0000 (08:53 -0700)
We use a similar target in CoreFx and I'll need it for another project that is planning on
using this SDK.

When ILResourceReference it will be disassembled to get native resources (EG: fileversion)
to pass to ILasm.

If ILResourceReference is not specified then it does nothing.

src/.nuget/Microsoft.NET.Sdk.IL/targets/Microsoft.NET.Sdk.IL.targets

index 035db37..cea740d 100644 (file)
@@ -29,6 +29,7 @@ Copyright (c) .NET Foundation. All rights reserved.
     <MicrosoftNetCoreIlasmPackageRuntimeId Condition="'$(MicrosoftNetCoreIlasmPackageRuntimeId)' == ''">$(_OSPlatform)-$(_OSArchitecture.ToLower())</MicrosoftNetCoreIlasmPackageRuntimeId>
     <MicrosoftNetCoreIlasmPackageVersion Condition="'$(MicrosoftNetCoreIlasmPackageVersion)' == ''">3.0.0</MicrosoftNetCoreIlasmPackageVersion>
     <MicrosoftNetCoreIlasmPackageName>runtime.$(MicrosoftNetCoreIlasmPackageRuntimeId).microsoft.netcore.ilasm</MicrosoftNetCoreIlasmPackageName>
+    <MicrosoftNetCoreIldasmPackageName>runtime.$(MicrosoftNetCoreIlasmPackageRuntimeId).microsoft.netcore.ildasm</MicrosoftNetCoreIldasmPackageName>
     <MicrosoftNetCoreRuntimeCoreClrPackageName>runtime.$(MicrosoftNetCoreIlasmPackageRuntimeId).microsoft.netcore.runtime.coreclr</MicrosoftNetCoreRuntimeCoreClrPackageName>
     <MicrosoftNetCoreJitPackageName>runtime.$(MicrosoftNetCoreIlasmPackageRuntimeId).microsoft.netcore.jit</MicrosoftNetCoreJitPackageName>
 
@@ -43,6 +44,7 @@ Copyright (c) .NET Foundation. All rights reserved.
 
   <ItemGroup Condition="'$(ILAsmToolPath)' == ''">
     <_IlasmPackageReference Include="$(MicrosoftNetCoreIlasmPackageName)" Version="$(MicrosoftNetCoreIlasmPackageVersion)" />
+    <_IlasmPackageReference Include="$(MicrosoftNetCoreIldasmPackageName)" Version="$(MicrosoftNetCoreIlasmPackageVersion)" />
     <_IlasmPackageReference Include="$(MicrosoftNetCoreRuntimeCoreClrPackageName)" Version="$(MicrosoftNetCoreIlasmPackageVersion)" />
     <_IlasmPackageReference Include="$(MicrosoftNetCoreJitPackageName)" Version="$(MicrosoftNetCoreIlasmPackageVersion)" />
     <PackageReference Include="@(_IlasmPackageReference)" PrivateAssets="all" IsImplicitlyDefined="true" />
@@ -70,6 +72,48 @@ Copyright (c) .NET Foundation. All rights reserved.
     <Copy DestinationFolder="$(_IlasmDir)" SourceFiles="@(_IlasmSourceFiles)" />
   </Target>
 
+  <!-- projects can define an ILResourceReference and we'll decompile it to get native resources -->
+  <Target Name="DisassembleIlasmResourceFile" 
+          BeforeTargets="CoreCompile" 
+          Condition="'$(OS)'=='Windows_NT'"
+          Inputs="@(ILResourceReference)"
+          Outputs="$(IntermediateOutputPath)$(MSBuildProjectName).ref.res.obj">
+    <Error Condition="'@(ILResourceReference->Count())' != '1'" Text="Only one ILResourceReference can be specified" />
+    <PropertyGroup>
+      <_ilResourceReference>%(ILResourceReference.FullPath)</_ilResourceReference>
+      <_IldasmCommand>$(_IlasmDir)ildasm</_IldasmCommand>
+      <_IldasmCommand>$(_IldasmCommand) "$(_ilResourceReference)"</_IldasmCommand>
+      <_IldasmCommand>$(_IldasmCommand) /OUT="$(IntermediateOutputPath)/$(MSBuildProjectName).ref.il"</_IldasmCommand>
+
+      <!-- Try to use cvtres.exe from the framework and fallback to the one that is on the PATH in case we can't find it -->
+      <_CvtResCommand>$(SystemRoot)\Microsoft.NET\Framework\v4.0.30319\cvtres.exe</_CvtResCommand>
+      <_CvtResCommand Condition="!Exists('$(_CvtResCommand)')">cvtres.exe</_CvtResCommand>
+      <_CvtResCommand>$(_CvtResCommand) /MACHINE:x86</_CvtResCommand>
+      <_CvtResCommand>$(_CvtResCommand) /OUT:"$(IntermediateOutputPath)$(MSBuildProjectName).ref.res.obj"</_CvtResCommand>
+      <_CvtResCommand>$(_CvtResCommand) "$(IntermediateOutputPath)$(MSBuildProjectName).ref.res"</_CvtResCommand>
+    </PropertyGroup>
+
+    <ItemGroup>
+      <FileWrites Include="$(IntermediateOutputPath)$(MSBuildProjectName).ref.*" />
+    </ItemGroup>
+
+    <!-- Getting the res file by disassemblying the contract assembly -->
+    <Exec Command="$(_IldasmCommand)" ConsoleToMSBuild="true" StandardOutputImportance="Low">
+      <Output TaskParameter="ExitCode" PropertyName="_IldasmCommandExitCode" />
+    </Exec>
+    <Error Condition="'$(_IldasmCommandExitCode)' != '0'" Text="ILDasm failed while running command: &quot;$(_IldasmCommand)&quot;" />
+
+    <!-- Calling cvtres.exe which should be on the path in order to transform the resource file to an obj -->
+    <Exec Command="$(_CvtResCommand)" ConsoleToMSBuild="true" StandardOutputImportance="Low">
+      <Output TaskParameter="ExitCode" PropertyName="_CvtResCommandExitCode" />
+    </Exec>
+    <Error Condition="'$(_CvtResCommandExitCode)' != '0'" Text="cvtres failed while running command: &quot;$(_CvtResCommand)&quot;" />
+
+    <PropertyGroup>
+      <IlasmResourceFile>$(IntermediateOutputPath)$(MSBuildProjectName).ref.res.obj</IlasmResourceFile>
+    </PropertyGroup>
+  </Target>
+
   <Target Name="CoreCompile"
           Inputs="$(MSBuildAllProjects);
                   @(Compile)"