myxiaonia 发表于 2015-4-27 10:37:47

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

电脑上软件总能获得其版本号,有些还能得到编译日期;嵌入式固件,应该也是可以做到这个要求的。有了版本号,软件出问题时可以立刻对应到正确版本调试,而编译日期间接作为保修依据

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

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

落叶随风 发表于 2015-4-27 10:51:39

编译日期倒是好获取,MDK下用__DATE__就行,就是版本号一直没找到好的方法,现在只能手动改改

myxiaonia 发表于 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月的意思)

落叶随风 发表于 2015-4-27 11:13:39

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




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

elecboy 发表于 2015-4-27 11:31:25

嗯,一直用 python 干这个,无论是 svn 还是 hg 或者 git,都可以,生成一个 prg_version.h,程序包含这个头。

dr2001 发表于 2015-4-27 11:33:44

编译操作用Makefile或者编译脚本之类的,这些都是容易实现的事情。

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

myxiaonia 发表于 2015-4-27 11:58:40

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

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

aozima 发表于 2015-4-27 12:00:44

本帖最后由 aozima 于 2015-4-27 12:18 编辑

int get_compile_datetime(const char *format, char * buffer)
{
    const int MONTH_PER_YEAR=12;
    const char szEnglishMonth= {"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"};
    char szTmpDate= {0};
    char szTmpTime= {0};
    char szMonth= {0};
    int iYear,iMonth,iDay,iHour,iMin,iSec;//,,

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

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

    for(int i=0; MONTH_PER_YEAR; i++)
    {
      if(strncmp(szMonth, szEnglishMonth, 3) == 0)
      {
            iMonth=i+1;
            break;
      }
    }

    if( format && buffer)
    {
      sprintf(buffer, format, iYear, iMonth, iDay, iHour, iMin, iSec);
    }

    return 0;//TODO: return timestamp.
}

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

myxiaonia 发表于 2015-4-27 12:01:41

dr2001 发表于 2015-4-27 11:33
编译操作用Makefile或者编译脚本之类的,这些都是容易实现的事情。

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

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

myxiaonia 发表于 2015-4-27 12:42:29

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

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

dr2001 发表于 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"

myxiaonia 发表于 2015-4-27 13:39:39

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

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

gzhuli 发表于 2015-4-27 13:46:05

http://tortoisesvn.net/docs/release/TortoiseSVN_en/tsvn-subwcrev.html

brahen 发表于 2015-4-27 13:50:19

你们说了这么久,svn id是按1累加的,程序版本是有大变动的,比如重大更新,1.21升到2.00,svn id还能用?

gzhuli 发表于 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流水号追加到版本号后面。

myxiaonia 发表于 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的

gzhuli 发表于 2015-4-27 16:57:31

我不用MDK,不知道。
或者弄个批处理呗,再不行按照COM interface范例写个js?

shamiao 发表于 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,不解释。

myxiaonia 发表于 2015-4-28 07:54:54

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

* 几乎无法保证每 ...

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

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

shamiao 发表于 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等后边“挂尾巴”的版本号。

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

myxiaonia 发表于 2016-8-2 11:45:21

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

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

百果 发表于 2016-8-2 12:55:30

我也正在寻找这样的方案。

ronic 发表于 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"

myxiaonia 发表于 2017-2-16 16:38:41

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




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

cece_co 发表于 2017-2-16 17:17:05

肯动能获取到的,我们之前做过,不过代码什么的不好找了~
页: [1]
查看完整版本: svn库获得版本号,系统时间获得编译日期,脚本能做到吗?