1#-------------------------------------------------------------------------
2#
3# Makefile.shlib
4#    Common rules for building shared libraries
5#
6# Copyright (c) 1998, Regents of the University of California
7#
8# IDENTIFICATION
9#    src/Makefile.shlib
10#
11#-------------------------------------------------------------------------
12
13# This file should be included by any Postgres module Makefile that
14# wants to build a shared library (if possible for the current
15# platform). A static library is also built from the same object
16# files. Only one library can be built per makefile.
17#
18# Before including this file, the module Makefile must define these
19# variables:
20#
21# NAME                  Name of library to build (no suffix nor "lib" prefix)
22# OBJS                  List of object files to include in library
23# SHLIB_LINK            Stuff to append to library's link command
24#                       (typically, -L and -l switches for external libraries)
25# SHLIB_LINK_INTERNAL   -L and -l switches for Postgres-supplied libraries
26# SHLIB_PREREQS         Order-only prerequisites for library build target
27# SHLIB_EXPORTS         (optional) Name of file containing list of symbols to
28#                       export, in the format "function_name  number"
29#
30# Don't use SHLIB_LINK for references to files in the build tree, or the
31# wrong things will happen --- use SHLIB_LINK_INTERNAL for those!
32#
33# When building a shared library, the following version information
34# must also be set.  It should be omitted when building a dynamically
35# loadable module.
36#
37# SO_MAJOR_VERSION      Major version number to use for shared library
38# SO_MINOR_VERSION      Minor version number to use for shared library
39# (If you want a patchlevel, include it in SO_MINOR_VERSION, e.g., "6.2".)
40#
41# The module Makefile must also include
42# $(top_builddir)/src/Makefile.global before including this file.
43# (Makefile.global sets PORTNAME and other needed symbols.)
44#
45# This makefile provides the following (phony) targets:
46#
47# all-lib               build the static and shared (if applicable) libraries
48# install-lib           install the libraries into $(libdir)
49# installdirs-lib       create installation directory $(libdir)
50# uninstall-lib         remove the libraries from $(libdir)
51# clean-lib             delete the static and shared libraries from the build dir
52#
53# Typically you would add `all-lib' to the `all' target so that `make all'
54# builds the libraries.  In the most simple case it would look like this:
55#
56#     all: all-lib
57#
58# Similarly, the install rule might look like
59#
60#     install: install-lib
61#
62# plus any additional things you want to install. Et cetera.
63#
64# Got that?  Look at src/interfaces/libpq/Makefile for an example.
65#
66
67
68COMPILER = $(CC) $(CFLAGS)
69LINK.static = $(AR) $(AROPT)
70
71LDFLAGS_INTERNAL += $(SHLIB_LINK_INTERNAL)
72
73
74
75ifdef SO_MAJOR_VERSION
76# Default library naming convention used by the majority of platforms
77shlib		= lib$(NAME)$(DLSUFFIX).$(SO_MAJOR_VERSION).$(SO_MINOR_VERSION)
78shlib_major	= lib$(NAME)$(DLSUFFIX).$(SO_MAJOR_VERSION)
79shlib_bare	= lib$(NAME)$(DLSUFFIX)
80# Testing the soname variable is a reliable way to determine whether a
81# linkable library is being built.
82soname		= $(shlib_major)
83pkgconfigdir = $(prefix)/libdata/pkgconfig
84else
85# Naming convention for dynamically loadable modules
86shlib		= $(NAME)$(DLSUFFIX)
87endif
88stlib		= lib$(NAME).a
89
90ifndef soname
91# additional flags for backend modules
92SHLIB_LINK += $(BE_DLLLIBS)
93endif
94
95# For each platform we support shared libraries on, set shlib to the
96# name of the library (if default above is not right), set
97# LINK.shared to the command to link the library,
98# and adjust SHLIB_LINK if necessary.
99
100# Try to keep the sections in some kind of order, folks...
101
102override CFLAGS += $(CFLAGS_SL)
103override CXXFLAGS += $(CFLAGS_SL)
104ifdef SO_MAJOR_VERSION
105# libraries ought to use this to refer to versioned gettext domain names
106override CPPFLAGS += -DSO_MAJOR_VERSION=$(SO_MAJOR_VERSION)
107endif
108
109ifeq ($(PORTNAME), aix)
110  ifdef SO_MAJOR_VERSION
111    shlib		= lib$(NAME)$(DLSUFFIX).$(SO_MAJOR_VERSION)
112  endif
113  haslibarule   = yes
114  # $(exports_file) is also usable as an import file
115  exports_file		= lib$(NAME).exp
116endif
117
118ifeq ($(PORTNAME), darwin)
119  ifdef soname
120    # linkable library
121    DLSUFFIX		= .dylib
122    ifneq ($(SO_MAJOR_VERSION), 0)
123      version_link	= -compatibility_version $(SO_MAJOR_VERSION) -current_version $(SO_MAJOR_VERSION).$(SO_MINOR_VERSION)
124    endif
125    LINK.shared		= $(COMPILER) -dynamiclib -install_name '$(libdir)/lib$(NAME).$(SO_MAJOR_VERSION)$(DLSUFFIX)' $(version_link) $(exported_symbols_list) -multiply_defined suppress
126    shlib		= lib$(NAME).$(SO_MAJOR_VERSION).$(SO_MINOR_VERSION)$(DLSUFFIX)
127    shlib_major		= lib$(NAME).$(SO_MAJOR_VERSION)$(DLSUFFIX)
128  else
129    # loadable module
130    DLSUFFIX		= .so
131    LINK.shared		= $(COMPILER) -bundle -multiply_defined suppress
132  endif
133  BUILD.exports		= $(AWK) '/^[^\#]/ {printf "_%s\n",$$1}' $< >$@
134  exports_file		= $(SHLIB_EXPORTS:%.txt=%.list)
135  ifneq (,$(exports_file))
136    exported_symbols_list = -exported_symbols_list $(exports_file)
137  endif
138endif
139
140ifeq ($(PORTNAME), openbsd)
141  LINK.shared		= $(COMPILER) -shared
142  ifdef soname
143    LINK.shared		+= -Wl,-x,-soname,$(soname)
144  endif
145  BUILD.exports		= ( echo '{ global:'; $(AWK) '/^[^\#]/ {printf "%s;\n",$$1}' $<; echo ' local: *; };' ) >$@
146  exports_file		= $(SHLIB_EXPORTS:%.txt=%.list)
147  ifneq (,$(exports_file))
148    LINK.shared		+= -Wl,--version-script=$(exports_file)
149  endif
150  SHLIB_LINK		+= -lc
151endif
152
153ifeq ($(PORTNAME), freebsd)
154  ifdef SO_MAJOR_VERSION
155    shlib		= lib$(NAME)$(DLSUFFIX).$(SO_MAJOR_VERSION)
156  endif
157  LINK.shared		= $(COMPILER) -shared
158  ifdef soname
159    LINK.shared		+= -Wl,-x,-soname,$(soname)
160  endif
161  BUILD.exports		= ( echo '{ global:'; $(AWK) '/^[^\#]/ {printf "%s;\n",$$1}' $<; echo ' local: *; };' ) >$@
162  exports_file		= $(SHLIB_EXPORTS:%.txt=%.list)
163  ifneq (,$(exports_file))
164    LINK.shared		+= -Wl,--version-script=$(exports_file)
165  endif
166endif
167
168ifeq ($(PORTNAME), netbsd)
169  LINK.shared		= $(COMPILER) -shared
170  ifdef soname
171    LINK.shared		+= -Wl,-x,-soname,$(soname)
172  endif
173  BUILD.exports		= ( echo '{ global:'; $(AWK) '/^[^\#]/ {printf "%s;\n",$$1}' $<; echo ' local: *; };' ) >$@
174  exports_file		= $(SHLIB_EXPORTS:%.txt=%.list)
175  ifneq (,$(exports_file))
176    LINK.shared		+= -Wl,--version-script=$(exports_file)
177  endif
178endif
179
180ifeq ($(PORTNAME), hpux)
181  ifdef SO_MAJOR_VERSION
182    shlib			= lib$(NAME)$(DLSUFFIX).$(SO_MAJOR_VERSION)
183  endif
184  ifeq ($(with_gnu_ld), yes)
185    LINK.shared		= $(CC) -shared -Wl,-Bsymbolic
186    ifdef soname
187      LINK.shared	+= -Wl,-h -Wl,$(soname)
188    endif
189  else
190    LINK.shared		= $(LD) -b -Bsymbolic
191    ifdef soname
192      LINK.shared	+= +h $(soname)
193    endif
194    # can't use the CC-syntax rpath pattern here, so instead:
195    rpath =
196    ifeq ($(enable_rpath), yes)
197      LINK.shared	+= +s +b '$(rpathdir)'
198    endif
199    # On HPUX platforms, gcc is usually configured to search for libraries
200    # in /usr/local/lib, but ld won't do so.  Add an explicit -L switch so
201    # ld can find the same libraries gcc does.  Make sure it goes after any
202    # -L switches provided explicitly.
203    ifeq ($(GCC), yes)
204      SHLIB_LINK	+= -L/usr/local/lib
205    endif
206  endif
207  # And we need to link with libgcc, too
208  ifeq ($(GCC), yes)
209    SHLIB_LINK		+= `$(CC) $(LDFLAGS) -print-libgcc-file-name`
210  endif
211endif
212
213ifeq ($(PORTNAME), linux)
214  LINK.shared		= $(COMPILER) -shared
215  ifdef soname
216    LINK.shared		+= -Wl,-soname,$(soname)
217  endif
218  BUILD.exports		= ( echo '{ global:'; $(AWK) '/^[^\#]/ {printf "%s;\n",$$1}' $<; echo ' local: *; };' ) >$@
219  exports_file		= $(SHLIB_EXPORTS:%.txt=%.list)
220  ifneq (,$(exports_file))
221    LINK.shared		+= -Wl,--version-script=$(exports_file)
222  endif
223endif
224
225ifeq ($(PORTNAME), solaris)
226  ifeq ($(GCC), yes)
227    LINK.shared		= $(COMPILER) -shared -Wl,-Bsymbolic
228  else
229    LINK.shared		= $(COMPILER) -G -Bsymbolic
230  endif
231  ifdef soname
232    ifeq ($(with_gnu_ld), yes)
233      LINK.shared	+= -Wl,-soname,$(soname)
234    else
235      LINK.shared	+= -h $(soname)
236    endif
237  endif
238endif
239
240ifeq ($(PORTNAME), cygwin)
241  LINK.shared		= $(CC) -shared
242  ifdef SO_MAJOR_VERSION
243    shlib		= cyg$(NAME)$(DLSUFFIX)
244  endif
245  haslibarule   = yes
246endif
247
248ifeq ($(PORTNAME), win32)
249  ifdef SO_MAJOR_VERSION
250    shlib		= lib$(NAME)$(DLSUFFIX)
251  endif
252  haslibarule   = yes
253endif
254
255
256
257##
258## BUILD
259##
260
261.PHONY: all-lib all-static-lib all-shared-lib
262
263all-lib: all-shared-lib
264ifdef soname
265# no static library when building a dynamically loadable module
266all-lib: all-static-lib
267all-lib: lib$(NAME).pc
268endif
269
270all-static-lib: $(stlib)
271
272all-shared-lib: $(shlib)
273
274# In this rule, "touch $@" works around a problem on some platforms wherein
275# ranlib updates the library file's mod time with a value calculated to
276# seconds precision.  If the filesystem has sub-second timestamps, this can
277# cause the library file to appear older than its input files, triggering
278# parallel-make problems.
279ifndef haslibarule
280$(stlib): $(OBJS) | $(SHLIB_PREREQS)
281	rm -f $@
282	$(LINK.static) $@ $^
283	$(RANLIB) $@
284	touch $@
285endif #haslibarule
286
287
288ifeq (,$(filter cygwin win32,$(PORTNAME)))
289ifneq ($(PORTNAME), aix)
290
291# Normal case
292$(shlib): $(OBJS) | $(SHLIB_PREREQS)
293	$(LINK.shared) -o $@ $(OBJS) $(LDFLAGS) $(LDFLAGS_SL) $(SHLIB_LINK)
294ifdef shlib_major
295# If we're using major and minor versions, then make a symlink to major-version-only.
296ifneq ($(shlib), $(shlib_major))
297	rm -f $(shlib_major)
298	$(LN_S) $(shlib) $(shlib_major)
299endif
300# Make sure we have a link to a name without any version numbers
301ifneq ($(shlib), $(shlib_bare))
302	rm -f $(shlib_bare)
303	$(LN_S) $(shlib) $(shlib_bare)
304endif
305endif # shlib_major
306
307# Where possible, restrict the symbols exported by the library to just the
308# official list, so as to avoid unintentional ABI changes.  On recent macOS
309# this also quiets multiply-defined-symbol warnings in programs that use
310# libpgport along with libpq.
311ifneq (,$(SHLIB_EXPORTS))
312ifdef BUILD.exports
313$(shlib): $(SHLIB_EXPORTS:%.txt=%.list)
314
315$(SHLIB_EXPORTS:%.txt=%.list): %.list: %.txt
316	$(BUILD.exports)
317endif
318endif
319
320else # PORTNAME == aix
321
322# AIX case
323
324# See notes in src/backend/parser/Makefile about the following two rules
325$(stlib): $(shlib)
326	touch $@
327
328$(shlib): $(OBJS) | $(SHLIB_PREREQS)
329	rm -f $(stlib)
330	$(LINK.static) $(stlib) $^
331	$(RANLIB) $(stlib)
332ifeq (,$(SHLIB_EXPORTS))
333	$(MKLDEXPORT) $(stlib) $(shlib) >$(exports_file)
334else
335	( echo '#! $(shlib)'; $(AWK) '/^[^#]/ {printf "%s\n",$$1}' $(SHLIB_EXPORTS) ) >$(exports_file)
336endif
337	$(COMPILER) -o $(shlib) $(stlib) -Wl,-bE:$(exports_file) $(LDFLAGS) $(LDFLAGS_SL) $(SHLIB_LINK)
338	rm -f $(stlib)
339	$(AR) $(AROPT) $(stlib) $(shlib)
340
341endif # PORTNAME == aix
342
343else # PORTNAME == cygwin || PORTNAME == win32
344
345ifeq ($(PORTNAME), cygwin)
346
347# Cygwin case
348
349$(shlib): $(OBJS) | $(SHLIB_PREREQS)
350	$(CC) $(CFLAGS)  -shared -o $@ -Wl,--out-implib=$(stlib) $(OBJS) $(LDFLAGS) $(LDFLAGS_SL) $(SHLIB_LINK) $(LIBS) $(LDAP_LIBS_BE)
351
352# see notes in src/backend/parser/Makefile  about use of this type of rule
353$(stlib): $(shlib)
354	touch $@
355
356else
357
358# Win32 case
359
360# See notes in src/backend/parser/Makefile about the following two rules
361$(stlib): $(shlib)
362	touch $@
363
364# XXX A backend that loads a module linked with libgcc_s_dw2-1.dll will exit
365# uncleanly, hence -static-libgcc.  (Last verified with MinGW-w64 compilers
366# from i686-4.9.1-release-win32-dwarf-rt_v3-rev1.)  Shared libgcc has better
367# support for C++/Java exceptions; while core PostgreSQL does not use them, it
368# would be nice to support shared libgcc for the benefit of extensions.
369#
370# If SHLIB_EXPORTS is set, the rules below will build a .def file from that.
371# Else we just use --export-all-symbols.
372ifeq (,$(SHLIB_EXPORTS))
373$(shlib): $(OBJS) | $(SHLIB_PREREQS)
374	$(CC) $(CFLAGS)  -shared -static-libgcc -o $@  $(OBJS) $(LDFLAGS) $(LDFLAGS_SL) $(SHLIB_LINK) $(LIBS) -Wl,--export-all-symbols -Wl,--out-implib=$(stlib)
375else
376DLL_DEFFILE = lib$(NAME)dll.def
377
378$(shlib): $(OBJS) $(DLL_DEFFILE) | $(SHLIB_PREREQS)
379	$(CC) $(CFLAGS)  -shared -static-libgcc -o $@  $(OBJS) $(DLL_DEFFILE) $(LDFLAGS) $(LDFLAGS_SL) $(SHLIB_LINK) $(LIBS) -Wl,--out-implib=$(stlib)
380
381UC_NAME = $(shell echo $(NAME) | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')
382
383$(DLL_DEFFILE): $(SHLIB_EXPORTS)
384	echo 'LIBRARY LIB$(UC_NAME).dll' >$@
385	echo 'EXPORTS' >>$@
386	sed -e '/^#/d' -e 's/^\(.*[ 	]\)\([0-9][0-9]*\)/    \1@ \2/' $< >>$@
387endif
388
389endif # PORTNAME == cygwin
390endif # PORTNAME == cygwin || PORTNAME == win32
391
392
393%.pc: $(MAKEFILE_LIST)
394	echo 'Name: lib$(NAME)' >$@
395	echo 'Description: PostgreSQL lib$(NAME) library' >>$@
396	echo 'Url: $(PACKAGE_URL)' >>$@
397	echo 'Version: $(VERSION)' >>$@
398	echo 'Requires: ' >>$@
399	echo 'Requires.private: $(PKG_CONFIG_REQUIRES_PRIVATE)' >>$@
400	echo 'Cflags: -I$(includedir)' >>$@
401	echo 'Libs: -L$(libdir) -l$(NAME)' >>$@
402# Record -L flags that the user might have passed in to the PostgreSQL
403# build to locate third-party libraries (e.g., ldap, ssl).  Filter out
404# those that point inside the build or source tree.  Use sort to
405# remove duplicates.  Also record the -l flags necessary for static
406# linking, but not those already covered by Requires.private.
407	echo 'Libs.private: $(sort $(filter-out -L.% -L$(top_srcdir)/%,$(filter -L%,$(LDFLAGS) $(SHLIB_LINK)))) $(filter-out $(PKG_CONFIG_REQUIRES_PRIVATE:lib%=-l%),$(filter -l%,$(SHLIB_LINK_INTERNAL:%_shlib=%) $(SHLIB_LINK)))' >>$@
408
409
410##
411## INSTALL
412##
413
414.PHONY: install-lib install-lib-static install-lib-shared installdirs-lib
415install-lib: install-lib-shared
416ifdef soname
417install-lib: install-lib-static
418install-lib: install-lib-pc
419endif
420
421install-lib-pc: lib$(NAME).pc installdirs-lib
422	$(INSTALL_DATA) $< '$(DESTDIR)$(pkgconfigdir)/lib$(NAME).pc'
423
424install-lib-static: $(stlib) installdirs-lib
425	$(INSTALL_STLIB) $< '$(DESTDIR)$(libdir)/$(stlib)'
426ifeq ($(PORTNAME), darwin)
427	cd '$(DESTDIR)$(libdir)' && \
428	$(RANLIB) $(stlib)
429endif
430
431install-lib-shared: $(shlib) installdirs-lib
432ifdef soname
433# we don't install $(shlib) on AIX
434# (see http://archives.postgresql.org/message-id/52EF20B2E3209443BC37736D00C3C1380A6E79FE@EXADV1.host.magwien.gv.at)
435ifneq ($(PORTNAME), aix)
436	$(INSTALL_SHLIB) $< '$(DESTDIR)$(libdir)/$(shlib)'
437ifneq ($(PORTNAME), cygwin)
438ifneq ($(PORTNAME), win32)
439ifneq ($(shlib), $(shlib_major))
440	cd '$(DESTDIR)$(libdir)' && \
441	rm -f $(shlib_major) && \
442	$(LN_S) $(shlib) $(shlib_major)
443endif
444ifneq ($(shlib), $(shlib_bare))
445	cd '$(DESTDIR)$(libdir)' && \
446	rm -f $(shlib_bare) && \
447	$(LN_S) $(shlib) $(shlib_bare)
448endif
449endif # not win32
450endif # not cygwin
451endif # not aix
452ifneq (,$(findstring $(PORTNAME),win32 cygwin))
453	$(INSTALL_SHLIB) $< '$(DESTDIR)$(bindir)/$(shlib)'
454endif
455else # no soname
456	$(INSTALL_SHLIB) $< '$(DESTDIR)$(pkglibdir)/$(shlib)'
457endif
458
459
460installdirs-lib:
461ifdef soname
462	$(MKDIR_P) '$(DESTDIR)$(libdir)' '$(DESTDIR)$(pkgconfigdir)' $(if $(findstring $(PORTNAME),win32 cygwin),'$(DESTDIR)$(bindir)')
463else
464	$(MKDIR_P) '$(DESTDIR)$(pkglibdir)'
465endif
466
467
468##
469## UNINSTALL
470##
471
472.PHONY: uninstall-lib
473uninstall-lib:
474ifdef soname
475	rm -f '$(DESTDIR)$(libdir)/$(stlib)'
476	rm -f '$(DESTDIR)$(libdir)/$(shlib_bare)' \
477	  '$(DESTDIR)$(libdir)/$(shlib_major)' \
478	  '$(DESTDIR)$(libdir)/$(shlib)' $(if $(findstring $(PORTNAME),win32 cygwin),'$(DESTDIR)$(bindir)/$(shlib)') \
479	  '$(DESTDIR)$(pkgconfigdir)/lib$(NAME).pc'
480else # no soname
481	rm -f '$(DESTDIR)$(pkglibdir)/$(shlib)'
482endif # no soname
483
484
485##
486## CLEAN
487##
488
489.PHONY: clean-lib
490clean-lib:
491	rm -f $(shlib) $(shlib_bare) $(shlib_major) $(stlib) $(exports_file) lib$(NAME).pc
492ifneq (,$(DLL_DEFFILE))
493	rm -f $(DLL_DEFFILE)
494endif
495