搜索
bottom↓
回复: 24

svn库获得版本号,系统时间获得编译日期,脚本能做到吗?

[复制链接]

出0入0汤圆

发表于 2015-4-27 10:37:47 | 显示全部楼层 |阅读模式
电脑上软件总能获得其版本号,有些还能得到编译日期;嵌入式固件,应该也是可以做到这个要求的。有了版本号,软件出问题时可以立刻对应到正确版本调试,而编译日期间接作为保修依据

我现在想用batch脚本,从svn库获得当前版本号,从系统时间获得编译日期,然后修改某个文件,将这两个信息写入到文件中,每次编译能更新这些信息

那么batch脚本能否做到呢,或者vbs可不可以,最好就是Windows下不需要安装其他脚本系统,使用原生的即可

阿莫论坛20周年了!感谢大家的支持与爱护!!

月入3000的是反美的。收入3万是亲美的。收入30万是移民美国的。收入300万是取得绿卡后回国,教唆那些3000来反美的!

出0入0汤圆

发表于 2015-4-27 10:51:39 | 显示全部楼层
编译日期倒是好获取,MDK下用__DATE__就行,就是版本号一直没找到好的方法,现在只能手动改改

出0入0汤圆

 楼主| 发表于 2015-4-27 11:08:16 | 显示全部楼层
落叶随风 发表于 2015-4-27 10:51
编译日期倒是好获取,MDK下用__DATE__就行,就是版本号一直没找到好的方法,现在只能手动改改 ...

__DATE__  这个好获取,但是却不符合我预期,需要再加工,这就需要用脚本来


我的预期是获得类似这样的宏
#define VERSION        “B“##”105“##”12 05“                //105是版本号,12 05是编译日期(其实是12年5月的意思)

出0入0汤圆

发表于 2015-4-27 11:13:39 | 显示全部楼层
myxiaonia 发表于 2015-4-27 11:08
__DATE__  这个好获取,但是却不符合我预期,需要再加工,这就需要用脚本来

确实,新版本的改为字母缩写表示月份了,我在显示的时候进行了转换,要在C源码里转换,可以用python脚本,不过这要安装python,可能不是你的预期

出0入0汤圆

发表于 2015-4-27 11:31:25 | 显示全部楼层
嗯,一直用 python 干这个,无论是 svn 还是 hg 或者 git,都可以,生成一个 prg_version.h,程序包含这个头。

出0入0汤圆

发表于 2015-4-27 11:33:44 | 显示全部楼层
编译操作用Makefile或者编译脚本之类的,这些都是容易实现的事情。

用IDE进行编译的话,就会略麻烦一些,但也不是不能够。

出0入0汤圆

 楼主| 发表于 2015-4-27 11:58:40 | 显示全部楼层
elecboy 发表于 2015-4-27 11:31
嗯,一直用 python 干这个,无论是 svn 还是 hg 或者 git,都可以,生成一个 prg_version.h,程序包含这个 ...

哈哈哈 能不能贡献下这个脚本啊    我不会python呢

出0入0汤圆

发表于 2015-4-27 12:00:44 | 显示全部楼层
本帖最后由 aozima 于 2015-4-27 12:18 编辑
  1. int get_compile_datetime(const char *format, char * buffer)
  2. {
  3.     const int MONTH_PER_YEAR=12;
  4.     const char szEnglishMonth[MONTH_PER_YEAR][4]= {"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"};
  5.     char szTmpDate[40]= {0};
  6.     char szTmpTime[20]= {0};
  7.     char szMonth[4]= {0};
  8.     int iYear,iMonth,iDay,iHour,iMin,iSec;//,,

  9.     sprintf(szTmpDate, "%s", __DATE__); //"Sep 18 2010"
  10.     sprintf(szTmpTime, "%s", __TIME__); //"10:59:19"

  11.     sscanf(szTmpDate, "%s %d %d", szMonth, &iDay, &iYear);
  12.     sscanf(szTmpTime, "%d:%d:%d", &iHour, &iMin, &iSec);

  13.     for(int i=0; MONTH_PER_YEAR; i++)
  14.     {
  15.         if(strncmp(szMonth, szEnglishMonth[i], 3) == 0)
  16.         {
  17.             iMonth=i+1;
  18.             break;
  19.         }
  20.     }

  21.     if( format && buffer)
  22.     {
  23.         sprintf(buffer, format, iYear, iMonth, iDay, iHour, iMin, iSec);
  24.     }

  25.     return 0;//TODO: return timestamp.
  26. }
复制代码


以前codeblocks是自己写了一个小工具去获取.svn里面的内容生成版本号,但后.svn里面的内容升级了,好像就没更新了。
然后现在C::B好像也使用git了,不知道后面情况如何。

出0入0汤圆

 楼主| 发表于 2015-4-27 12:01:41 | 显示全部楼层
dr2001 发表于 2015-4-27 11:33
编译操作用Makefile或者编译脚本之类的,这些都是容易实现的事情。

用IDE进行编译的话,就会略麻烦一些, ...

mdk可以设置程序在编译前运行   如果我有这样一个脚本 就可以让它先运行生成一个符合预期的宏

出0入0汤圆

 楼主| 发表于 2015-4-27 12:42:29 | 显示全部楼层
aozima 发表于 2015-4-27 12:00
以前codeblocks是自己写了一个小工具去获取.svn里面的内容生成版本号,但后.svn里面的内容升级了,好像就 ...

有没有直接用脚本外部处理的,  这个是c代码啊, 我希望外部脚本操作就可以获得 版本号和编译日期,而不是c代码在运行时产生

出0入0汤圆

发表于 2015-4-27 13:35:27 | 显示全部楼层
myxiaonia 发表于 2015-4-27 12:01
mdk可以设置程序在编译前运行   如果我有这样一个脚本 就可以让它先运行生成一个符合预期的宏  ...

对于编译日期和时间,可以直接使用C标准中规定的宏获得,一般没有必要用脚本单独获得系统时间。除非对时间的格式有独特要求或者要进行特殊处理。

SVN当前Working Copy的版本号获取似乎是有问题的。
如果CI了一个更改,但是没有Update的话,此时工作拷贝和版本库的版本号好像是不一致的。

代码很简单,比如
svn info file:///b:/repo | sed -n -e "s#Revision: ##p"

出0入0汤圆

 楼主| 发表于 2015-4-27 13:39:39 | 显示全部楼层
dr2001 发表于 2015-4-27 13:35
对于编译日期和时间,可以直接使用C标准中规定的宏获得,一般没有必要用脚本单独获得系统时间。除非对时 ...

这个格式是shell下用的么,Windows下好像不行啊

出0入618汤圆

发表于 2015-4-27 13:46:05 | 显示全部楼层
http://tortoisesvn.net/docs/rele ... /tsvn-subwcrev.html

出0入0汤圆

发表于 2015-4-27 13:50:19 | 显示全部楼层
你们说了这么久,svn id是按1累加的,程序版本是有大变动的,比如重大更新,1.21升到2.00,svn id还能用?

出0入618汤圆

发表于 2015-4-27 14:02:20 | 显示全部楼层
brahen 发表于 2015-4-27 13:50
你们说了这么久,svn id是按1累加的,程序版本是有大变动的,比如重大更新,1.21升到2.00,svn id还能用? ...

这个牵涉到Continous Integration了,一般是用tag来管理发布的版本号,然后把CI的auto build流水号追加到版本号后面。

出0入0汤圆

 楼主| 发表于 2015-4-27 14:50:04 | 显示全部楼层
本帖最后由 myxiaonia 于 2015-4-27 15:09 编辑
gzhuli 发表于 2015-4-27 14:02
这个牵涉到Continous Integration了,一般是用tag来管理发布的版本号,然后把CI的auto build流水号追加到 ...


大师 SubWCRev 果然好用  


现在遇上个问题  mdk里可以使用key sequence,本来可以写成这样  SubWCRev $E VERSION.tmpl .\src\VERSION.H

但是这里$E没有被识别出来,直接被忽略了  我在其他地方都可以正确的使用key sequence的

出0入618汤圆

发表于 2015-4-27 16:57:31 | 显示全部楼层
我不用MDK,不知道。
或者弄个批处理呗,再不行按照COM interface范例写个js?

出30入25汤圆

发表于 2015-4-28 00:30:47 | 显示全部楼层
本帖最后由 shamiao 于 2015-4-28 00:35 编辑

把版本号和svn提交,用自动化的手段正式挂钩,可能真的不是一个好主意。理由主要在于:

* 几乎无法保证每一次提交之后的程序,都是能完整的编译执行的。
* 就算可以通过dev-master分离分支解决此问题,也不好难保证所有的参与者都自觉遵守。

* 程序代码可以通过脱离仓库的方式分发(参考GitHub每打一个tag就生成一个zip包的机制),此时如果程序源码缺乏独立性,依赖与svn互动才能编译那就崩了。
* 更糟的是代码仓库是不应当存放二进制文件的。则上一个问题出现时,代码编译不出,还没有二进制烧录文件兜底,程序的可用性一刻毁光。

我认为代码的编译和发布需要一个冷化的正式流程。我的建议方法如下:

* 代码内部明确写死版本号,要求拿到代码一眼看得出的那么明显(例如头文件)。
* 版本号手动维护、手动增加。这样便于根据开发进度,人工判断增加的是大版本、小版本还是修订版本。
* 其他版本更新时必须改动的文档(CHANGELOG等)也要附带在代码仓库中。

