我想通过.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>两个项目的输出类型都设置为module。"Exe“项目通过AddModules开关使用"Lib”netmodule (编译时需要)。这会在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获得输出类型“模块”。
发布于 2020-02-28 19:36:49
我会用两种方法中的一种来处理它。
解决方案1:再创建一个项目,将它们全部带到一起,并通过一个任务将它们绑定在一起。
在此项目的.csproj中,添加以下内容就足够了:
<ItemGroup>
<AddModules Include="Lib.netmodule" />
<AddModules Include="Exe.netmodule" />
</ItemGroup>这应该将这些文件作为AddModules参数传递给编译器任务(请参阅Microsoft.CSharp.CurrentVersion.targets中Csc任务的用法,第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,如果有些东西不能工作,我很乐意改进这个答案。
https://stackoverflow.com/questions/55468103
复制相似问题