zoukankan      html  css  js  c++  java
  • __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就不同了。

    总结:

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

  • 相关阅读:
    Study Plan The Twelfth Day
    Study Plan The Fifteenth Day
    Study Plan The Seventeenth Day
    Study Plan The Tenth Day
    Study Plan The Eighth Day
    Study Plan The Eleventh Day
    Study Plan The Sixteenth Day
    Study Plan The Thirteenth Day
    Study Plan The Fourteenth Day
    Study Plan The Ninth Day
  • 原文地址:https://www.cnblogs.com/huoqs/p/14277675.html
Copyright © 2011-2022 走看看