__USE_KERNEL_IPV6_DEFS 定义问题排查

背景:

想编译一下阿里云iot的 sdk4.0(主要是学习目的),下载后,直接执行make命令,报错信息如下:

: Compiling portfiles/aiot_port/posix_port.c ...
In file included from portfiles/aiot_port/posix_port.c:13:
./components/das/src/service/compat/netinet/in.h:506:48: error: ‘struct sockaddr_in6’ declared inside parameter list will not be visible outside of this definition or declaration [-Werror]
  506 | extern int bindresvport6 (int __sockfd, struct sockaddr_in6 *__sock_in)
      |                                                ^~~~~~~~~~~~
cc1: all warnings being treated as errors
make: *** [Makefile:42: output/./portfiles/aiot_port/posix_port.o] Error 1

环境:

Ubuntu 20.04 LTS

gcc --version

gcc (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0
Copyright (C) 2019 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

原因:

sdk将部分GNU C Library的源码放在了源文件路径下,但其实又没放全。导致自带的文件和系统的文件不兼容。看下头文件的声明日期。

sdk内的 netinet/in.h:

/* Copyright (C) 1991-2016 Free Software Foundation, Inc.
   This file is part of the GNU C Library.

   The GNU C Library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 of the License, or (at your option) any later version.

   The GNU C Library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, see
   <http://www.gnu.org/licenses/>.  */

系统目录下的 /usr/include/netinet/in.h

/* Copyright (C) 1991-2020 Free Software Foundation, Inc.
   This file is part of the GNU C Library.

   The GNU C Library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 of the License, or (at your option) any later version.

   The GNU C Library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, see
   <https://www.gnu.org/licenses/>.  */

两者其实都包含了文件    #include <bits/in.h>

主要问题在使用宏定义的判断方式差别。

sdk中:

#ifndef __USE_KERNEL_IPV6_DEFS
.....
#endif /* !__USE_KERNEL_IPV6_DEFS */

系统文件中:

#if !__USE_KERNEL_IPV6_DEFS
......#endif /* !__USE_KERNEL_IPV6_DEFS */

而在bits/in.h文件中,其实是不管怎样都定义了该变量的

/* If the application has already included linux/in6.h from a linux-based
   kernel then we will not define the IPv6 IPPROTO_* defines, in6_addr (nor the
   defines), sockaddr_in6, or ipv6_mreq. Same for in6_ptkinfo or ip6_mtuinfo
   in linux/ipv6.h. The ABI used by the linux-kernel and glibc match exactly.
   Neither the linux kernel nor glibc should break this ABI without coordination.
   In upstream kernel 56c176c9 the _UAPI prefix was stripped so we need to check
   for _LINUX_IN6_H and _IPV6_H now, and keep checking the old versions for
   maximum backwards compatibility.  */
#if defined _UAPI_LINUX_IN6_H 
    || defined _UAPI_IPV6_H 
    || defined _LINUX_IN6_H 
    || defined _IPV6_H
/* This is not quite the same API since the kernel always defines s6_addr16 and
   s6_addr32. This is not a violation of POSIX since POSIX says "at least the
   following member" and that holds true.  */
# define __USE_KERNEL_IPV6_DEFS 1
#else
# define __USE_KERNEL_IPV6_DEFS 0
#endif

这样会导致sdk中的判断永远为否。

这里面涉及到了,#ifndef 和 #if 的差别,简单讲,#ifndef  只管是否有这个定义,而不管这个值是真是假。而#if就不同了。

总结:

部分系统文件(特别是与其他系统文件相关的)还是不要放在源代码中好,指明最低编译器的版本即可。因为绝大部分编译器都是向后兼容的。除非特别老的代码。

原文地址:https://www.cnblogs.com/huoqs/p/14277675.html