在编译时获取大纪元时间

时间:2013-08-13 17:47:29

标签: c c-preprocessor epoch

上下文:我正在编写一种非平凡的客户端 - 服务器UDP多播程序,我正在某些无线节点上进行部署。部署方法是我编写的一个脚本,广播ping这些节点所在的网络,获取节点列表(基于IP地址),部署我的包并安装它。我注意到,有时在部署时并未检测到所有节点,并且未安装我正在开发的最新软件包。最终,可能是在一个节点上运行的服务器比希望与服务器通信的客户端更旧的情况。因为服务器获取数据包,并根据此数据包中的条目分配内存,所以如果结构发生更改,服务器通常会在段错误中崩溃。作为一种解决方案,我正在考虑在客户端和服务器之间发送的数据包中实现版本号,以便在服务器/客户端读取版本号不相同的数据包时(或者由于重组而导致垃圾邮件)数据包),该数据包被忽略,日志被更新,或者紧急数据包被发送给原始发送者。

所以,我正在尝试在编译时获得这个“版本号”的最佳方法,它可以作为#define位于标题中。我查找了__time__预处理器宏,但这是一个字符串的形式。有没有办法在编译期间获得纪元时间,这样我就可以将它命名为无符号整数(如果我正确地考虑这个问题,那么它应该在136年之后滚动)?

很抱歉,如果我不清楚。

2 个答案:

答案 0 :(得分:1)

这取决于你的构建系统,但如果你正在使用gmake,那么你 可以做类似的事情:

CXX_TIME = -DBUILDTIME=$(shell python -c "import time; print( int( time.time() ) )" )

将此添加到您的其他编译器选项中,然后使用 您的代码中的宏BUILDTIME

(这假设你已经在你的路径中安装了Python。 如果没有,您可以安装它,或者做类似的事情 您已安装的工具。)

答案 1 :(得分:0)

您可以从__DATE__预处理程序宏中获取纪元。

getCompileTimeEpoch()函数下面,该函数又依赖于其他两个简单的辅助函数,这些函数返回月号,而另一个则将月首字母缩写转换为小写。

让我感到困惑的是, GCC 开发人员如何引入一个具有人类可读日期而不是带有纪元的宏,从中可以最大程度地得出日期的其他信息。

如果您需要将时间添加到纪元中,可以很容易地从__TIME__宏中添加时间。

我选择了此解决方案,因为它可以将所有内容保留在代码中并且不依赖于编译器选项。

char *tolowercase(char *letstr){
    int l;
    for(l=0;l<=strlen(letstr);l++){
        if(letstr[l]>=65 && letstr[l]<=92){
            letstr[l]=letstr[l]+32;
        }
    }
    return letstr;
}

int getMonFromAbbr(char *abbr){
    if (strlen(abbr) > 0)
        tolowercase(abbr);
    if ( strcmp(abbr, "jan") == 0 )
        return 0;
    if ( strcmp(abbr, "feb") == 0 )
        return 1;
    if ( strcmp(abbr, "mar") == 0 )
        return 2;
    if ( strcmp(abbr, "apr") == 0 )
        return 3;
    if ( strcmp(abbr, "may") == 0 )
        return 4;
    if ( strcmp(abbr, "jun") == 0 )
        return 5;
    if ( strcmp(abbr, "jul") == 0 )
        return 6;
    if ( strcmp(abbr, "aug") == 0 )
        return 7;
    if ( strcmp(abbr, "sep") == 0 )
        return 8;
    if ( strcmp(abbr, "oct") == 0 )
        return 9;
    if ( strcmp(abbr, "nov") == 0 )
        return 10;
    if ( strcmp(abbr, "dec") == 0 )
        return 11;
    return(-1);
}

// Convert from __DATE__ macro
uint64_t getCompileTimeEpoch(){
    char date_macro[20]="";
    strcpy(date_macro, __DATE__);
    char *token;
    int yea=0;
    int mon=0;
    int day=0;
    token=strtok(date_macro, " ");
    if (token != NULL){
        mon=getMonFromAbbr(token);
        token=strtok(NULL, " ");
        if (token != NULL){
            day=atoi(token);
            token=strtok(NULL, " ");
            if (token != NULL){
                yea=atoi(token);
                struct tm t;
                time_t epoch_t;
                t.tm_year = yea-1900;    // Year - 1900
                t.tm_mon = mon;          // Month, where 0 = jan
                t.tm_mday = day;         // Day of the month
                t.tm_hour = 0;
                t.tm_min = 0;
                t.tm_sec = 0;
                t.tm_isdst = 0;         // Is DST on? 1 = yes, 0 = no, -1 = unknown
                epoch_t = mktime(&t);               
                return epoch_t;
            }           
        }
    }
    return(-1);
}