use ExtUtils::MakeMaker; # See lib/ExtUtils/MakeMaker.pm for details of how to influence # the contents of the Makefile that is written. use Cwd; require 'Depends.pm'; #import ExtUtils::Depends; #print "Configuring Perl/Gtk+... Note that additional packages can be added\n"; #print "by giving switches to Makefile.PL, including:\n\n"; foreach (<*/pkg*.pl>) { next unless m!(.*)/pkg(.*)\.pl!; my ($name) = lc $1.$2; next if $name eq "gtk"; $package{$name} = $_; } foreach (sort keys %package) { # print "\t--with-$_\n"; } #print "\nWe are going to guess some packages, if we guess wrong just use\n"; #print qq{the flags above but change "with" to "without".\n\n}; #print "Unfortunately, these packages aren't terribly smart, and you may need\n"; #print "to tweak the resultant Makefile or the */pkg*.pl files to properly\n"; #print "locate the files needed for a package.\n\n"; # Guess packages print "You may also use '--lazy-load', which will reduce initial memory usage\n"; print "and loading time, at the cost of some internal glitches.\n\n"; %conf = ( gdkimlib => "imlib-config", gnome => "gnome-config", ); for(keys %conf) { my $v; if( ($v = qx($conf{$_} --version)) =~ /[0-9]/ ) { # no default submodule compilation #print "Guessing $_ - got version $v from $conf{$_}\n"; #$defaultpack{$_} = 1; } } @defines = (); # Starting with Perl 5.005 all embed variables got PL_ prefix # so, to avoid errorswith sv_undef, we enable polluting name space.. if ($] > 5.004) { push @defines, "-DPERL_POLLUTE"; } sub estr { # Take out blanks local $_ = $_[0]; s/\s+/ /g; return $_; } # Search for a gnomeConf.sh file (waiting for gnome-config) ... # One can also 'source' in the shell the proper gnomeConf.sh file # before running perl Makefile.PL. if(qx{gnome-config}) { print "gnome-config found\n"; $gnome_version = qx{gnome-config --version}; $gnome_version =~ s/\S+\s//; print "gnome version = $gnome_version\n"; if($gnome_version =~ /0\.99/ || $gnome_version =~ /^1\./) { push @defines, "-DNEW_GNOME"; print "new gnome found\n"; } $ENV{GNOME_INCLUDEDIR}=estr(qx{gnome-config --cflags gnome}); $ENV{GNOME_LIBDIR}=estr(qx{gnome-config --libdir}); $ENV{GNOMEUI_LIBS}=estr(qx{gnome-config --libs gnomeui}); $ENV{GTKXMHTML_LIBS}=estr(qx{gnome-config --libs gtkxmhtml}); } else { print "gnome-config not found!\n"; print "If you did not enable any gnome options, "; print "you can ignore the above message\n"; } $Lazy = grep($_ eq "--lazy-load", @ARGV); @ARGV = grep($_ ne "--lazy-load", @ARGV); $Directory = ""; if ($Lazy) { print "\n\nLazy loading enabled -- if anything breaks, please try disabling this.\n"; push @defines, "-DLAZY_LOAD"; } elsif ($] < 5.004) { push @defines, "-DNEED_DERIVED"; } $libs = `gtk-config --libs`; $libs = "-L/usr/X11R6/lib -lgtk -lgdk -lglib -lX11 -lXext" if not defined $libs; $inc = `gtk-config --cflags`; $libs =~ s/\s+/ /g; $inc =~ s/\s+/ /g; $gtk_version = gtk_version(); if ($gtk_version =~ /^(\d+)\.(\d+)\.(\d+)/) { $gtk_major = $1; $gtk_minor = $2; $gtk_micro = $3; if ($gtk_major < 1 or ($gtk_major == 1 and $gtk_minor == 0 and $gtk_micro == 0)) { push @defines, "-DGTK_MAJOR_VERSION=$gtk_major", "-DGTK_MINOR_VERSION=$gtk_minor", "-DGTK_MICRO_VERSION=$gtk_micro"; } } else { $gtk_major = 0; $gtk_minor = 0; $gtk_micro = 0; } $gtk_hverstr = sprintf("0x%02x%02x%02x", $gtk_major, $gtk_minor, $gtk_micro); $gtk_hver = hex($gtk_hverstr); push @defines, "-DGTK_HVER=$gtk_hverstr"; if (not defined $gtk_version) { print "Unable to find Gtk version...\n"; } else { print "Located Gtk version $gtk_version...\n"; } mkdir("build", 0777); $typemap = [cwd() . "/build/GtkTypemap"]; $object = 'build/GtkDefs.o build/PerlGtkExt.o'; $pm = { 'build/GtkTypes.pm' => '$(INST_ARCHLIBDIR)/Gtk/Types.pm', 'build/GtkKeysyms.pm' => '$(INST_ARCHLIBDIR)/Gtk/Keysyms.pm' }; @clean = qw( build/perl-gtk-ref.pod build/perl-gtk-ds.pod build/GtkTypes.pm build/GtkKeysyms.pm build/GtkTypemap build/GtkDefs.c build/GtkDefs.h build/Objects.xpl build/boxed.xsh build/extension.xsh build/objects.xsh build/PerlGtkExt.c build/PerlGtkExt.h build/PerlGtkInt.h build/IFiles.pm */*.o */*/*.o); %xs = (); %typemaps = (); %defs = (); %boot = (); { local($Directory) = "Gtk/"; do "Gtk/pkg.pl"; $inc .= " -I./Gtk"; } # build the keysyms mapping { my ($incfile) = `gtk-config --prefix`; chomp($incfile); $incfile .= "/include/gdk/gdkkeysyms.h"; open(OUT, '>build/GtkKeysyms.pm') || die "Cannot open build/GtkKeysyms.pm: $!"; print OUT "# DO NOT EDIT!\n"; print OUT "# This file was built by Gtk's Makefile.PL from $incfile.\n"; print OUT "\npackage Gtk::Keysyms;\n\n"; print OUT "%Gtk::Keysyms = (\n"; if (open(IN, $incfile)) { while() { print OUT "\t'$1'\t=>\t$2,\n" if /^\s*#\s*define\s+GDK_([a-zA-Z0-9_]+)\s+(\w+)$/; } close(IN); } print OUT ");\n\n1;\n"; close(OUT); } sub include_package { my($p) = @_; if (exists $package{$p}) { local($Directory); my($f) = $package{$p}; if ($f =~ m!^(.*/)!) { $Directory = $1; $inc .= " -I./$Directory"; } print "Dir = $Directory\n"; do $f; } else { die "Unknown package $p\n"; } } foreach (@ARGV) { if (/^--with-/) { #include_package($'); $defaultpack{$'} = 1; } elsif(/^--without-/) { print "Not including package $'\n"; delete $defaultpack{$'}; } } for(keys %defaultpack) { include_package($_); } $inc .= " -I./build"; require "tools/gendefs.pl"; print "Invoking gendefs.pl with [",join(", ",sort {$defs{$a} <=> $defs{$b}} keys %defs), "].\n"; print "Please wait, this may take a moment...\n"; add_headers ('', '"GtkTypes.h"', '"GdkTypes.h"', '"MiscTypes.h"'); @a = ( '-f', 'Gtk', '-p', 'Gtk=Gtk', '-p', 'GdkGL=Gtk::Gdk::GL', '-p', 'GdkRgb=Gtk::Gdk::Rgb', '-p', 'Gdk=Gtk::Gdk', '-p', 'Gnome=Gnome', '-p', 'Panel=Gnome::Panel', '-m', 'Gtk'); if ($Lazy) { push @a, "-L"; } foreach (sort {$defs{$a} <=> $defs{$b}} keys %defs) { push @a, '-d', $_; } foreach (sort {$headers{$a} <=> $headers{$b}} keys %headers) { push @a, '-i', $_; } #system(@a); #foreach (split(' ', (do 'Objects.xpl'))) { # add_xs($_); #} add_raw_xs(gendefs::gendefs(@a)); # documentation gendefs::gen_doc(); system("./tools/gendoc.pl", keys %xs); $xfiles = {}; foreach (sort {$xs{$a} <=> $xs{$b}} keys %xs) { my($xs) = $_; s/\.xs$/.c/; #s!^.*/!!; $xfiles->{$xs} = $_; s/\.c$/.o/; $object .= " $_"; } foreach (sort {$c{$a} <=> $c{$b}} keys %c) { s/\.c$/.o/; $object .= " $_"; } foreach (<*/.xs>, <*/xs/*.xs>) { if (not exists $xfiles->{$_}) { s/\.xs$/.c/; push @clean, $_; } } open (EXT, ">build/extension.xsh"); print EXT "\n\n# Do not edit this file, as it is automatically generated by Makefile.PL\n\n"; print EXT "BOOT:\n{\n"; foreach (sort {$boot{$a} <=> $boot{$b}} keys %boot) { my($b) = $_; $b =~ s/::/__/g; $b = "boot_$b"; print EXT "extern void $b(CV *cv);\n"; } foreach (sort {$boot{$a} <=> $boot{$b}} keys %boot) { my($b) = $_; $b =~ s/::/__/g; $b = "boot_$b"; print EXT "callXS($b, cv, mark);\n"; } print EXT "}\n"; close(EXT); foreach (sort {$typemap{$a} <=> $typemap{$b}} keys %typemap) { push @$typemap, cwd() . "/" . $_; } use File::Basename; foreach ( 'build/GtkDefs.h', 'build/PerlGtkExt.h', 'build/PerlGtkInt.h', 'Gtk/ppport.h', 'Gtk/GtkTypes.h', 'Gtk/GdkTypes.h', 'Gtk/MiscTypes.h', 'tools/gendefs.pl', 'tools/genext.pl', 'tools/gendoc.pl') { $pm->{$_} = '$(INST_ARCHLIBDIR)/Gtk/Install/' . basename($_); } #$archinstall = join(' ', map( "Gtk/Install/$_", @archinstall)); #open(I, ">build/IFiles.pm"); #print I <<'EOT'; ##!/usr/bin/perl # #package Gtk::Install::Files; # #@typemaps = qw( #EOT # #foreach (@$typemap) { # my($b) = basename($_); # print I " $b\n"; # $pm->{$_} = '$(INST_ARCHLIBDIR)/Gtk/Install/' . $b; #} # #print I <<'EOT'; #); # #@defs = qw( #EOT # #foreach (sort {$defs{$a} <=> $defs{$b}} keys %defs) { # my($b) = basename($_); # print I " $b\n"; # #$pm->{$_} = '$(INST_ARCHLIBDIR)/Gtk/Install/' . $b; #} # #print I <<'EOT'; #); # #@headers = qw( #EOT # #foreach (sort {$headers{$a} <=> $headers{$b}} keys %headers) { # print I " $_\n"; #} # #print I <<'EOT'; #); # #EOT # #print I "\$libs = '$libs';\n"; #print I "\$inc = '$inc';\n"; # #print I <<'EOT'; # #$CORE = undef; #foreach (@INC) { # if ( -f $_ . "/Gtk/Install/gendefs.pl") { # $CORE = $_ . "/Gtk/Install/"; # last; # } #} # #1; # #EOT # #close(I); #$pm->{"IFiles.pm"} = '$(INST_ARCHLIBDIR)/Gtk/Install/Files.pm'; $libs =~ s/(^|\s)-[rR]\S+//g; @libs = split(/\s+/, $libs); %seenlibs = (); @revlibs=(); @lflags=(); foreach (@libs) { if (/^-l/) { unshift(@revlibs, $_); } else { unshift(@lflags, $_) unless $seenlibs{$_}++; } } #print "LIBS=@libs\n"; @libs=(); foreach (@revlibs) { unshift(@libs, $_) unless $seenlibs{$_}++; } #print "REVLIBS=@revlibs\n"; print "LIBS=@lflags @libs\n"; #exit 0; $libs = "@lflags @libs"; @L = (LIBS => [$libs]); if (defined $inc and $inc !~ /^\s*$/) { @I = (INC => $inc); } else { @I = (); #e.g, INC => -I/usr/other/include } $depend = {'build/GtkDefs.c' => 'build/PerlGtkExt.h build/PerlGtkInt.h'}; ExtUtils::Depends::save_config('Gtk', 'build/IFiles.pm', $inc, $libs, $typemap, [keys %defs], [@defines], [keys %headers], $pm); WriteMakefile( 'DISTNAME' => 'Gtk-Perl', 'NAME' => 'Gtk', 'VERSION_FROM' => 'Gtk/Gtk.pm', 'PM' => $pm, 'TYPEMAPS' => $typemap, 'XS' => $xfiles, 'XSOPT' => '-noversioncheck', 'DEFINE' => join(' ',@defines), 'DIR' => '', 'OBJECT' => $object, 'XSPROTOARG' => '-noprototypes', 'clean' => {FILES => join(' ', @clean) }, 'depend' => $depend, 'dist' => { COMPRESS=>"gzip", SUFFIX=>"gz" }, @I, @L, ); sub MY::postamble { ' Makefile: ' . join(' ', sort {$defs{$a} <=> $defs{$b}} keys %defs, <*/pkg*.pl> ) . ' build/PerlGtkExt.h build/PerlGtkExt.c build/PerlGtkInt.h: build/GtkDefs.h tools/genext.pl $(PERL) tools/genext.pl Gtk '; } sub MY::c_o { package MY; # so that "SUPER" works right my $inherited = shift->SUPER::c_o(@_); $inherited =~ s/CCCMD.*$/$&\n\t\@if test -f `basename \$*.o` -a "`basename \$*.o`" != "\$*.o"; then mv `basename \$*.o` \$*.o; fi/m; $inherited; } sub MY::const_config { package MY; my $self = shift; my $flags = $self->{'CCCDLFLAGS'}; $flags =~ s/(-[fK]?\s*)pic\b/${1}PIC/; $self->{'CCCDLFLAGS'} = $flags; return $self->SUPER::const_config; } sub gtk_version { my($result); $result = `gtk-config --version`; chomp $result; if (not defined $result) { unlink("gtkvertmp.out"); open(T, ">gtkvertmp.c"); print T <<'EOT'; #include #include int main(int argc, char *argv[]) { FILE * f = fopen("gtkvertmp.out", "w"); fprintf(f,"%d.%d.%d\n", gtk_major_version, gtk_minor_version, gtk_micro_version); fclose(f); return 0; } EOT close(T); use Config; $c = "$Config{cc} $Config{ccflags} $inc gtkvertmp.c $Config{ldflags} $libs $Config{libs} -o gtkvertmp"; system("$c && ./gtkvertmp"); unlink("gtkvertmp.c"); unlink("gtkvertmp.o"); unlink("gtkvertmp"); open(T, "; chomp $result; close(T); unlink("gtkvertmp.out"); } return $result; } $add = 0; sub add_xs { foreach (@_) { $xs{$Directory . "xs/" .$_} = $add++; } } sub add_raw_xs { foreach (@_) { $xs{$_} = $add++; } } sub remove_xs { foreach (@_) { delete $xs{$Directory . "xs/". $_}; } } sub add_pm { my($k,$v); while (($k,$v) = splice(@_, 0, 2)) { $k = $Directory . $k; $pm->{$k} = $v; } } sub add_c { foreach (@_) { $c{$Directory . $_} = $add++; } } sub remove_c { foreach (@_) { delete $c{$Directory . $_}; } } sub add_typemap { foreach (@_) { $typemap{$Directory . $_} = $add++; } } sub remove_typemap { foreach (@_) { delete $typemap{$Directory . $_}; } } sub add_defs { foreach (@_) { $defs{$Directory . $_} = $add++; } } sub remove_defs { foreach (@_) { delete $defs{$Directory . $_}; } } sub add_headers { foreach (@_) { $headers{$_} = $add++; } } sub remove_headers { foreach (@_) { delete $headers{$_}; } } sub add_boot { foreach (@_) { $boot{$_} = $add++; } } sub remove_boot { foreach (@_) { delete $boot{$_}; } }