1use ExtUtils::MakeMaker;
2use Config;
3use strict;
4use warnings;
5use 5.008001;
6
7## No version.pm for this one, as the prereqs are not loaded yet.
8my $VERSION = '3.15.0';
9
10## App::Info is stored inside t/lib
11## Create a proper path so we can use it below
12my $lib;
13BEGIN {
14    use vars qw/$sep/;
15    my %seplist = (
16               MacOS   => ':',
17               MSWin32 => '\\',
18               os2     => '\\',
19               VMS     => '\\',
20               NetWare => '\\',
21               dos     => '\\',
22               );
23    $sep = $seplist{$^O} || '/';
24    $lib = join $sep, 't', 'lib';
25}
26
27use lib $lib;
28
29if ($VERSION =~ /_/) {
30    print "WARNING! This is a test version ($VERSION) and should not be used in production!\n";
31}
32
33if (grep { /help/ } @ARGV) {
34    print qq{
35Usage: perl $0
36
37No other options are necessary, although you may need to
38set some evironment variables. See the README file for full details.
39
40In brief:
41
42By default Makefile.PL uses App::Info to find the location of the
43PostgreSQL library and include directories.  However, if you want to
44control it yourself, define the environment variables POSTGRES_INCLUDE
45and POSTGRES_LIB, or define just POSTGRES_HOME. Note that if you have
46compiled PostgreSQL with SSL support, you must define the POSTGRES_LIB
47environment variable and add "-lssl" to it, like this:
48
49export POSTGRES_LIB="/usr/local/pgsql/lib -lssl"
50
51The usual steps to install DBD::Pg:
52
531.   perl Makefile.PL
542.   make
553.   make test
564.   make install
57
58Do steps 1 to 3 as a normal user, not as root!
59
60If all else fails, email dbd-pg\@perl.org for help.
61
62};
63    exit 1;
64
65}
66
67print "Configuring DBD::Pg $VERSION\n";
68
69my $POSTGRES_INCLUDE;
70my $POSTGRES_LIB;
71
72# We need the version information to properly set compiler options later
73# Use App::Info to get the data we need.
74require App::Info::RDBMS::PostgreSQL;
75my $prompt;
76if ($ENV{PERL_MM_USE_DEFAULT} or $ENV{AUTOMATED_TESTING}) {
77    require App::Info::Handler::Print;
78    $prompt = App::Info::Handler::Print->new;
79}
80else {
81    require App::Info::Handler::Prompt;
82    $prompt = App::Info::Handler::Prompt->new;
83}
84
85my $pg = App::Info::RDBMS::PostgreSQL->new(on_unknown => $prompt);
86my ($major_ver, $minor_ver, $patch, $conf, $bindir) = map {$pg->$_}
87    qw/major_version minor_version patch_version configure bin_dir/;
88my $initdb = '';
89if (defined $bindir and -d $bindir) {
90    my $testinitdb = "$bindir${sep}initdb";
91    if (-e $testinitdb) {
92        $initdb = $testinitdb;
93    }
94}
95my $serverversion = 0;
96my $defaultport = 0;
97
98if (defined $major_ver) {
99    $serverversion = sprintf '%d%.02d%.02d', $major_ver, $minor_ver, $patch;
100    $defaultport = $conf =~ /with-pgport=([0-9]+)/ ? $1 : 5432;
101}
102
103# We set POSTGRES_INCLUDE and POSTGRES_LIB from the first found of:
104# 1. environment variable
105# 2. App::Info::RDBMS::PostgreSQL information
106# 3. subdirectory of $ENV{POSTGRES_HOME}
107
108$POSTGRES_INCLUDE = $ENV{POSTGRES_INCLUDE} || $pg->inc_dir;
109
110if (! defined $POSTGRES_INCLUDE) {
111	if (! defined $ENV{POSTGRES_HOME}) {
112		warn "No POSTGRES_HOME defined, cannot find automatically\n";
113		exit 0;
114	}
115	$POSTGRES_INCLUDE = "$ENV{POSTGRES_HOME}/include";
116}
117
118$POSTGRES_LIB = $ENV{POSTGRES_LIB} || $pg->lib_dir || "$ENV{POSTGRES_HOME}/lib";
119
120my $os = $^O;
121print "PostgreSQL version: $serverversion (default port: $defaultport)\n";
122my $showhome = $ENV{POSTGRES_HOME} || '(not set)';
123print "POSTGRES_HOME: $showhome\n";
124my $showinc = $POSTGRES_INCLUDE || '(not set)';
125print "POSTGRES_INCLUDE: $showinc\n";
126my $showlib = $POSTGRES_LIB || '(not set)';
127print "POSTGRES_LIB: $showlib\n";
128print "OS: $os\n";
129
130my $baddir = 0;
131sub does_path_exist {
132    my ($path_name, $path) = @_;
133
134    return if ! defined $path or ! length $path or -d $path;
135    printf "The value of %s points to a non-existent directory: %s\n",
136        $path_name, $path;
137    $baddir++;
138    return;
139}
140
141does_path_exist('POSTGRES_HOME', $ENV{POSTGRES_HOME});
142does_path_exist('POSTGRES_INCLUDE',  $POSTGRES_INCLUDE);
143
144if ($baddir) {
145    print "Cannot build unless the directories exist, exiting.\n";
146    exit 0;
147}
148
149if ($serverversion < 11) {
150    print "Could not determine the PostgreSQL library version.\n".
151    "Please ensure that a valid path is given to the 'pg_config' command,\n".
152    "either manually or by setting the environment variables\n".
153    "POSTGRES_DATA, POSTGRES_INCLUDE, and POSTGRES_LIB\n";
154    exit 0;
155}
156
157if ($os =~ /Win32/) {
158    for ($POSTGRES_INCLUDE, $POSTGRES_LIB) {
159        $_ = qq{"$_"} if index $_,'"';
160    }
161}
162
163## Warn about older versions
164if ($serverversion < 80000) {
165    print "\n****************\n";
166    print "WARNING! DBD::Pg no longer supports versions less than 8.0.\n";
167    print "You must upgrade PostgreSQL to a newer version.\n";
168    print "****************\n\n";
169    exit 1;
170}
171
172my $dbi_arch_dir;
173{
174    eval {
175        require DBI::DBD;
176    };
177    if ($@) {
178        print "Could not load DBI::DBD - is the DBI module installed?\n";
179        exit 0;
180    }
181    local *STDOUT; ## Prevent duplicate debug info as WriteMakefile also calls this
182    $dbi_arch_dir = DBI::DBD::dbd_dbi_arch_dir();
183}
184
185my $defines = " -DPGLIBVERSION=$serverversion -DPGDEFPORT=$defaultport";
186my $comp_opts = $Config{q{ccflags}} . $defines;
187
188if ($ENV{DBDPG_GCCDEBUG}) {
189    warn "Enabling many compiler options\n";
190    $comp_opts .= ' -Wchar-subscripts -Wcomment';
191    $comp_opts .= ' -Wformat=2'; ## does -Wformat,-Wformat-y2k,-Wformat-nonliteral,-Wformat-security
192    $comp_opts .= ' -Wnonnull';
193    $comp_opts .= ' -Wuninitialized -Winit-self'; ## latter requires the former
194    $comp_opts .= ' -Wimplicit'; ## does -Wimplicit-int and -Wimplicit-function-declaration
195    $comp_opts .= ' -Wmain -Wmissing-braces -Wparentheses -Wsequence-point -Wreturn-type -Wswitch -Wswitch-enum -Wtrigraphs';
196    $comp_opts .= ' -Wunused'; ## contains -Wunused- function,label,parameter,variable,value
197    $comp_opts .= ' -Wunknown-pragmas -Wstrict-aliasing';
198    $comp_opts .= ' -Wall'; ## all of above, but we enumerate anyway
199    $comp_opts .= ' -Wextra -Wendif-labels -Wpointer-arith';
200    $comp_opts .= ' -Wbad-function-cast -Wcast-qual -Wcast-align -Wsign-compare -Waggregate-return';
201    $comp_opts .= ' -Wmissing-prototypes -Wmissing-declarations -Wmissing-format-attribute -Wpacked -Winline -Winvalid-pch';
202    $comp_opts .= ' -Wdisabled-optimization';
203    $comp_opts .= ' -Wnested-externs';
204    $comp_opts .= ' -Wstrict-prototypes'; ## Still hits a couple places in types.h
205    $comp_opts .= ' -Wswitch-default';
206    $comp_opts .= ' -Wsystem-headers';
207    $comp_opts .= ' -Wmissing-noreturn';
208    $comp_opts .= ' -Wfloat-equal'; ## Does not like SvTRUE() calls
209}
210
211my %opts =
212    (
213     NAME           => 'DBD::Pg',
214     VERSION_FROM   => 'Pg.pm',
215     INC            => "-I$POSTGRES_INCLUDE -I$dbi_arch_dir $comp_opts",
216     OBJECT         => 'Pg$(OBJ_EXT) dbdimp$(OBJ_EXT) quote$(OBJ_EXT) types$(OBJ_EXT)',
217     LIBS           => ["-L$POSTGRES_LIB -lpq -lm"],
218     AUTHOR         => 'Greg Sabino Mullane',
219     ABSTRACT       => 'PostgreSQL database driver for the DBI module',
220     PREREQ_PM      => {
221                        'ExtUtils::MakeMaker' => '6.11',
222                        'DBI'                 => '1.614',
223                        'Test::More'          => '0.88',
224                        'Time::HiRes'         => '0',
225                        'version'             => '0',
226                       },
227     PERL_MALLOC_OK => 1,
228     NEEDS_LINKING  => 1,
229     NO_META        => 1,
230     NORECURS       => 1,
231     PM             => {
232                        'Pg.pm' => '$(INST_LIBDIR)/Pg.pm',
233                        'lib/Bundle/DBD/Pg.pm' => '$(INST_LIB)/Bundle/DBD/Pg.pm',
234                       },
235     clean          => { FILES => 'trace Pg.xsi README.testdatabase cover_db' },
236     realclean      => { FILES => 'dbdpg_test_database/' },
237);
238
239if ($os eq 'hpux') {
240    my $osvers = $Config{osvers};
241    if ($osvers < 10) {
242        print "Warning: Forced to build static not dynamic on $os $osvers.\a\n";
243        $opts{LINKTYPE} = 'static';
244    }
245}
246elsif ($os =~ /Win32/) {
247    my $msdir = $POSTGRES_LIB;
248    $msdir =~ s{"$}{/ms"};
249    $opts{LIBS}[0] .= " -L$msdir -lsecur32";
250}
251
252if ($Config{dlsrc} =~ /dl_none/) {
253    $opts{LINKTYPE} = 'static';
254}
255
256{
257    package MY; ## no critic
258    sub MY::test { ## no critic
259        my $string = shift->SUPER::test(@_);
260        $string =~ s/(PERL_DL_NONLAZY=1)/PGINITDB="$initdb" $1/g;
261        return "HARNESS_OPTIONS=j1\n$string";
262    }
263}
264
265sub constants {
266    my $self = shift;
267
268    my $old_constants = $self->SUPER::constants();
269    my $new_constants = '';
270    for my $line (split /\n/ => $old_constants) {
271        if ($line =~ /^INC = .*strawberry.*/ ) {
272            print qq(Strawberry Perl found; adjusting the INC variable;\n);
273            $line .= ' -I ' . DBI::DBD::dbd_dbi_arch_dir();
274            print qq(INC is now $line\n);
275        }
276        $new_constants .= "$line\n";
277    }
278    return $new_constants;
279}
280
281sub MY::postamble { ## no critic ProhibitQualifiedSubDeclarations
282    no strict 'subs'; ## no critic ProhibitNoStrict
283    my $string = DBI::DBD->dbd_postamble();
284    use strict 'subs';
285    ## Evil, evil stuff - but we really want to suppress the "duplicate function" message!
286    $string =~ s/dependancy/dependency/g; ## why not, while we are here
287    $string =~ s{(BASEEXT\)/g)}{$1; s/^do\\\(/dontdo\\\(/};
288
289        my $tags = <<'MAKE_FRAG';
290.PHONY: tags
291
292tags:
293	ctags -f tags --recurse --totals \
294		--exclude=blib \
295		--exclude=.git \
296		--exclude='*~' \
297		--languages=Perl,C --langmap=c:+.h,Perl:+.t \
298
299MAKE_FRAG
300        $string = "$string\n$tags\n";
301
302	$string .= <<'MAKE_SPLINT';
303
304## This must be version 3.2.1 or better: earlier versions have many
305## problems parsing the DBI header files
306SPLINT = splint
307
308## Temp directory, for use with +keep
309SPLINT_TMP = $(TMP)/splint_dbdpg
310
311SPLINTFLAGS =            \
312  -message-stream-stdout \
313  -linelen 90            \
314  -boolops               \
315  -tmpdir $(SPLINT_TMP)  \
316  +posixstrictlib        \
317  +ignoresigns           \
318  +showdeephistory       \
319  -predboolint           \
320  -nullpass              \
321  +charint               \
322  +boolint               \
323  +allglobals            \
324
325SPLINTFLAGS_TEST =
326
327SDEFINES =
328
329splint: $(H_FILES) $(C_FILES)
330	$(MKPATH) $(SPLINT_TMP)
331	$(SPLINT) $(SPLINTFLAGS) $(SPLINTFLAGS_TEST) $(SDEFINES) -I$(PERL_INC) $(INC) $(C_FILES)
332
333MAKE_SPLINT
334
335    $string =~ s/SDEFINES = /SDEFINES =$defines/;
336
337    return $string;
338}
339
340my $output = WriteMakefile(%opts);
341
342if (!exists $output->{EXTRALIBS} or
343
344    ($output->{EXTRALIBS} !~ /\-lpq/ and $output->{EXTRALIBS} !~ /libpq/)) {
345
346    my $makefile = exists $output->{MAKEFILE}
347        ? "\nRemoving ($output->{MAKEFILE})\n" : '';
348
349    warn qq{
350==========================================================
351
352WARNING! No libpq libraries were detected!
353
354You need to install the postgresql-libs package for your system,
355
356or set the POSTGRES_LIB environment variable to the correct place.
357$makefile
358===========================================================
359
360};
361
362    ## Do not let make proceed
363    unlink $output->{MAKEFILE} if $makefile;
364
365    exit 1;
366}
367
368exit 0;
369
370# end of Makefile.PL
371