* 将代码分离成三个分支:dev、staging和master。
* 频繁的开发变动一律使用dev。
* 开发变动可以封死后,并入staging做最后检查。
* dev并入staging的这个行为需要严肃对待,但并不添加机器规则去做约束和检查。
* staging责任者检查过后,手工增加版本号,填写CHANGELOG等文档。(当然这一步dev做,staging审也可以)
* staging确认无误后,将修改并入master上,完成软件正式发布
* master分支的每一个提交,都是一个版本的推进,不回溯、不推翻、不改变,取出提交历史就是软件的历代发布记录
* master分支需要在版本管理系统上挂一个钩子,比对新的提交和上一个提交,版本号上是否正确提升,该填写的CHANGELOG等文件是否确实增加了内容。
* 如果这个钩子不符合,就拒绝接受新提交,从而既防止人工出错,又保留人工控制版本提升的精确性。

* 烧录文件建议使用自动手段来维护,每检测到一个master分支变动就编译一次,并把编译好的烧录文件用版本号起文件名,存储到规定的位置永久存档。
* 这个自动机也应该挂到版本管理系统的钩子上——只有编译通过的提交才可以接受,编译过不了的提交也必须否决。
* 编译必须用脚本,不能依赖IDE,不解释。

出0入0汤圆

 楼主| 发表于 2015-4-28 07:54:54 | 显示全部楼层
shamiao 发表于 2015-4-28 00:30
把版本号和svn提交,用自动化的手段正式挂钩,可能真的不是一个好主意。理由主要在于:

* 几乎无法保证每 ...

你的整改措施好复杂。。。看上去应该不错,只不过我的代码还是比较简单的,依赖关系也简单,所以暂时用简单办法还能应付得过去

等到哪天项目变得十分复杂时,不得不再思考更好的管理办法时,我估计那时候再看你的建议肯定会有更多的收获

出30入25汤圆

发表于 2015-4-28 10:24:39 | 显示全部楼层
myxiaonia 发表于 2015-4-28 07:54
你的整改措施好复杂。。。看上去应该不错,只不过我的代码还是比较简单的,依赖关系也简单,所以暂时用简 ...

如果简单的话,用版本管理系统的tag功能就行了。需要发布明确版本的时候,改一下代码中的版本号,做一个新提交。提交之后打个标签,明确标记这个提交是一个可用的新版本。

编译行为,可以用自动机跟踪tag的变化,也可以手动来,这个就不重要了;

加编译日期这个需求其实也很好,这个试着改一下Makefile吧。毕竟各种IDE的构建行为一般都等同于命令行下跑一下make

dev-staging-master三段式的方法只是一种特定场合的建议。实际中只需考虑以下原则来设计自己的流程:
0、一定不能让编译行为依赖于IDE的存在;
1、一定不能让编译行为依赖于版本管理系统的存在;
2、一定不能把二进制文件(hex、bin等)存入代码仓库;
3、确定版本是一件严肃的事情。某个特定版本的代码和二进制文件,死也不能变动,只能推出后续版本修正。

-------------------------------------

其他参考知识:

实际上我看了一下,依赖提交记录的编译行为是有的,这个叫做nightly(每夜构建)。

编译机每夜翻阅提交历史,如果今日有新的提交,就会自动进行构建。构建时编译机克隆一次最新的代码,然后把当前日期“挂”到代码中的版本号后边再编译。

所以每夜构建经常会产生一些40.0.0-alpha-20150401或者40.0.0-alpha-r157023等后边“挂尾巴”的版本号。

每夜构建仅仅用于软件的测试用途,因为电脑只会机械编译,而必然不知道某个时刻人的工作是否完成了。自动标定的版本号肯定是不可靠的。

出0入0汤圆

 楼主| 发表于 2016-8-2 11:45:21 | 显示全部楼层
aozima 发表于 2015-4-27 12:00
以前codeblocks是自己写了一个小工具去获取.svn里面的内容生成版本号,但后.svn里面的内容升级了,好像就 ...

aozima 兄,我刚在坛子里学到了用tcc把c作为脚本生成需要的代码,所以你的办法现在也是可行了呵呵,当然用古大师说的subwcrev更加方便

出0入0汤圆

发表于 2016-8-2 12:55:30 | 显示全部楼层
我也正在寻找这样的方案。

出0入4汤圆

发表于 2017-2-14 23:02:47 | 显示全部楼层
分享一个刚刚写好的用来获取git 版本号的DOS批处理命令文件, svn应该简单改改就可以使用了。


set a=#define COMMIT_ID ^"
git rev-parse HEAD > User\version.h
set /p b= < User\version.h
set c=^"
echo %a%%b%%c% > User\version.h

最后获得的这样的version.h文件
#define COMMIT_ID "e77759ba7f417eb99e084d90404c860fc8308f27"

出0入0汤圆

 楼主| 发表于 2017-2-16 16:38:41 | 显示全部楼层
ronic 发表于 2017-2-14 23:02
分享一个刚刚写好的用来获取git 版本号的DOS批处理命令文件, svn应该简单改改就可以使用了。

SubWCRev 命令更加简单,看看文档就明白了,这种东西就是自己闷头干脑细胞都死光了,高人一点拨立马柳暗花明,很神奇的感觉

出0入0汤圆

发表于 2017-2-16 17:17:05 | 显示全部楼层
肯动能获取到的,我们之前做过,不过代码什么的不好找了~
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-25 15:32

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表