66# Copyright (c) 1998, Regents of the University of California
77#
88# IDENTIFICATION
9- # $PostgreSQL: pgsql/src/Makefile.shlib,v 1.109 2007 /02/20 22:45:57 momjian Exp $
9+ # $PostgreSQL: pgsql/src/Makefile.shlib,v 1.110 2008 /02/26 06:41:23 petere Exp $
1010#
1111#-------------------------------------------------------------------------
1212
2424# OBJS List of object files to include in library
2525# SHLIB_LINK If shared library relies on other libraries,
2626# additional stuff to put in its link command
27+ # SHLIB_EXPORTS (optional) Name of file containing list of symbols to
28+ # export
2729# (If you want a patchlevel, include it in SO_MINOR_VERSION, e.g., "6.2".)
2830#
2931# Optional flags when building DLL's (only applicable to win32 and cygwin
3032# platforms).
3133# DLLTOOL_DEFFLAGS Additional flags when creating the dll .def file
3234# DLLTOOL_LIBFLAGS Additional flags when creating the lib<module>.a file
3335# DLLWRAP_FLAGS Additional flags to dllwrap
34- # DLL_DEFFILE Use pre-existing .def file instead of auto-generating
35- # one with all exports in it (win32 only).
3636#
3737# The module Makefile must also include
3838# $(top_builddir)/src/Makefile.global before including this file.
4444# install-lib install the libraries into $(libdir)
4545# uninstall-lib remove the libraries from $(libdir)
4646# clean-lib delete the static and shared libraries from the build dir
47+ # maintainer-clean-lib delete .def files built for win32
4748#
4849# Since `all-lib' is the first rule in this file you probably want to
4950# have the `all' target before including this file. In the most simple
@@ -115,6 +116,10 @@ ifeq ($(PORTNAME), darwin)
115116 endif
116117 shlib= lib$(NAME).$(SO_MAJOR_VERSION).$(SO_MINOR_VERSION)$(DLSUFFIX)
117118 shlib_major= lib$(NAME).$(SO_MAJOR_VERSION)$(DLSUFFIX)
119+ BUILD.exports= $(AWK) '/^[^#]/ {printf "_%s\n",$$1}' $< >$@
120+ ifneq (,$(SHLIB_EXPORTS))
121+ exported_symbols_list = -exported_symbols_list $(SHLIB_EXPORTS:%.txt=%.list)
122+ endif
118123endif
119124
120125ifeq ($(PORTNAME), openbsd)
@@ -186,7 +191,11 @@ ifeq ($(PORTNAME), irix)
186191endif
187192
188193ifeq ($(PORTNAME), linux)
189- LINK.shared= $(COMPILER) -shared -Wl,-soname,$(soname) $(exported_symbols_list)
194+ LINK.shared= $(COMPILER) -shared -Wl,-soname,$(soname)
195+ BUILD.exports= ( echo '{ global:'; $(AWK) '/^[^\#]/ {printf "%s;\n",$$1}' $<; echo ' local: *; };' ) >$@
196+ ifneq (,$(SHLIB_EXPORTS))
197+ LINK.shared+= -Wl,--version-script=$(SHLIB_EXPORTS:%.txt=%.list)
198+ endif
190199endif
191200
192201ifeq ($(PORTNAME), solaris)
@@ -293,6 +302,19 @@ ifneq ($(shlib), $(shlib_bare))
293302$(LN_S) $(shlib) $(shlib_bare)
294303endif
295304
305+ # Where possible, restrict the symbols exported by the library to just the
306+ # official list, so as to avoid unintentional ABI changes. On recent Darwin
307+ # this also quiets multiply-defined-symbol warnings in programs that use
308+ # libpgport along with libpq.
309+ ifneq (,$(SHLIB_EXPORTS))
310+ ifdef BUILD.exports
311+ $(shlib): $(SHLIB_EXPORTS:%.txt=%.list)
312+
313+ $(SHLIB_EXPORTS:%.txt=%.list): %.list: %.txt
314+ $(BUILD.exports)
315+ endif
316+ endif
317+
296318else # PORTNAME == aix
297319
298320# AIX case
@@ -303,7 +325,7 @@ $(shlib) lib$(NAME).a: $(OBJS)
303325$(COMPILER) $(LDFLAGS_NO_L) $(LDFLAGS_SL) -o $(shlib) lib$(NAME).a -Wl,-bE:lib$(NAME)$(EXPSUFF) $(SHLIB_LINK)
304326rm -f lib$(NAME).a
305327$(AR) $(AROPT) lib$(NAME).a $(shlib)
306-
328+
307329endif # PORTNAME == aix
308330
309331else # PORTNAME == cygwin
@@ -323,6 +345,10 @@ endif # PORTNAME == cygwin
323345
324346else # PORTNAME == win32
325347
348+ ifneq (,$(SHLIB_EXPORTS))
349+ DLL_DEFFILE = lib$(NAME)dll.def
350+ endif
351+
326352# win32 case
327353$(shlib) lib$(NAME).a: $(OBJS)
328354ifndef DLL_DEFFILE
@@ -339,6 +365,46 @@ endif # PORTNAME == win32
339365endif # enable_shared
340366
341367
368+ # We need several not-quite-identical variants of .DEF files to build
369+ # DLLs for Windows. These are made from the single source file
370+ # exports.txt. Since we can't assume that Windows boxes will have
371+ # sed, the .DEF files are always built and included in distribution
372+ # tarballs.
373+
374+ ifneq (,$(SHLIB_EXPORTS))
375+ all: def-files
376+
377+ distprep: def-files
378+
379+ .PHONY: def-files
380+
381+ def-files: $(srcdir)/lib$(NAME)dll.def $(srcdir)/lib$(NAME)ddll.def $(srcdir)/blib$(NAME)dll.def
382+
383+ UC_NAME = $(shell echo $(NAME) | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')
384+
385+ $(srcdir)/lib$(NAME)dll.def: $(SHLIB_EXPORTS)
386+ echo '; DEF file for MS VC++' >$@
387+ echo 'LIBRARY LIB$(UC_NAME)' >>$@
388+ echo 'EXPORTS' >>$@
389+ sed -e '/^#/d' -e 's/^\(.* \)\([0-9][0-9]*\)/ \1@ \2/' $< >>$@
390+
391+ $(srcdir)/lib$(NAME)ddll.def: $(SHLIB_EXPORTS)
392+ echo '; DEF file for MS VC++' >$@
393+ echo 'LIBRARY LIB$(UC_NAME)D' >>$@
394+ echo 'EXPORTS' >>$@
395+ sed -e '/^#/d' -e 's/^\(.* \)\([0-9][0-9]*\)/ \1@ \2/' $< >>$@
396+
397+ $(srcdir)/blib$(NAME)dll.def: $(SHLIB_EXPORTS)
398+ echo '; DEF file for Borland C++ Builder' >$@
399+ echo 'LIBRARY BLIB$(UC_NAME)' >>$@
400+ echo 'EXPORTS' >>$@
401+ sed -e '/^#/d' -e 's/^\(.* \)\([0-9][0-9]*\)/ _\1@ \2/' $< >>$@
402+ echo >>$@
403+ echo '; Aliases for MS compatible names' >> $@
404+ sed -e '/^#/d' -e 's/^\(.* \)\([0-9][0-9]*\)/ \1= _\1/' $< | sed 's/ *$$//' >>$@
405+ endif # SHLIB_EXPORTS
406+
407+
342408##
343409## INSTALL
344410##
@@ -398,7 +464,7 @@ endif # enable_shared
398464clean-lib:
399465rm -f lib$(NAME).a
400466ifeq ($(enable_shared), yes)
401- rm -f $(shlib_bare) $(shlib_major) $(shlib)
467+ rm -f $(shlib_bare) $(shlib_major) $(shlib) $(SHLIB_EXPORTS:%.txt=%.list)
402468ifdef EXPSUFF
403469rm -f lib$(NAME)$(EXPSUFF)
404470endif
@@ -410,3 +476,8 @@ endif
410476ifeq ($(PORTNAME), win32)
411477rm -f $(NAME).dll $(NAME).def
412478endif
479+
480+ ifneq (,$(SHLIB_EXPORTS))
481+ maintainer-clean-lib:
482+ rm -f $(srcdir)/lib$(NAME)dll.def $(srcdir)/lib$(NAME)ddll.def $(srcdir)/blib$(NAME)dll.def
483+ endif