Fix build with xapian-core < 1.4.10
[xapian.git] / search-xapian / Makefile.PL
blob7230f28fb34dd385402c624bfc2513d43f8f87b1
1 use ExtUtils::MakeMaker;
2 use strict;
3 use Config;
4 use File::Spec;
6 my $builddir;
8 my $srcdir = $0;
9 if ($srcdir =~ s!/([^/]*)$!!) {
10     # Set $0 to be just the leafname.  If we don't, WriteMakefile() reruns this
11     # script for reasons unknown, leading to a seemingly infinite loop
12     # consuming increasing amounts of memory.  With setting $0, it still reruns
13     # this script, but only once.
14     $0 = $1;
15     $builddir = `pwd`;
16     chdir $srcdir;
17     if ($builddir eq `pwd`) {
18         # Just an explicit path to the current directory.
19         undef $builddir;
20     } else {
21         chomp($builddir);
22     }
25 my $xapian_config;
26 my $CC;
27 my %var = ();
28 my $devnull = File::Spec->devnull();
30 # Write out args for use by t/symboltest.t.
31 open ARGS, '>', 'makefile-pl-args' or die $!;
32 for (@ARGV) {
33     print ARGS $_, "\n";
34     if (/^XAPIAN_CONFIG=(.*)/) {
35         $xapian_config = $1;
36     } elsif (/^CXX=(.*)/) {
37         $CC = $1;
38     } elsif (/^(C(?:XX|PP)FLAGS)=(.*)/) {
39         $var{$1} = $2;
40     }
42 close ARGS or die $!;
44 if (!defined $xapian_config && exists $ENV{XAPIAN_CONFIG}) {
45     $xapian_config = $ENV{XAPIAN_CONFIG};
46     push @ARGV, "XAPIAN_CONFIG=$xapian_config";
48 $xapian_config ||= 'xapian-config';
50 if (!defined $CC && exists $ENV{CXX}) {
51     $CC = $ENV{CXX};
52     push @ARGV, "CXX=$CC";
54 $CC ||= 'g++';
56 my $LD = '$(CC)';
57 if ($^O eq 'cygwin' and $CC eq 'g++') {
58     # Cygwin packages of Perl < 5.9.5 used "ld2" for $Config{ld} and
59     # $Config{lddlflags} didn't contain -shared so we need to specify
60     # this explicitly.  Perl >= 5.9.5 package do away with "ld2", but
61     # it should be harmless to specify "-shared" there.
62     $LD = 'g++ -shared';
65 my $xver = `$xapian_config --version`;
66 if ($xver eq '') {
67     print STDERR <<END;
68 $xapian_config not found.
70 You need Xapian installed before you can build Search::Xapian.  If you have
71 installed Xapian from a package, you will also need to install the correspoding
72 -dev or -devel package.  If Xapian is installed but xapian-config isn't on your
73 PATH you can tell Makefile.PL this by running it like so:
75     perl Makefile.PL XAPIAN_CONFIG=/path/to/xapian-config
76 END
77     # Perversely, the CPAN automatic testing script expects exit status 0 to
78     # indicate "can't build because of missing dependencies" (which it
79     # distinguishes from "all OK" by seeing if Makefile is generated).  So we
80     # exit with status 0 in this case to avoid being spammed with useless
81     # "bug" reports from testers without Xapian installed.
82     exit(0);
84 chomp($xver);
85 $xver =~ s/.*\s//; # "xapian 1.2.0" -> "1.2.0"
87 my $inc = `$xapian_config --cxxflags`;
88 chomp($inc);
90 my @writemakefile_args = ();
91 my $libsvar = 'LIBS';
92 my $libs = `$xapian_config --libs 2> $devnull`;
93 chomp($libs);
94 my ($xapian_config_dir) = $xapian_config =~ /^(.*?)[^\/]*$/;
95 if ($? || ($xapian_config_dir ne '' && -f "${xapian_config_dir}Makefile")) {
96     # Assume we're being asked to build against an uninstalled xapian-core.
97     my $libtool = "${xapian_config_dir}libtool";
98     unless (-x $libtool) {
99         die "You've asked me to link against what appears to be an uninstalled xapian-core tree, but I can't find libtool in that tree\n";
100     }
102     # We can't pass a .la file in LIBS since MakeMaker "knows better" and
103     # ignores it.  Passing it in LDLOADLIBS works, but generates a warning.
104     # We can avoid the warning by setting LDLOADLIBS using 'macro'.
105     $libsvar = 'macro';
106     $libs = `$xapian_config --ltlibs`;
107     chomp($libs);
108     $libs = {'LDLOADLIBS' => $libs};
109     open LDWRAP, '>', 'ld-wrapper' or die $!;
110     print LDWRAP <<END;
111 #!/bin/sh
112 set -e
113 SO=\$1
114 INST_ARCHAUTODIR=\$2
115 shift
116 shift
117 "\$\@"
118 ln -sf ".libs/Xapian.\$SO" "\$INST_ARCHAUTODIR/Xapian.\$SO"
120     chmod 0755, *LDWRAP or die $!;
121     close LDWRAP or die $!;
122     $LD = "./ld-wrapper \"\$(SO)\" \"\$(INST_ARCHAUTODIR)\"";
123     $LD .= " $libtool --tag=CXX --mode=link $CC -avoid-version -module";
124     $LD .= " -rpath \$(PERL_ARCHLIB)/auto/\$(FULLEXT)";
125     $LD .= " -shrext .".$Config{'dlext'};
126     $CC = "$libtool --tag=CXX --mode=compile $CC";
127     push @writemakefile_args, (
128         'OBJ_EXT'       => '.lo',
129         'DLEXT'         => 'la'
130     );
133 system($^X, "generate-perl-exceptions", ".", $xver) == 0
134     or die "Running generate-perl-exceptions failed: $?";
136 # Filter out some gcc options which g++ doesn't support.
137 my $CCFLAGS = $Config{'ccflags'};
138 # Perl is built with -Wdeclaration-after-statement on RHEL5 - this isn't
139 # meaningful for C++ - it only emits a warning but it's easy to fix.
140 $CCFLAGS =~ s/(?:^|\s+)-Wdeclaration-after-statement(?:\s+|$)/ /;
141 # The generated code causes "variable may be used uninitialized" warnings
142 # if Perl was built with -Wall.
143 $CCFLAGS =~ s/(^|\s+)-Wall(\s+|$)/$1-Wall -Wno-uninitialized$2/;
145 if (exists $var{CPPFLAGS}) {
146     $CCFLAGS .= ' ' . $var{CPPFLAGS};
147 } elsif (exists $ENV{CPPFLAGS}) {
148     $CCFLAGS .= ' ' . $ENV{CPPFLAGS};
150 if (exists $var{CXXFLAGS}) {
151     $CCFLAGS .= ' ' . $var{CXXFLAGS};
152 } elsif (exists $ENV{CXXFLAGS}) {
153     $CCFLAGS .= ' ' . $ENV{CXXFLAGS};
156 # See lib/ExtUtils/MakeMaker.pm for details of how to influence
157 # the contents of the Makefile that is written.
158 push @writemakefile_args, (
159     'NAME'              => 'Search::Xapian',
160     'VERSION_FROM'      => 'Xapian.pm', # finds $VERSION
161     'PREREQ_PM'         => {}, # e.g., Module::Name => 1.1
162     ($] >= 5.005 ?    ## Add these new keywords supported since 5.005
163       (ABSTRACT_FROM => 'Xapian.pm', # retrieve abstract from module
164        AUTHOR     => 'Alex Bowley <xapian-discuss@lists.xapian.org>') : ()),
165 #       AUTHOR     => 'Alex Bowley <kilinrax@cpan.org>') : ()),
166     'META_MERGE' => {
167         'meta-spec' => { version => 2 },
168          resources => {
169              repository => {
170                  type => 'git',
171                  web  => 'https://git.xapian.org/?p=xapian;a=tree;f=search-xapian;hb=refs/heads/svn/1.2'
172              },
173              bugtracker => {
174                  web => 'https://trac.xapian.org/'
175              },
176              homepage   => 'https://xapian.org/',
177          },
178     },
179     $libsvar            => $libs, # e.g., '-lm'
180     'LICENSE'           => 'perl',
181     'MIN_PERL_VERSION'  => '5.6.0',
182     'BUILD_REQUIRES'    => { 'Devel::Leak' => 0 },
183     'DEFINE'            => '', # e.g., '-DHAVE_SOMETHING'
184     'CC'                => $CC,
185     'CCFLAGS'           => $CCFLAGS,
186     'LD'                => $LD,
187     'INC'               => $inc, # e.g., '-I/usr/include/other'
188     'OBJECT'            => '$(BASEEXT)$(OBJ_EXT) handle_exception$(OBJ_EXT)',
189     'XSOPT'             => '-C++',
190     # 'typemap' is implicitly added to this list.
191     'TYPEMAPS'          => ['perlobject.map', 'typemap-errorclasses'],
192     'clean'             => { 'FILES' => 'ld-wrapper makefile-pl-args' },
193     # Add "make check" as alias for "make test".
194     # Make sure that we rebuild the Makefile if the version number changes.
195     'depend'            => { 'check' => 'test', 'Makefile' => 'Xapian.pm' },
198 # Throw away STDOUT from WriteMakefile() to suppress warnings about parameters
199 # we allow the user to specify: CPPFLAGS CXX CXXFLAGS XAPIAN_CONFIG
200 *TEMP = *STDOUT;
201 open DEVNULL, '>', $devnull;
202 *STDOUT = *DEVNULL;
203 WriteMakefile(@writemakefile_args);
204 *STDOUT = *TEMP;
205 close DEVNULL;
207 my $VERSION = "unknown";
208 open F, "Makefile" or die $!;
209 while (<F>) {
210     if (/^VERSION\s*=\s*(\S*)/) {
211         $VERSION = $1;
212         last;
213     }
215 close F;
217 my ($BASEVERSION) = $VERSION =~ /^([0-9]+\.[0-9]+\.[0-9]+)/;
218 if ($xver !~ /^\Q$BASEVERSION\E(?:_(?:svn|git)[0-9]+)?$/) {
219     # We definitely need Xapian 1.2.x, 1.4.x, 1.5.x or 1.6.x.
220     my $no_chance = ($xver !~ /^1\.[2456]\./);
221     my $msg;
222     if ($no_chance) {
223         $msg = "Xapian version $xver is incompatible with Search::Xapian $VERSION\n";
224     } elsif ($BASEVERSION =~ /^1\.2\./ && $xver =~ /^1\.4\./) {
225         # Search::Xapian 1.2.x and xapian-core 1.4.y should work together
226         # (for x >= 24).
227     } else {
228         # We try to keep working with Xapian 1.5.x and up but no promises.
229         $msg = "Xapian version $xver may be incompatible with Search::Xapian $VERSION\n";
230     }
232     if ($ENV{AUTOMATED_TESTING} && defined $msg) {
233         # Don't let automated testers continue, as we don't want bogus failure
234         # reports due to builds with incompatible versions.
235         print $msg;
236         # Remove Makefile since "exit status 0 without generating Makefile"
237         # is taken to indicate "can't build because of missing dependencies"
238         # by CPAN test building scripts.
239         unlink "Makefile";
240         exit 0;
241     }
242     if ($no_chance) {
243         unlink "Makefile";
244         die $msg;
245     }
246     warn "Warning: $msg" if defined $msg;
249 my @bad;
250 for my $file (qw(Changes README)) {
251     open F, $file or next;
252     my $ok;
253     while (<F>) {
254         if (/\b\Q$VERSION\E\b/) {
255             $ok = 1;
256             last;
257         }
258     }
259     close F;
260     if (!$ok) {
261         push @bad, $file;
262     }
264 if (scalar @bad) {
265     unlink "Makefile";
266     die(join(",",@bad).": No mention of current version: $VERSION\n");
269 # If we're doing a fake VPATH build, add a stub Makefile which forwards all
270 # invocations (.DEFAULT is a GNU-make-ism).
271 if (defined $builddir) {
272     open M, '>', "$builddir/Makefile~" or die $!;
273     print M <<"EOF";
274 all .DEFAULT:
275 \t\$(MAKE) -C "$srcdir" \$\@
277 .PHONY: all Search-Xapian-$VERSION.tar.gz
279 dist tardist Search-Xapian-$VERSION.tar.gz:
280 \t\$(MAKE) -C "$srcdir" \$\@
281 \trm -f Search-Xapian-$VERSION.tar.gz
282 \tcp "$srcdir"/Search-Xapian-$VERSION.tar.gz .
285     close M or die $!;
286     rename "$builddir/Makefile~", "$builddir/Makefile" or die $!;
289 sub MY::postamble {
290   return "\$(XS_FILES): ".join(" ", <XS/*.xs>)."\n\ttouch \$(XS_FILES)";