use strict;
use warnings;
use 5.006001;
use File::Spec();
use File::Find();
# Bug in ExUtils::MakeMaker 5.45 that ships with ActiveState Perl
# 5.6.1, writes the subdirs target with dmake syntax, that breaks
# nmake. Fixed in EU::MM 5.47
# $(DIRFILESEP) macro requires EU::MM 6.06
use ExtUtils::MakeMaker 6.06;
use Config;
use lib 'build_tools';
use MMUtil();
our $W32G_CORE = 1;
$main::USERESOURCE = 1;
$main::BUILDENV = '';
$main::BUILDENV_SETONCMDLINE = 0;
# parse our command line options, removing them from @ARGV so that
# MakeMaker doesn't warn that they are unrecoginised.
my @tmp;
foreach (@ARGV) {
if(/USERESOURCE=0/) {
$main::USERESOURCE = -1;
}
elsif(/USERESOURCE=1/) {
$main::USERESOURCE = 1;
}
elsif(/BUILDENV=(.*)/) {
$main::BUILDENV = $1;
$main::BUILDENV_SETONCMDLINE = 1;
}
else {
push @tmp, $_;
}
}
@ARGV=@tmp;
# determine the build environment, and report it. We support 3 variants:
# (1) MSWin32 and Visual C++ BUILDENV=vc
# (2) MSWin32 and MinGW BUILDENV=mingw
# (3) Cygwin (and gcc) BUILDENV=cygwin
my %allowed = (
vc => 'MSWin32 and Visual C++',
mingw => 'MSWin32 and MinGW',
cygwin => 'Cygwin',
);
if (not $main::BUILDENV) {
if ($^O eq "cygwin") {
$main::BUILDENV = 'cygwin';
}
elsif ($^O eq "MSWin32") {
if($Config{'cc'} =~ /^cl(\.exe)?/i) {
$main::BUILDENV = 'vc';
}
elsif($Config{'cc'} =~ /^gcc(\.exe)?/i) {
$main::BUILDENV = 'mingw';
}
}
else {
print STDERR <<"__OSUNSUPPORTED";
Building on OS '$^O' is unsupported. Only 'MSWin32' and 'Cygwin' are valid
build environments.
__OSUNSUPPORTED
# Attempt to stop CPAN Testers reporting build failures
# for OS's like linux!
print("OS unsupported\n");
exit(0);
}
}
if (not $main::BUILDENV) {
print STDERR <<__NOBUILDENV;
Building on OS $^O with compiler $Config{'cc'} is not officially supported.
To force a build call this script with the additional parameter 'BUILDENV':
perl Makefile.PL BUILDENV=xxxx
where xxxx is one of:
__NOBUILDENV
print "$_\t($allowed{$_})\n" for (keys %allowed);
die("Build Environment unsupported\n");
}
if ( not exists $allowed{$main::BUILDENV} ) {
print STDERR <<__BADBUILDENV;
Unrecognised build environment BUILDENV=$main::BUILDENV
Allowed values are:
__BADBUILDENV
print "$_\t($allowed{$_})\n" for (keys %allowed);
die("Build Environment unsupported\n");
}
print "\n\nBUILDENV=$main::BUILDENV Used build environment is: $allowed{$main::BUILDENV}\n\n";
# If we got this far, then we have a buildenv and compiler that
# we want to try to use. Check that we can find the compiler,
# and exit with a nice error message if we can't. This stops
# us from failing CPAN Smoke tests on boxes that don't have
# compilers.
if($main::BUILDENV_SETONCMDLINE == 0) {
my @path = File::Spec->path();
unshift @path, ('', '.');
my $found = 0;
foreach my $prog ( map { ( $_, "$_.exe" ) } ($Config{cc}) ) {
foreach my $path ( @path ) {
if( -f File::Spec->catfile( $path, $prog ) ) {
$found=1, last;
}
}
}
if(!$found) {
print STDERR <<__NOCOMPILER;
Makefile.PL was unable to find compiler '$Config{cc}' on your path.
To force a build call this script with the additional parameter 'BUILDENV':
perl Makefile.PL BUILDENV=xxxx
where xxxx is one of:
__NOCOMPILER
print "$_\t($allowed{$_})\n" for (keys %allowed);
exit(1);
}
}
if($main::USERESOURCE == -1) {
$main::USERESOURCE = 0;
} else {
print <<____EXPLAIN;
NOTE: Makefile.PL will add the instruction to use the Resource Compiler to
your Makefile; if you don't want to compile resources with your extension,
call this script with this additional argument:
perl Makefile.PL USERESOURCE=0
____EXPLAIN
$main::USERESOURCE = 1;
}
my @subpackages = qw(
Animation
Bitmap
Button
Combobox
DateTime
DC
Font
Header
ImageList
Label
Listbox
ListView
MDI
MonthCal
NotifyIcon
ProgressBar
Rebar
RichEdit
Splitter
StatusBar
TabStrip
Textfield
Toolbar
Tooltip
Trackbar
TreeView
UpDown
Window
);
my @c_files = qw(
GUI
GUI_Events
GUI_Helpers
GUI_Options
GUI_MessageLoops
);
my $c_ext = "cpp";
my @arg_c = ();
my $arg_object = "";
foreach (@c_files) {
push( @arg_c, $_ . '.' . $c_ext );
$arg_object .= ' ' . $_ . $Config{'obj_ext'};
}
my %arg_xs = ( 'GUI.xs' => 'GUI.' . $c_ext );
my @arg_dl_funcs = ( 'boot_Win32__GUI' );
foreach (@subpackages) {
$arg_xs{$_.'.xs'} = $_ . '.' . $c_ext;
push( @arg_c, $_ . '.' . $c_ext );
push( @arg_dl_funcs, 'boot_Win32__GUI__' . $_ );
$arg_object .= ' ' . $_ . $Config{'obj_ext'};
}
$arg_object .= ' GUI.res' if $main::USERESOURCE;
my @demos;
File::Find::find(sub { push @demos, $File::Find::name if $File::Find::name =~ /\.(pl|bmp|ico|cur)$/ }, 'samples');
(my $dist_ver = $Config{version}) =~ s/^(\d+\.\d+).*$/$1/;
my %MakefileArgs = (
NAME => 'Win32::GUI',
LICENSE => 'perl',
VERSION_FROM => 'GUI.pm',
LIBS => [':nosearch -lcomctl32 -lcomdlg32 -lshell32 -lgdi32 -luser32 -lversion -lmsimg32'],
PREREQ_PM => {
'Test::More' => 0,
},
PM => {
'GUI.pm' => '$(INST_LIBDIR)/GUI.pm',
'GridLayout.pm' => '$(INST_LIBDIR)/GUI/GridLayout.pm',
},
XS => { %arg_xs },
C => [ @arg_c ],
OBJECT => $arg_object,
EXE_FILES => [ 'scripts/win32-gui-demos.pl', ],
DL_FUNCS => { 'Win32::GUI' => [ @arg_dl_funcs ] },
META_MERGE => {
resources => {
#homepage => 'http://perl-win32-gui.sourceforge.net',
repository => 'http://sourceforge.net/p/perl-win32-gui/git/',
bugtracker => 'http://sourceforge.net/p/perl-win32-gui/bugs/',
},
no_index => {
directory => [qw( build_tools samples docs
Win32-GUI_ReleaseNotes
Win32-GUI_Constants/hash
Win32-GUI_AxWindow/t Win32-GUI_BitmapInline/t Win32-GUI_Constants/t Win32-GUI_DIBitmap/t
Win32-GUI_DropFiles/t Win32-GUI_Grid/t Win32-GUI_ReleaseNotes/t Win32-GUI_Scintilla/t
Win32-GUI_DIBitmap/demos Win32-GUI_Scintilla/demos Win32-GUI_Grid/demos
Win32-GUI_DropFiles/demos Win32-GUI_Constants/demos Win32-GUI_AxWindow/demos
)],
file => [qw( Win32-GUI_DIBitmap/extlib/Readme.txt
Win32-GUI_DropFiles/Readme.txt
Win32-GUI_Scintilla/Include/Readme.txt
README.html
)],
},
},
dist => {
PREOP => '$(PERL) -Ibuild_tools build_tools/doPodDocs.pl $(DISTVNAME)/GENERATED',
$^O eq 'cygwin' ?
(
TAR => 'ptar',
TARFLAGS => '-c -C -f',
)
:
(
ZIP => 'zip',
ZIPFLAGS => '-r9',
DIST_DEFAULT => 'zipdist',
)
},
($] < 5.005 ? () : (
AUTHOR => 'Aldo Calpini <dada@perl.it>',
ABSTRACT => 'Perl-Win32 Graphical User Interface Extension',
)),
BINARY_LOCATION => 'Win32-GUI.tar.gz',
macro => {
BUILD_TOOLS => './build_tools',
PPMDISTVNAME => '$(DISTVNAME)-PPM-' . $dist_ver,
INST_DEMODIR => '$(INST_LIBDIR)/GUI/demos',
DEMOS => "@demos",
},
clean => {
FILES => 'comctl32.def cygwin.o libcyg.a GUI.res',
},
realclean => {
FILES => '$(PPMDISTVNAME) Readme.old Readme.html.old',
},
depend => {
distdir => 'readmedocs',
},
);
if($Config{cc} =~ /gcc/i) {
$MakefileArgs{CCFLAGS} = "$Config{ccflags} -Wno-write-strings";
}
if ($main::BUILDENV eq "cygwin") {
$MakefileArgs{'LIBS'} = ['-L/usr/lib/w32api -lcomctl32 -lcomdlg32 -lshell32 -lgdi32 -luser32 -lversion -lmsimg32'];
$MakefileArgs{'DEFINE'} = '-UWIN32';
$MakefileArgs{'MYEXTLIB'} = './libcyg.a';
}
MMUtil::Extend_MM();
WriteMakefile( %MakefileArgs );
# tweak the generated Makefile
package MY;
use strict;
use warnings;
sub pasthru {
my $inherited = shift->SUPER::pasthru(@_);
chomp $inherited;
$inherited .= "\\\n\tW32G_CORE=1";
return $inherited;
}
sub xs_c {
my $inherited = shift->SUPER::xs_c(@_);
$inherited =~ s/\.c/.cpp/g;
return $inherited;
}
sub xs_o {
my $inherited = shift->SUPER::xs_o(@_);
$inherited =~ s/\.c$/.cpp/mg;
return $inherited;
}
# Remove the Test-More dependency from the PPD file, as it is not
# a requirement for a binary distribution
sub ppd {
my $inherited = shift->SUPER::ppd(@_);
#perl 5.6
$inherited =~ s/qq\{\\t\\t<DEPENDENCY NAME=.*Test-More.*?\}\.//s;
#perl 5.8
$inherited =~ s/^.*DEPENDENCY.*Test-More.*$//m;
return $inherited;
}
# In the following here-doc fragments, ensure that command lines are indented with TAB
# and not space for gnu-make compatibility (cygwin)
sub postamble {
my $cygwin_frag = '';
# cygwin w32api comctl32 before 2004-12-02 misses some stubs
if ($main::BUILDENV eq "cygwin") {
my $missing = '';
my $defs = `nm -g /usr/lib/w32api/libcomctl32.a`;
for (qw(ImageList_Duplicate@4 ImageList_DrawIndirect@4 ImageList_Copy@20)) {
unless ($defs =~ / _$_/) {
$missing .= "\t" . '$(NOECHO)$(ECHO) "' . $_ . '" >>$@' . "\n";
}
}
if($missing) {
$cygwin_frag = sprintf <<'CYGWIN_FRAG1', $missing;
# -- Win32::GUI Cygwin section --
comctl32.def:
$(NOECHO)$(ECHO) "LIBRARY COMCTL32.DLL" >$@
$(NOECHO)$(ECHO) "EXPORTS" >>$@
%s
libcyg.a: comctl32.def cygwin.o
dlltool -k --output-lib libcyg.a --def comctl32.def
ar r libcyg.a cygwin.o
CYGWIN_FRAG1
} else {
$cygwin_frag = <<'CYGWIN_FRAG2';
# -- Win32::GUI Cygwin section --
libcyg.a: cygwin.o
ar r libcyg.a cygwin.o
CYGWIN_FRAG2
}
}
my $rc_frag = '';
if($main::USERESOURCE) {
if ($main::BUILDENV eq 'vc') { # Visual C++
$rc_frag = <<'RC_FRAG1';
# -- Win32::GUI resource section --
GUI.res: GUI.rc
rc.exe /l 0x409 /fo"GUI.res" GUI.rc
RC_FRAG1
} else { # cygwin and MinGW
$rc_frag = <<'RC_FRAG2';
# -- Win32::GUI resource section --
GUI.res: GUI.rc
windres -O coff -i GUI.rc -o GUI.res
RC_FRAG2
}
$rc_frag .= <<'RC_FRAG3'
GUI.rc: GUI.pm
$(PERL) -I$(BUILD_TOOLS) $(BUILD_TOOLS)/updateRC.pl
$(NOECHO) $(TOUCH) GUI.rc
RC_FRAG3
}
my $doc_frag = <<'DOC_FRAG';
# -- Win32::GUI documents section --
readmedocs:
$(NOECHO) $(PERL) -I$(BUILD_TOOLS) $(BUILD_TOOLS)/doReadme.pl
poddocs:
$(NOECHO) $(PERL) -I$(BUILD_TOOLS) $(BUILD_TOOLS)/doPodDocs.pl
htmldocs: poddocs
$(NOECHO) $(PERL) -I$(BUILD_TOOLS) $(BUILD_TOOLS)/doHTMLDocs.pl
pure_all :: demo_to_blib
$(NOECHO) $(NOOP)
demo_to_blib: $(DEMOS)
$(NOECHO) $(MKPATH) $(INST_DEMODIR)
$(CP) $? $(INST_DEMODIR)
$(NOECHO) $(TOUCH) demo_to_blib
clean ::
-$(RM_F) demo_to_blib
all:: poddocs
DOC_FRAG
my $ppm_frag = '';
if ($main::BUILDENV eq "vc" || $main::BUILDENV eq "mingw") {
$ppm_frag = <<'PPM_FRAG';
# -- Win32::GUI ppm section --
ppmdist: all htmldocs
$(TAR) -$(TARFLAGS) $(DISTNAME).tar blib
$(COMPRESS) $(DISTNAME).tar
ppm: readmedocs ppd ppmdist
$(RM_RF) $(PPMDISTVNAME)
$(MKPATH) $(PPMDISTVNAME)
$(CP) Readme $(PPMDISTVNAME)/Readme.txt
$(CP) Readme.html $(PPMDISTVNAME)/Readme.html
$(CP) CHANGELOG $(PPMDISTVNAME)/Changelog.txt
$(MV) $(DISTNAME).tar.gz $(PPMDISTVNAME)
$(MV) $(DISTNAME).ppd $(PPMDISTVNAME)
$(RM_F) $(PPMDISTVNAME).zip
$(ZIP) $(ZIPFLAGS) $(PPMDISTVNAME).zip $(PPMDISTVNAME)
$(RM_RF) $(PPMDISTVNAME)
PPM_FRAG
}
return $cygwin_frag . $rc_frag . $doc_frag . $ppm_frag;
}