把编译时间加入到目标文件

原文:https://www.cnblogs.com/pingwen/p/8183728.html

1、问题背景:如何保证发布出去的bin文件是最终测试通过的版本?

一般的来讲,代码到了测试后期,master分支就不会频繁的提交了,并且提交也会更加谨慎。

但是人为操作总会出现纰漏,希望只要代码被重新编译过,那么bin文件就包含新的时间信息,而这个信息是可以从外部通信或printf来查看的。

在嵌入式开发中,版本号一般的都是一个int变量或字符串变量。但是若修改了代码而没有改version变量或宏定义,那么从version上就看不出来文件的变化。

那么最终编译的版本到底是哪个版本,是否与测试的版本完全一致,这个问题尤为突出。

目标文件中带有编译时间可以防止代码被改动过,只要代码被重新编译,那么就生成新的时间信息。

git能够记录文件修改信息,但是调试信息或工程配置等,很多文件都是ignore的,这些信息代表着最终的bin文件的运行环境。

某些复杂bug情况下,只有运行环境一致,仿真器才能attach到目标文件。

2. 如何获取时间:DATA, TIME

这两个宏是日期和时间,格式如下。如果把这两个宏加入到代码,那么就得到了时间的字符串信息。

// Example of __DATE__ string: "Dec 27 2017"
// Example of __TIME__ string: "15:06:19"
const char *BuildInfo = "Version: " VERSION " " __DATE__ " " __TIME__;

代码实现获取日期和时间的方法很多,比如:

左右滑动查看全部代码>>>

unsigned int mk_Build_Date(void)
{int    year = 0, month = 0, day = 0;int hour = 0, minute = 0, seconds = 0;char m[4] = {0};sscanf(__DATE__, "%3s %2d %4d", m, &day, &year);for (month = 0; month < 12; month++){if (strcmp(m, short_char_months[month]) == 0){break;}}sscanf(__TIME__, "%2d:%2d:%2d", &hour, &minute, &seconds);#ifdef SHORT_DATA_CHAR__printf("[null]  ** Build at:\t%04u-%02u-%02us %02u:%02u:%02u\n",year, month, day,hour, minute,seconds);#elseprintf("[null]  ** Build at:\t%04u-%02u-%02u %02u:%02u:%02u\n",year, month, day,hour, minute,seconds);#endifDEBUG("buildDate: %s %s\n", __DATE__, __TIME__);return 0;
}

把上面的函数加入到代码中,就能获取工程编译的时间。

但是如果该代码所在的文件没有被修改,在非build-all情况下,编译器不会再次编译此文件,所以时间信息也就不会被更新。

如果每次都使用re-build all,一来繁琐,二来也不能保证每次都会记得点击build all按钮,靠技术手段来保证每次build都更新时间信息才是正道。

3. 如何保证时间每次编译都更新:使用预编译指令,每次更新包含时间宏的文件或对应的链接文件。

在IAR环境下,官方已经给出了解决的方法(Using pre-build actions for time stamping)。

https://www.iar.com/support/tech-notes/ide/build-actions-pre-build-and-post-build/

方法1:修改文件的时间,引起编译器对文件进行重新编译。

cmd /c "touch /cygdrive/d/test.c"

方法虽好,可惜IAR用户大多数是Windows用户,包括我在内,touch是linux命令,必须Cywin环境。如果安装过这个环境的话,那就大功告成了。

Cygwin touch commandYou can enter "cygwin-application.exe" on the pre- and post-build command lines, if the environment variable PATH includes the directory where the "cygwin-application.exe" is located.You can run the Cygwin command "touch" on the pre-build command line, but if you add a file path, for example "touch d:/test.c", the file path is not accepted by Cygwin.Cygwin expects the POSIX path /cygdrive/d/test.c so the resulting command line would be "touch /cygdrive/d/test.c", however this command cannot be executed directly on the pre- and post-build command. Instead you have to run indirectly using:cmd /c "touch /cygdrive/d/test.c"
The .bat file (located in project directory) alternative would look like:Pre-build command line:$PROJ_DIR$\pre-build.bat
File pre-build.bat:touch /cygdrive/d/test.c

方法2:修改文件对应的链接文件,触发编译器重新编译该文件,生成新的链接文件,那么就会生成新的带有时间信息的目标文件。

An alternative to the "touch" command is to have a pre-build action that deletes the object file, for example the Pre-build command line:cmd /c "del "$OBJ_DIR$\test.o""

在pre-build中加入上面的命令,就会在编译前删除test.o文件。

在这种模式下,工程代码只要任何位置发生变化,代码重新编译,就会触发删除test.o,然后链接过程发现没有test.o文件,那么就会重新编译一次test.c,那么新的时间信息就会记录下来了。

