对于C ++项目,我想自动生成带有项目定义的defs.h
文件,例如date,git commit,...以自动化我的应用程序的版本控制过程。
因此,我正在尝试创建一个MSBuild目标,它将提取最新的git标记,git commit和当前日期,并将其保存到临时gitinfo.txt
文件中。
另一个构建目标将依赖于该文件并生成.h文件。
为了避免不必要的重新编译我的项目,.h文件,因此gitinfo.txt
文件只有在任何信息发生变化时才会被重写。
所以我的想法如下:
gitinfo.txt
gitinfo.txt
我已经掌握了步骤1.和2.但是我不确定如何在阅读后处理这些值。
<!-- 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>
这可能是gitinfo.txt
v4.1.4
04fe34ab
1
31.07.2016
我现在不太确定如何比较这些值。我需要将$(NewGitTag)
与$(Version)
版本变量中的第一个值进行比较,依此类推。
我还没有找到一个例子,它实际上是在从文件中读取变量后访问它们的。 official documentation没有提供任何帮助,也没有在stackoverflow或类似内容中找到任何内容。
我只知道$(Version)
变量包含一个列表,我可以批量处理它。如何将其内容与定义的变量$(NewGitTag)
,$(NewGitCommitHash)
,$(NewGitCommitCount)
和$(NewBuildDate)
进行比较?
答案 0 :(得分:1)
假设我们从这些数据开始:
<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>
然后这里至少 3种方式来实现比较(除了评论中提到的方法)并且可能还有其他方法(如果我能提出,我会发布它们别的):
只需比较商品
我不确定为什么你要分别比较一切,当它同样有效时:一次比较整个ItemGroup。
<Target Name="Compare1">
<PropertyGroup>
<VersionChanged>True</VersionChanged>
<VersionChanged Condition="'@(Version)' == '$(GitTag);$(GitSHA);$(Count);$(Date)'">False</VersionChanged>
</PropertyGroup>
<Message Text="VersionChanged = $(VersionChanged)" />
</Target>
批处理并检查是否存在差异
将每个版本的项目与例如GitTag通过批处理。如果存在差异,结果将为False;False;False;False
,否则为True;False;False;False
。计算不同的元素,如果它是2则意味着我们得到后者,所以GitTag没有改变。请注意,只有当您的每个源项永远不会与其他项之一具有相同的值时,这种情况才有效。
<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>