问题
I'm working through some compile errors when building OpenSSL with no-asm -ansi
. I'm catching the error:
$ ./config no-asm -ansi
...
$ make
...
gcc -DDSO_DLFCN -DHAVE_DLFCN_H -DOPENSSL_THREADS -DOPENSSL_NO_STATIC_ENGINE -DOPENSSL_PIC
-DOPENSSLDIR="\"/usr/local/ssl\"" -DENGINESDIR="\"/usr/local/lib/engines\"" -Wall -O3
-pthread -m64 -DL_ENDIAN -ansi -fPIC -Iinclude -I. -Icrypto/include -MMD -MF
crypto/bio/bss_dgram.d.tmp -MT crypto/bio/bss_dgram.o -c -o crypto/bio/bss_dgram.o
crypto/bio/bss_dgram.c
In file included from /usr/include/netdb.h:27:0,
from ./e_os.h:443,
from crypto/bio/bio_lcl.h:2,
from crypto/bio/bss_dgram.c:62:
crypto/bio/bss_dgram.c: In function ‘dgram_get_mtu_overhead’:
crypto/bio/bss_dgram.c:433:20: error: ‘const struct in6_addr’ has no member named ‘s6_addr32’
&& IN6_IS_ADDR_V4MAPPED(&tmp_addr))
^
I found the struct in /usr/include/linux/in6.h
:
#if __UAPI_DEF_IN6_ADDR
struct in6_addr {
union {
__u8 u6_addr8[16];
#if __UAPI_DEF_IN6_ADDR_ALT
__be16 u6_addr16[8];
__be32 u6_addr32[4];
#endif
} in6_u;
#define s6_addr in6_u.u6_addr8
#if __UAPI_DEF_IN6_ADDR_ALT
#define s6_addr16 in6_u.u6_addr16
#define s6_addr32 in6_u.u6_addr32
#endif
};
#endif /* __UAPI_DEF_IN6_ADDR */
I don't recall needing to define __UAPI_DEF_IN6_ADDR_ALT
in the past. Searching for it reveals the following from the kernel's libc-compat.h, line 95 or so (if I am parsing it correctly):
#define __UAPI_DEF_IN6_ADDR 1
/* We unconditionally define the in6_addr macros and glibc must coordinate. */
#define __UAPI_DEF_IN6_ADDR_ALT 1
#define __UAPI_DEF_SOCKADDR_IN6 1
#define __UAPI_DEF_IPV6_MREQ 1
#define __UAPI_DEF_IPPROTO_V6 1
#define __UAPI_DEF_IPV6_OPTIONS 1
#define __UAPI_DEF_IN6_PKTINFO 1
#define __UAPI_DEF_IP6_MTUINFO 1
How should I proceed to get the alternate symbols defined?
The system is Ubuntu 14.04 (x86_64):
$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 14.04.4 LTS
Release: 14.04
Codename: trusty
GCC is:
$ gcc --version
gcc (Ubuntu 4.8.4-2ubuntu1~14.04.1) 4.8.4
Copyright (C) 2013 Free Software Foundation, Inc.
回答1:
This turned out to be interesting... The short of it is I needed to add both -ansi
and -D_DEFAULT_SOURCE=1
. However, -D_DEFAULT_SOURCE=1
kind of undoes what -ansi
is trying to accomplish so it needs to be contained.
First, /usr/include/linux/in6.h
was the wrong header. I found it through a grep for struct in6_addr
, and not tracing includes like needed to be done.
Next... -D_DEFAULT_SOURCE=1
indirectly came from /usr/include/netinet/in.h
:
#ifndef __USE_KERNEL_IPV6_DEFS
/* IPv6 address */
struct in6_addr
{
union
{
uint8_t __u6_addr8[16];
#ifdef __USE_MISC
uint16_t __u6_addr16[8];
uint32_t __u6_addr32[4];
#endif
} __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 */
Manually enabling __USE_MISC
did not work. Tracing things for __USE_MISC
in /usr/include/features.h
:
/*
...
__USE_MISC Define things from 4.3BSD or System V Unix.
...
*/
#undef __USE_MISC
...
#if defined _DEFAULT_SOURCE
# define __USE_MISC 1
#endif
And finally, from a comment in /usr/include/features.h
:
_DEFAULT_SOURCE The default set of features (taking precedence over __STRICT_ANSI__).
Though _DEFAULT_SOURCE=1
diverges from -ansi
, the impact can be limited to the one source file that's affected by IN6_IS_ADDR_V4MAPPED
. That is, in for the C source file crypto/bio/bss_dgram.c
:
/* OpenSSL copyright ... */
#ifndef _DEFAULT_SOURCE
# define _DEFAULT_SOURCE 1
#endif
#include <stdio.h>
#include <errno.h>
#include <netinet/in.h>
...
Fiddling with __USE_KERNEL_IPV6_DEFS
made things even worse. I believe it enabled /usr/include/linux/in6.h
, which had similar (but completely different) member names than <netinet/in.h>
.
来源:https://stackoverflow.com/questions/36220341/struct-in6-addr-has-no-member-named-s6-addr32-with-ansi