#
# NAME Name of library to build (no suffix nor "lib" prefix)
# OBJS List of object files to include in library
-# SHLIB_LINK If shared library relies on other libraries,
-# additional stuff to put in its link command
+# SHLIB_LINK Stuff to append to library's link command
+# (typically, -L and -l switches for external libraries)
+# SHLIB_LINK_INTERNAL -L and -l switches for Postgres-supplied libraries
# SHLIB_PREREQS Order-only prerequisites for library build target
# SHLIB_EXPORTS (optional) Name of file containing list of symbols to
# export, in the format "function_name number"
#
+# Don't use SHLIB_LINK for references to files in the build tree, or the
+# wrong things will happen --- use SHLIB_LINK_INTERNAL for those!
+#
# When building a shared library, the following version information
# must also be set. It should be omitted when building a dynamically
# loadable module.
# clean-lib delete the static and shared libraries from the build dir
# maintainer-clean-lib delete .def files built for win32
#
-# Since `all-lib' is the first rule in this file you probably want to
-# have the `all' target before including this file. In the most simple
-# case it would look like this:
+# Typically you would add `all-lib' to the `all' target so that `make all'
+# builds the libraries. In the most simple case it would look like this:
#
# all: all-lib
#
#
# Got that? Look at src/interfaces/libpq/Makefile for an example.
#
-# While the linker allows creation of most shared libraries,
-# -Bsymbolic requires resolution of all symbols, making the
-# compiler a better choice for shared library creation on ELF platforms.
-# With the linker, -Bsymbolic requires the crt1.o startup object file.
-# bjm 2001-02-10
COMPILER = $(CC) $(CFLAGS)
LINK.static = $(AR) $(AROPT)
+LDFLAGS_INTERNAL += $(SHLIB_LINK_INTERNAL)
+
ifdef SO_MAJOR_VERSION
# Try to keep the sections in some kind of order, folks...
override CFLAGS += $(CFLAGS_SL)
+override CXXFLAGS += $(CFLAGS_SL)
ifdef SO_MAJOR_VERSION
# libraries ought to use this to refer to versioned gettext domain names
override CPPFLAGS += -DSO_MAJOR_VERSION=$(SO_MAJOR_VERSION)
shlib = lib$(NAME)$(DLSUFFIX).$(SO_MAJOR_VERSION)
endif
haslibarule = yes
+ # $(exports_file) is also usable as an import file
exports_file = lib$(NAME).exp
endif
ifdef soname
LINK.shared += -Wl,-x,-soname,$(soname)
endif
+ BUILD.exports = ( echo '{ global:'; $(AWK) '/^[^\#]/ {printf "%s;\n",$$1}' $<; echo ' local: *; };' ) >$@
+ exports_file = $(SHLIB_EXPORTS:%.txt=%.list)
+ ifneq (,$(exports_file))
+ LINK.shared += -Wl,--version-script=$(exports_file)
+ endif
SHLIB_LINK += -lc
else
LINK.shared = $(LD) -x -Bshareable -Bforcearchive
ifdef soname
LINK.shared += -Wl,-x,-soname,$(soname)
endif
+ BUILD.exports = ( echo '{ global:'; $(AWK) '/^[^\#]/ {printf "%s;\n",$$1}' $<; echo ' local: *; };' ) >$@
+ exports_file = $(SHLIB_EXPORTS:%.txt=%.list)
+ ifneq (,$(exports_file))
+ LINK.shared += -Wl,--version-script=$(exports_file)
+ endif
else
ifdef SO_MAJOR_VERSION
shlib = lib$(NAME)$(DLSUFFIX).$(SO_MAJOR_VERSION).$(SO_MINOR_VERSION)
ifdef soname
LINK.shared += -Wl,-x,-soname,$(soname)
endif
+ BUILD.exports = ( echo '{ global:'; $(AWK) '/^[^\#]/ {printf "%s;\n",$$1}' $<; echo ' local: *; };' ) >$@
+ exports_file = $(SHLIB_EXPORTS:%.txt=%.list)
+ ifneq (,$(exports_file))
+ LINK.shared += -Wl,--version-script=$(exports_file)
+ endif
else
LINK.shared = $(LD) -x -Bshareable -Bforcearchive
endif
shlib = lib$(NAME)$(DLSUFFIX).$(SO_MAJOR_VERSION)
endif
ifeq ($(with_gnu_ld), yes)
- LINK.shared = $(CC) -shared
+ LINK.shared = $(CC) -shared -Wl,-Bsymbolic
ifdef soname
LINK.shared += -Wl,-h -Wl,$(soname)
endif
else
- LINK.shared = $(LD) -b
+ LINK.shared = $(LD) -b -Bsymbolic
ifdef soname
LINK.shared += +h $(soname)
endif
# can't use the CC-syntax rpath pattern here, so instead:
rpath =
ifeq ($(enable_rpath), yes)
- LINK.shared += +b '$(rpathdir)'
+ LINK.shared += +s +b '$(rpathdir)'
endif
# On HPUX platforms, gcc is usually configured to search for libraries
# in /usr/local/lib, but ld won't do so. Add an explicit -L switch so
ifeq ($(PORTNAME), solaris)
ifeq ($(GCC), yes)
- LINK.shared = $(COMPILER) -shared
+ LINK.shared = $(COMPILER) -shared -Wl,-Bsymbolic
else
- LINK.shared = $(COMPILER) -G
+ LINK.shared = $(COMPILER) -G -Bsymbolic
endif
ifdef soname
ifeq ($(with_gnu_ld), yes)
endif
endif
-ifeq ($(PORTNAME), sco)
- ifeq ($(GCC), yes)
- LINK.shared = $(CC) -shared
- else
- LINK.shared = $(CC) -G
- endif
- LINK.shared += -Wl,-z,text
- ifdef soname
- LINK.shared += -Wl,-h,$(soname)
- endif
-endif
-
-ifeq ($(PORTNAME), unixware)
- ifeq ($(GCC), yes)
- LINK.shared = $(CC) -shared
- else
- LINK.shared = $(CC) -G
- endif
- LINK.shared += -Wl,-z,text
- ifdef soname
- LINK.shared += -Wl,-h,$(soname)
- endif
-endif
-
ifeq ($(PORTNAME), cygwin)
LINK.shared = $(CC) -shared
ifdef SO_MAJOR_VERSION
all-shared-lib: $(shlib)
+# In this rule, "touch $@" works around a problem on some platforms wherein
+# ranlib updates the library file's mod time with a value calculated to
+# seconds precision. If the filesystem has sub-second timestamps, this can
+# cause the library file to appear older than its input files, triggering
+# parallel-make problems.
ifndef haslibarule
$(stlib): $(OBJS) | $(SHLIB_PREREQS)
+ rm -f $@
$(LINK.static) $@ $^
$(RANLIB) $@
+ touch $@
endif #haslibarule
endif # shlib_major
# Where possible, restrict the symbols exported by the library to just the
-# official list, so as to avoid unintentional ABI changes. On recent Darwin
+# official list, so as to avoid unintentional ABI changes. On recent macOS
# this also quiets multiply-defined-symbol warnings in programs that use
# libpgport along with libpq.
ifneq (,$(SHLIB_EXPORTS))
else # PORTNAME == aix
# AIX case
-$(shlib) $(stlib): $(OBJS) | $(SHLIB_PREREQS)
+
+# See notes in src/backend/parser/Makefile about the following two rules
+$(stlib): $(shlib)
+ touch $@
+
+$(shlib): $(OBJS) | $(SHLIB_PREREQS)
+ rm -f $(stlib)
$(LINK.static) $(stlib) $^
$(RANLIB) $(stlib)
- $(MKLDEXPORT) $(stlib) >$(exports_file)
+ $(MKLDEXPORT) $(stlib) $(shlib) >$(exports_file)
$(COMPILER) -o $(shlib) $(stlib) -Wl,-bE:$(exports_file) $(LDFLAGS) $(LDFLAGS_SL) $(SHLIB_LINK)
rm -f $(stlib)
$(AR) $(AROPT) $(stlib) $(shlib)
# Cygwin case
$(shlib): $(OBJS) | $(SHLIB_PREREQS)
- $(CC) $(CFLAGS) -shared -o $@ $(OBJS) $(LDFLAGS) $(LDFLAGS_SL) $(SHLIB_LINK) $(LIBS) $(LDAP_LIBS_BE)
+ $(CC) $(CFLAGS) -shared -o $@ -Wl,--out-implib=$(stlib) $(OBJS) $(LDFLAGS) $(LDFLAGS_SL) $(SHLIB_LINK) $(LIBS) $(LDAP_LIBS_BE)
-$(stlib): $(OBJS) | $(SHLIB_PREREQS)
- $(LINK.static) $@ $^
- $(RANLIB) $@
+# see notes in src/backend/parser/Makefile about use of this type of rule
+$(stlib): $(shlib)
+ touch $@
else
# Win32 case
-# There is no correct way to write a rule that generates two files.
-# Rules with two targets don't have that meaning, they are merely
-# shorthand for two otherwise separate rules. To be safe for parallel
-# make, we must chain the dependencies like this. The semicolon is
-# important, otherwise make will choose some built-in rule.
-
-$(stlib): $(shlib) ;
+# See notes in src/backend/parser/Makefile about the following two rules
+$(stlib): $(shlib)
+ touch $@
+# XXX A backend that loads a module linked with libgcc_s_dw2-1.dll will exit
+# uncleanly, hence -static-libgcc. (Last verified with MinGW-w64 compilers
+# from i686-4.9.1-release-win32-dwarf-rt_v3-rev1.) Shared libgcc has better
+# support for C++/Java exceptions; while core PostgreSQL does not use them, it
+# would be nice to support shared libgcc for the benefit of extensions.
+#
# If SHLIB_EXPORTS is set, the rules below will build a .def file from that.
# Else we just use --export-all-symbols.
ifeq (,$(SHLIB_EXPORTS))
$(shlib): $(OBJS) | $(SHLIB_PREREQS)
- $(CC) $(CFLAGS) -shared -o $@ $(OBJS) $(LDFLAGS) $(LDFLAGS_SL) $(SHLIB_LINK) $(LIBS) -Wl,--export-all-symbols -Wl,--out-implib=$(stlib)
+ $(CC) $(CFLAGS) -shared -static-libgcc -o $@ $(OBJS) $(LDFLAGS) $(LDFLAGS_SL) $(SHLIB_LINK) $(LIBS) -Wl,--export-all-symbols -Wl,--out-implib=$(stlib)
else
DLL_DEFFILE = lib$(NAME)dll.def
$(shlib): $(OBJS) $(DLL_DEFFILE) | $(SHLIB_PREREQS)
- $(CC) $(CFLAGS) -shared -o $@ $(OBJS) $(DLL_DEFFILE) $(LDFLAGS) $(LDFLAGS_SL) $(SHLIB_LINK) $(LIBS) -Wl,--out-implib=$(stlib)
+ $(CC) $(CFLAGS) -shared -static-libgcc -o $@ $(OBJS) $(DLL_DEFFILE) $(LDFLAGS) $(LDFLAGS_SL) $(SHLIB_LINK) $(LIBS) -Wl,--out-implib=$(stlib)
endif
-endif # PORTNAME == cgywin
+endif # PORTNAME == cygwin
endif # PORTNAME == cygwin || PORTNAME == win32
# tarballs.
ifneq (,$(SHLIB_EXPORTS))
-distprep: lib$(NAME)dll.def lib$(NAME)ddll.def blib$(NAME)dll.def
+distprep: lib$(NAME)dll.def lib$(NAME)ddll.def
UC_NAME = $(shell echo $(NAME) | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')
lib$(NAME)dll.def: $(SHLIB_EXPORTS)
- echo '; DEF file for MS VC++' >$@
- echo 'LIBRARY LIB$(UC_NAME)' >>$@
+ echo '; DEF file for Makefile.shlib (MinGW)' >$@
+ echo 'LIBRARY LIB$(UC_NAME).dll' >>$@
echo 'EXPORTS' >>$@
sed -e '/^#/d' -e 's/^\(.*[ ]\)\([0-9][0-9]*\)/ \1@ \2/' $< >>$@
lib$(NAME)ddll.def: $(SHLIB_EXPORTS)
- echo '; DEF file for MS VC++' >$@
- echo 'LIBRARY LIB$(UC_NAME)D' >>$@
+ echo '; DEF file for Makefile.shlib (MinGW)' >$@
+ echo 'LIBRARY LIB$(UC_NAME)D.dll' >>$@
echo 'EXPORTS' >>$@
sed -e '/^#/d' -e 's/^\(.*[ ]\)\([0-9][0-9]*\)/ \1@ \2/' $< >>$@
-blib$(NAME)dll.def: $(SHLIB_EXPORTS)
- echo '; DEF file for Borland C++ Builder' >$@
- echo 'LIBRARY BLIB$(UC_NAME)' >>$@
- echo 'EXPORTS' >>$@
- sed -e '/^#/d' -e 's/^\(.*[ ]\)\([0-9][0-9]*\)/ _\1@ \2/' $< >>$@
- echo >>$@
- echo '; Aliases for MS compatible names' >> $@
- sed -e '/^#/d' -e 's/^\(.*[ ]\)\([0-9][0-9]*\)/ \1= _\1/' $< | sed 's/ *$$//' >>$@
endif # SHLIB_EXPORTS
$(INSTALL_STLIB) $< '$(DESTDIR)$(libdir)/$(stlib)'
ifeq ($(PORTNAME), darwin)
cd '$(DESTDIR)$(libdir)' && \
- ranlib $(stlib)
+ $(RANLIB) $(stlib)
endif
install-lib-shared: $(shlib) installdirs-lib
endif # not win32
endif # not cygwin
endif # not aix
+ifneq (,$(findstring $(PORTNAME),win32 cygwin))
+ $(INSTALL_SHLIB) $< '$(DESTDIR)$(bindir)/$(shlib)'
+endif
else # no soname
$(INSTALL_SHLIB) $< '$(DESTDIR)$(pkglibdir)/$(shlib)'
endif
installdirs-lib:
ifdef soname
- $(MKDIR_P) '$(DESTDIR)$(libdir)' '$(DESTDIR)$(pkgconfigdir)'
+ $(MKDIR_P) '$(DESTDIR)$(libdir)' '$(DESTDIR)$(pkgconfigdir)' $(if $(findstring $(PORTNAME),win32 cygwin),'$(DESTDIR)$(bindir)')
else
$(MKDIR_P) '$(DESTDIR)$(pkglibdir)'
endif
rm -f '$(DESTDIR)$(libdir)/$(stlib)'
rm -f '$(DESTDIR)$(libdir)/$(shlib_bare)' \
'$(DESTDIR)$(libdir)/$(shlib_major)' \
- '$(DESTDIR)$(libdir)/$(shlib)' \
+ '$(DESTDIR)$(libdir)/$(shlib)' $(if $(findstring $(PORTNAME),win32 cygwin),'$(DESTDIR)$(bindir)/$(shlib)') \
'$(DESTDIR)$(pkgconfigdir)/lib$(NAME).pc'
else # no soname
rm -f '$(DESTDIR)$(pkglibdir)/$(shlib)'
ifneq (,$(SHLIB_EXPORTS))
maintainer-clean-lib:
- rm -f lib$(NAME)dll.def lib$(NAME)ddll.def blib$(NAME)dll.def
+ rm -f lib$(NAME)dll.def lib$(NAME)ddll.def
endif