2
# $Header: /cvsroot/gtk2-perl/gtk2-perl-xs/Glib/MakeHelper.pm,v 1.28.2.4 2004/04/12 02:26:37 muppetman Exp $
5
package Glib::MakeHelper;
11
Glib::MakeHelper - Makefile.PL utilities for Glib-based extensions
15
eval "use Glib::MakeHelper; 1"
16
or complain_that_glib_is_too_old_and_die();
18
%xspod_files = Glib::MakeHelper->do_pod_files (@xs_files);
22
return Glib::MakeHelper->postamble_clean ()
23
. Glib::MakeHelper->postamble_docs (@main::xs_files)
24
. Glib::MakeHelper->postamble_rpms (
25
MYLIB => $build_reqs{MyLib},
31
The Makefile.PL for your typical Glib-based module is huge and hairy, thanks to
32
all the crazy hoops you have to jump through to get things right. This module
33
wraps up some of the more intense and error-prone bits to reduce the amount of
34
copied code and potential for errors.
49
=item HASH = Glib::MakeHelper->do_pod_files (@xs_files)
51
Scan the I<@xs_files> and return a hash describing the pod files that will
52
be created. This is in the format wanted by WriteMakefile(). If @ARGV contains
53
the string C<disable-apidoc> an empty list will be returned and thus no apidoc
54
pod will be generated speeding up the build process.
60
return () if (grep /disable[-_]apidoc/i, @ARGV);
61
print STDERR "Including ApiDoc pod.\n";
65
# try to get it from pwd first, then fall back to installed
66
# this is so Glib will get associated copy, and everyone else
67
# should use the installed glib copy
68
eval { require 'ParseXSDoc.pm'; 1; } or require Glib::ParseXSDoc;
70
import Glib::ParseXSDoc;
74
open PARSE, '>build/doc.pl';
76
my $pods = xsdocparse (@_);
82
my $path = '$(INST_LIB)';
83
$pod = File::Spec->catfile ($path, split (/::/, $_)) . ".pod";
84
push @gend_pods, $pod;
85
$pod_files{$pod} = '$(INST_MAN3DIR)/'.$_.'.$(MAN3EXT)';
87
$pod_files{'$(INST_LIB)/$(FULLEXT)/index.pod'} = '$(INST_MAN3DIR)/$(NAME)::index.$(MAN3EXT)';
92
=item string = Glib::MakeHelper->postamble_clean (@files)
94
Create and return the text of a realclean rule that cleans up after much
95
of the autogeneration performed by Glib-based modules. Everything in @files
96
will be deleted, too (it may be empty).
98
The reasoning behind using this instead of just having you use the 'clean'
99
or 'realclean' keys is that this avoids you having to remember to put Glib's
100
stuff in your Makefile.PL's WriteMakefile arguments.
106
shift; # package name
109
-\$(RM_RF) build blib_done perl-\$(DISTNAME).spec ".join(" ", @_)."
113
=item string = Glib::MakeHelper->postamble_docs (@xs_files)
115
NOTE: this is The Old Way. see L<postamble_docs_full> for The New Way.
117
Create and return the text of Makefile rules to build documentation from
118
the XS files with Glib::ParseXSDoc and Glib::GenPod.
120
Use this in your MY::postamble to enable autogeneration of POD.
122
This updates dependencies with the list of pod names generated by an earlier
123
run of C<do_pod_files>.
125
There is a special Makefile variable POD_DEPENDS that should be set to the
126
list of files that need to be created before the doc.pl step is run, include
129
There is also a variable BLIB_DONE which should be used as a dependency
130
anywhere a rule needs to be sure that a loadable and working module resides in
131
the blib directory before running.
137
my ($class, @xs_files) = @_;
138
return Glib::MakeHelper->postamble_docs_full (XS_FILES => \@xs_files);
141
=item string = Glib::MakeHelper->postamble_docs_full (...)
143
Create and return the text of Makefile rules to build documentation from
144
the XS files with Glib::ParseXSDoc and Glib::GenPod.
146
Use this in your MY::postamble to enable autogeneration of POD.
148
This updates dependencies with the list of pod names generated by an earlier
149
run of C<do_pod_files>.
151
There is a special Makefile variable POD_DEPENDS that should be set to the
152
list of files that need to be created before the doc.pl step is run, include
155
There is also a variable BLIB_DONE which should be used as a dependancy
156
anywhere a rule needs to be sure that a loadable and working module resides in
157
the blib directory before running.
159
The parameters are a list of key=>value pairs. You must specify at minimum
160
either DEPENDS or XS_FILES.
164
=item DEPENDS => ExtUtils::Depends object
166
Most gtk2-perl modules use ExtUtils::Depends to find headers, typemaps,
167
and other data from parent modules and to install this data for child
168
modules. We can find from this object the list of XS files to scan for
169
documentation, doctype mappings for parent modules, and other goodies.
171
=item XS_FILES => \@xs_file_names
173
A list of xs files to scan for documentation. Ignored if DEPENDS is
176
=item DOCTYPES => \@doctypes_file_names
178
List of filenames to pass to C<Glib::GenPod::add_types>. May be omitted.
180
=item COPYRIGHT => string
182
POD text to be inserted in the 'COPYRIGHT' section of each generated page.
185
=item COPYRIGHT_FROM => file name
187
The name of a file containing the POD to be inserted in the 'COPYRIGHT'
188
section of each generated page. May be omitted.
190
=item NAME => extension name
192
The name of the extension, used to set $Glib::GenPod::MAIN_MOD (used in the
193
generated see-also listings). May be omitted in favor of the name held
194
inside the ExtUtils::Depends object. If DEPENDS is also specified, NAME wins.
200
sub postamble_docs_full {
201
my $class = shift; # package name
204
croak "Usage: $class\->postamble_docs_full (...)\n"
205
. " where ... is a list of key/value pairs including at the\n"
206
. " very least one of DEPENDS=>\$extutils_depends_object or\n"
207
. " XS_FILES=>\@xs_files\n"
209
unless $params{DEPENDS} or $params{XS_FILES};
217
if ($params{DOCTYPES}) {
218
@doctypes = ('ARRAY' eq ref $params{DOCTYPES})
219
? @{$params{DOCTYPES}}
220
: ($params{DOCTYPES});
223
if (UNIVERSAL::isa ($params{DEPENDS}, 'ExtUtils::Depends')) {
224
my $dep = $params{DEPENDS};
226
# fetch list of XS files from depends object.
227
# HACK ALERT: the older versions of ExtUtils::Depends
228
# (<0.2) use a different key layout and don't store enough
229
# metadata about the dependencies, so we require >=0.2;
230
# however, the older versions don't support import version
231
# checking (in fact they don't support version-checking at
232
# all), so the "use" test in a Makefile.PL can't tell if
233
# it has loaded a new enough version!
234
# the rewrite at version 0.200 added the get_dep() method,
235
# which we use, so let's check for that.
236
unless (defined &ExtUtils::Depends::get_deps) {
237
use ExtUtils::MakeMaker;
238
warn "ExtUtils::Depends is too old, need at "
239
. "least version 0.2";
240
# this is so that CPAN builds will do the upgrade
244
PREREQ_PM => { 'ExtUtils::Depends' => 0.2, },
246
exit 1; # not reached.
248
# continue with the excessive validation...
249
croak "value of DEPENDS key must be an ExtUtils::Depends object"
250
unless UNIVERSAL::isa $dep, 'ExtUtils::Depends';
251
croak "corrupt or invalid ExtUtils::Depends instance -- "
253
.(exists ($dep->{xs}) ? "missing" : "broken")."!"
254
unless exists $dep->{xs}
255
and 'ARRAY' eq ref $dep->{xs};
257
# finally, *this* is what we wanted.
258
@xs_files = @{$dep->{xs}};
260
# fetch doctypes files from the depends' dependencies.
261
my %deps = $dep->get_deps;
262
foreach my $d (keys %deps) {
263
my $f = File::Spec->catfile ($deps{$d}{instpath},
265
#warn "looking for $f\n";
270
# the depends object conveniently knows the main module name.
271
$name = $dep->{name};
273
@xs_files = @{ $params{XS_FILES} };
276
if ($params{COPYRIGHT}) {
277
$copyright = $params{COPYRIGHT};
278
} elsif ($params{COPYRIGHT_FROM}) {
279
open IN, $params{COPYRIGHT_FROM} or
280
croak "can't open $params{COPYRIGHT_FROM} for reading: $!\n";
287
# this text has to be escaped for both make and the shell.
288
$copyright =~ s/\n/\\n/gm; # collapse to one line.
289
$copyright =~ s/"/\"/gm; # escape double-quotes
290
$copyright = "\$\$Glib::GenPod::COPYRIGHT=\"$copyright\";";
293
# the module name specified explicitly overrides the one in a
295
$name = $params{NAME} if $params{NAME};
298
# this is supposed to be a module name; names don't have
299
# things in them that need escaping, so let's leave it alone.
300
# that way, if there's a quoting error, the user will figure
302
$name = "\$\$Glib::GenPod::MAIN_MOD=\"$name\";";
305
#warn "".scalar(@doctypes)." doctype files\n";
306
#warn "".scalar(@xs_files)." xs files\n";
308
$add_types = "add_types (".join(", ",map {"\"$_\""} @doctypes)."); "
318
. 'xsdoc2pod("build/doc.pl", "$(INST_LIB)", "build/podindex");';
320
#warn "docgen_code: $docgen_code\n";
322
# BLIB_DONE should be set to something we can depend on that will
323
# ensure that we are safe to link against an up to date module out
324
# of blib. basically what we need to wait on is the static/dynamic
325
# lib file to be created. the following trick is intended to handle
326
# both of those cases without causing the other to happen.
328
# this is very sloppy, because different makes have different
329
# conditional syntaxes.
331
if ($Config{make} eq 'nmake') {
332
warn "loathe nmake.\n";
334
!If \"\$(LINKTYPE)\" == \"dynamic\"
335
BLIB_DONE=\$(INST_DYNAMIC)
337
BLIB_DONE=\$(INST_STATIC)
343
ifeq (\$(LINKTYPE), dynamic)
344
BLIB_DONE=\$(INST_DYNAMIC)
346
BLIB_DONE=\$(INST_STATIC)
355
# documentation stuff
356
build/doc.pl :: Makefile @xs_files
357
$^X -I \$(INST_LIB) -I \$(INST_ARCHLIB) -MGlib::ParseXSDoc \\
358
-e 'xsdocparse (".join(", ",map {"\"$_\""} @xs_files).")' > \$@
360
# passing all of these files through the single podindex file, which is
361
# created at the same time, prevents problems with -j4 where xsdoc2pod would
362
# have multiple instances
363
@gend_pods :: build/podindex \$(POD_DEPENDS)
365
build/podindex :: \$(BLIB_DONE) Makefile build/doc.pl
366
$^X -I \$(INST_LIB) -I \$(INST_ARCHLIB) -MGlib::GenPod -M\$(NAME) \\
369
\$(INST_LIB)/\$(FULLEXT)/:
370
$^X -MExtUtils::Command -e mkpath \$@
372
\$(INST_LIB)/\$(FULLEXT)/index.pod :: \$(INST_LIB)/\$(FULLEXT)/ build/podindex
373
$^X -e 'print \"\\n=head1 NAME\\n\\n\$(NAME) API Reference Pod Index\\n\\n=head1 PAGES\\n\\n=over\\n\\n\"' \\
374
> \$(INST_LIB)/\$(FULLEXT)/index.pod
375
$^X -nae 'print \"=item L<\$\$F[1]>\\n\\n\";' < build/podindex >> \$(INST_LIB)/\$(FULLEXT)/index.pod
376
$^X -e 'print \"=back\\n\\n\";' >> \$(INST_LIB)/\$(FULLEXT)/index.pod
380
=item string = Glib::MakeHelper->postamble_rpms (HASH)
382
Create and return the text of Makefile rules to manage building RPMs.
383
You'd put this in your Makefile.PL's MY::postamble.
385
I<HASH> is a set of search and replace keys for the spec file. All
386
occurences of @I<key>@ in the spec file template perl-$(DISTNAME).spec.in
387
will be replaced with I<value>. 'VERSION' and 'SOURCE' are supplied for
390
Glib::MakeHelper->postamble_rpms (
391
MYLIB => 2.0.0, # we can work with anything from this up
392
MYLIB_RUN => 2.3.1, # we are actually compiled against this one
393
PERL_GLIB => 1.01, # you must have this version of Glib
396
will replace @MYLIB@, @MYLIB_RUN@, and @PERL_GLIB@ in spec file. See
397
the build setups for Glib and Gtk2 for examples.
399
Note: This function just returns an empty string on Win32.
405
shift; # package name
407
return '' if $^O eq 'MSWin32';
409
my @dirs = qw{$(RPMS_DIR) $(RPMS_DIR)/BUILD $(RPMS_DIR)/RPMS
410
$(RPMS_DIR)/SOURCES $(RPMS_DIR)/SPECS $(RPMS_DIR)/SRPMS};
413
chomp (my $date = `date +"%a %b %d %Y"`);
416
'VERSION' => '$(VERSION)',
417
'SOURCE' => '$(DISTNAME)-$(VERSION).tar.gz',
422
my $substitute = '$(PERL) -npe \''.join('; ', map {
423
"s/\\\@$_\\\@/$subs{$_}/g";
428
RPMS_DIR=\$(HOME)/rpms
433
SUBSTITUTE=$substitute
435
perl-\$(DISTNAME).spec :: perl-\$(DISTNAME).spec.in \$(VERSION_FROM) Makefile
436
\$(SUBSTITUTE) \$< > \$@
438
dist-rpms :: Makefile dist perl-\$(DISTNAME).spec \$(RPMS_DIR)/
439
cp \$(DISTNAME)-\$(VERSION).tar.gz \$(RPMS_DIR)/SOURCES/
440
rpmbuild -ba --define \"_topdir \$(RPMS_DIR)\" perl-\$(DISTNAME).spec
442
dist-srpms :: Makefile dist perl-\$(DISTNAME).spec \$(RPMS_DIR)/
443
cp \$(DISTNAME)-\$(VERSION).tar.gz \$(RPMS_DIR)/SOURCES/
444
rpmbuild -bs --nodeps --define \"_topdir \$(RPMS_DIR)\" perl-\$(DISTNAME).spec
454
The MakeMaker distributed with perl 5.8.x generates makefiles with a bug that
455
causes object files to be created in the wrong directory. There is an override
456
inserted by this module under the name MY::const_cccmd to fix this issue.
461
my $inherited = shift->SUPER::const_cccmd (@_);
462
return '' unless $inherited;
464
# a more sophisticated match may be necessary, but this works for me.
465
if ($Config{cc} eq "cl") {
466
warn "you are using MSVC... my condolences.\n";
467
$inherited .= ' /Fo$@';
469
$inherited .= ' -o $@';
478
Ross McFarland E<lt>rwmcfa1 at neces dot comE<gt>
480
hacked up and documented by muppet.
482
=head1 COPYRIGHT AND LICENSE
484
Copyright 2003-2004 by the gtk2-perl team
486
This library is free software; you can redistribute it and/or modify
487
it under the terms of the Lesser General Public License (LGPL). For
488
more information, see http://www.fsf.org/licenses/lgpl.txt