/usr/local/CPAN/Gtk-Perl/Makefile.PL


#!/usr/bin/perl -w
use ExtUtils::MakeMaker;
use Config;

# data structure to handle sub-module detection and dependencies
# the key in the hash is the tag name
# the value is a hash ref with these keys:
# 	dir		string		directory with Makefile.PL (required)
#	order	number		compilation order (required)
#	check	sub ref		returns true if module can be compiled (required)
#	needed	bool		module must be compiled
#	skip	bool		do not compile nor check this module
#	force	bool		compile even if check fails
#	depends array ref	names of the submodules the module depends upon

%detect = (
	gtk => {order => 1, dir => 'Gtk', needed => 1, 
		check => sub {cconfig('gtk-config --version', '1\.2\.')}},
	gdkimlib => {order => 2, dir => 'GdkImlib', depends => [qw(gtk)],
		check => sub {cconfig('imlib-config --version', '1\.9\.') && `imlib-config --libs-gdk`}},
	gtkglarea => {order => 2, dir => 'GtkGLArea', depends => [qw(gtk)],
		check => sub {ccompile('#include <gtkgl/gtkglarea.h>', "", `gtk-config --cflags`,
					"-lgtkgl  -lGL -lGLU " . `gtk-config --libs`)}},
	gdkpixbuf => {order => 2, dir => 'GdkPixbuf', depends => [qw(gtk)],
		check => sub {cconfig('gdk-pixbuf-config --version', '0\.(8|9|1\d|2\d)\.?')}},
	gtkhtml => {order => 2, dir => 'GtkHTML', depends => [qw(gtk)],
		check => sub {cconfig('gnome-config --modversion gtkhtml', 'gtkhtml-0\.(8|9|10|11|12|13|14|15)')}},
	gtkxmhtml => {order => 2, dir => 'GtkXmHTML', depends => [qw(gtk)],
		check => sub {cconfig('gnome-config --libs gtkxmhtml', '-lgtkxmhtml')}},
	gnome => {order => 3, dir => 'Gnome', depends => [qw(gdkimlib)],
		check => sub {cconfig('gnome-config --version', '1\.[234]\.')}},
	gnomeprint => {order => 4, dir => 'GnomePrint', depends => [qw(gnome gdkpixbuf)],
		check => sub {cconfig('gnome-config --modversion print', 'gnome-print-0\.(2[5-9]|[3-9][0-9])')}},
	applets => {order => 4, dir => 'Applet', depends => [qw(gnome)],
		check => sub {cconfig('gnome-config --modversion applets', 'applets-1\.[234]\.') &&
			# --modversion capplet is broken
			cconfig('gnome-config --modversion capplet', 'capplet-')}},
	glade => {order => 4, dir => 'Glade', depends => [qw(gtk)],
		check => sub {cconfig('libglade-config --version', '0\.1\d')}},
);

@subdirs = ();
$dontguess = 0;

# autodetect available packages...
foreach (@ARGV) {
	if (/^--without-guessing$/) {
		$dontguess = 1;
		next;
	}
	if (/^--with(out)?-([^-]+)(-force)?/) {
		my $pkg = $2;
		die Usage("No module '$pkg'.\n") unless exists $detect{$pkg};
		$detect{$pkg}->{needed} = 1;
		$detect{$pkg}->{skip} = 1 if defined $1;
		$detect{$pkg}->{force} = 1 if defined $3;
	}
}
@ARGV = grep {!/^--with/} @ARGV;

foreach (sort {$detect{$a}->{order} <=> $detect{$b}->{order}} keys %detect) {
	my $pkg = $detect{$_};
	next if $pkg->{skip};
	next if ($dontguess && !$pkg->{needed});
	foreach my $submodule (@{$pkg->{depends}}) {
		die "Submodule $submodule is needed to build $_ but it appears \nit's misdetected or not selected for compilation.\n".Usage()
			unless ($detect{$submodule}->{ok});
	}
	if ($pkg->{check}->()) {
		push @subdirs, $pkg->{dir};
		$pkg->{ok} = 1;
		next;
	}
	if ($pkg->{force}) {
		warn "Adding package $_ even if it's misdetected.\n";
		push @subdirs, $pkg->{dir};
		$pkg->{ok} = 1;
		next;
	}
	if ($pkg->{needed}) {
		die "Package '$_' needed but it was not detected on your system.\n".
			"You may want to force it using --with-$_-force if you know better than me.\n";
	}
}

