怎么在 C 代码中知道自己用 C 标准库是 musl libc?

2021-01-09 17:58:58 +08:00
 c137rick

Linux 下常见的 C 标准库为 glibc,可以通过宏 __GLIBC__ 识别,但是 musl libc 没有提供类似 __MUSL__ 这样的宏来进行标记(官方解释),那么应该怎么在 C 代码中识别呢?最好不要因为这个写两套代码。

起因就是 glibc 和 musl libc 中 struct in6_addr 的成员名不一样导致编译错误。

/* musl libc 的实现 */

struct in6_addr {
        union {
                uint8_t __s6_addr[16];
                uint16_t __s6_addr16[8];
                uint32_t __s6_addr32[4];
        } __in6_union;
};
/* glibc 实现 */

#if !__USE_KERNEL_IPV6_DEFS
/* IPv6 address */
struct in6_addr
  {
    union
      {
	uint8_t	__u6_addr8[16];
	uint16_t __u6_addr16[8];
	uint32_t __u6_addr32[4];
      } __in6_u;
#define s6_addr			__in6_u.__u6_addr8
#ifdef __USE_MISC
# define s6_addr16		__in6_u.__u6_addr16
# define s6_addr32		__in6_u.__u6_addr32
#endif
  };
#endif /* !__USE_KERNEL_IPV6_DEFS */

目前一个不怎么靠谱的想法是排除法。可以通过宏识别 glibc 、eglibc 和 uclibc 。算上 musl libc 常见的大概也就这四个吧?那么通过宏识别到都不是 glibc 、eglibc 和 uclibc 后,就默认是 musl libc 。但是说实话不太靠谱,因为万一还有别的库就容易出问题。

1558 次点击
所在节点    问与答
4 条回复
favourstreet
2021-01-09 18:26:30 +08:00
人家成员名前面加了一个下划线还不够,加了两个下划线,楼主你好最好解释一下为什么要“把手伸进去”倒腾一个摆明了不给外人看的东西?
minami
2021-01-09 18:33:08 +08:00
成员名不一样,但内存长度是一样的吧,自己重定义下结构体就可以了
c137rick
2021-01-09 18:43:10 +08:00
@favourstreet #1 原因就是要分别识别 IPV6 每一个 bit 用来做成前缀树进行网段匹配,所以需要 `in6_addr.__in6_union.__s6_addr[16]`。不过这么一说确实这不应该是我了解的,按照二楼的方法重新定一个结构体就行了。
c137rick
2021-01-09 18:44:55 +08:00
@minami #2 确实,这方法简单,我怎么就没想到,谢啦。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/743369

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX