Recent versions of Darwin spew a lot of multiply-defined-symbol warnings
while building Postgres, mostly because the programs in src/bin import
both libpq and libpgport, and libpq includes copies of many of the
libpgport files.  Since the libpgport routines aren't officially part of
the libpq API, it'd be better if those symbols weren't visible from
outside libpq.  The attached patch makes this so, using the already
existing exports.txt list as the definition of libpq's official API.

I found while testing the patch that we have one API leak in current
sources: ecpglib is depending on the libpq-exported pqGetpwuid()
because src/port/path.c requires it but src/port/thread.c isn't included
into ecpglib.  The patch corrects this oversight.  This BTW is
sufficient reason for a libpq major version bump if we apply this patch;
we learned that lesson last time we fixed an API leak.  (Did we already
bump libpq's major version for 8.2?  I don't recall.)

The reason I didn't go ahead and apply this is that I'm wondering if
there's some more-portable solution that would work for other platforms
besides Darwin.  I seem to recall that we've discussed the point before,
but no patch has been forthcoming.

Comments?

                        regards, tom lane

Index: src/Makefile.shlib
===================================================================
RCS file: /cvsroot/pgsql/src/Makefile.shlib,v
retrieving revision 1.103
diff -c -r1.103 Makefile.shlib
*** src/Makefile.shlib  19 Apr 2006 16:32:08 -0000      1.103
--- src/Makefile.shlib  20 Apr 2006 00:56:38 -0000
***************
*** 107,117 ****
    ifeq ($(DLTYPE), library)
      # linkable library
      DLSUFFIX          := .dylib
!     LINK.shared               = $(COMPILER) -dynamiclib -install_name 
$(libdir)/lib$(NAME).$(SO_MAJOR_VERSION)$(DLSUFFIX) $(version_link) 
-multiply_defined suppress
    else
      # loadable module (default case)
      DLSUFFIX          := .so
!     LINK.shared               = $(COMPILER) -bundle
    endif
    shlib                       = 
lib$(NAME).$(SO_MAJOR_VERSION).$(SO_MINOR_VERSION)$(DLSUFFIX)
    shlib_major         = lib$(NAME).$(SO_MAJOR_VERSION)$(DLSUFFIX)
--- 107,117 ----
    ifeq ($(DLTYPE), library)
      # linkable library
      DLSUFFIX          := .dylib
!     LINK.shared               = $(COMPILER) -dynamiclib -install_name 
$(libdir)/lib$(NAME).$(SO_MAJOR_VERSION)$(DLSUFFIX) $(version_link) 
$(exported_symbols_list) -multiply_defined suppress
    else
      # loadable module (default case)
      DLSUFFIX          := .so
!     LINK.shared               = $(COMPILER) -bundle -multiply_defined suppress
    endif
    shlib                       = 
lib$(NAME).$(SO_MAJOR_VERSION).$(SO_MINOR_VERSION)$(DLSUFFIX)
    shlib_major         = lib$(NAME).$(SO_MAJOR_VERSION)$(DLSUFFIX)
Index: src/interfaces/libpq/Makefile
===================================================================
RCS file: /cvsroot/pgsql/src/interfaces/libpq/Makefile,v
retrieving revision 1.143
diff -c -r1.143 Makefile
*** src/interfaces/libpq/Makefile       11 Apr 2006 20:26:40 -0000      1.143
--- src/interfaces/libpq/Makefile       20 Apr 2006 00:56:39 -0000
***************
*** 125,130 ****
--- 125,143 ----
        echo '; Aliases for MS compatible names' >> $@
        sed -e '/^#/d' -e 's/^\(.* \)\([0-9][0-9]*\)/    \1= _\1/' < $< | sed 
's/ *$$//' >> $@
  
+ # On Darwin, restrict the symbols exported by the library to just the
+ # official list, so as to avoid multiply-defined-symbol warnings in
+ # programs that use libpgport along with libpq.
+ 
+ ifeq ($(PORTNAME), darwin)
+ $(shlib): exports.darwin
+ 
+ exports.darwin: exports.txt
+       $(AWK) '/^[^#]/ {printf "_%s\n",$$1}' $< >$@
+ 
+ exported_symbols_list = -exported_symbols_list exports.darwin
+ endif
+ 
  # depend on Makefile.global to force rebuild on re-run of configure
  $(srcdir)/libpq.rc: libpq.rc.in $(top_builddir)/src/Makefile.global
        sed -e 's/\(VERSION.*\),0 *$$/\1,'`date '+%y%j' | sed 's/^0*//'`'/' < 
