- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我正在使用 visual studio 2013 和 git 开发一个项目。
我必须分发项目的一些库,所以我想用当前的 git commit hash 设置它们的版本号,这样我就可以确定它们使用的是哪个库版本。
有没有办法以自动方式将散列作为版本号,即使用预构建事件,而不是每次都手动执行?
最佳答案
以下是使用资源文件的 native 项目可能实现的一些片段。这个想法是向项目添加一个属性表,它有一个预构建事件,它根据 git 提交哈希创建一个 .res 文件,并将这个 .res 文件添加为资源。这是属性表:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ImportGroup Label="PropertySheets" />
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<VersionResourceOut>$(MSBuildProjectDirectory)\version.res</VersionResourceOut>
</PropertyGroup>
<ItemGroup>
<Resource Include="$(VersionResourceOut)" />
</ItemGroup>
<Import Project="$(BuildToolsDir)tools\versionrc.targets" />
<Target Name="CreateGitVersionResource" BeforeTargets="BuildGenerateSources">
<CallTarget Targets="CreateGitVersionResInBuild" />
<MakeSameWriteTime SourceFile="$(OutDir)$(TargetName)$(TargetExt)" DestFile="$(VersionResourceOut)"/>
</Target>
</Project>
$(BuildToolsDir)tools\versionrc.targets 文件是实际创建资源文件的地方。完整的实现相当冗长,因为它也适用于 svn 并允许进行大量自定义 - 此处要发布的内容有点多,所以我只列出其内容:
提交哈希存储在 msbuild 属性中,获取它的命令是
git --work-tree=$(GitVersionDir) --git-dir=$(GitVersionDir)\.git rev-parse --short HEAD
$(GitVersionDir) 通常设置为 $(MsbuildProjectDirectory),因为我们在源根目录中有大多数 .vcxproj 文件。
我也喜欢包含构建日期,因此最终进入 StringFileinfo block 的 FileDescription 条目的属性是
<FileDesc>$(GitVersion) $([System.DateTime]::Now.ToString('HH:mm:ss dd/MM/yyyy'))</FileDesc>
实际文件/产品版本、公司名称和其他字段是从其他地方获取的。通常我们有一个通用的头文件,定义了 RC 文件模板(见下文)所需的所有 VRC_XXX 宏,以及一个包含例如每个项目的头文件。 #define VRC_FILEDESC“Project Foo”,这些 header 使用 ReadLinesFromFile/WriteLinesToFile 任务 merge 。无论如何,这个想法是以一个像
这样的头文件结束的#define VRC_FILEVERSION 4,4,1,0
#define VRC_PRODUCTVERSION 4.4.1.0
#define VRC_COMPANYNAME MyCompany
#define VRC_PRODUCTNAME VRC_COMPANYNAME Libraries
#define VRC_FILEDESC Project Foo
#define VRC_FILEDESCRIPTION VRC_FILEDESC VRC_FILEDESCGIT
谁的路径存储在 $(VersionMainInclude) 属性中。
所有这些都被馈送到 rc.exe
以创建 .res 文件。完整的命令类似于
rc /d VRC_INCLUDE=$(VersionMainInclude)
/d VRC_ORIGINALFILENAME=$(TargetName)$(TargetExt)
/d VRC_FILETYPE=$(FileType)
/d VRC_FILEDESCGIT=$(FileDesc)
/d VRC_COPYRIGHT=VRC_COMPANYNAME \251 $([System.DateTime]::Now.ToString(`yyyy`))
/fo $(VersionResourceOut) $(MsBuildThisFileDirectory)version.rc
请注意 MakeSameWriteTime
技巧,将 .res 文件的修改时间设置为与输出文件相同,以确保预构建事件不会在每次 .res 文件时触发新构建。生成res文件。可能有更好的方法来做到这一点,但这个对我有用:
<UsingTask TaskName="MakeSameWriteTime" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll" >
<ParameterGroup>
<SourceFile Required="true" ParameterType="System.String"/>
<DestFile Required="true" ParameterType="System.String"/>
</ParameterGroup>
<Task>
<Code Type="Fragment" Language="cs">
<![CDATA[
System.IO.File.SetLastWriteTime( DestFile, System.IO.File.GetLastWriteTime( SourceFile ) );]]>
</Code>
</Task>
</UsingTask>
这是使用的完整 .rc 模板:
#include <winver.h>
#define stringize( x ) stringizei( x )
#define stringizei( x ) #x
#ifdef VRC_INCLUDE
#include stringize( VRC_INCLUDE )
#endif
#ifdef _WIN32
LANGUAGE 0x9,0x1
#pragma code_page( 1252 )
#endif
1 VERSIONINFO
FILEVERSION VRC_FILEVERSION
PRODUCTVERSION VRC_PRODUCTVERSION
FILEFLAGSMASK 0x1L
FILEFLAGS VS_FF_DEBUG
FILEOS VOS__WINDOWS32
FILETYPE VRC_FILETYPE
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904E4"
BEGIN
VALUE "CompanyName", stringize( VRC_COMPANYNAME )
VALUE "FileDescription", stringize( VRC_FILEDESCRIPTION )
VALUE "FileVersion", stringize( VRC_FILEVERSION )
VALUE "LegalCopyright", stringize( VRC_COPYRIGHT )
VALUE "InternalName", stringize( VRC_ORIGINALFILENAME )
VALUE "OriginalFilename", stringize( VRC_ORIGINALFILENAME )
VALUE "ProductName", stringize( VRC_PRODUCTNAME )
VALUE "ProductVersion", stringize( VRC_PRODUCTVERSION )
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1200
END
END
关于git - 在 visual studio 中将 git commit hash 设置为 dll 版本号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34738689/
替换双
这个问题在这里已经有了答案: How to initialize var? (11 个答案) 关闭 8 年前。 我想给一个变量赋初值 null,并在下一个 if-else block 中赋值,但是编
我正在使用 TypeScript 3.8 编写 JS 和 TS 混合的代码。我写了以下行: export * as Easing from './easing'; 应该是 fair game在 Typ
我需要将 R 代码中的“/”更改为“\”。我有这样的事情: tmp <- paste(getwd(),"tmp.xls",sep="/") 所以我的 tmp是 c:/Study/tmp.xls 我希望
我有个问题。例如我有这个: id truth count 1 1 1 2 1 2 3 0 0 4 1 1 5 1 2 6 1
我正在尝试使用“IN”和“=”来查找一些 bean。我目前正在使用此代码: $ids = array(1,2,3,4); $user = 1; $things = R::find( 'thing'
是否可以在 Xcode 中部署到其他人的手机上?我没有 iPhone,但我想测试我在 friend 手机上制作的应用程序。在我支付 99 美元之前,我想确保这不会造成麻烦。 谢谢。 最佳答案 不会有任
我试图得到一个非常大的数字(超过 unsigned long long int )。所以我把它作为一个字符串,然后一个数字一个数字地转换成整数并使用它。 #include #include int
我在 Rust 中有 C 语言库的绑定(bind),但它们并不完整。 在 C 代码中,我定义了一个简化的宏,如下所示: #define MY_MACROS1(PTR) (((my_struct1
我正在努力解决这个问题。 http://jsfiddle.net/yhcqfy44/ 动画应该自动相对于 滚动到顶部每次出现滚动条时的高度。 我已经写了这个,但没有运气: var hheight =
我正在处理一个将数字作为字符串返回的 JSON API。例如 "12" ,但是,该字段值也可以是非数字的,例如:"-" . 我已将 JSON 数据解析为映射,我想将此字段提取为 elixir 中的整数
我正在尝试编写一个类,将.wav文件转换为.aiff文件作为项目的一部分。 我遇到了几个库Alvas.Audio(http://alvas.net/alvas.audio,overview.aspx)
我想在 Lucene 中将像“New York”这样的“复合词”索引为单个术语,而不是像“new”、“york”那样。这样,如果有人搜索“new place”,则包含“new york”的文档将不会匹
我希望这个解释能让我更好地了解使用宏的优点。 最佳答案 在函数中,所有参数在调用之前都会被评估。 这意味着 or 作为函数不能是惰性的,而宏可以将 or 重写为 if 语句,该语句仅在以下情况下计算分
我有一些看起来像这样的 XML foo ]]> (注意 > 登录 "> foo")和 XSLT 样式表 当我运行xsltproc stylesheet.xs
当我尝试将 Any 转换为 List 时,如下面的示例所示,我得到“Unchecked cast: Any!”到列表'警告。有没有解决此类问题的方法? val x: List = objectOfTy
我正在使用 Python 开发一个简单的爬虫。目的是创建一个 sitemap.xml。(你可以在这里找到真正的 alpha 版本:http://code.google.com/p/sitemappy/
我想知道在 VBScript 中是否可以在多行中中断 If 语句。喜欢: If (UCase(Trim(objSheet.Cells(i, a).Value)) = "YES") Or _ (UCas
for (String item : someList) { System.out.println(item); } 使用“do while”是否等效? 谢谢。 最佳答案 如果列表为空,f
这个问题已经有答案了: 已关闭10 年前。 Possible Duplicate: Split string with delimiters in C 在 C 中将“,”分隔的列表拆分为数组的最佳方法
我有一个如下所示的字符数组: [0, 10, 20, 30, 670] 如何将此字符串转换为整数数组? 这是我的数组 int i=0; size_t dim = 1; char* array = (c
我是一名优秀的程序员,十分优秀!