我想通过.netmodules运送由多个C#项目生成的单个.NET程序集。
我已经尝试了ILmerge,但是它还有其他问题。我也看过AssemblyResolve的方式,但我不太了解(都在这里介绍:How to merge multiple assemblies into one?)。
我找到了一个可能的解决方案,该解决方案通过.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获取输出类型“ Module”。
答案 0 :(得分:1)
我会以两种方式之一来处理它。
在该项目的.csproj中,应该足以添加:
<ItemGroup>
<AddModules Include="Lib.netmodule" />
<AddModules Include="Exe.netmodule" />
</ItemGroup>
这应将这些文件作为AddModules
参数传递给编译器任务(请参阅Csc
,第250行中Microsoft.CSharp.CurrentVersion.targets
任务的用法)。
这将导致一个组装。该程序集将跨越.netmodule
文件和编译第三个项目所产生的文件。这意味着您需要复制/分发所有组件才能使该组件正常工作。
但是您确实是这样做的,您的AddModule
中已经有Exe.csproj
个项目,因此我可能缺少了一些东西。
可以这样做:
<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,如果某些方法不起作用,我很乐意改进此答案。