虽有些曲线救国的味道,但还是很顺利的实现了目标。

只要工程的任何地方有改动,生成新的目标文件,那么目标文件中就会带有最新的编译时间。

方法3:直接告诉编译器每次重新编译某个文件更直接,MDK支持此功能。

时隔一年半再次来这里,发现当时自己简直是小白,还洋洋得意曲线救国,实际上舍近求远罢了。

如果对工具多一些了解,万万是不会用上面的方法的,当然上面的方法也是通用想法,是通用型知识点,容易想到,也能达到目标。

新的方法,不需要写任何脚本,如果想让代码每次都编译更新DATA 和 TIME两个宏,那么让这个文件每次都编译一次就可以了,不需要删除它的obj文件然后让编译器找不到文件而触发重新编一次,其实直接告诉编译器每次重新编译更直接,MDK支持此功能。

下面是测试的效果:

其它资料:

https://stackoverflow.com/questions/11697820/how-to-use-date-and-time-predefined-macros-in-as-two-integers-then-stri

 

 推荐阅读:

    专辑|Linux文章汇总

    专辑|程序人生

    专辑|C语言

嵌入式Linux

微信扫描二维码,关注我的公众号 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/467230.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

大数据基础篇(一):联机分析处理(OLAP) 与 联机事务处理(OLTP)

联机事务处理(OLTP) OLTP也称实时系统(Real Time System)&#xff0c;支持事务快速响应和大并发&#xff0c;这类系统典型的有ATM机(Automated Teller Machine)系统、自动售票系统等&#xff0c;但有些银行转账并不是实时到账的。OLTP反映企业当前的运行状态&#xff0c;完成企…

[JavaScript] 正则表达式

简单模式• 创建&#xff1a; 一个文本格式或正则表达式构造函数 文本格式&#xff1a; /pattern/flags 正则表达式构造函数&#xff1a; new RegExp("pattern"[,"flags"]); • 参数说明&#xff1a; pattern -- 一个正则表达式文本 flags -- 如果存…

1核2G云服务器 标准型S4 S5,腾讯云服务器标准型S4和S5配置性能参数区别及选择攻略...

腾讯云服务器标准型S4和标准型S5实例有什么区别&#xff1f;标准型S5相对于S4是新一代云服务器规格&#xff0c;S5实例CPU采用2.5GHz主频至强Cascade Lake&#xff0c;S4实例处理器采用2.4GHz主频至强Skylake&#xff0c;腾讯云S4/S5均为标准型服务器&#xff0c;具有均衡的计算…

单精度浮点数与十六进制转换

#include <stdio.h>/*--------------------------- 十六进制到浮点数 ---------------------------*/ float Hex_To_Decimal(unsigned char *Byte,int num) { #if 0char cByte[4];//方法一for (int i0;i<num;i){cByte[i] Byte[i];}float pfValue*(float*)&cByte;…

zipline-benchmarks.py文件改写

改写原因&#xff1a;在这个模块中的 get_benchmark_returns() 方法回去谷歌财经下载对应SPY&#xff08;类似于上证指数&#xff09;的数据&#xff0c;但是Google上下载的数据在最后写入Io操作的时候会报一个恶心的编码的错误&#xff0c;很烦人&#xff0c;时好时坏的那种&a…

css普通压缩不去,使用css-loader的minimize压缩css不起作用?

