# Copyright (C) 2010-2013 Torsten Schoenfeld <kaffeetisch@gmx.de>
#
# This library is free software; you can redistribute it and/or modify it under
# the terms of the GNU Library General Public License as published by the Free
# Software Foundation; either version 2.1 of the License, or (at your option)
# any later version.
#
# This library is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for
# more details.
#
# You should have received a copy of the GNU Library General Public License
# along with this library; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
BEGIN { require 5.008; }
use strict;
use warnings;
use ExtUtils::MakeMaker;
use File::Spec;
use Config;
use Cwd;
my %RUNTIME_REQ_PM = (
'Glib' => 1.280,
);
my %CONFIG_REQ_PM = (
'ExtUtils::Depends' => 0.300,
'ExtUtils::PkgConfig' => 1.000,
'Glib' => $RUNTIME_REQ_PM{Glib},
);
my %BUILD_REQ = (
'gobject-introspection-1.0' => '0.10.0',
'gmodule-2.0' => '2.0.0',
'libffi' => '3.0.0',
);
my @xs_files = qw(GObjectIntrospection.xs);
my %pm_files = (
'lib/Glib/Object/Introspection.pm' => '$(INST_LIBDIR)/Introspection.pm',
);
my %pod_files = (
'lib/Glib/Object/Introspection.pm'
=> '$(INST_MAN3DIR)/Glib::Object::Introspection.$(MAN3EXT)',
);
my %meta_merge = (
q(meta-spec) => {
version => '2',
url => 'http://search.cpan.org/perldoc?CPAN::Meta::Spec',
},
author =>
['Glib::Object::Introspection Team <gtk-perl-list at gnome dot org>'],
release_status => 'unstable',
# valid values: https://metacpan.org/module/CPAN::Meta::Spec#license
license => 'lgpl_2_1',
resources => {
license => 'http://www.gnu.org/licenses/lgpl-2.1.html',
homepage => 'http://gtk2-perl.sourceforge.net',
x_MailingList =>
'https://mail.gnome.org/mailman/listinfo/gtk-perl-list',
bugtracker => {
web =>
'http://rt.cpan.org/Public/Dist/Display.html?Name=Glib-Object-Introspection',
mailto => 'bug-Glib-Object-Introspection [at] rt.cpan.org',
},
repository => {
url => 'git://git.gnome.org/perl-Glib-Object-Introspection',
type => 'git',
web => 'http://git.gnome.org/browse/perl-Glib-Object-Introspection',
},
},
prereqs => {
configure => {
requires => {%CONFIG_REQ_PM}, # no direct ref for 5.14 compatibility
},
runtime => {
requires => {%RUNTIME_REQ_PM}, # no direct ref for 5.14 compatibility
},
},
no_index => {
file => \@xs_files,
package => [ 'MY', 'Glib::Object::Introspection::_FuncWrapper' ],
},
);
my $dep_success = eval <<__EOE__;
use ExtUtils::Depends $CONFIG_REQ_PM{'ExtUtils::Depends'};
use ExtUtils::PkgConfig $CONFIG_REQ_PM{'ExtUtils::PkgConfig'};
use Glib $CONFIG_REQ_PM{'Glib'};
use Glib::MakeHelper;
1;
__EOE__
if (!$dep_success) {
warn $@;
exit 0;
}
my %cfg;
my $cfg_success = eval {
%cfg = ExtUtils::PkgConfig->find (
"gobject-introspection-1.0 >= $BUILD_REQ{'gobject-introspection-1.0'}");
1;
};
if (!$cfg_success) {
warn $@;
exit 0;
}
$cfg_success = eval {
my %cfg_gmod = ExtUtils::PkgConfig->find (
"gmodule-2.0 >= $BUILD_REQ{'gmodule-2.0'}");
$cfg{cflags} .= " $cfg_gmod{cflags}";
$cfg{libs} .= " $cfg_gmod{libs}";
1;
};
if (!$cfg_success) {
warn $@;
exit 0;
}
$cfg_success = eval {
my %cfg_ffi = ExtUtils::PkgConfig->find (
"libffi >= $BUILD_REQ{'libffi'}");
$cfg{cflags} .= " $cfg_ffi{cflags}";
$cfg{libs} .= " $cfg_ffi{libs}";
1;
};
if (!$cfg_success) {
warn $@;
exit 0;
}
mkdir 'build', 0777;
compile_test_libraries();
ExtUtils::PkgConfig->write_version_macros (
"build/gi-version.h",
"gobject-introspection-1.0" => "GI",
);
my $deps = ExtUtils::Depends->new ('Glib::Object::Introspection' => 'Glib');
$deps->set_inc ($cfg{cflags});
$deps->set_libs ($cfg{libs});
$deps->add_pm (%pm_files);
$deps->add_xs (@xs_files);
$deps->save_config ('build/IFiles.pm');
WriteMakefile(
NAME => 'Glib::Object::Introspection',
VERSION_FROM => 'lib/Glib/Object/Introspection.pm',
ABSTRACT_FROM => 'lib/Glib/Object/Introspection.pm',
PREREQ_PM => \%CONFIG_REQ_PM,
XSPROTOARG => '-noprototypes',
MAN3PODS => \%pod_files,
META_MERGE => \%meta_merge,
$deps->get_makefile_vars,
);
sub compile_test_libraries {
chdir 'build';
my $build_dir = cwd();
local $| = 1;
print 'Trying to build test libraries... ';
my $success = eval {
my $gidatadir = ExtUtils::PkgConfig->variable ('gobject-introspection-1.0',
'gidatadir');
die 'Could not find gobject-introspection-1.0' unless defined $gidatadir;
my $testsdir = $gidatadir . '/tests';
my $have_cairo_gobject = !system (qw/pkg-config --exists cairo-gobject/);
my %cairo_flags = ExtUtils::PkgConfig->find ('cairo');
my %cairo_gobject_flags = $have_cairo_gobject ?
ExtUtils::PkgConfig->find ('cairo-gobject') :
(cflags => '', libs => '');
my %gio_flags = ExtUtils::PkgConfig->find ('gio-2.0');
my @commands;
my $c_flags = qq(-shared -fPIC);
my $gir_cmd = qq(LD_LIBRARY_PATH=$build_dir:\$LD_LIBRARY_PATH g-ir-scanner);
my $prefix = q();
my $pipe = qq(1>/dev/null 2>/dev/null);
if ($^O eq 'MSWin32') {
my @path = File::Spec->path;
my $found = 0;
foreach my $base (map { File::Spec->catfile ($_, 'g-ir-scanner') } @path) {
if (-f $base) {
$gir_cmd = qq(python $base);
$found = 1;
last;
}
}
return 0 unless $found;
$c_flags = qq(-shared);
$pipe = qq(1>NUL 2>NUL);
# XXX: We need the lib prefix for --library argument to G-O-I on Win32,
# else DLL resolution fails...
$prefix = 'lib';
}
push @commands,
qq(gcc $c_flags -g \\
$cairo_flags{cflags} $cairo_gobject_flags{cflags} $gio_flags{cflags} \\
$testsdir/regress.c \\
$cairo_flags{libs} $cairo_gobject_flags{libs} $gio_flags{libs} \\
-o libregress.$Config{dlext} $pipe);
push @commands,
qq($gir_cmd \\
--include=cairo-1.0 --include=Gio-2.0 \\
--namespace=Regress --nsversion=1.0 \\
--quiet --warn-all --warn-error \\
--library=${prefix}regress \\
--output=Regress-1.0.gir \\
$testsdir/regress.h $testsdir/regress.c \\
$pipe);
push @commands,
qq(g-ir-compiler Regress-1.0.gir -o Regress-1.0.typelib \\
$pipe);
push @commands,
qq(gcc $c_flags -g \\
$gio_flags{cflags} \\
$testsdir/gimarshallingtests.c \\
$gio_flags{libs} \\
-o libgimarshallingtests.$Config{dlext} $pipe);
push @commands,
qq($gir_cmd \\
--include=Gio-2.0 \\
--namespace=GIMarshallingTests \\
--symbol-prefix=gi_marshalling_tests --nsversion=1.0 \\
--quiet --warn-all --warn-error \\
--library=${prefix}gimarshallingtests \\
--output=GIMarshallingTests-1.0.gir \\
$testsdir/gimarshallingtests.h $testsdir/gimarshallingtests.c \\
$pipe);
push @commands,
qq(g-ir-compiler GIMarshallingTests-1.0.gir \\
-o GIMarshallingTests-1.0.typelib $pipe);
if ($^O eq 'MSWin32') {
my $path = $ENV{PATH};
# XXX: G-O-I defaults to CC=cc
$ENV{CC} = 'gcc' unless exists $ENV{CC};
$ENV{PATH} .= ';' . $build_dir;
foreach my $command (@commands) {
# XXX: Cmd.exe do not support \ as line break ...
$command =~ s/\\\n//mg;
$command =~ s/\s\s+/ /mg;
system ($command) == 0 or return 0;
}
$ENV{PATH} = $path;
}
else {
foreach my $command (@commands) {
system ($command) == 0 or return 0;
}
}
1;
};
print $success ? "OK\n" : "not OK\n";
if ($@) {
print "Error: $@";
print "Continuing without test library support...\n";
}
chdir '..';
}
package MY; # so that "SUPER" works right
sub test {
my $inherited = shift->SUPER::test(@_);
if ($^O eq 'MSWin32') {
# put "build" into PATH for the tests
# FIXME: Might need tweaking for nmake...
$inherited =~ s/(test_dynamic :: pure_all\n\t)/.IMPORT: PATH\nPATH += ;build\n.EXPORT: PATH\n$1/;
}
else {
# put "build" into LD_LIBRARY_PATH for the tests
$inherited =~ s/(test_dynamic :: pure_all)\n\t/$1\n\tLD_LIBRARY_PATH=\${LD_LIBRARY_PATH}:build /;
}
$inherited;
}
sub postamble {
my $additional_deps = "\n\n\$(OBJECT) : gperl-i11n-*.c\n\n";
if ($^O eq 'MSWin32') {
# FIXME: Might need tweaking for nmake...
$additional_deps = "\n\n\$(OBJECT) : \$(wildcard gperl-i11n-*.c)\n\n";
}
return Glib::MakeHelper->postamble_clean () . $additional_deps;
}