MSBuild:比较项目组或按索引访问 对于一个C++项目,我想用项目定义自动生成一个 DEFS.H./Cux>文件,如日期、Git提交、…自动化应用程序的版本控制过程
因此,我试图创建一个MSBuild目标,该目标将提取最新的git标记、git commit和当前日期,并将其保存到一个临时的MSBuild:比较项目组或按索引访问 对于一个C++项目,我想用项目定义自动生成一个 DEFS.H./Cux>文件,如日期、Git提交、…自动化应用程序的版本控制过程,msbuild,Msbuild,因此,我试图创建一个MSBuild目标,该目标将提取最新的git标记、git commit和当前日期,并将其保存到一个临时的gitinfo.txt文件中。 另一个构建目标将依赖于该文件并生成一个.h文件。 为了避免对我的项目进行不必要的重新编译,.h文件以及基于此原因,gitinfo.txt文件只能在任何信息发生更改时重写 因此,我的想法如下: 计算git和日期信息 如果可用,请阅读现有的gitinfo.txt 将计算值与txt文件中的值进行比较 如果有任何更改,请重写gitinfo.txt 我
gitinfo.txt
文件中。
另一个构建目标将依赖于该文件并生成一个.h文件。
为了避免对我的项目进行不必要的重新编译,.h文件以及基于此原因,gitinfo.txt
文件只能在任何信息发生更改时重写
因此,我的想法如下:
gitinfo.txt
gitinfo.txt
<!-- The purpose of this target is to update gitinfo.txt if git information (commit...) has changed -->
<Target
Name="GetHeaderInfos"
BeforeTargets="ClCompile"
Outputs="$(IntDir)\gitinfo.txt"
>
<!-- Get information about the state of this repo-->
<GitDescribe>
<Output TaskParameter="Tag" PropertyName="NewGitTag" />
<Output TaskParameter="CommitHash" PropertyName="NewGitCommitHash" />
<Output TaskParameter="CommitCount" PropertyName="NewGitCommitCount" />
</GitDescribe>
<!-- Get the current date -->
<Time Format="dd.MM.yyyy">
<Output TaskParameter="FormattedTime" PropertyName="NewBuildDate" />
</Time>
<ReadLinesFromFile File="$(IntDir)\gitinfo.txt" Condition="Exists('$(IntDir)\gitinfo.txt')">
<Output TaskParameter="Lines" ItemName="Version" />
</ReadLinesFromFile>
<!-- Comparison here! HOW TO DO IT PROPERLY -->
<PropertyGroup>
<TagChanged> <!-- `$(NewGitTag)` == `$(Version)[0]` --> </TagChanged>
<!-- Other comparisons -->
</PropertyGroup>
</Target>
我现在不太确定如何比较这些值。我需要将$(NewGitTag)
与$(Version)
版本变量中的第一个值进行比较,依此类推
我还没有找到一个实例,它实际上是在从文件中读取变量之后访问变量的。没有提供任何帮助,我也没有在stackoverflow之类的网站上找到任何东西
我只知道
$(Version)
变量包含一个列表,我可以批处理它。如何将其内容与定义的变量$(NewGitTag)
、$(NewGitCommitHash)
、$(NewGitCommitCount)
和$(NewBuildDate)
进行比较?假设我们从以下数据开始:
<ItemGroup>
<Version Include="v4.1.4;04fe34ab;1;31.07.2016"/>
</ItemGroup>
<PropertyGroup>
<GitTag>v4.1.4</GitTag>
<GitSHA>04fe34ab</GitSHA>
<Count>1</Count>
<Date>31.07.2016</Date>
</PropertyGroup>
然后还可以比较其他项目并合并结果
使用内联任务按索引访问项目
这与您的问题最接近,但它确实需要一些内联代码
<UsingTask TaskName="IndexItemGroup" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll" >
<ParameterGroup>
<Items Required="true" ParameterType="Microsoft.Build.Framework.ITaskItem[]"/>
<Index Required="true" ParameterType="System.Int32"/>
<Item Output="true" ParameterType="Microsoft.Build.Framework.ITaskItem"/>
</ParameterGroup>
<Task>
<Code Type="Fragment" Language="cs">
<![CDATA[Item = Items[ Index ];]]>
</Code>
</Task>
</UsingTask>
<Target Name="Compare3">
<IndexItemGroup Items="@(Version)" Index="1">
<Output PropertyName="OldGitSHA" TaskParameter="Item"/>
</IndexItemGroup>
<PropertyGroup>
<SHAChanged>True</SHAChanged>
<SHAChanged Condition="'$(GitSHA)' == '$(OldGitSHA)'">False</SHAChanged>
</PropertyGroup>
<Message Text="OldGitSHA = $(OldGitSHA), changed = $(SHAChanged)" />
</Target>
真的
假的
另一种方法:将git信息和日期写入文件,使用Exec任务比较这些文件以调用窗口的fc.exe,并使用其返回值确定文件是否相等,如果不相等,则复制文件。类似于这里:是的,这是一种有效的方法。我试试看。然而,我真的很想知道它是如何实现的,对于未来的用例也是如此。也许还可以编辑你的问题/标题,让未来的访问者更容易发现它:基本上是“如何通过索引从项目组访问项目”,甚至只是“如何比较项目组”。也可以让它更简单:你只需要从一个项目组和一堆项目开始,然后你想要比较它们。这些项目是来自文件还是来自GitDescripte都无关紧要,这使得测试代码变得更加困难,因为不是每个人都有GitDescripte。关于第二个,如果一切都改变了,那么它将是真的;是的;是的;正确
,因此它会被错误地标记为“未更改”?至于第三个,我不知道它会这么复杂,但至少我知道它是如何使用的;是的;是的;如果版本以某种方式等于“v4.1.4;v4.1.4;v4.1.4;v4.1.4”
<Target Name="Compare1">
<PropertyGroup>
<VersionChanged>True</VersionChanged>
<VersionChanged Condition="'@(Version)' == '$(GitTag);$(GitSHA);$(Count);$(Date)'">False</VersionChanged>
</PropertyGroup>
<Message Text="VersionChanged = $(VersionChanged)" />
</Target>
<Target Name="Compare2">
<PropertyGroup>
<TagChanged>True</TagChanged>
<TagChanged Condition="'@(Version->Contains($(GitTag))->Distinct()->Count())' == '2'">False</TagChanged>
</PropertyGroup>
<Message Text="TagChanged = $(TagChanged)" />
</Target>
<UsingTask TaskName="IndexItemGroup" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll" >
<ParameterGroup>
<Items Required="true" ParameterType="Microsoft.Build.Framework.ITaskItem[]"/>
<Index Required="true" ParameterType="System.Int32"/>
<Item Output="true" ParameterType="Microsoft.Build.Framework.ITaskItem"/>
</ParameterGroup>
<Task>
<Code Type="Fragment" Language="cs">
<![CDATA[Item = Items[ Index ];]]>
</Code>
</Task>
</UsingTask>
<Target Name="Compare3">
<IndexItemGroup Items="@(Version)" Index="1">
<Output PropertyName="OldGitSHA" TaskParameter="Item"/>
</IndexItemGroup>
<PropertyGroup>
<SHAChanged>True</SHAChanged>
<SHAChanged Condition="'$(GitSHA)' == '$(OldGitSHA)'">False</SHAChanged>
</PropertyGroup>
<Message Text="OldGitSHA = $(OldGitSHA), changed = $(SHAChanged)" />
</Target>