From 37dac00e2ad6445f496e68fcf815723432ecb5a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cristian=20Rodr=C3=ADguez?= Date: Mon, 15 Nov 2010 20:31:25 +0100 Subject: src: implement both GCC visibility support and export script MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Read "How to write shared libraries" from Ulrich Drepper for more information on this patch. Specifically section 2.2: Export control and section 3: Maintaining APIs and ABIs. Signed-off-by: Cristian Rodríguez Signed-off-by: Pablo Neira Ayuso --- Make_global.am | 2 +- configure.ac | 2 +- include/libmnl/libmnl.h | 104 +++++++++++++++++++++++++----------------------- m4/visibility.m4 | 52 ++++++++++++++++++++++++ src/Makefile.am | 5 ++- src/libmnl.map | 58 +++++++++++++++++++++++++++ 6 files changed, 170 insertions(+), 53 deletions(-) create mode 100644 m4/visibility.m4 create mode 100644 src/libmnl.map diff --git a/Make_global.am b/Make_global.am index 4aff85c..b0dc429 100644 --- a/Make_global.am +++ b/Make_global.am @@ -20,5 +20,5 @@ # LIBVERSION=0:0:0 -CPPFLAGS = -I$(top_srcdir)/include +AM_CPPFLAGS = -I$(top_srcdir)/include AM_CFLAGS = -Wall -Wextra -Wno-unused-parameter diff --git a/configure.ac b/configure.ac index 9281156..6373fab 100644 --- a/configure.ac +++ b/configure.ac @@ -10,7 +10,7 @@ AM_PROG_CC_C_O AC_EXEEXT AC_DISABLE_STATIC LT_INIT - +gl_VISIBILITY case $target in *-*-linux*) ;; *) AC_MSG_ERROR([Linux only, dude!]);; diff --git a/include/libmnl/libmnl.h b/include/libmnl/libmnl.h index c4806d5..d2fc2d4 100644 --- a/include/libmnl/libmnl.h +++ b/include/libmnl/libmnl.h @@ -13,6 +13,12 @@ extern "C" { #endif +#if defined(HAVE_VISIBILITY) && defined(BUILDING_MNL) +#define MNL_API extern __attribute__ ((visibility("default"))) +#else +#define MNL_API extern +#endif + /* * Netlink socket API */ @@ -22,15 +28,15 @@ extern "C" { struct mnl_socket; -extern struct mnl_socket *mnl_socket_open(int type); -extern int mnl_socket_bind(struct mnl_socket *nl, unsigned int groups, pid_t pid); -extern int mnl_socket_close(struct mnl_socket *nl); -extern int mnl_socket_get_fd(const struct mnl_socket *nl); -extern unsigned int mnl_socket_get_portid(const struct mnl_socket *nl); -extern int mnl_socket_sendto(const struct mnl_socket *nl, const void *req, size_t siz); -extern int mnl_socket_recvfrom(const struct mnl_socket *nl, void *buf, size_t siz); -extern int mnl_socket_setsockopt(const struct mnl_socket *nl, int type, void *buf, socklen_t len); -extern int mnl_socket_getsockopt(const struct mnl_socket *nl, int type, void *buf, socklen_t *len); +MNL_API struct mnl_socket *mnl_socket_open(int type); +MNL_API int mnl_socket_bind(struct mnl_socket *nl, unsigned int groups, pid_t pid); +MNL_API int mnl_socket_close(struct mnl_socket *nl); +MNL_API int mnl_socket_get_fd(const struct mnl_socket *nl); +MNL_API unsigned int mnl_socket_get_portid(const struct mnl_socket *nl); +MNL_API int mnl_socket_sendto(const struct mnl_socket *nl, const void *req, size_t siz); +MNL_API int mnl_socket_recvfrom(const struct mnl_socket *nl, void *buf, size_t siz); +MNL_API int mnl_socket_setsockopt(const struct mnl_socket *nl, int type, void *buf, socklen_t len); +MNL_API int mnl_socket_getsockopt(const struct mnl_socket *nl, int type, void *buf, socklen_t *len); /* * Netlink message API @@ -40,31 +46,31 @@ extern int mnl_socket_getsockopt(const struct mnl_socket *nl, int type, void *bu #define MNL_ALIGN(len) (((len)+MNL_ALIGNTO-1) & ~(MNL_ALIGNTO-1)) #define MNL_NLMSG_HDRLEN MNL_ALIGN(sizeof(struct nlmsghdr)) -extern size_t mnl_nlmsg_size(size_t len); -extern size_t mnl_nlmsg_total_size(size_t len); -extern size_t mnl_nlmsg_get_payload_len(const struct nlmsghdr *nlh); +MNL_API size_t mnl_nlmsg_size(size_t len); +MNL_API size_t mnl_nlmsg_total_size(size_t len); +MNL_API size_t mnl_nlmsg_get_payload_len(const struct nlmsghdr *nlh); /* Netlink message header builder */ -extern struct nlmsghdr *mnl_nlmsg_put_header(void *buf); -extern void *mnl_nlmsg_put_extra_header(struct nlmsghdr *nlh, size_t size); +MNL_API struct nlmsghdr *mnl_nlmsg_put_header(void *buf); +MNL_API void *mnl_nlmsg_put_extra_header(struct nlmsghdr *nlh, size_t size); /* Netlink message iterators */ -extern bool mnl_nlmsg_ok(const struct nlmsghdr *nlh, int len); -extern struct nlmsghdr *mnl_nlmsg_next(const struct nlmsghdr *nlh, int *len); +MNL_API bool mnl_nlmsg_ok(const struct nlmsghdr *nlh, int len); +MNL_API struct nlmsghdr *mnl_nlmsg_next(const struct nlmsghdr *nlh, int *len); /* Netlink sequence tracking */ -extern bool mnl_nlmsg_seq_ok(const struct nlmsghdr *nlh, unsigned int seq); +MNL_API bool mnl_nlmsg_seq_ok(const struct nlmsghdr *nlh, unsigned int seq); /* Netlink portID checking */ -extern bool mnl_nlmsg_portid_ok(const struct nlmsghdr *nlh, unsigned int portid); +MNL_API bool mnl_nlmsg_portid_ok(const struct nlmsghdr *nlh, unsigned int portid); /* Netlink message getters */ -extern void *mnl_nlmsg_get_payload(const struct nlmsghdr *nlh); -extern void *mnl_nlmsg_get_payload_offset(const struct nlmsghdr *nlh, size_t offset); -extern void *mnl_nlmsg_get_payload_tail(const struct nlmsghdr *nlh); +MNL_API void *mnl_nlmsg_get_payload(const struct nlmsghdr *nlh); +MNL_API void *mnl_nlmsg_get_payload_offset(const struct nlmsghdr *nlh, size_t offset); +MNL_API void *mnl_nlmsg_get_payload_tail(const struct nlmsghdr *nlh); /* Netlink message printer */ -extern void mnl_nlmsg_fprintf(FILE *fd, const void *data, size_t datalen, size_t extra_header_size); +MNL_API void mnl_nlmsg_fprintf(FILE *fd, const void *data, size_t datalen, size_t extra_header_size); /* * Netlink attributes API @@ -72,31 +78,31 @@ extern void mnl_nlmsg_fprintf(FILE *fd, const void *data, size_t datalen, size_t #define MNL_ATTR_HDRLEN MNL_ALIGN(sizeof(struct nlattr)) /* TLV attribute getters */ -extern uint16_t mnl_attr_get_type(const struct nlattr *attr); -extern uint16_t mnl_attr_get_len(const struct nlattr *attr); -extern uint16_t mnl_attr_get_payload_len(const struct nlattr *attr); -extern void *mnl_attr_get_payload(const struct nlattr *attr); -extern uint8_t mnl_attr_get_u8(const struct nlattr *attr); -extern uint16_t mnl_attr_get_u16(const struct nlattr *attr); -extern uint32_t mnl_attr_get_u32(const struct nlattr *attr); -extern uint64_t mnl_attr_get_u64(const struct nlattr *attr); -extern const char *mnl_attr_get_str(const struct nlattr *attr); +MNL_API uint16_t mnl_attr_get_type(const struct nlattr *attr); +MNL_API uint16_t mnl_attr_get_len(const struct nlattr *attr); +MNL_API uint16_t mnl_attr_get_payload_len(const struct nlattr *attr); +MNL_API void *mnl_attr_get_payload(const struct nlattr *attr); +MNL_API uint8_t mnl_attr_get_u8(const struct nlattr *attr); +MNL_API uint16_t mnl_attr_get_u16(const struct nlattr *attr); +MNL_API uint32_t mnl_attr_get_u32(const struct nlattr *attr); +MNL_API uint64_t mnl_attr_get_u64(const struct nlattr *attr); +MNL_API const char *mnl_attr_get_str(const struct nlattr *attr); /* TLV attribute putters */ -extern void mnl_attr_put(struct nlmsghdr *nlh, uint16_t type, size_t len, const void *data); -extern void mnl_attr_put_u8(struct nlmsghdr *nlh, uint16_t type, uint8_t data); -extern void mnl_attr_put_u16(struct nlmsghdr *nlh, uint16_t type, uint16_t data); -extern void mnl_attr_put_u32(struct nlmsghdr *nlh, uint16_t type, uint32_t data); -extern void mnl_attr_put_u64(struct nlmsghdr *nlh, uint16_t type, uint64_t data); -extern void mnl_attr_put_str(struct nlmsghdr *nlh, uint16_t type, const char *data); -extern void mnl_attr_put_strz(struct nlmsghdr *nlh, uint16_t type, const char *data); +MNL_API void mnl_attr_put(struct nlmsghdr *nlh, uint16_t type, size_t len, const void *data); +MNL_API void mnl_attr_put_u8(struct nlmsghdr *nlh, uint16_t type, uint8_t data); +MNL_API void mnl_attr_put_u16(struct nlmsghdr *nlh, uint16_t type, uint16_t data); +MNL_API void mnl_attr_put_u32(struct nlmsghdr *nlh, uint16_t type, uint32_t data); +MNL_API void mnl_attr_put_u64(struct nlmsghdr *nlh, uint16_t type, uint64_t data); +MNL_API void mnl_attr_put_str(struct nlmsghdr *nlh, uint16_t type, const char *data); +MNL_API void mnl_attr_put_strz(struct nlmsghdr *nlh, uint16_t type, const char *data); /* TLV attribute nesting */ -extern struct nlattr *mnl_attr_nest_start(struct nlmsghdr *nlh, uint16_t type); -extern void mnl_attr_nest_end(struct nlmsghdr *nlh, struct nlattr *start); +MNL_API struct nlattr *mnl_attr_nest_start(struct nlmsghdr *nlh, uint16_t type); +MNL_API void mnl_attr_nest_end(struct nlmsghdr *nlh, struct nlattr *start); /* TLV validation */ -extern int mnl_attr_type_valid(const struct nlattr *attr, uint16_t maxtype); +MNL_API int mnl_attr_type_valid(const struct nlattr *attr, uint16_t maxtype); enum mnl_attr_data_type { MNL_TYPE_UNSPEC, @@ -114,12 +120,12 @@ enum mnl_attr_data_type { MNL_TYPE_MAX, }; -extern int mnl_attr_validate(const struct nlattr *attr, enum mnl_attr_data_type type); -extern int mnl_attr_validate2(const struct nlattr *attr, enum mnl_attr_data_type type, size_t len); +MNL_API int mnl_attr_validate(const struct nlattr *attr, enum mnl_attr_data_type type); +MNL_API int mnl_attr_validate2(const struct nlattr *attr, enum mnl_attr_data_type type, size_t len); /* TLV iterators */ -extern bool mnl_attr_ok(const struct nlattr *attr, int len); -extern struct nlattr *mnl_attr_next(const struct nlattr *attr, int *len); +MNL_API bool mnl_attr_ok(const struct nlattr *attr, int len); +MNL_API struct nlattr *mnl_attr_next(const struct nlattr *attr, int *len); #define mnl_attr_for_each(attr, nlh, offset) \ int __len__ = mnl_nlmsg_get_payload_len(nlh); \ @@ -136,8 +142,8 @@ extern struct nlattr *mnl_attr_next(const struct nlattr *attr, int *len); /* TLV callback-based attribute parsers */ typedef int (*mnl_attr_cb_t)(const struct nlattr *attr, void *data); -extern int mnl_attr_parse(const struct nlmsghdr *nlh, unsigned int offset, mnl_attr_cb_t cb, void *data); -extern int mnl_attr_parse_nested(const struct nlattr *attr, mnl_attr_cb_t cb, void *data); +MNL_API int mnl_attr_parse(const struct nlmsghdr *nlh, unsigned int offset, mnl_attr_cb_t cb, void *data); +MNL_API int mnl_attr_parse_nested(const struct nlattr *attr, mnl_attr_cb_t cb, void *data); /* * callback API @@ -148,10 +154,10 @@ extern int mnl_attr_parse_nested(const struct nlattr *attr, mnl_attr_cb_t cb, vo typedef int (*mnl_cb_t)(const struct nlmsghdr *nlh, void *data); -extern int mnl_cb_run(const void *buf, size_t numbytes, unsigned int seq, +MNL_API int mnl_cb_run(const void *buf, size_t numbytes, unsigned int seq, unsigned int portid, mnl_cb_t cb_data, void *data); -extern int mnl_cb_run2(const void *buf, size_t numbytes, unsigned int seq, +MNL_API int mnl_cb_run2(const void *buf, size_t numbytes, unsigned int seq, unsigned int portid, mnl_cb_t cb_data, void *data, mnl_cb_t *cb_ctl_array, unsigned int cb_ctl_array_len); diff --git a/m4/visibility.m4 b/m4/visibility.m4 new file mode 100644 index 0000000..2ff6330 --- /dev/null +++ b/m4/visibility.m4 @@ -0,0 +1,52 @@ +# visibility.m4 serial 1 (gettext-0.15) +dnl Copyright (C) 2005 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl From Bruno Haible. + +dnl Tests whether the compiler supports the command-line option +dnl -fvisibility=hidden and the function and variable attributes +dnl __attribute__((__visibility__("hidden"))) and +dnl __attribute__((__visibility__("default"))). +dnl Does *not* test for __visibility__("protected") - which has tricky +dnl semantics (see the 'vismain' test in glibc) and does not exist e.g. on +dnl MacOS X. +dnl Does *not* test for __visibility__("internal") - which has processor +dnl dependent semantics. +dnl Does *not* test for #pragma GCC visibility push(hidden) - which is +dnl "really only recommended for legacy code". +dnl Set the variable CFLAG_VISIBILITY. +dnl Defines and sets the variable HAVE_VISIBILITY. + +AC_DEFUN([gl_VISIBILITY], +[ + AC_REQUIRE([AC_PROG_CC]) + CFLAG_VISIBILITY= + HAVE_VISIBILITY=0 + if test -n "$GCC"; then + AC_MSG_CHECKING([for simple visibility declarations]) + AC_CACHE_VAL(gl_cv_cc_visibility, [ + gl_save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -fvisibility=hidden" + AC_TRY_COMPILE( + [extern __attribute__((__visibility__("hidden"))) int hiddenvar; + extern __attribute__((__visibility__("default"))) int exportedvar; + extern __attribute__((__visibility__("hidden"))) int hiddenfunc (void); + extern __attribute__((__visibility__("default"))) int exportedfunc (void);], + [], + gl_cv_cc_visibility=yes, + gl_cv_cc_visibility=no) + CFLAGS="$gl_save_CFLAGS"]) + AC_MSG_RESULT([$gl_cv_cc_visibility]) + if test $gl_cv_cc_visibility = yes; then + CFLAG_VISIBILITY="-fvisibility=hidden" + HAVE_VISIBILITY=1 + fi + fi + AC_SUBST([CFLAG_VISIBILITY]) + AC_SUBST([HAVE_VISIBILITY]) + AC_DEFINE_UNQUOTED([HAVE_VISIBILITY], [$HAVE_VISIBILITY], + [Define to 1 or 0, depending whether the compiler supports simple visibility declarations.]) +]) diff --git a/src/Makefile.am b/src/Makefile.am index 064ccf5..dd1b1b7 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,6 +1,7 @@ include $(top_srcdir)/Make_global.am - +AM_CFLAGS += $(CFLAG_VISIBILITY) +AM_CPPFLAGS += -DBUILDING_MNL lib_LTLIBRARIES = libmnl.la -libmnl_la_LDFLAGS = -version-info $(LIBVERSION) +libmnl_la_LDFLAGS = -Wl,--version-script=$(srcdir)/libmnl.map -version-info $(LIBVERSION) libmnl_la_SOURCES = socket.c callback.c nlmsg.c attr.c diff --git a/src/libmnl.map b/src/libmnl.map new file mode 100644 index 0000000..804aa0e --- /dev/null +++ b/src/libmnl.map @@ -0,0 +1,58 @@ +LIBMNL_1.0 { +global: + mnl_attr_get_len; + mnl_attr_get_payload; + mnl_attr_get_payload_len; + mnl_attr_get_str; + mnl_attr_get_type; + mnl_attr_get_u16; + mnl_attr_get_u32; + mnl_attr_get_u64; + mnl_attr_get_u8; + mnl_attr_nest_end; + mnl_attr_nest_start; + mnl_attr_next; + mnl_attr_ok; + mnl_attr_parse; + mnl_attr_parse_nested; + mnl_attr_put; + mnl_attr_put_str; + mnl_attr_put_strz; + mnl_attr_put_u16; + mnl_attr_put_u32; + mnl_attr_put_u64; + mnl_attr_put_u8; + mnl_attr_type_valid; + mnl_attr_validate; + mnl_attr_validate2; + mnl_cb_run; + mnl_cb_run2; + mnl_nlmsg_fprintf; + mnl_nlmsg_get_payload; + mnl_nlmsg_get_payload_len; + mnl_nlmsg_get_payload_offset; + mnl_nlmsg_get_payload_tail; + mnl_nlmsg_next; + mnl_nlmsg_ok; + mnl_nlmsg_portid_ok; + mnl_nlmsg_put_extra_header; + mnl_nlmsg_put_header; + mnl_nlmsg_seq_ok; + mnl_nlmsg_size; + mnl_nlmsg_total_size; + mnl_socket_bind; + mnl_socket_close; + mnl_socket_get_fd; + mnl_socket_get_portid; + mnl_socket_getsockopt; + mnl_socket_open; + mnl_socket_recvfrom; + mnl_socket_sendto; + mnl_socket_setsockopt; + +local: *; +}; + +#LIBMNL_1.1 { +# mnl_my_new_func; +#} LIBMNL_1.0; -- cgit v1.2.3