我刚刚使用继承的属性表为我们现有的 C++ 代码设置了一个异地构建系统,该特性似乎是 Visual C++ 产品特有的。异地构建需要更改许多项目设置,而继承的属性表允许我通过将属性表附加到项目来更改所有必要的设置。我正在将我们的团队从用于 UI 的 C++/MFC 迁移到 C# 和 WPF,但我需要提供相同的异地构建功能,希望具有相同的便利性。我似乎找不到使用 C# 项目执行此操作的方法 - 我首先查看是否可以引用 MsBuild 目标文件,但找不到执行此操作的方法。我知道我可以将 MsBuild 用于整个事情,但这似乎比必要的复杂。
3 回答
我不太确定什么是“异地”构建系统,但如果您只需要将编译文件(或其他资源)复制到其他目录的能力,您可以通过绑定到 MSBuild 构建目标来实现.
在我们的项目中,我们将编译后的 dll 移动到 lib 文件夹中,并在构建完成后将文件放入适当的位置。为此,我们创建了一个自定义构建 .target 文件,该文件创建了Target
's、Property
's 和ItemGroup
's,然后我们使用它们来填充我们的外部输出文件夹。
我们的自定义目标文件看起来有点像这样:
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectName>TheProject</ProjectName>
<ProjectDepthPath>..\..\</ProjectDepthPath>
<ProjectsLibFolder>..\..\lib\</ProjectsLibFolder>
<LibFolder>$(ProjectsLibFolder)$(ProjectName)\$(Configuration)\</LibFolder>
</PropertyGroup>
<Target Name="DeleteLibFiles">
<Delete Files="@(LibFiles-> '$(ProjectDepthPath)$(LibFolder)%(filename)%(extension)')" TreatErrorsAsWarnings="true" />
</Target>
<Target Name="CopyLibFiles">
<Copy SourceFiles="@(LibFiles)" DestinationFolder="$(ProjectDepthPath)$(LibFolder)" SkipUnchangedFiles="True" />
</Target>
<ItemGroup>
<LibFiles Include=" ">
<Visible>false</Visible>
</LibFiles>
</ItemGroup>
</Project>
Visual Studio 中的 .csproj 文件随后与此自定义目标文件集成:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="3.5" ... >
...
<Import Project="..\..\..\..\build\OurBuildTargets.targets" />
<ItemGroup>
<LibFiles Include="$(OutputPath)$(AssemblyName).dll">
<Visible>false</Visible>
</LibFiles>
</ItemGroup>
<Target Name="BeforeClean" DependsOnTargets="DeleteLibFiles" />
<Target Name="AfterBuild" DependsOnTargets="CopyLibFiles" />
</Project>
简而言之,此构建脚本首先告诉 MSBuild 加载我们的自定义构建脚本,然后将编译后的文件添加到LibFiles
ItemGroup,最后将我们的自定义构建目标绑定DeleteLibFiles
到CopyLibFiles
构建过程中。我们为解决方案中的每个项目进行了设置,因此只有更新的文件会被删除/复制,并且每个项目都负责自己的文件(dll、图像等)。
我希望这有帮助。如果我误解了异地构建系统的含义,我深表歉意,这对您来说完全没用!
有没有办法可以为目录定义宏并在输出路径中使用它
您是否查看过项目的构建前和构建后事件?
实际上,预构建和构建后事件似乎只是添加批处理文件类型命令的地方。不幸的是,这无助于我为我们的项目设置标准构建目录。对于像 C#、IMO 这样的现代语言,让这些事件创建批处理文件似乎是 1980 年的方法。
在深入挖掘和试验之后,我发现您可以将 <Import> 指令添加到您的 .csproj 文件中。当您执行此操作时,IDE 会弹出一个警告对话框,提示您的项目中有一个不安全的入口点 - 但您可以忽略它,并且您可以通过编辑注册表项使其根本不出现,显然。因此,这将给我一种方法来获取包含我需要的目录路径的变量到 .csproj 文件中。
现在让输出路径引用它 - 不幸的是,当您将“$(MySpecialPath)/Debug”之类的字符串添加到输出路径字段并保存项目时,$ 和 () 字符将转换为十六进制,并且您的文件获取放在名为“$(MySpecialPath)”的目录下的 Debug 目录中。啊。如果您在文本编辑器中编辑 .csproj 文件,则可以正确设置它,并且只要 <Import> 标记出现在包含输出路径的 <PropertyGroup> 之前,它似乎就可以工作。
所以我认为我的解决方案是在标准位置创建一个标准 OurTeam.targets MsBuild 文件,添加一个用于更改注册表的安装程序,这样它就不会标记警告,然后创建 <Import> 这个文件的自定义项目模板,并将输出路径设置为使用 OurTeam.targets 文件中定义的属性。可悲的是,与 C++ 中的属性表继承机制相比,这需要更多的工作和不太优雅的解决方案。