print "Packages to compile: ", join(' ', @subdirs), ".\n";

@clean = map {"build/$_"} qw(
GtkKeysyms.pm  IFiles.pm	PerlGtkExt.o  extension.xsh    perl-gtk-ref.xml
GtkDefs.c  GtkTypemap	  PerlGtkExt.c	PerlGtkInt.h  objects.xsh
GtkDefs.o  GtkTypes.pm	  PerlGtkExt.h	boxed.xsh     perl-gtk-ds.pod
);

WriteMakefile (
	'DISTNAME' => 'Gtk-Perl',
    'NAME'	=> 'Gtk::base',
	'NEEDS_LINKING' => 0,
	'PM' => {},
	'OPTIMIZE' => '-O2 -g',
    'VERSION_FROM'	=> 'Gtk/Gtk.pm',
    'XSOPT' => '-noversioncheck',
    'DIR'	=> [shift @subdirs], # only Gtk here
	'XSPROTOARG' => '-noprototypes',
	'dist' => { COMPRESS=>"gzip", SUFFIX=>"gz" },
	'linkext' => {LINKTYPE => ''},
	'clean' => {FILES => join(' ', @clean)},
	'PREREQ_PM' => {'XML::Writer'=>0, 'XML::Parser' => 0},
);

# subdirs are handled here because we need to build dependent
# sub-module _before_ running perl Makefile.PL ...
sub MY::postamble {
	my $out='';
	foreach my $d (@subdirs) {
		$out .= <<"		EOM";

		subdirs :: $d/Makefile
			\@cd $d && \$(MAKE) all \$(PASTHRU)

		install ::
			cd $d && \$(MAKE) install INSTALLDIRS=\$(INSTALLDIRS)

		clean ::
			-cd $d && \$(TEST_F) Makefile && \$(MAKE) clean

		realclean purge :: clean
			-cd $d && \$(TEST_F) Makefile.old && \$(MAKE) -f Makefile.old realclean
			-cd $d && \$(TEST_F) Makefile && \$(MAKE)  realclean

		$d/Makefile: Makefile $d/Makefile.PL
			cd $d && \$(PERL) Makefile.PL \$(PASTHRU) INSTALLDIRS=\$(INSTALLDIRS)

		EOM
	}
	$out =~ s/^\t\t//gm;
	return $out;
}

sub cconfig {
	my ($cmd, $re) = @_;
	$out = `$cmd`;
	return 0 unless defined $out;
	return $out =~ /$re/;
}

sub ccompile {
	my ($headers, $main, $cflags, $libs) = @_;
	my $fname = "temctest";
	my $r;
	chomp($cflags, $libs);
	open(CTEST, ">$fname.c") || return 0;
	print CTEST <<"EOTEST";
$headers

int main (int argc, char* argv[]) {
$main;
}
EOTEST
	close(CTEST);
	$r = system("$Config{cc} -o $fname $fname.c $cflags $libs 2>/dev/null 1>/dev/null");
	warn("RUNNING: $Config{cc} -o $fname $fname.c $cflags $libs\n") if $ENV{VERBOSE};
	unlink($fname, "$fname.c");
	return $r == 0;
}

sub Usage {
	my $out = shift;
	my @pkgs = sort {$detect{$a}->{order} <=> $detect{$b}->{order}} keys %detect;
	$out .= "Available modules: @pkgs.\n\n";
	$out .= "You can disable the inclusion of a module using --without-pkgname.\n";
	$out .= "If a package is misdetected and you still want it to compile \nuse --with-pkgname-force.\n";
	$out .= "To disable autodetection of modules use --without-guessing.\n";
}