$< > $@
***************
*** 147,153 ****
        rm -f '$(DESTDIR)$(includedir)/libpq-fe.h' 
'$(DESTDIR)$(includedir_internal)/libpq-int.h' 
'$(DESTDIR)$(includedir_internal)/pqexpbuffer.h' 
'$(DESTDIR)$(datadir)/pg_service.conf.sample'
  
  clean distclean: clean-lib
!       rm -f $(OBJS) pg_config_paths.h crypt.c getaddrinfo.c inet_aton.c 
noblock.c pgstrcasecmp.c snprintf.c strerror.c open.c thread.c md5.c ip.c 
encnames.c wchar.c pthread.h
        rm -f pg_config_paths.h # Might be left over from a Win32 client-only 
build
  
  maintainer-clean: distclean
--- 160,166 ----
        rm -f '$(DESTDIR)$(includedir)/libpq-fe.h' 
'$(DESTDIR)$(includedir_internal)/libpq-int.h' 
'$(DESTDIR)$(includedir_internal)/pqexpbuffer.h' 
'$(DESTDIR)$(datadir)/pg_service.conf.sample'
  
  clean distclean: clean-lib
!       rm -f $(OBJS) pg_config_paths.h crypt.c getaddrinfo.c inet_aton.c 
noblock.c pgstrcasecmp.c snprintf.c strerror.c open.c thread.c md5.c ip.c 
encnames.c wchar.c pthread.h exports.darwin
        rm -f pg_config_paths.h # Might be left over from a Win32 client-only 
build
  
  maintainer-clean: distclean
Index: src/interfaces/ecpg/ecpglib/Makefile
===================================================================
RCS file: /cvsroot/pgsql/src/interfaces/ecpg/ecpglib/Makefile,v
retrieving revision 1.38
diff -c -r1.38 Makefile
*** src/interfaces/ecpg/ecpglib/Makefile        17 Jan 2006 19:49:23 -0000      
1.38
--- src/interfaces/ecpg/ecpglib/Makefile        20 Apr 2006 00:56:39 -0000
***************
*** 25,31 ****
  LIBS := $(filter-out -lpgport, $(LIBS))
  
  OBJS= execute.o typename.o descriptor.o data.o error.o prepare.o memory.o \
!       connect.o misc.o path.o exec.o \
        $(filter snprintf.o, $(LIBOBJS))
  
  SHLIB_LINK = -L../pgtypeslib -lpgtypes $(libpq) \
--- 25,31 ----
  LIBS := $(filter-out -lpgport, $(LIBS))
  
  OBJS= execute.o typename.o descriptor.o data.o error.o prepare.o memory.o \
!       connect.o misc.o path.o exec.o thread.o \
        $(filter snprintf.o, $(LIBOBJS))
  
  SHLIB_LINK = -L../pgtypeslib -lpgtypes $(libpq) \
***************
*** 46,52 ****
  # necessarily use the same object files as the backend uses. Instead,
  # symlink the source files in here and build our own object file.
  
! path.c exec.c snprintf.c: % : $(top_srcdir)/src/port/%
        rm -f $@ && $(LN_S) $< .
  
  path.o: path.c $(top_builddir)/src/port/pg_config_paths.h
--- 46,52 ----
  # necessarily use the same object files as the backend uses. Instead,
  # symlink the source files in here and build our own object file.
  
! path.c exec.c snprintf.c thread.c: % : $(top_srcdir)/src/port/%
        rm -f $@ && $(LN_S) $< .
  
  path.o: path.c $(top_builddir)/src/port/pg_config_paths.h
***************
*** 62,68 ****
  uninstall: uninstall-lib
  
  clean distclean maintainer-clean: clean-lib
!       rm -f $(OBJS) path.c exec.c snprintf.c
  
  depend dep:
        $(CC) -MM $(CFLAGS) *.c >depend
--- 62,68 ----
  uninstall: uninstall-lib
  
  clean distclean maintainer-clean: clean-lib
!       rm -f $(OBJS) path.c exec.c snprintf.c thread.c
  
  depend dep:
        $(CC) -MM $(CFLAGS) *.c >depend
---------------------------(end of broadcast)---------------------------
TIP 1: if posting/reading through Usenet, please send an appropriate
       subscribe-nomail command to [EMAIL PROTECTED] so that your
       message can get through to the mailing list cleanly

Reply via email to