Initial step towards the ability to reduce c-ares exported symbols

based on the 'visibility' attribute for GNUC and __global for Sun
compilers, taking also in account __declspec function decoration
for Win32 and Symbian DLL's.

Introducing configure options --enable-hidden-symbols and
--disable-hidden-symbols following libcurl's naming.
This commit is contained in:
Yang Tse
2009-10-28 19:45:26 +00:00
parent a732ace461
commit 9cac6a4625
5 changed files with 370 additions and 72 deletions
+1 -3
View File
@@ -91,9 +91,7 @@ if NO_UNDEFINED
UNDEF = -no-undefined UNDEF = -no-undefined
endif endif
# EXPORT_SYMBOLS = -export-symbols-regex '^ares_[[:alnum:]].*' libcares_la_LDFLAGS = $(UNDEF) $(VER)
libcares_la_LDFLAGS = $(UNDEF) $(VER) $(EXPORT_SYMBOLS)
# Makefile.inc provides the CSOURCES and HHEADERS defines # Makefile.inc provides the CSOURCES and HHEADERS defines
include Makefile.inc include Makefile.inc
+180 -58
View File
@@ -45,9 +45,9 @@
#endif #endif
#if defined(WATT32) #if defined(WATT32)
#include <netinet/in.h> # include <netinet/in.h>
#include <sys/socket.h> # include <sys/socket.h>
#include <tcp.h> # include <tcp.h>
#elif defined(WIN32) #elif defined(WIN32)
# ifndef WIN32_LEAN_AND_MEAN # ifndef WIN32_LEAN_AND_MEAN
# define WIN32_LEAN_AND_MEAN # define WIN32_LEAN_AND_MEAN
@@ -56,14 +56,36 @@
# include <winsock2.h> # include <winsock2.h>
# include <ws2tcpip.h> # include <ws2tcpip.h>
#else #else
#include <sys/socket.h> # include <sys/socket.h>
#include <netinet/in.h> # include <netinet/in.h>
#endif #endif
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
/*
** c-ares external API function linkage decorations.
*/
#if !defined(CARES_STATICLIB) && \
(defined(WIN32) || defined(_WIN32) || defined(__SYMBIAN32__))
/* __declspec function decoration for Win32 and Symbian DLL's */
# if defined(CARES_BUILDING_LIB)
# define CARES_EXTERN __declspec(dllexport)
# else
# define CARES_EXTERN __declspec(dllimport)
# endif
#else
/* visibility function decoration for other cases */
# ifdef CARES_HIDDEN_SYMBOLS
# define CARES_EXTERN CARES_EXTERN_SYMBOL
# else
# define CARES_EXTERN
# endif
#endif
#define ARES_SUCCESS 0 #define ARES_SUCCESS 0
/* Server error codes (ARES_ENODATA indicates no relevant answer) */ /* Server error codes (ARES_ENODATA indicates no relevant answer) */
@@ -241,62 +263,143 @@ struct hostent;
struct timeval; struct timeval;
struct sockaddr; struct sockaddr;
struct ares_channeldata; struct ares_channeldata;
typedef struct ares_channeldata *ares_channel; typedef struct ares_channeldata *ares_channel;
typedef void (*ares_callback)(void *arg, int status, int timeouts,
unsigned char *abuf, int alen); typedef void (*ares_callback)(void *arg,
typedef void (*ares_host_callback)(void *arg, int status, int timeouts, int status,
int timeouts,
unsigned char *abuf,
int alen);
typedef void (*ares_host_callback)(void *arg,
int status,
int timeouts,
struct hostent *hostent); struct hostent *hostent);
typedef void (*ares_nameinfo_callback)(void *arg, int status, int timeouts,
char *node, char *service); typedef void (*ares_nameinfo_callback)(void *arg,
int status,
int timeouts,
char *node,
char *service);
typedef int (*ares_sock_create_callback)(ares_socket_t socket_fd, typedef int (*ares_sock_create_callback)(ares_socket_t socket_fd,
int type, void *data); int type,
void *data);
int ares_library_init(int flags); CARES_EXTERN int ares_library_init(int flags);
void ares_library_cleanup(void);
const char *ares_version(int *version);
int ares_init(ares_channel *channelptr); CARES_EXTERN void ares_library_cleanup(void);
int ares_init_options(ares_channel *channelptr, struct ares_options *options,
CARES_EXTERN const char *ares_version(int *version);
CARES_EXTERN int ares_init(ares_channel *channelptr);
CARES_EXTERN int ares_init_options(ares_channel *channelptr,
struct ares_options *options,
int optmask); int optmask);
int ares_save_options(ares_channel channel, struct ares_options *options,
CARES_EXTERN int ares_save_options(ares_channel channel,
struct ares_options *options,
int *optmask); int *optmask);
void ares_destroy_options(struct ares_options *options);
int ares_dup(ares_channel *dest, ares_channel src); CARES_EXTERN void ares_destroy_options(struct ares_options *options);
void ares_destroy(ares_channel channel);
void ares_cancel(ares_channel channel); CARES_EXTERN int ares_dup(ares_channel *dest,
ares_channel src);
CARES_EXTERN void ares_destroy(ares_channel channel);
CARES_EXTERN void ares_cancel(ares_channel channel);
void ares_set_socket_callback(ares_channel channel, void ares_set_socket_callback(ares_channel channel,
ares_sock_create_callback callback, ares_sock_create_callback callback,
void *user_data); void *user_data);
void ares_send(ares_channel channel, const unsigned char *qbuf, int qlen,
ares_callback callback, void *arg); CARES_EXTERN void ares_send(ares_channel channel,
void ares_query(ares_channel channel, const char *name, int dnsclass, const unsigned char *qbuf,
int type, ares_callback callback, void *arg); int qlen,
void ares_search(ares_channel channel, const char *name, int dnsclass, ares_callback callback,
int type, ares_callback callback, void *arg); void *arg);
void ares_gethostbyname(ares_channel channel, const char *name, int family,
ares_host_callback callback, void *arg); CARES_EXTERN void ares_query(ares_channel channel,
int ares_gethostbyname_file(ares_channel channel, const char *name, const char *name,
int family, struct hostent **host); int dnsclass,
void ares_gethostbyaddr(ares_channel channel, const void *addr, int addrlen, int type,
int family, ares_host_callback callback, void *arg); ares_callback callback,
void ares_getnameinfo(ares_channel channel, const struct sockaddr *sa, void *arg);
ares_socklen_t salen, int flags,
CARES_EXTERN void ares_search(ares_channel channel,
const char *name,
int dnsclass,
int type,
ares_callback callback,
void *arg);
CARES_EXTERN void ares_gethostbyname(ares_channel channel,
const char *name,
int family,
ares_host_callback callback,
void *arg);
CARES_EXTERN int ares_gethostbyname_file(ares_channel channel,
const char *name,
int family,
struct hostent **host);
CARES_EXTERN void ares_gethostbyaddr(ares_channel channel,
const void *addr,
int addrlen,
int family,
ares_host_callback callback,
void *arg);
CARES_EXTERN void ares_getnameinfo(ares_channel channel,
const struct sockaddr *sa,
ares_socklen_t salen,
int flags,
ares_nameinfo_callback callback, ares_nameinfo_callback callback,
void *arg); void *arg);
int ares_fds(ares_channel channel, fd_set *read_fds, fd_set *write_fds);
int ares_getsock(ares_channel channel, int *socks, int numsocks); CARES_EXTERN int ares_fds(ares_channel channel,
struct timeval *ares_timeout(ares_channel channel, struct timeval *maxtv, fd_set *read_fds,
fd_set *write_fds);
CARES_EXTERN int ares_getsock(ares_channel channel,
int *socks,
int numsocks);
CARES_EXTERN struct timeval *ares_timeout(ares_channel channel,
struct timeval *maxtv,
struct timeval *tv); struct timeval *tv);
void ares_process(ares_channel channel, fd_set *read_fds, fd_set *write_fds);
void ares_process_fd(ares_channel channel, ares_socket_t read_fd, CARES_EXTERN void ares_process(ares_channel channel,
fd_set *read_fds,
fd_set *write_fds);
CARES_EXTERN void ares_process_fd(ares_channel channel,
ares_socket_t read_fd,
ares_socket_t write_fd); ares_socket_t write_fd);
int ares_mkquery(const char *name, int dnsclass, int type, unsigned short id, CARES_EXTERN int ares_mkquery(const char *name,
int rd, unsigned char **buf, int *buflen); int dnsclass,
int ares_expand_name(const unsigned char *encoded, const unsigned char *abuf, int type,
int alen, char **s, long *enclen); unsigned short id,
int ares_expand_string(const unsigned char *encoded, const unsigned char *abuf, int rd,
int alen, unsigned char **s, long *enclen); unsigned char **buf,
int *buflen);
CARES_EXTERN int ares_expand_name(const unsigned char *encoded,
const unsigned char *abuf,
int alen,
char **s,
long *enclen);
CARES_EXTERN int ares_expand_string(const unsigned char *encoded,
const unsigned char *abuf,
int alen,
unsigned char **s,
long *enclen);
/* /*
* NOTE: before c-ares 1.6.1 we would most often use the system in6_addr * NOTE: before c-ares 1.6.1 we would most often use the system in6_addr
@@ -338,21 +441,40 @@ struct srv_reply {
** their TTLs in that array, and set *naddrttls to the number of addresses ** their TTLs in that array, and set *naddrttls to the number of addresses
** so written. ** so written.
*/ */
int ares_parse_a_reply(const unsigned char *abuf, int alen,
CARES_EXTERN int ares_parse_a_reply(const unsigned char *abuf,
int alen,
struct hostent **host, struct hostent **host,
struct addrttl *addrttls, int *naddrttls); struct addrttl *addrttls,
int ares_parse_aaaa_reply(const unsigned char *abuf, int alen, int *naddrttls);
CARES_EXTERN int ares_parse_aaaa_reply(const unsigned char *abuf,
int alen,
struct hostent **host, struct hostent **host,
struct addr6ttl *addrttls, int *naddrttls); struct addr6ttl *addrttls,
int ares_parse_ptr_reply(const unsigned char *abuf, int alen, const void *addr, int *naddrttls);
int addrlen, int family, struct hostent **host);
int ares_parse_ns_reply(const unsigned char *abuf, int alen, CARES_EXTERN int ares_parse_ptr_reply(const unsigned char *abuf,
int alen,
const void *addr,
int addrlen,
int family,
struct hostent **host); struct hostent **host);
int ares_parse_srv_reply(const unsigned char* abuf, int alen,
struct srv_reply** srv_out, int *nsrvreply); CARES_EXTERN int ares_parse_ns_reply(const unsigned char *abuf,
void ares_free_string(void *str); int alen,
void ares_free_hostent(struct hostent *host); struct hostent **host);
const char *ares_strerror(int code);
CARES_EXTERN int ares_parse_srv_reply(const unsigned char* abuf,
int alen,
struct srv_reply** srv_out,
int *nsrvreply);
CARES_EXTERN void ares_free_string(void *str);
CARES_EXTERN void ares_free_hostent(struct hostent *host);
CARES_EXTERN const char *ares_strerror(int code);
#ifdef __cplusplus #ifdef __cplusplus
} }
+23
View File
@@ -14,6 +14,7 @@ CARES_CHECK_OPTION_DEBUG
CARES_CHECK_OPTION_OPTIMIZE CARES_CHECK_OPTION_OPTIMIZE
CARES_CHECK_OPTION_WARNINGS CARES_CHECK_OPTION_WARNINGS
CARES_CHECK_OPTION_CURLDEBUG CARES_CHECK_OPTION_CURLDEBUG
CARES_CHECK_OPTION_HIDDEN_SYMBOLS
CARES_CHECK_PATH_SEPARATOR_REQUIRED CARES_CHECK_PATH_SEPARATOR_REQUIRED
@@ -110,6 +111,25 @@ esac
dnl libtool setup dnl libtool setup
AC_PROG_LIBTOOL AC_PROG_LIBTOOL
AC_MSG_CHECKING([if we need CARES_BUILDING_LIB])
case $host in
*-*-mingw*)
AC_DEFINE(CARES_BUILDING_LIB, 1, [when building c-ares library])
AC_MSG_RESULT(yes)
AC_MSG_CHECKING([if we need CARES_STATICLIB])
if test "X$enable_shared" = "Xno"
then
AC_DEFINE(CARES_STATICLIB, 1, [when not building a shared library])
AC_MSG_RESULT(yes)
else
AC_MSG_RESULT(no)
fi
;;
*)
AC_MSG_RESULT(no)
;;
esac
dnl ********************************************************************** dnl **********************************************************************
dnl platform/compiler/architecture specific checks/flags dnl platform/compiler/architecture specific checks/flags
dnl ********************************************************************** dnl **********************************************************************
@@ -144,6 +164,7 @@ esac
CARES_CHECK_COMPILER_HALT_ON_ERROR CARES_CHECK_COMPILER_HALT_ON_ERROR
CARES_CHECK_COMPILER_ARRAY_SIZE_NEGATIVE CARES_CHECK_COMPILER_ARRAY_SIZE_NEGATIVE
CARES_CHECK_COMPILER_HIDDEN_SYMBOLS
CARES_CHECK_NO_UNDEFINED CARES_CHECK_NO_UNDEFINED
AM_CONDITIONAL(NO_UNDEFINED, test x$need_no_undefined = xyes) AM_CONDITIONAL(NO_UNDEFINED, test x$need_no_undefined = xyes)
@@ -876,6 +897,8 @@ fi
CARES_CHECK_OPTION_NONBLOCKING CARES_CHECK_OPTION_NONBLOCKING
CARES_CHECK_NONBLOCKING_SOCKET CARES_CHECK_NONBLOCKING_SOCKET
CARES_CONFIGURE_HIDDEN_SYMBOLS
CARES_PRIVATE_LIBS="$LIBS" CARES_PRIVATE_LIBS="$LIBS"
AC_SUBST(CARES_PRIVATE_LIBS) AC_SUBST(CARES_PRIVATE_LIBS)
+95 -1
View File
@@ -16,7 +16,7 @@
#*************************************************************************** #***************************************************************************
# File version for 'aclocal' use. Keep it a single number. # File version for 'aclocal' use. Keep it a single number.
# serial 56 # serial 59
dnl CARES_CHECK_COMPILER dnl CARES_CHECK_COMPILER
@@ -1249,6 +1249,100 @@ AC_DEFUN([CARES_CHECK_COMPILER_ARRAY_SIZE_NEGATIVE], [
]) ])
dnl CARES_CHECK_COMPILER_HIDDEN_SYMBOLS
dnl -------------------------------------------------
dnl Verify if compiler supports hiding library internal symbols, setting
dnl shell variable hidden_symbols_supported value as appropriate, as well
dnl as variable hidden_symbols_CFLAGS when supported.
AC_DEFUN([CARES_CHECK_COMPILER_HIDDEN_SYMBOLS], [
AC_REQUIRE([CARES_CHECK_COMPILER])dnl
AC_BEFORE([$0],[CARES_CONFIGURE_HIDDEN_SYMBOLS])dnl
AC_MSG_CHECKING([if compiler supports hiding library internal symbols])
hidden_symbols_supported="no"
hidden_symbols_CFLAGS=""
tmp_CFLAGS=""
tmp_extern=""
case "$compiler_id" in
GNU_C)
dnl Only gcc 3.4 or later
if test "$compiler_num" -ge "304"; then
if $CC --help --verbose 2>&1 | grep fvisibility= > /dev/null ; then
tmp_extern="__attribute__ ((visibility (\"default\")))"
tmp_CFLAGS="-fvisibility=hidden"
hidden_symbols_supported="yes"
echo " " >&6
echo "debug: should work with this compiler and version" >&6
echo " " >&6
fi
fi
;;
INTEL_UNIX_C)
dnl Only icc 9.0 or later
if test "$compiler_num" -ge "900"; then
if $CC --help --verbose 2>&1 | grep fvisibility= > /dev/null ; then
tmp_extern="__attribute__ ((visibility (\"default\")))"
tmp_CFLAGS="-fvisibility=hidden"
hidden_symbols_supported="yes"
echo " " >&6
echo "debug: should work with this compiler and version" >&6
echo " " >&6
fi
fi
;;
SUNPRO_C)
if $CC 2>&1 | grep flags >/dev/null && $CC -flags | grep xldscope= >/dev/null ; then
tmp_extern="__global"
tmp_CFLAGS="-xldscope=hidden"
hidden_symbols_supported="yes"
echo " " >&6
echo "debug: should work with this compiler and version" >&6
echo " " >&6
fi
;;
esac
if test "$hidden_symbols_supported" = "yes"; then
tmp_save_CFLAGS="$CFLAGS"
CFLAGS="$tmp_save_CFLAGS $tmp_CFLAGS"
squeeze CFLAGS
AC_COMPILE_IFELSE([
AC_LANG_PROGRAM([[
$tmp_extern char *dummy(char *buff);
char *dummy(char *buff)
{
if(buff)
return ++buff;
else
return buff;
}
]],[[
char b[16];
char *r = dummy(&b);
if(r)
return (int)*r;
]])
],[
hidden_symbols_supported="yes"
],[
hidden_symbols_supported="no"
sed 's/^/cc-src: /' conftest.$ac_ext >&6
sed 's/^/cc-err: /' conftest.err >&6
])
CFLAGS="$tmp_save_CFLAGS"
fi
if test "$hidden_symbols_supported" = "yes"; then
AC_MSG_RESULT([yes])
AC_DEFINE_UNQUOTED(CARES_HIDDEN_SYMBOLS, 1,
[Define to 1 to enable hiding of library internal symbols.])
AC_DEFINE_UNQUOTED(CARES_EXTERN_SYMBOL, $tmp_extern,
[Definition to make a library symbol externally visible.])
hidden_symbols_CFLAGS="$tmp_CFLAGS"
else
AC_MSG_RESULT([no])
fi
])
dnl CARES_CHECK_COMPILER_STRUCT_MEMBER_SIZE dnl CARES_CHECK_COMPILER_STRUCT_MEMBER_SIZE
dnl ------------------------------------------------- dnl -------------------------------------------------
dnl Verifies if the compiler is capable of handling the dnl Verifies if the compiler is capable of handling the
+62 -1
View File
@@ -16,7 +16,7 @@
#*************************************************************************** #***************************************************************************
# File version for 'aclocal' use. Keep it a single number. # File version for 'aclocal' use. Keep it a single number.
# serial 5 # serial 6
dnl CARES_CHECK_OPTION_CURLDEBUG dnl CARES_CHECK_OPTION_CURLDEBUG
@@ -92,6 +92,46 @@ AC_HELP_STRING([--disable-debug],[Disable debug build options]),
]) ])
dnl CARES_CHECK_OPTION_HIDDEN_SYMBOLS
dnl -------------------------------------------------
dnl Verify if configure has been invoked with option
dnl --enable-hidden-symbols or --disable-hidden-symbols,
dnl setting shell variable want_hidden_symbols value.
AC_DEFUN([CARES_CHECK_OPTION_HIDDEN_SYMBOLS], [
AC_BEFORE([$0],[CARES_CHECK_COMPILER_HIDDEN_SYMBOLS])dnl
AC_MSG_CHECKING([whether to enable hiding symbols])
OPT_HIDDEN_SYMBOLS="default"
AC_ARG_ENABLE(hidden-symbols,
AC_HELP_STRING([--enable-hidden-symbols],[Enable hiding of library internal symbols])
AC_HELP_STRING([--disable-hidden-symbols],[Disable hiding of library internal symbols]),
OPT_HIDDEN_SYMBOLS=$enableval)
case "$OPT_HIDDEN_SYMBOLS" in
no)
dnl --disable-hidden-symbols option used.
dnl This is an indication to not attempt hiding of library internal
dnl symbols. Default symbol visibility will be used, which normally
dnl exposes all library internal symbols.
want_hidden_symbols="no"
AC_MSG_RESULT([no])
;;
default)
dnl configure's hidden-symbols option not specified.
dnl Handle this as if --enable-hidden-symbols option was given.
want_hidden_symbols="yes"
AC_MSG_RESULT([not specified (assuming yes)])
;;
*)
dnl --enable-hidden-symbols option used.
dnl This is an indication to attempt hiding of library internal
dnl symbols. This is only supported on some compilers/linkers.
want_hidden_symbols="yes"
AC_MSG_RESULT([yes])
;;
esac
])
dnl CARES_CHECK_OPTION_NONBLOCKING dnl CARES_CHECK_OPTION_NONBLOCKING
dnl ------------------------------------------------- dnl -------------------------------------------------
dnl Verify if configure has been invoked with option dnl Verify if configure has been invoked with option
@@ -252,3 +292,24 @@ AC_DEFUN([CARES_CHECK_NONBLOCKING_SOCKET], [
fi fi
]) ])
dnl CARES_CONFIGURE_HIDDEN_SYMBOLS
dnl -------------------------------------------------
dnl Depending on --enable-hidden-symbols or --disable-hidden-symbols
dnl configure option, and compiler capability to actually honor such
dnl option, compiler flags will be modified as appropriate.
dnl This macro should not be used until all compilation tests have
dnl been done to prevent interferences on other tests.
AC_DEFUN([CARES_CONFIGURE_HIDDEN_SYMBOLS], [
AC_MSG_CHECKING([whether to actually hide library internal symbols])
if test "$want_hidden_symbols" = "yes" &&
test "$hidden_symbols_supported" = "yes"; then
tmp_save_CFLAGS="$CFLAGS"
CFLAGS="$tmp_save_CFLAGS $hidden_symbols_CFLAGS"
AC_MSG_RESULT([yes])
else
AC_MSG_RESULT([no])
fi
])