Skip to content
Jim Nasby edited this page Aug 29, 2015 · 1 revision

This is a more advanced makefile than I've seen for most modules. It comes from test_factory.

Fairly standard stuff to start with...

EXTENSION = $(shell grep -m 1 '"name":' META.json | \
sed -e 's/[[:space:]]*"name":[[:space:]]*"\([^"]*\)",/\1/')
EXTVERSION = $(shell grep -m 1 '"version":' META.json | \
sed -e 's/[[:space:]]*"version":[[:space:]]*"\([^"]*\)",\{0,1\}/\1/')

DATA         = $(filter-out $(wildcard sql/*--*.sql),$(wildcard sql/*.sql))
DOCS         = $(wildcard doc/*.asc)
TESTS        = $(wildcard test/sql/*.sql)
REGRESS      = $(patsubst test/sql/%.sql,%,$(TESTS))
REGRESS_OPTS = --inputdir=test --load-language=plpgsql
#
# Uncoment the MODULES line if you are adding C files
# to your extention.
#
#MODULES      = $(patsubst %.c,%,$(wildcard src/*.c))
PG_CONFIG    = pg_config

EXTRA_CLEAN  = $(wildcard $(EXTENSION)-*.zip) $(wildcard sql/$(EXTENSION)--$(EXTVERSION).sql)

# Get Postgres version, as well as major (9.4, etc) version. Remove '.' from MAJORVER.
VERSION 	 = $(shell $(PG_CONFIG) --version | awk '{print $$2}' | sed -e 's/devel$$//')
MAJORVER 	 = $(shell echo $(VERSION) | cut -d . -f1,2 | tr -d .)

# Function for testing a condition
test		 = $(shell test $(1) $(2) $(3) && echo yes || echo no)

GE91		 = $(call test, $(MAJORVER), -ge, 91)

ifeq ($(GE91),yes)
all: sql/$(EXTENSION)--$(EXTVERSION).sql

sql/$(EXTENSION)--$(EXTVERSION).sql: sql/$(EXTENSION).sql META.json
	cp $< $@

DATA = $(wildcard sql/*--*.sql)
EXTRA_CLEAN += sql/$(EXTENSION)--$(EXTVERSION).sql
endif

PGXS := $(shell $(PG_CONFIG) --pgxs)
include $(PGXS)

This is essentially a "modification" being made to the standard PGXS make. In fact, everything after the "include $(PGXS)" line above potentially changes or over-rides PGXS, so be careful.

# Don't have installcheck bomb on error
.IGNORE: installcheck

This is an example of how you can install another PGXN module as a dependency. (Depends on having the PGXN CLI installed...)

#
# pgtap
#
.PHONY: pgtap
pgtap: $(DESTDIR)$(datadir)/extension/pgtap.control

$(DESTDIR)$(datadir)/extension/pgtap.control:
	pgxn install pgtap

These rules make running tests easier. They're mostly wrappers around the standard PGXS installcheck stuff.

#
# testdeps
#
.PHONY: testdeps
testdeps: pgtap

.PHONY: test
test: clean testdeps install installcheck
	@if [ -r regression.diffs ]; then cat regression.diffs; fi

.PHONY: results
results: test
	rsync -rlpgovP results/ test/expected

This deals with the idea of tagging your releases as branches in git.

rmtag:
	git fetch origin # Update our remotes
	@test -z "$$(git branch --list $(EXTVERSION))" || git branch -d $(EXTVERSION)
	@test -z "$$(git branch --list -r origin/$(EXTVERSION))" || git push --delete origin $(EXTVERSION)

tag:
	@test -z "$$(git status --porcelain)" || (echo 'Untracked changes!'; echo; git status; exit 1)
	git branch $(EXTVERSION)
	git push --set-upstream origin $(EXTVERSION)

.PHONY: forcetag
forcetag: rmtag tag

Once we have a tag, we can turn it into a distribution zip file, ready for upload. (It'd be great if someone found a way to automagically do the upload too!)

dist: tag
	git archive --prefix=$(EXTENSION)-$(EXTVERSION)/ -o ../$(EXTENSION)-$(EXTVERSION).zip $(EXTVERSION)

.PHONY: forcedist
forcedist: forcetag dist

This last bit is just a handy tool to see what make is doing.

# To use this, do make print-VARIABLE_NAME
print-%  : ; @echo $* = $($*)