1# $Id: Makefile.PL,v 1.1.1.1 2004/05/20 17:57:51 jpetri Exp $
2
3use ExtUtils::MakeMaker;
4use Config;
5use Symbol;
6use File::Spec;
7
8$|=0;
9
10my %config;
11
12my ( $lib_major, $lib_minor, $lib_patch ) = (2, 4, 20);
13
14while($_ = shift) {
15    my ($key, $val) = split(/=/, $_, 2);
16    $config{$key} = $val;
17}
18
19my $DEBUG = delete $config{DEBUG};
20
21# $config{DEFINE} .= " -DXS_WARNINGS";
22
23if ( $] >= 5.006 ) {
24    warn "enable native perl UTF8\n";
25    $config{DEFINE} .= " -DHAVE_UTF8";
26}
27
28# get libs and inc from gnome-config
29
30unless ( $is_Win32 ) {
31    eval {
32        my $xml2cfg = "xml2-config";
33        if ( defined $ENV{XMLPREFIX} ) {
34            $xml2cfg = $ENV{XMLPREFIX} . '/bin/' . $xml2cfg;
35        }
36
37        print "running xml2-config... ";
38        my $ver = backtick("$xml2cfg --version");
39        my ($major, $minor, $point) = $ver =~ /(\d+).(\d+)\.(\d+)/g;
40        die "VERSION $major.$minor.$point" unless $major > $lib_major
41          || ($major == $lib_major && $minor > $lib_minor)
42            || ($major == $lib_major && $minor == $lib_minor && $point >= $lib_patch);
43        $config{LIBS} ||= backtick("$xml2cfg --libs");
44        $config{INC}  ||= backtick("$xml2cfg --cflags");
45        print "ok\n";
46    };
47    if ($@) {
48        print "failed\n";
49        if ($@ =~ /^VERSION/) {
50            die "XML::LibXML needs libxml2 version $lib_major.$lib_minor.$lib_patch or higher (found $@)\n";
51        }
52        warn "*** ", $@ if $DEBUG;
53        warn "using fallback values for LIBS and INC\n";
54        # backtick fails if gnome-config didn't exist...
55        $config{LIBS} = '-L/usr/local/lib -L/usr/lib -lxml2 -lz -lm';
56        $config{INC} = '-I/usr/local/include -I/usr/include';
57
58        print <<OPT;
59options:
60  LIBS='$config{LIBS}'
61  INC='$config{INC}'
62If this is wrong, Re-run as:
63  \$ $^X Makefile.PL LIBS='-L/path/to/lib' INC='-I/path/to/include'
64
65OPT
66    }
67}
68
69
70if ($config{LIBS} !~ /\-lxml2\b/) {
71    $config{LIBS} .= $is_Win32 ? ' -llibxml2' : ' -lxml2';
72}
73
74if ($config{LIBS} !~ /\-lz\b/) {
75    $config{LIBS} .= $is_Win32 ? ' -lzlib' :' -lz';
76}
77
78if ($config{LIBS} !~ /\-lm\b/) {
79    $config{LIBS} .= $is_Win32 ? '' :' -lm';
80}
81
82if ( $config{DEBUG} ) {
83    warn "win32 compile\n" if $is_Win32;
84}
85
86unless (have_library("xml2") or have_library("libxml2")) {
87    die <<DEATH;
88libxml2 not found
89Try setting LIBS and INC values on the command line
90Or get libxml2 from
91  http://www.libxml.org/
92If you install via RPMs, make sure you also install the -devel
93RPMs, as this is where the headers (.h files) are.
94DEATH
95}
96
97WriteMakefile(
98    'NAME'		=> 'XML::LibXML::Common',
99    'VERSION_FROM'	=> 'Common.pm', # finds $VERSION
100    'PREREQ_PM'		=> {}, # e.g., Module::Name => 1.1
101    'AUTHOR'        => 'Christian Glahn <christian.glahn@uibk.ac.at>',
102    'ABSTRACT'      => 'Routines and Constants common for XML::LibXML and XML::GDOME',
103    %config,
104);
105
106
107###################################################################
108# Functions
109#  - these should really be in MakeMaker... But &shrug;
110###################################################################
111
112use Config;
113use Cwd;
114use Symbol;
115use File::Spec;
116
117use vars qw/$DEVNULL $is_Win32/;
118
119BEGIN {
120    $is_Win32 = ($^O =~ /Win32/);
121    if ($is_Win32) {
122        $DEVNULL = 'DEVNULL';
123    }
124    else {
125        $DEVNULL = eval { File::Spec->devnull };
126        if ($@) { $DEVNULL = '/dev/null' }
127    }
128}
129
130sub rm_f {
131    my @files = @_;
132    my @realfiles;
133    foreach (@files) {
134        push @realfiles, glob($_);
135    }
136    if (@realfiles) {
137        chmod(0777, @realfiles);
138        unlink(@realfiles);
139    }
140}
141
142sub rm_fr {
143    my @files = @_;
144    my @realfiles;
145    foreach (@files) {
146        push @realfiles, glob($_);
147    }
148    foreach my $file (@realfiles) {
149        if (-d $file) {
150            # warn("$file is a directory\n");
151            rm_fr("$file/*");
152            rm_fr("$file/.exists");
153            rmdir($file) || die "Couldn't remove $file: $!";
154        }
155        else {
156            # warn("removing $file\n");
157            chmod(0777, $file);
158            unlink($file);
159        }
160    }
161}
162
163sub xsystem {
164    my $command = shift;
165    if ($DEBUG) {
166        print $command, "\n";
167        if (system($command) != 0) {
168            die "system call to '$command' failed";
169        }
170        return 1;
171    }
172    open(OLDOUT, ">&STDOUT");
173    open(OLDERR, ">&STDERR");
174    open(STDOUT, ">$DEVNULL");
175    open(STDERR, ">$DEVNULL");
176    my $retval = system($command);
177    open(STDOUT, ">&OLDOUT");
178    open(STDERR, ">&OLDERR");
179    if ($retval != 0) {
180        die "system call to '$command' failed";
181    }
182    return 1;
183}
184
185sub backtick {
186    my $command = shift;
187    if ($DEBUG) {
188        print $command, "\n";
189        my $results = `$command`;
190        chomp $results;
191        if ($? != 0) {
192            die "backticks call to '$command' failed";
193        }
194        return $results;
195    }
196    open(OLDOUT, ">&STDOUT");
197    open(OLDERR, ">&STDERR");
198    open(STDOUT, ">$DEVNULL");
199    open(STDERR, ">$DEVNULL");
200    my $results = `$command`;
201    my $retval = $?;
202    open(STDOUT, ">&OLDOUT");
203    open(STDERR, ">&OLDERR");
204    if ($retval != 0) {
205        die "backticks call to '$command' failed";
206    }
207    chomp $results;
208    return $results;
209}
210
211sub try_link0 {
212    my ($src, $opt) = @_;
213    my $cfile = gensym();
214    # local $config{LIBS};
215    # $config{LIBS} .= $opt;
216    unless (mkdir(".testlink", 0777)) {
217        rm_fr(".testlink");
218        mkdir(".testlink", 0777) || die "Cannot create .testlink dir: $!";
219    }
220    chdir(".testlink");
221    open($cfile, ">Conftest.xs") || die "Cannot write to file Conftest.xs: $!";
222print $cfile <<EOT;
223#ifdef __cplusplus
224extern "C" {
225#endif
226#include <EXTERN.h>
227#include <perl.h>
228#include <XSUB.h>
229#ifdef __cplusplus
230}
231#endif
232
233EOT
234    print $cfile $src;
235    print $cfile <<EOT;
236
237MODULE = Conftest          PACKAGE = Conftest
238
239PROTOTYPES: DISABLE
240
241EOT
242    close($cfile);
243    open($cfile, ">Conftest.pm") || die "Cannot write to file Conftest.pm: $!";
244    print $cfile <<'EOT';
245package Conftest;
246$VERSION = 1.0;
247require DynaLoader;
248@ISA = ('DynaLoader');
249bootstrap Conftest $VERSION;
2501;
251EOT
252    close($cfile);
253    open($cfile, ">Makefile.PL") || die "Cannot write to file Makefile.PL: $!";
254    print $cfile <<'EOT';
255use ExtUtils::MakeMaker;
256my %config;
257while($_ = shift @ARGV) {
258    my ($k, $v) = split /=/, $_, 2;
259    warn("$k = $v\n");
260    $config{$k} = $v;
261}
262WriteMakefile(NAME => "Conftest", VERSION_FROM => "Conftest.pm", %config);
263EOT
264    close($cfile);
265    open($cfile, ">test.pl") || die "Cannot write to file test.pl: $!";
266    print $cfile <<EOT;
267use Test; BEGIN { plan tests => 1; } END { ok(\$loaded) }
268use Conftest; \$loaded++;
269EOT
270    close($cfile);
271    my $quote = $is_Win32 ? '"' : "'";
272    xsystem("$^X Makefile.PL " . join(' ', map { "${quote}$_=$config{$_}${quote}" } keys %config));
273    xsystem("$Config{make} test ${quote}OTHERLDFLAGS=${opt}${quote}");
274} # end try_link0
275
276sub try_link {
277    my $start_dir = cwd();
278    my $result = eval {
279        try_link0(@_);
280    };
281    warn $@ if $DEBUG && $@;
282    chdir($start_dir);
283    rm_fr(".testlink");
284    return $result;
285}
286
287sub have_library {
288    my ($lib, $func) = (@_, "blank");
289    printf("checking for %s() in -l%s... ", $func, $lib) if $func ne "blank";
290    printf("looking for -l%s... ", $lib) if $func eq "blank";
291
292    my $result;
293    if ($func) {
294        my $libs = $is_Win32 ? " $lib.lib  " : "-l$lib";
295#        my $libs = "-l$lib";
296        if ($is_Win32) {
297            $result = try_link(<<"SRC",undef );
298#include <windows.h>
299#include <winsock.h>
300blank() { return 0; }
301int t() { ${func}(); return 0; }
302SRC
303            unless ($result) {
304                $result = try_link(<<"SRC", undef);
305#include <windows.h>
306#include <winsock.h>
307blank() { return 0; }
308int t() { void ((*p)()); p = (void ((*)()))${func}; return 0; }
309SRC
310            }
311        }
312        else {
313            $result = try_link(<<"SRC", undef);
314blank() { return 0; }
315int t() { ${func}(); return 0; }
316SRC
317        }
318    }
319
320    unless ($result) {
321        print "no\n";
322        return 0;
323    }
324
325    if ($func ne "main") {
326        $config{DEFINE} .= uc(" -Dhave_$func");
327    }
328
329    print "yes\n";
330    return 1;
331}
332