summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorBruno Haible <bruno@clisp.org>2009-04-11 16:09:45 +0200
committerBruno Haible <bruno@clisp.org>2009-04-11 16:09:45 +0200
commitd598f9e1e016735397e9dca53b436d13c6fb28f3 (patch)
tree98b8e47c701495b3f12ea0739c9705cb17ebd134 /lib
parent3f5fe3223382a51a3057e0806aa02463addd12e4 (diff)
downloadlibunistring-d598f9e1e016735397e9dca53b436d13c6fb28f3.tar.gz
Limit the exported symbols through a config.h trick.
Diffstat (limited to 'lib')
-rw-r--r--lib/Makefile.am79
-rwxr-xr-xlib/declared.sh135
-rw-r--r--lib/exported.sh.in24
3 files changed, 238 insertions, 0 deletions
diff --git a/lib/Makefile.am b/lib/Makefile.am
index 4e8d6a6..6eaed43 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -136,6 +136,85 @@ clean-local: clean-generic
fi; \
:
+# List of header files that get installed and that declared 'extern' symbols.
+HEADERS_WITH_EXTERNS = \
+ unitypes.h \
+ unistr.h \
+ uniconv.h \
+ unistdio.h \
+ uniname.h \
+ unictype.h \
+ uniwidth.h \
+ uniwbrk.h \
+ unilbrk.h \
+ uninorm.h \
+ unicase.h \
+ localcharset.h \
+ iconveh.h
+
+# List of exported symbols.
+# We extract it from the header files that get installed, removing symbols
+# start with "_UC".
+# This file has the same format as the one expected by the libtool option
+# '-export-symbols', but we don't use this option, because it would prevent us
+# from building some of the gnulib unit tests.
+libunistring.sym : $(HEADERS_WITH_EXTERNS)
+ for f in $(HEADERS_WITH_EXTERNS); do cat $(srcdir)/$$f; done \
+ | $(srcdir)/declared.sh | LC_ALL=C sort | LC_ALL=C uniq \
+ | grep -v '^_UC' \
+ > $@-t
+ mv $@-t $@
+# We distribute it because declared.sh relies on GNU sed.
+MOSTLYCLEANFILES += libunistring.sym-t
+MAINTAINERCLEANFILES += libunistring.sym
+EXTRA_DIST += libunistring.sym
+
+# Hide undesired symbols that are defined by libunistring_la_SOURCES or
+# libunistring_la_LIBADD from the global namespace, by prefixing them with
+# "libunistring_".
+all check install: config.h
+config.h: $(BUILT_SOURCES) libunistring.sym
+ { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
+ : "Avoid double inclusion, to avoid a warning about redefinition of DLL_VARIABLE."; \
+ echo '#ifndef UNISTRING_CONFIG_H'; \
+ echo '#define UNISTRING_CONFIG_H'; \
+ echo; \
+ echo '#include "../config.h"'; \
+ : "All code is collected in a single library,"; \
+ : "No references to variables in other libraries exist."; \
+ echo '#undef DLL_VARIABLE'; \
+ echo '#define DLL_VARIABLE'; \
+ echo; \
+ echo '#endif /* UNISTRING_CONFIG_H */'; \
+ } > config.h && \
+ if test -n "$(HAVE_GLOBAL_SYMBOL_PIPE)"; then \
+ { \
+ for f in $(libunistring_la_SOURCES) $(libunistring_la_LIBADD); do \
+ case $$f in \
+ *.c | *.$(OBJEXT) | *.lo ) \
+ sf=`echo "$$f" | sed -e 's,\\.[^.]*$$,,'`.c; \
+ test -f $$sf || sf=$(srcdir)/$$sf; \
+ of=`echo "$$f" | sed -e 's,^.*/,,' -e 's,\\.[^.]*$$,,'`.$(OBJEXT); \
+ $(COMPILE) -c $$sf || { rm -f config.h; exit 1; }; \
+ sh ./exported.sh $$of 1>&5; \
+ rm -f $$of `echo "$$of" | sed -e 's,\\.$(OBJEXT)$$,.lo,'`; \
+ ;; \
+ esac; \
+ done; \
+ } 5>&1 \
+ | sed -e 's,.* ,,' | LC_ALL=C sort | LC_ALL=C uniq \
+ | LC_ALL=C join -v 1 - $(srcdir)/libunistring.sym \
+ | sed -e 's,^\(.*\)$$,#define \1 libunistring_\1,' > config.h-t && \
+ if test -f config.h; then \
+ cat config.h-t >> config.h; \
+ rm -f config.h-t; \
+ else \
+ rm -f config.h-t; \
+ exit 1; \
+ fi \
+ fi
+MOSTLYCLEANFILES += config.h config.h-t
+
# Libtool's library version information for libunistring.
# See the libtool documentation, section "Library interface versions".
LTV_CURRENT=0
diff --git a/lib/declared.sh b/lib/declared.sh
new file mode 100755
index 0000000..c254417
--- /dev/null
+++ b/lib/declared.sh
@@ -0,0 +1,135 @@
+#! /bin/sh
+#
+# Copyright (C) 2009 Free Software Foundation, Inc.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+# This script determines the declared global symbols in a C header file.
+# Assumptions:
+# - The header files are in C, with only C89 comments.
+# - No use of macros with parameters.
+# - All global declarations are marked with 'extern'.
+# - All declarations end in ';' on the same line.
+# - Not more than one symbol is declared in a declaration.
+
+# func_usage
+# outputs to stdout the --help usage message.
+func_usage ()
+{
+ echo "\
+Usage: declared.sh [OPTION]... < SOURCE.h
+
+Extracts the declared global symbols of a C header file.
+
+Options:
+ --help print this help and exit
+ --version print version information and exit
+
+Report bugs to <bruno@clisp.org>."
+}
+
+# func_version
+# outputs to stdout the --version message.
+func_version ()
+{
+ echo "declared.sh (GNU libunistring)"
+ echo "Copyright (C) 2006, 2009 Free Software Foundation, Inc.
+License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
+This is free software: you are free to change and redistribute it.
+There is NO WARRANTY, to the extent permitted by law."
+ echo "Written by" "Bruno Haible"
+}
+
+# func_fatal_error message
+# outputs to stderr a fatal error message, and terminates the program.
+func_fatal_error ()
+{
+ echo "declared.sh: *** $1" 1>&2
+ echo "declared.sh: *** Stop." 1>&2
+ exit 1
+}
+
+# Command-line option processing.
+while test $# -gt 0; do
+ case "$1" in
+ --help | --hel | --he | --h )
+ func_usage
+ exit 0 ;;
+ --version | --versio | --versi | --vers | --ver | --ve | --v )
+ func_version
+ exit 0 ;;
+ -- ) # Stop option prcessing
+ shift; break ;;
+ -* )
+ func_fatal_error "unrecognized option: $option"
+ ;;
+ * )
+ break ;;
+ esac
+done
+
+if test $# -gt 0; then
+ func_fatal_error "too many arguments"
+fi
+
+# A sed expression that removes ANSI C and ISO C99 comments.
+sed_remove_comments="
+/[/][/*]/{
+ ta
+ :a
+ s,^\\(\\([^\"'/]\\|\"\\([^\\\"]\\|[\\].\\)*\"\\|'\\([^\\']\\|[\\].\\)*'\\|[/][^\"'/*]\\|[/]\"\\([^\\\"]\\|[\\].\\)*\"\\|[/]'\\([^\\']\\|[\\].\\)*'\\)*\\)//.*,\\1,
+ te
+ s,^\\(\\([^\"'/]\\|\"\\([^\\\"]\\|[\\].\\)*\"\\|'\\([^\\']\\|[\\].\\)*'\\|[/][^\"'/*]\\|[/]\"\\([^\\\"]\\|[\\].\\)*\"\\|[/]'\\([^\\']\\|[\\].\\)*'\\)*\\)/[*]\\([^*]\\|[*][^/*]\\)*[*][*]*/,\\1 ,
+ ta
+ /^\\([^\"'/]\\|\"\\([^\\\"]\\|[\\].\\)*\"\\|'\\([^\\']\\|[\\].\\)*'\\|[/][^\"'/*]\\|[/]\"\\([^\\\"]\\|[\\].\\)*\"\\|[/]'\\([^\\']\\|[\\].\\)*'\\)*[/][*]/{
+ s,^\\(\\([^\"'/]\\|\"\\([^\\\"]\\|[\\].\\)*\"\\|'\\([^\\']\\|[\\].\\)*'\\|[/][^\"'/*]\\|[/]\"\\([^\\\"]\\|[\\].\\)*\"\\|[/]'\\([^\\']\\|[\\].\\)*'\\)*\\)/[*].*,\\1 ,
+ tu
+ :u
+ n
+ s,^\\([^*]\\|[*][^/*]\\)*[*][*]*/,,
+ tv
+ s,^.*\$,,
+ bu
+ :v
+ }
+ :e
+}"
+
+# Check that 'sed' supports the kind of regular expressions used in
+# sed_remove_comments. The use of \| meaning alternation of basic regular
+# expressions is a GNU extension.
+sed_test='s,^\(\(a\|X\)*\)//.*,\1,'
+sed_result=`echo 'aaa//bcd' | sed -e "$sed_test"`
+test "$sed_result" = 'aaa' \
+ || func_fatal_error "The 'sed' program is not GNU sed. Try installing GNU sed."
+
+# A sed expression that joins 'extern' declarations that are broken over
+# several lines.
+sed_join_multiline_externs='
+/^extern [^;]*$/{
+ :a
+ N
+ s/\n/ /g
+ /^extern [^;]*$/{
+ ba
+ }
+}'
+
+# A sed expression that extracts the identifier of each 'extern' declaration.
+sed_extract_extern_declared='s/^extern .* \([A-Za-z_][A-Za-z0-9_]*\) *[;(].*$/\1/p'
+
+sed -e "$sed_remove_comments" \
+ | sed -e "$sed_join_multiline_externs" \
+ | sed -n -e "$sed_extract_extern_declared"
diff --git a/lib/exported.sh.in b/lib/exported.sh.in
new file mode 100644
index 0000000..89e4008
--- /dev/null
+++ b/lib/exported.sh.in
@@ -0,0 +1,24 @@
+#! /bin/sh
+#
+# Copyright (C) 2006 Free Software Foundation, Inc.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+# This is a script that determines the exported symbols of an object file.
+# This is a separate script because $(GLOBAL_SYMBOL_PIPE) cannot be used in a
+# Makefile, since it may contain dollar signs.
+
+nm_cmd="@NM@ $1 | @GLOBAL_SYMBOL_PIPE@"
+eval $nm_cmd