undefined reference to `stime‘引发的查看glibc版本号

undefined reference to `stime’

在编译代码是出现了“undefined reference to `stime’”。实际上这个代码在公司的编译服务器(Ubuntu16.4)上并没有这个问题,但是有个同事使用的是Ubuntu20.4版本,编译的时候一直提示未定义。
查阅资料或者man手册(Ubuntu20.4中才有):

DESCRIPTION         top
       NOTE: This function is deprecated; use clock_settime(2) instead.

       stime() sets the system's idea of the time and date.  The time,
       pointed to by t, is measured in seconds since the Epoch,
       1970-01-01 00:00:00 +0000 (UTC).  stime() may be executed only by
       the superuser.
       #不建议使用此功能;使用clock_settime(2)代替。stime()设置系统的时间和日期概念。
       #时间,t所指向的时间,是自大纪元以来的秒数,1970-01-01 00:00:00 +0000(UTC)。 stime()只能由超级用户执行。

NOTES
       Starting with glibc 2.31, this function is no longer available to newly linked applications and is no longer declared in <time.h>.
       #从glibc2.31开始,此函数不再适用于新链接的应用程序,并且不再在<time.h>中声明。

然后查看ubuntu16.4和20.4的glibc版本使用一下命令:

(16.4) wu@wu:~$ ldd --version
ldd (Ubuntu GLIBC 2.23-0ubuntu10) 2.23
Copyright (C) 2016 自由软件基金会。
这是一个自由软件;请见源代码的授权条款。本软件不含任何没有担保;甚至不保证适销性
或者适合某些特殊目的。
由 Roland McGrath 和 Ulrich Drepper 编写。
(20.4) wu@wu:~$ ldd --version
ldd (Ubuntu GLIBC 2.31-0ubuntu9.2) 2.31
Copyright (C) 2020 自由软件基金会。。。。

正好说明了为什么在16.4中man手册没有NOTE的相关说明
解决版本办法则是:

...
#if __GLIBC_MINOR__ == 31
        struct timespec res;
        res.tv_sec = set_now;
        clock_settime(CLOCK_REALTIME,&res);
#else
        stime(&set_now);
#endif
...

至此,编译问题解决了。但是这个问题并不是我解决的,我只是想学一下别人的思路,即,他是如何知道这个宏的—— “__GLIBC_MINOR__”。于是我自己查阅资料,装作自己没见过这个。

如何找到这个宏 __GLIBC_MINOR__

从一开始查怎么看glibc的版本号,发现都是在告诉你命令行怎么查看,并没有相关宏的信息。再到在源码中是如何确定这个版本号的,根据这个作者的提供:
https://stackoverflow.com/questions/9705660/check-glibc-version-for-a-particular-gcc-compiler

/*
* 如果您关心的是编译时版本(即在中提供标头的版本/usr/include),则应查看宏__GLIBC__和__GLIBC_MINOR__。
* 这些扩展为正整数,将被定义为包括GNU C库提供的任何头文件的副作用;
* 这意味着您可以包含标准标头,然后使用#ifdef __GLIBC__来决定是否可以包含非标准标头,
* 例如gnu/libc-version.h 
* 
* 测试代码
*/
#include <stdio.h>
#ifdef  __GLIBC__
#include <gnu/libc-version.h>
#endif
int
main(void)
{
#ifdef __GLIBC __
  printf("GNU libc compile-time version: %u.%u\n", __GLIBC__,  __GLIBC_MINOR__);
  printf("GNU libc runtime version:      %s\n", gnu_get_libc_version());
  return 0;
#else
  puts("Not the GNU C Library");
  return 1;
#endif
}
# 查看依赖
(16.4)
wu@wu:~$ ldd a.out |grep libc
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fb08328a000)
        
# 执行结果:
wu@wu:~$ ./a.out
wu@wu:~$ GNU libc compile-time version: 2.23
wu@wu:~$ GNU libc runtime version:      2.23


(20.4)
wu@wu:~$ ./a.out
wu@wu:~$ GNU libc compile-time version: 2.31
wu@wu:~$ GNU libc runtime version:      2.31

基本可以确定,glibc的版本好是由这两个宏共同定义的.

之后又在另外篇博客上看到了这两个宏的说明:

GUN C 语言函数库是 Linux 上最常用的库 (glibc) http://www.gnu.org/
应用程序可以通过测试常量和调用库函数两种方法,来确定系统安装的glibc版本,从2.0开始,glibc提供两个常量__GLIBC__ 和 __GLIBC_MINOR__

  • 6
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值