| # PGXS: PostgreSQL extensions makefile |
| |
| # src/makefiles/pgxs.mk |
| |
| # This file contains generic rules to build many kinds of simple |
| # extension modules. You only need to set a few variables and include |
| # this file, the rest will be done here. |
| # |
| # Use the following layout for your Makefile: |
| # |
| # [variable assignments, see below] |
| # |
| # PG_CONFIG = pg_config |
| # PGXS := $(shell $(PG_CONFIG) --pgxs) |
| # include $(PGXS) |
| # |
| # [custom rules, rarely necessary] |
| # |
| # Set one of these three variables to specify what is built: |
| # |
| # MODULES -- list of shared-library objects to be built from source files |
| # with same stem (do not include library suffixes in this list) |
| # MODULE_big -- a shared library to build from multiple source files |
| # (list object files in OBJS) |
| # PROGRAM -- an executable program to build (list object files in OBJS) |
| # |
| # The following variables can also be set: |
| # |
| # EXTENSION -- name of extension (there must be a $EXTENSION.control file) |
| # MODULEDIR -- subdirectory of $PREFIX/share into which DATA and DOCS files |
| # should be installed (if not set, default is "extension" if EXTENSION |
| # is set, or "contrib" if not) |
| # DATA -- random files to install into $PREFIX/share/$MODULEDIR |
| # DATA_built -- random files to install into $PREFIX/share/$MODULEDIR, |
| # which need to be built first |
| # DATA_TSEARCH -- random files to install into $PREFIX/share/tsearch_data |
| # DOCS -- random files to install under $PREFIX/doc/$MODULEDIR |
| # SCRIPTS -- script files (not binaries) to install into $PREFIX/bin |
| # SCRIPTS_built -- script files (not binaries) to install into $PREFIX/bin, |
| # which need to be built first |
| # HEADERS -- files to install into $(includedir_server)/$MODULEDIR/$MODULE_big |
| # HEADERS_built -- as above but built first (but NOT cleaned) |
| # HEADERS_$(MODULE) -- files to install into |
| # $(includedir_server)/$MODULEDIR/$MODULE; the value of $MODULE must be |
| # listed in MODULES or MODULE_big |
| # HEADERS_built_$(MODULE) -- as above but built first (also NOT cleaned) |
| # REGRESS -- list of regression test cases (without suffix) |
| # REGRESS_OPTS -- additional switches to pass to pg_regress |
| # TAP_TESTS -- switch to enable TAP tests |
| # ISOLATION -- list of isolation test cases |
| # ISOLATION_OPTS -- additional switches to pass to pg_isolation_regress |
| # NO_INSTALL -- don't define an install target, useful for test modules |
| # that don't need their build products to be installed |
| # NO_INSTALLCHECK -- don't define an installcheck target, useful e.g. if |
| # tests require special configuration, or don't use pg_regress |
| # EXTRA_CLEAN -- extra files to remove in 'make clean' |
| # PG_CPPFLAGS -- will be prepended to CPPFLAGS |
| # PG_CFLAGS -- will be appended to CFLAGS |
| # PG_CXXFLAGS -- will be appended to CXXFLAGS |
| # PG_LDFLAGS -- will be prepended to LDFLAGS |
| # PG_LIBS -- will be added to PROGRAM link line |
| # PG_LIBS_INTERNAL -- same, for references to libraries within build tree |
| # SHLIB_LINK -- will be added to MODULE_big link line |
| # SHLIB_LINK_INTERNAL -- same, for references to libraries within build tree |
| # PG_CONFIG -- path to pg_config program for the PostgreSQL installation |
| # to build against (typically just "pg_config" to use the first one in |
| # your PATH) |
| # |
| # Better look at some of the existing uses for examples... |
| |
| ifndef PGXS |
| ifndef NO_PGXS |
| $(error pgxs error: makefile variable PGXS or NO_PGXS must be set) |
| endif |
| endif |
| |
| |
| ifdef PGXS |
| |
| # External extensions must assume generated headers are available |
| NO_GENERATED_HEADERS=yes |
| # The temp-install rule won't work, either |
| NO_TEMP_INSTALL=yes |
| |
| # We assume that we are in src/makefiles/, so top is ... |
| top_builddir := $(dir $(PGXS))../.. |
| include $(top_builddir)/src/Makefile.global |
| |
| # These might be set in Makefile.global, but if they were not found |
| # during the build of PostgreSQL, supply default values so that users |
| # of pgxs can use the variables. |
| ifeq ($(BISON),) |
| BISON = bison |
| endif |
| ifeq ($(FLEX),) |
| FLEX = flex |
| endif |
| |
| endif # PGXS |
| |
| |
| override CPPFLAGS := -I. -I$(srcdir) $(CPPFLAGS) |
| |
| ifdef MODULES |
| override CFLAGS += $(CFLAGS_SL) |
| endif |
| |
| ifdef MODULEDIR |
| datamoduledir := $(MODULEDIR) |
| docmoduledir := $(MODULEDIR) |
| incmoduledir := $(MODULEDIR) |
| else |
| ifdef EXTENSION |
| datamoduledir := extension |
| docmoduledir := extension |
| incmoduledir := extension |
| else |
| datamoduledir := contrib |
| docmoduledir := contrib |
| incmoduledir := contrib |
| endif |
| endif |
| |
| ifdef MODULEDIR |
| datamoduledir := $(MODULEDIR) |
| docmoduledir := $(MODULEDIR) |
| else |
| ifdef EXTENSION |
| datamoduledir := extension |
| docmoduledir := extension |
| else |
| datamoduledir := contrib |
| docmoduledir := contrib |
| endif |
| endif |
| |
| ifdef PG_CPPFLAGS |
| override CPPFLAGS := $(PG_CPPFLAGS) $(CPPFLAGS) |
| endif |
| ifdef PG_CFLAGS |
| override CFLAGS := $(CFLAGS) $(PG_CFLAGS) |
| endif |
| ifdef PG_CXXFLAGS |
| override CXXFLAGS := $(CXXFLAGS) $(PG_CXXFLAGS) |
| endif |
| ifdef PG_LDFLAGS |
| override LDFLAGS := $(PG_LDFLAGS) $(LDFLAGS) |
| endif |
| |
| # logic for HEADERS_* stuff |
| |
| # get list of all names used with or without built_ prefix |
| # note that use of HEADERS_built_foo will get both "foo" and "built_foo", |
| # we cope with that later when filtering this list against MODULES. |
| # If someone wants to name a module "built_foo", they can do that and it |
| # works, but if they have MODULES = foo built_foo then they will need to |
| # force building of all headers and use HEADERS_built_foo and |
| # HEADERS_built_built_foo. |
| HEADER_alldirs := $(patsubst HEADERS_%,%,$(filter HEADERS_%, $(.VARIABLES))) |
| HEADER_alldirs += $(patsubst HEADERS_built_%,%,$(filter HEADERS_built_%, $(.VARIABLES))) |
| |
| # collect all names of built headers to use as a dependency |
| HEADER_allbuilt := |
| |
| ifdef MODULE_big |
| |
| # we can unconditionally add $(MODULE_big) here, because we will strip it |
| # back out below if it turns out not to actually define any headers. |
| HEADER_dirs := $(MODULE_big) |
| HEADER_unbuilt_$(MODULE_big) = $(HEADERS) |
| HEADER_built_$(MODULE_big) = $(HEADERS_built) |
| HEADER_allbuilt += $(HEADERS_built) |
| # treat "built" as an exclusion below as well as "built_foo" |
| HEADER_xdirs := built built_$(MODULE_big) |
| |
| else # not MODULE_big, so check MODULES |
| |
| # HEADERS is an error in the absence of MODULE_big to provide a dir name |
| ifdef HEADERS |
| $(error HEADERS requires MODULE_big to be set) |
| endif |
| # make list of modules that have either HEADERS_foo or HEADERS_built_foo |
| HEADER_dirs := $(foreach m,$(MODULES),$(if $(filter $(m) built_$(m),$(HEADER_alldirs)),$(m))) |
| # make list of conflicting names to exclude |
| HEADER_xdirs := $(addprefix built_,$(HEADER_dirs)) |
| |
| endif # MODULE_big or MODULES |
| |
| # HEADERS_foo requires that "foo" is in MODULES as a sanity check |
| ifneq (,$(filter-out $(HEADER_dirs) $(HEADER_xdirs),$(HEADER_alldirs))) |
| $(error $(patsubst %,HEADERS_%,$(filter-out $(HEADER_dirs) $(HEADER_xdirs),$(HEADER_alldirs))) defined with no module) |
| endif |
| |
| # assign HEADER_unbuilt_foo and HEADER_built_foo, but make sure |
| # that "built" takes precedence in the case of conflict, by removing |
| # conflicting module names when matching the unbuilt name |
| $(foreach m,$(filter-out $(HEADER_xdirs),$(HEADER_dirs)),$(eval HEADER_unbuilt_$(m) += $$(HEADERS_$(m)))) |
| $(foreach m,$(HEADER_dirs),$(eval HEADER_built_$(m) += $$(HEADERS_built_$(m)))) |
| $(foreach m,$(HEADER_dirs),$(eval HEADER_allbuilt += $$(HEADERS_built_$(m)))) |
| |
| # expand out the list of headers for each dir, attaching source prefixes |
| header_file_list = $(HEADER_built_$(1)) $(addprefix $(srcdir)/,$(HEADER_unbuilt_$(1))) |
| $(foreach m,$(HEADER_dirs),$(eval HEADER_files_$(m) := $$(call header_file_list,$$(m)))) |
| |
| # note that the caller's HEADERS* vars have all been expanded now, and |
| # later changes will have no effect. |
| |
| # remove entries in HEADER_dirs that produced an empty list of files, |
| # to ensure we don't try and install them |
| HEADER_dirs := $(foreach m,$(HEADER_dirs),$(if $(strip $(HEADER_files_$(m))),$(m))) |
| |
| # Functions for generating install/uninstall commands; the blank lines |
| # before the "endef" are required, don't lose them |
| # $(call install_headers,dir,headers) |
| define install_headers |
| $(MKDIR_P) '$(DESTDIR)$(includedir_server)/$(incmoduledir)/$(1)/' |
| $(INSTALL_DATA) $(2) '$(DESTDIR)$(includedir_server)/$(incmoduledir)/$(1)/' |
| |
| endef |
| # $(call uninstall_headers,dir,headers) |
| define uninstall_headers |
| rm -f $(addprefix '$(DESTDIR)$(includedir_server)/$(incmoduledir)/$(1)'/, $(notdir $(2))) |
| |
| endef |
| |
| # end of HEADERS_* stuff |
| |
| |
| all: $(PROGRAM) $(DATA_built) $(HEADER_allbuilt) $(SCRIPTS_built) $(addsuffix $(DLSUFFIX), $(MODULES)) $(addsuffix .control, $(EXTENSION)) |
| |
| ifeq ($(with_llvm), yes) |
| all: $(addsuffix .bc, $(MODULES)) $(patsubst %.o,%.bc, $(OBJS)) |
| endif |
| |
| ifdef MODULE_big |
| # shared library parameters |
| NAME = $(MODULE_big) |
| |
| include $(top_srcdir)/src/Makefile.shlib |
| |
| all: all-lib |
| endif # MODULE_big |
| |
| |
| ifndef NO_INSTALL |
| |
| install: all installdirs |
| ifneq (,$(EXTENSION)) |
| $(INSTALL_DATA) $(addprefix $(srcdir)/, $(addsuffix .control, $(EXTENSION))) '$(DESTDIR)$(datadir)/extension/' |
| endif # EXTENSION |
| ifneq (,$(DATA)$(DATA_built)) |
| $(INSTALL_DATA) $(addprefix $(srcdir)/, $(DATA)) $(DATA_built) '$(DESTDIR)$(datadir)/$(datamoduledir)/' |
| endif # DATA |
| ifneq (,$(DATA_TSEARCH)) |
| $(INSTALL_DATA) $(addprefix $(srcdir)/, $(DATA_TSEARCH)) '$(DESTDIR)$(datadir)/tsearch_data/' |
| endif # DATA_TSEARCH |
| ifdef MODULES |
| $(INSTALL_SHLIB) $(addsuffix $(DLSUFFIX), $(MODULES)) '$(DESTDIR)$(pkglibdir)/' |
| ifeq ($(with_llvm), yes) |
| $(foreach mod, $(MODULES), $(call install_llvm_module,$(mod),$(mod).bc)) |
| endif # with_llvm |
| endif # MODULES |
| ifdef DOCS |
| ifdef docdir |
| $(INSTALL_DATA) $(addprefix $(srcdir)/, $(DOCS)) '$(DESTDIR)$(docdir)/$(docmoduledir)/' |
| endif # docdir |
| endif # DOCS |
| ifdef PROGRAM |
| $(INSTALL_PROGRAM) $(PROGRAM)$(X) '$(DESTDIR)$(bindir)' |
| endif # PROGRAM |
| ifdef SCRIPTS |
| $(INSTALL_SCRIPT) $(addprefix $(srcdir)/, $(SCRIPTS)) '$(DESTDIR)$(bindir)/' |
| endif # SCRIPTS |
| ifdef SCRIPTS_built |
| $(INSTALL_SCRIPT) $(SCRIPTS_built) '$(DESTDIR)$(bindir)/' |
| endif # SCRIPTS_built |
| ifneq (,$(strip $(HEADER_dirs))) |
| $(foreach dir,$(HEADER_dirs),$(call install_headers,$(dir),$(HEADER_files_$(dir)))) |
| endif # HEADERS |
| ifdef MODULE_big |
| ifeq ($(with_llvm), yes) |
| $(call install_llvm_module,$(MODULE_big),$(OBJS)) |
| endif # with_llvm |
| |
| install: install-lib |
| endif # MODULE_big |
| |
| |
| installdirs: |
| ifneq (,$(EXTENSION)) |
| $(MKDIR_P) '$(DESTDIR)$(datadir)/extension' |
| endif |
| ifneq (,$(DATA)$(DATA_built)) |
| $(MKDIR_P) '$(DESTDIR)$(datadir)/$(datamoduledir)' |
| endif |
| ifneq (,$(DATA_TSEARCH)) |
| $(MKDIR_P) '$(DESTDIR)$(datadir)/tsearch_data' |
| endif |
| ifneq (,$(MODULES)) |
| $(MKDIR_P) '$(DESTDIR)$(pkglibdir)' |
| endif |
| ifdef DOCS |
| ifdef docdir |
| $(MKDIR_P) '$(DESTDIR)$(docdir)/$(docmoduledir)' |
| endif # docdir |
| endif # DOCS |
| ifneq (,$(PROGRAM)$(SCRIPTS)$(SCRIPTS_built)) |
| $(MKDIR_P) '$(DESTDIR)$(bindir)' |
| endif |
| |
| ifdef MODULE_big |
| installdirs: installdirs-lib |
| endif # MODULE_big |
| |
| |
| uninstall: |
| ifneq (,$(EXTENSION)) |
| rm -f $(addprefix '$(DESTDIR)$(datadir)/extension'/, $(notdir $(addsuffix .control, $(EXTENSION)))) |
| endif |
| ifneq (,$(DATA)$(DATA_built)) |
| rm -f $(addprefix '$(DESTDIR)$(datadir)/$(datamoduledir)'/, $(notdir $(DATA) $(DATA_built))) |
| endif |
| ifneq (,$(DATA_TSEARCH)) |
| rm -f $(addprefix '$(DESTDIR)$(datadir)/tsearch_data'/, $(notdir $(DATA_TSEARCH))) |
| endif |
| ifdef MODULES |
| rm -f $(addprefix '$(DESTDIR)$(pkglibdir)'/, $(addsuffix $(DLSUFFIX), $(MODULES))) |
| ifeq ($(with_llvm), yes) |
| $(foreach mod, $(MODULES), $(call uninstall_llvm_module,$(mod))) |
| endif # with_llvm |
| endif # MODULES |
| ifdef DOCS |
| rm -f $(addprefix '$(DESTDIR)$(docdir)/$(docmoduledir)'/, $(DOCS)) |
| endif |
| ifdef PROGRAM |
| rm -f '$(DESTDIR)$(bindir)/$(PROGRAM)$(X)' |
| endif |
| ifdef SCRIPTS |
| rm -f $(addprefix '$(DESTDIR)$(bindir)'/, $(SCRIPTS)) |
| endif |
| ifdef SCRIPTS_built |
| rm -f $(addprefix '$(DESTDIR)$(bindir)'/, $(SCRIPTS_built)) |
| endif |
| ifneq (,$(strip $(HEADER_dirs))) |
| $(foreach dir,$(HEADER_dirs),$(call uninstall_headers,$(dir),$(HEADER_files_$(dir)))) |
| endif # HEADERS |
| |
| ifdef MODULE_big |
| ifeq ($(with_llvm), yes) |
| $(call uninstall_llvm_module,$(MODULE_big)) |
| endif # with_llvm |
| |
| uninstall: uninstall-lib |
| endif # MODULE_big |
| |
| else # NO_INSTALL |
| |
| # Need this so that temp-install builds artifacts not meant for |
| # installation (Normally, check should depend on all, but we don't do |
| # that because of parallel make risk (dbf2ec1a1c0).) |
| install: all |
| |
| endif # NO_INSTALL |
| |
| |
| clean: |
| ifdef MODULES |
| rm -f $(addsuffix $(DLSUFFIX), $(MODULES)) $(addsuffix .o, $(MODULES)) $(if $(PGFILEDESC),$(WIN32RES)) \ |
| $(addsuffix .bc, $(MODULES)) |
| endif |
| ifdef DATA_built |
| rm -f $(DATA_built) |
| endif |
| ifdef SCRIPTS_built |
| rm -f $(SCRIPTS_built) |
| endif |
| ifdef PROGRAM |
| rm -f $(PROGRAM)$(X) |
| endif |
| ifdef OBJS |
| rm -f $(OBJS) $(patsubst %.o,%.bc, $(OBJS)) |
| endif |
| ifdef EXTRA_CLEAN |
| rm -rf $(EXTRA_CLEAN) |
| endif |
| ifdef REGRESS |
| # things created by various check targets |
| rm -rf $(pg_regress_clean_files) |
| ifeq ($(PORTNAME), win) |
| rm -f regress.def |
| endif |
| endif # REGRESS |
| ifdef TAP_TESTS |
| rm -rf tmp_check/ |
| endif |
| ifdef ISOLATION |
| rm -rf output_iso/ tmp_check_iso/ |
| endif |
| |
| ifdef MODULE_big |
| clean: clean-lib |
| endif |
| |
| distclean maintainer-clean: clean |
| |
| |
| ifdef REGRESS |
| |
| REGRESS_OPTS += --dbname=$(CONTRIB_TESTDB) |
| |
| # When doing a VPATH build, must copy over the data files so that the |
| # driver script can find them. We have to use an absolute path for |
| # the targets, because otherwise make will try to locate the missing |
| # files using VPATH, and will find them in $(srcdir), but the point |
| # here is that we want to copy them from $(srcdir) to the build |
| # directory. |
| |
| ifdef VPATH |
| abs_builddir := $(shell pwd) |
| test_files_src := $(wildcard $(srcdir)/data/*.data) |
| test_files_build := $(patsubst $(srcdir)/%, $(abs_builddir)/%, $(test_files_src)) |
| |
| all: $(test_files_build) |
| $(test_files_build): $(abs_builddir)/%: $(srcdir)/% |
| $(MKDIR_P) $(dir $@) |
| ln -s $< $@ |
| endif # VPATH |
| endif # REGRESS |
| |
| .PHONY: submake |
| submake: |
| ifndef PGXS |
| $(MAKE) -C $(top_builddir)/src/test/regress pg_regress$(X) |
| $(MAKE) -C $(top_builddir)/src/test/isolation all |
| endif |
| |
| ifdef ISOLATION |
| ISOLATION_OPTS += --dbname=$(ISOLATION_TESTDB) |
| endif |
| |
| # Standard rules to run regression tests including multiple test suites. |
| # Runs against an installed postmaster. |
| ifndef NO_INSTALLCHECK |
| installcheck: submake $(REGRESS_PREP) |
| ifdef REGRESS |
| $(pg_regress_installcheck) $(REGRESS_OPTS) $(REGRESS) |
| endif |
| ifdef ISOLATION |
| $(pg_isolation_regress_installcheck) $(ISOLATION_OPTS) $(ISOLATION) |
| endif |
| ifdef TAP_TESTS |
| $(prove_installcheck) |
| endif |
| endif # NO_INSTALLCHECK |
| |
| # Runs independently of any installation |
| ifdef PGXS |
| check: |
| @echo '"$(MAKE) check" is not supported.' |
| @echo 'Do "$(MAKE) install", then "$(MAKE) installcheck" instead.' |
| else |
| check: submake $(REGRESS_PREP) |
| ifdef REGRESS |
| $(pg_regress_check) $(REGRESS_OPTS) $(REGRESS) |
| endif |
| ifdef ISOLATION |
| $(pg_isolation_regress_check) $(ISOLATION_OPTS) $(ISOLATION) |
| endif |
| ifdef TAP_TESTS |
| $(prove_check) |
| endif |
| endif # PGXS |
| |
| ifndef NO_TEMP_INSTALL |
| checkprep: EXTRA_INSTALL+=$(subdir) |
| endif |
| |
| |
| # STANDARD RULES |
| |
| ifneq (,$(MODULES)$(MODULE_big)) |
| %.sql: %.sql.in |
| sed 's,MODULE_PATHNAME,$$libdir/$*,g' $< >$@ |
| endif |
| |
| ifdef PROGRAM |
| $(PROGRAM): $(OBJS) |
| $(CC) $(CFLAGS) $(OBJS) $(PG_LIBS_INTERNAL) $(LDFLAGS) $(LDFLAGS_EX) $(PG_LIBS) $(LIBS) -o $@$(X) |
| endif |