簡體   English   中英

將網絡模塊鏈接到 msbuild 中的單個文件

[英]Linking netmodules to a single file in msbuild

我想通過 .netmodules 發送從多個 C# 項目生成的單個 .NET 程序集。

我已經嘗試過 ILmerge,但它還有其他問題。 我還查看了 AssemblyResolve 方式,但我並不真正理解它(兩者都在這里介紹: 如何將多個程序集合並為一個? )。

我找到了一個可能的解決方案,它可以通過 .netmodules 很好地完成任務。 沒有外部程序、標准工具,生成的程序集看起來像是來自一個項目(在 ildasm 中)。

這是一個 MWE:Lib.csproj

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <OutputType>Module</OutputType>
    <OutputPath>bin\</OutputPath>
    ...
  </PropertyGroup>
  ...
  <ItemGroup>
    <Compile Include="Lib.cs" />
  </ItemGroup>
  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

exe.csproj

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <OutputType>Module</OutputType>
    <OutputPath>bin\</OutputPath>
    ...
  </PropertyGroup>
  ...
  <ItemGroup>
    <AddModules Include="..\Lib\bin\Lib.netmodule" />
    <Compile Include="Program.cs" />
  </ItemGroup>
  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

兩個項目的輸出類型都設置為模塊。 “Exe”項目通過 AddModules 開關(編譯所需)使用“Lib”網絡模塊。 這會在 Exe 輸出目錄中生成兩個 .netmodules。

在最后一步中,鏈接器用於將所有 .netmodules 鏈接到一個程序集(請參閱https://docs.microsoft.com/en-us/cpp/build/reference/netmodule-files-as-linker-input?view =vs-2017 ):

link Lib.netmodule Exe.netmodule -subsystem:console -out:Exe.exe -ltcg -entry:Exe.Program.Main

問題:這最后一步可以由 MSBuild 執行嗎? CMake 解決方案也將不勝感激,但我無法從 CMake 獲得輸出類型“模塊”。

我會以兩種方式之一來處理它。

解決方案 1:再創建一個項目以將它們全部引入並通過任務綁定它們。

在這個項目的 .csproj 中添加:

<ItemGroup>
    <AddModules Include="Lib.netmodule" />
    <AddModules Include="Exe.netmodule" />
</ItemGroup>

這應該將這些文件作為AddModules參數傳遞給編譯器任務(請參閱Microsoft.CSharp.CurrentVersion.targetsCsc任務的用法,第 250 行)。

這將導致一個程序集。 該程序集將跨越.netmodule文件和編譯第三個項目產生的文件。 這意味着您需要復制/分發所有這些文件才能使該程序集正常工作。

但是你真的是自己做的,你的Exe.csproj已經有AddModule項目,所以我可能遺漏了一些東西。

解決方案 2:讓第二個項目構建程序集。

可以這樣做:

<ItemGroup>
  <ModulesToInclude Include="Lib.netmodule" />
</ItemGroup>

<Target Name="LordOfTheRings">
  <!-- The below uses the netmodule generated from VB code, together with C# files, to generate the assembly -->
  <Csc Sources="@(Compile)"
       References="@(ReferencePath)"
       AddModules="@(ModulesToInclude)"
       TargetType="exe" />
</Target>

<Target Name="AfterBuild" DependsOnTargets="LordOfTheRings">
  <!-- This target is there to ensure that the custom target is executed -->
</Target>

我有一個非常相似的解決方案。 以上更多是關於如何處理它的提示,即復制粘貼解決方案。


免責聲明:我最近才開始嘗試使用 msbuild,如果某些東西不起作用,我很樂意改進這個答案。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM