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