使用C#进行异地构建
我刚刚完成了使用继承的属性表为我们现有的C ++代码设置就地构建系统的功能,该功能似乎特定于Visual C ++产品。异地构建需要更改许多项目设置,而继承的属性表使我仅通过将属性表添加到项目即可更改所有必要的设置。我正在将团队从C ++ / MFC for UI迁移到Cand WPF,但我需要提供相同的异位构建功能,希望具有相同的便利性。我似乎找不到使用Cprojects进行此操作的方法,我首先查看了是否可以引用MsBuild目标文件,但是找不到执行此操作的方法。我知道我可以在整个过程中使用MsBuild,但这似乎比必需的更为复杂。例如,是否可以使用一种方法为目录定义宏并在输出路径中使用它?
解决方案
回答
Is there a way I can define a macro for a directory and use it in the output path
我们是否看过项目的构建前和构建后事件?
回答
实际上,构建前和构建后事件似乎只是添加批处理文件类型命令的地方。不幸的是,这无助于我为项目设置标准的构建目录。让这些事件创建批处理文件似乎是1980年代使用C#,IMO等现代语言的方法。
在深入研究并进行实验之后,我发现我们可以在.csproj文件中添加<Import>指令。当我们执行此操作时,IDE会弹出一个警告对话框,提示项目中存在不安全的入口点,但是我们可以忽略它,并且显然可以通过编辑注册表项使其完全不显示。因此,这将为我提供一种将包含所需目录路径的变量获取到.csproj文件中的方法。
现在,当在输出路径字段中添加" $(MySpecialPath)/ Debug"之类的字符串并保存项目时,不幸的是要获取输出路径以引用它,并保存项目,将$和()字符转换为十六进制,然后将文件将其放入名为" $(MySpecialPath)"的目录下的Debug目录中。啊啊如果在文本编辑器中编辑.csproj文件,则可以正确设置此文件,并且只要<Import>标记出现在包含输出路径的<PropertyGroup>之前,它就可以正常工作。
因此,我认为对我来说解决方案将是在标准位置创建一个标准OurTeam.targets MsBuild文件,添加一个用于更改注册表的安装程序,使其不标记警告,然后创建用于<导入>此文件的自定义项目模板,并设置输出路径以使用OurTeam.targets文件中定义的属性。遗憾的是,与C ++中的属性表继承机制相比,这是更多的工作,并且解决方案不够完善。
回答
我不太确定什么是"异位"构建系统,但是如果我们只需要将已编译文件(或者其他资源)复制到其他目录的能力,则可以通过绑定MSBuild构建目标来实现。 。
在我们的项目中,我们将已编译的dll移动到lib文件夹中,并在构建完成后将文件放置在正确的位置。为此,我们创建了一个自定义生成.target文件,该文件创建了" Target"," Property"和" ItemGroup",然后将其用于填充外部输出文件夹。
我们的自定义目标文件看起来像这样:
<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,图像等)。
我希望这有帮助。如果我误解了过旧的构建系统的含义,对不起,这对我们完全没有用!