1# Makefile for database package for Octave
2#
3# Copyright (C) 2016-2019 Olaf Till <i7tiol@t-online.de>
4#
5# This program is free software; you can redistribute it and/or modify
6# it under the terms of the GNU General Public License as published by
7# the Free Software Foundation; either version 3 of the License, or
8# (at your option) any later version.
9#
10# This program is distributed in the hope that it will be useful, but
11# WITHOUT ANY WARRANTY; without even the implied warranty of
12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13# General Public License for more details.
14#
15# You should have received a copy of the GNU General Public License
16# along with this program; if not, see <http://www.gnu.org/licenses/>.
17
18
19# before cross building, pre-build at least $(TEXIFILE) natively,
20# e.g. with targets 'doc', 'html', or 'prebuild'
21
22
23CXXCPP = @CXXCPP@
24
25MKOCTFILE ?= @MKOCTFILE@
26PG_CONFIG ?= @PG_CONFIG@
27OCTAVE_CONFIG ?= @OCTAVE_CONFIG@
28ifndef CXXFLAGS
29CXXFLAGS := $(shell $(MKOCTFILE) -p CXXFLAGS) -Wall
30endif
31# OCT_LINK_OPTS should have been in stable Octave since version
32# 3.6. It is used here with 'mkoctfile' to specify the library
33# directory for external libraries (pq in this case). 'mkoctfile' puts
34# $(OCT_LINK_OPTS) _after_ the -L options for Octave libraries in the
35# resulting commandline, which is important for avoiding to link to a
36# wrong Octave library. -L options given in the commandline calling
37# 'mkoctfile' are placed differently by 'mkoctfile' in the resulting
38# commandline (_before_ -L options for Octave libraries).
39ifndef OCT_LINK_OPTS
40OCT_LINK_OPTS := $(shell $(MKOCTFILE) -p OCT_LINK_OPTS)
41endif
42OCT_LINK_OPTS := $(OCT_LINK_OPTS) -L$(shell $(PG_CONFIG) --libdir)
43#
44
45CANONICAL_HOST_TYPE := $(shell $(OCTAVE_CONFIG) -p CANONICAL_HOST_TYPE))
46
47EXTRALIBS =
48ifneq (,$(findstring mingw,$(CANONICAL_HOST_TYPE)))
49  EXTRALIBS = -lws2_32
50endif
51
52octs = pq_interface.oct $(extra_octs)
53
54extra_octs = var2bytea.oct bytea2var.oct
55
56IFOBJECTS := __pq_connect__.o pq_close.o pq_exec.o converters.o \
57             converters_arr_comp.o pq_connection.o command.o \
58             pq_update_types.o pq_lo.o pq_conninfo.o __pq_internal_exit__.o \
59             error-helpers.o pkglock.o
60
61INFOFILE := ../doc/database.info
62TEXIFILE := $(addsuffix .texi,$(basename $(INFOFILE)))
63TXIFILE := $(addsuffix .txi,$(basename $(INFOFILE)))
64HTMLDIR := ../doc/html/
65
66DEFUNDLDFILES := pq_close.cc pq_exec.cc pq_update_types.cc pq_lo.cc \
67                 pq_conninfo.cc var2bytea.cc bytea2var.cc
68DSFILES := $(addsuffix .docstrings,$(DEFUNDLDFILES))
69MFILES := $(wildcard *.m) $(wildcard ../inst/*.m)
70.PHONY: all clean distclean maintainer-clean doc prebuild html
71
72.INTERMEDIATE: MFDOCSTRINGS $(DSFILES)
73
74all: $(octs)
75
76prebuild: doc html
77
78pq_interface.oct: $(IFOBJECTS)
79	OCT_LINK_OPTS="$(OCT_LINK_OPTS)" $(MKOCTFILE) -o pq_interface.oct -lpq $(IFOBJECTS) $(EXTRALIBS)
80
81%.oct: %.o error-helpers.o
82	$(MKOCTFILE) $< error-helpers.o
83
84converters.o: converters.cc converters.h wrap_endian.h config.h error-helpers.h
85	CXXFLAGS="$(CXXFLAGS)" $(MKOCTFILE) -I`$(PG_CONFIG) --includedir` -c converters.cc
86
87converters_arr_comp.o: converters_arr_comp.cc converters.h wrap_endian.h \
88                       pq_connection.h command.h config.h error-helpers.h
89	CXXFLAGS="$(CXXFLAGS)" $(MKOCTFILE) -I`$(PG_CONFIG) --includedir` -c converters_arr_comp.cc
90
91error-helpers.o: error-helpers.cc error-helpers.h config.h
92	CXXFLAGS="$(CXXFLAGS)" $(MKOCTFILE) -c error-helpers.cc
93
94pkglock.o: pkglock.cc
95	CXXFLAGS="$(CXXFLAGS)" $(MKOCTFILE) -c pkglock.cc
96
97# be on the safe side with respect to include files
98%.o: %.cc converters.h pq_connection.h command.h config.h error-helpers.h
99	CXXFLAGS="$(CXXFLAGS)" $(MKOCTFILE) -I`$(PG_CONFIG) --includedir` -c $<
100
101doc: $(INFOFILE)
102
103$(INFOFILE): $(TEXIFILE)
104	makeinfo $(TEXIFILE) -o $(INFOFILE)
105
106html: $(TEXIFILE)
107	makeinfo --html -o $(HTMLDIR) $(TEXIFILE)
108
109$(TEXIFILE): $(TXIFILE) MFDOCSTRINGS $(DSFILES) munge-texi.pl
110	./munge-texi.pl MFDOCSTRINGS $(DSFILES) < $(TXIFILE) > $(TEXIFILE)
111
112MFDOCSTRINGS: $(MFILES) mkdoc.pl
113	./mkdoc.pl $(MFILES) > MFDOCSTRINGS
114
115# take long CPP macro names, unlikely to be present in package code
116# (which is checked) or to be defined by Octave (which can't be
117# checked)
118RDEFUN_DLD := DEFUN_DLD_REPLACEMENT_FOR_PACKAGE_DOCS
119RDEFUNX_DLD := DEFUNX_DLD_REPLACEMENT_FOR_PACKAGE_DOCS
120# Docstrings defined as C strings are obtained from a compiled C
121# program. This should be the cleanest way to correctly get all
122# special characters defined in these strings.
123%.cc.docstrings: %.bin
124	(echo "### This file is generated automatically from the"; echo "### corresponding .cc file by a Makefile rule."; echo ""; ./$<) > $@
125# Explanation of the command after the checks: Macro names are changed
126# by `sed' so that a different definition can be given to them on the
127# `cpp' commandline. After running the `cpp' command, one can be sure
128# that there are not more than one `$(RDEFUN_DLD)' resulting from a
129# DEFUN(X)_DLD invocation in the original code at one line, that every
130# occurance of `$(RDEFUN_DLD)' indeed corresponds to an original macro
131# invocation, and not to `DEFUN(X)_DLD' within a comment or a string,
132# and that we have all necessary information within one line of
133# text. The package code is expected to give the function
134# documentation as a string constant directly in the macro invocation,
135# as is normally done.
136%.bin: %.cc
137	if grep -q $(RDEFUN_DLD) $<; then echo "The string '$(RDEFUN_DLD)' must not be present in source code, but is in $<."; exit 1; fi
138	if grep -q $(RDEFUNX_DLD) $<; then echo "The string '$(RDEFUNX_DLD)' must not be present in source code, but is in $<."; exit 1; fi
139	(echo "#include <stdio.h>"; echo "int main () {"; sed -e s/DEFUN_DLD/$(RDEFUN_DLD)/g -e s/DEFUNX_DLD/$(RDEFUNX_DLD)/g $< | $(CXXCPP) `$(MKOCTFILE) -p INCFLAGS` -I`$(PG_CONFIG) --includedir` -x c++ -iquote '.' -D'$(RDEFUN_DLD)(name,args,nargout,doc)=$(RDEFUN_DLD)(name,doc)' -D'$(RDEFUNX_DLD)(name,fname,gname,args,nargout,doc)=$(RDEFUN_DLD)(name,doc)' - | sed -e '/.*$(RDEFUN_DLD)/!D'; echo "}";) | $(CXX) -x c++ -D'$(RDEFUN_DLD)(name,doc)=printf("%c" #name "\n@c " #name " $<\n" doc "\n\n", 0x1D);' -o $@ -
140
141clean:
142	$(RM) *.o octave-core *.oct *.cc.docstrings MFDOCSTRINGS *~
143
144distclean:
145	$(RM) *.o octave-core *.oct *.cc.docstrings MFDOCSTRINGS *~ config.h config.log config.status
146
147maintainer-clean:
148	$(RM) *.o octave-core *.oct *.cc.docstrings MFDOCSTRINGS *~ config.h config.log config.status $(INFOFILE) $(TEXIFILE)
149