{ test: /\.(scss|css)$/, use: [!env.production? style-loader: MiniCssExtractPlugin.loader,{ loader: css-loader, options: { modules: true, minimize: true //设置css压缩}},{ loader:…

华为3COM交换机PVLAN配置使用说明

1.  PVLAN的引入   <?xml:namespace prefix o ns "urn:schemas-microsoft-com:office:office" /><?xml:namespace prefix v ns "urn:schemas-microsoft-com:vml" />在实际应用中有这样一个需求&#xff0c;组网图如上图所示。    …

Linux cpuidle framework

背景Kernel版本&#xff1a;4.14ARM64处理器使用工具&#xff1a;Source Insight 3.5&#xff0c; Visio1. 介绍在Linux OS中&#xff0c;Idle进程的运行会让CPU进入cpuidle状态。当没有其他进程处于运行状态时&#xff0c;Scheduler会选择Idle进程来运行&#xff0c;此时CPU无…

Linux利器:QEMU!用它模拟开发板能替代真开发板?

不想错过我的推送&#xff0c;记得右上角-查看公众号-设为星标&#xff0c;摘下星星送给我&#xff01;QEMU&#xff0c;搞嵌入式开发的一定不陌生&#xff0c;最近各大群里都讨论疯了&#xff0c;说它是Linux利器一点也不夸张。它是一款知名的而且开源的模拟器&#xff08;官网…

CPU怎么认识代码的?

# 语言这个东西&#xff1f;首先说明下&#xff0c;我们正常使用的python、C、C语言等等&#xff0c;我们自己能读得懂的语言&#xff0c;包括汇编语言&#xff0c;CPU都是不认识的&#xff0c;CPU 只认识一种语言&#xff0c;那就是 机器语言&#xff0c;也就是我们很多人&…

节日才需要快乐吗?

---- 当然需要天天快乐2020年的国庆和中秋是挺特别的&#xff0c;也是国庆&#xff0c;也是中秋&#xff0c;而且今天还能看NBA总决赛助兴。这么愉快的节日&#xff0c;祝我们的国家繁荣昌盛&#xff0c;国泰民安&#xff0c;也祝大家中秋快乐&#xff0c;当然中秋后也需要快乐…

我在富士康13年

以下是一个读者朋友的日记---- ???? 有点恨铁不成钢的感觉这个读者跟我一样的年纪&#xff0c;都是89年&#xff0c;好吧&#xff0c;说到这里突然觉得又马上要老一岁了&#xff0c;因为小云跟我说&#xff0c;我马上就要过生日了&#xff0c;我从来就记不清自己的生日&…

域名服务器的配置文档,dns域名服务器的配置

dns域名服务器的配置 内容精选换一换使用mount命令挂载文件系统到云服务器&#xff0c;云服务器系统提示timed out。原因1&#xff1a;网络状态不稳定。原因2&#xff1a;网络连接异常。原因3&#xff1a;云服务器DNS配置错误&#xff0c;导致解析不到文件系统的域名&#xff0…

广东阳西的小城生活

国庆放假&#xff0c;回小云老家&#xff0c;广东阳江阳西县。我们是昨天下午5点出发&#xff0c;晚上11点到家&#xff0c;刚好错开拥堵高峰&#xff0c;不过在沿江高速上川岛附近还是遇到了交通堵塞&#xff0c;一直缓缓前行&#xff0c;等到我们通过那个事故点的时候&#x…

10.5 0819吉米牛逼

吉米真牛逼&#xff0c;这场比赛热火赢得漂亮&#xff0c;没有阿德巴约&#xff0c;没有德拉季奇的情况下&#xff0c;吉米硬生生把自己变成了詹姆斯。右侧45度拿球&#xff0c;突破顶着老詹急停跳投&#xff0c;又一次在老詹面前拿下两分&#xff0c;马上回防&#xff0c;面对…

既生Flash,又何生EEPROM?

我们正常编译生成的二进制文件&#xff0c;需要下载烧录到单片机里面去&#xff0c;这个文件保存在单片机的ROM中&#xff0c;ROM这个名称指的是「read only memory」的意思&#xff0c;所有可以完成「read only memory」这种特性的存储介质都可以称为ROM&#xff0c;我们一般使…

文本或代码中 \n 和 \r 的区别

我们使用printf打印时基本都会用到 \n 和 \r 之类控制字符&#xff0c;比如&#xff1a;printf("hello world!\r\n");那你知道这些 \n 和 \r 的区别吗&#xff1f;# 关于「 \n 」 和「 \r 」在ASCII码中&#xff0c;我们会看到有一类不可显示的字符&#xff0c;叫控制…

中兴5G和展锐原厂芯片开发,怎么选?

最近跟一个读友聊天&#xff0c;谈到的还是offer选择的问题&#xff0c;我觉得讨论这个问题比讨论技术问题更加重要「特别是刚出校门的学生&#xff0c;选择一个好的行业比刚毕业的薪资重要」。当然了&#xff0c;肯定有人跟我说我不务正业&#xff0c;整天瞎BB&#xff0c;好的…

40张动图揭示各种传感器工作原理!

应变加速度感应器▼称重式料位计▼电子皮带秤重示意图▼电子吊车秤▼荷重传感器用于测量汽车衡的原理▼荷重传感器的应用▼TiO2氧浓度传感器结构及测量电路▼布料张力测量及控制原理▼直滑式电位器控制气缸活塞行程▼电位器式传感器▼陶瓷湿度传感器▼多孔性氧化铝湿敏电容原理…

lpad与rpad

--lpad(str, n, [pad_str])--rpad(str, n, [pad_str])-- 如果n<length(str),则显示substr(str,1,n)-- 否则&#xff0c;分别从左边和右边使用pad_str进行填充-- 其中n表示最后输出结果字符串的长度-- 如果pad_str为空&#xff0c;则用空格来填充select lpad(abc,2,#) from d…