source: trunk/debbuild@ 29

Last change on this file since 29 was 29, checked in by kdeugau, 18 years ago

/trunk

Checkpoint

  • Property svn:executable set to *
  • Property svn:keywords set to Date Rev Author
File size: 25.0 KB
Line 
1#!/usr/bin/perl
2# debbuild script
3# Shamlessly steals intreface from rpm's "rpmbuild" to create
4# Debian packages. Please note that such packages are highly
5# unlikely to conform to "Debian Policy".
6###
7# SVN revision info
8# $Date: 2005-12-14 23:20:12 +0000 (Wed, 14 Dec 2005) $
9# SVN revision $Rev: 29 $
10# Last update by $Author: kdeugau $
11###
12
13use strict;
14use warnings;
15use Fcntl; # for sysopen flags
16
17# regex debugger
18#use re "debug";
19
20# Program flow:
21# -> Parse/execute "system" config/macros (if any - should be rare)
22# -> Parse/execute "user" config/macros (if any - *my* requirement is %_topdir)
23# -> Parse command line for options, spec file/tarball/.src.deb (NB - also accept .src.rpm)
24
25# User's prefs for dirs, environment, etc,etc,etc.
26# config file ~/.debmacros
27# Default ordered search paths for config/macros:
28# /usr/lib/rpm/rpmrc /usr/lib/rpm/redhat/rpmrc /etc/rpmrc ~/.rpmrc
29# /usr/lib/rpm/macros /usr/lib/rpm/redhat/macros /etc/rpm/macros ~/.rpmmacros
30# **NOTE: May be possible to (ab)use bits of debhelper
31
32# Build tree
33# default is /usr/src/debian/{BUILD,SOURCES,SPECS,DEBS,SDEBS}
34
35# Globals
36my $specfile;
37my $tarball;
38my $srcpkg;
39my $cmdbuildroot;
40my $tarballdir; # This should really be initialized, but the coding makes it, um, ugly.
41my %specglobals; # For %define's in specfile, among other things.
42
43# Initialized globals
44my $verbosity = 0;
45my %cmdopts = (type => '',
46 stage => 'a',
47 short => 'n'
48 );
49my $topdir = "/usr/src/debian";
50my $buildroot = "%{_tmppath}/%{name}-%{version}-%{release}.root".int(rand(99998)+1);
51
52# "Constants"
53my %targets = ('p' => 'Prep',
54 'c' => 'Compile',
55 'i' => 'Install',
56 'l' => 'Verify %files',
57 'a' => 'Build binary and source',
58 'b' => 'Build binary',
59 's' => 'Build source'
60 );
61my $scriptletbase =
62q(#!/bin/sh
63
64 RPM_SOURCE_DIR="%{_topdir}/SOURCES"
65 RPM_BUILD_DIR="%{_topdir}/BUILD"
66 RPM_OPT_FLAGS="-O2 -g -march=i386 -mcpu=i686"
67 RPM_ARCH="i386"
68 RPM_OS="linux"
69 export RPM_SOURCE_DIR RPM_BUILD_DIR RPM_OPT_FLAGS RPM_ARCH RPM_OS
70 RPM_DOC_DIR="/usr/share/doc"
71 export RPM_DOC_DIR
72 RPM_PACKAGE_NAME="%{name}"
73 RPM_PACKAGE_VERSION="%{version}"
74 RPM_PACKAGE_RELEASE="%{release}"
75 export RPM_PACKAGE_NAME RPM_PACKAGE_VERSION RPM_PACKAGE_RELEASE
76 RPM_BUILD_ROOT="%{buildroot}"
77 export RPM_BUILD_ROOT
78);
79foreach (`dpkg-architecture`) {
80 s/=(.+)/="$1"/;
81 $scriptletbase .= " $_";
82}
83$scriptletbase .=
84q(
85 set -x
86 umask 022
87 cd %{_topdir}/BUILD
88);
89
90# Package data
91# This is the form of $pkgdata{pkgname}{meta}
92# meta includes Summary, Name, Version, Release, Group, Copyright,
93# Source, URL, Packager, BuildRoot, Description
94# 10/31/2005 Maybe this should be flatter? -kgd
95my %pkgdata;
96my @pkglist = ('main'); #sigh
97# Files listing. Embedding this in %pkgdata would be, um, messy.
98my %filelist;
99
100# Scriptlets
101my $prepscript;
102my $buildscript;
103# %install doesn't need the full treatment from %clean; just an empty place to install to.
104# NB - rpm doesn't do this; is it really necessary?
105my $installscript = '[ "$RPM_BUILD_ROOT" != "/" ] && rm -rf $RPM_BUILD_ROOT'."\n";
106my $cleanscript;
107# pre/post (un)install scripts. Note that these will likely barf as-is. :/
108my $preinstscript = '';
109my $postinstscript = '';
110my $preuninstscript = '';
111my $postuninstscript = '';
112
113die "Not enough arguments\n" if #$argv == 0;
114
115# Snag some environment data
116my $tmpdir;
117if (defined $ENV{TMP} && $ENV{TMP} =~ /^(\/var)?\/tmp$/) {
118 $tmpdir = $ENV{TMP};
119} else {
120 $tmpdir = "/var/tmp";
121}
122
123##main
124
125load_userconfig();
126parse_cmd();
127
128if ($cmdopts{type} eq 'b') {
129 # Need to read the spec file to find the tarball. Note that
130 # this also generates most of the shell script required.
131 parse_spec();
132}
133
134# Hokay. Need to:
135# -> prep if -.p OR (-.[cilabs] AND !--short-circuit)
136if ($cmdopts{stage} eq 'p' || ($cmdopts{stage} =~ /[cilabs]/ && $cmdopts{short} ne 'y')) {
137 prep();
138}
139# -> build if -.c OR (-.[ilabs] AND !--short-circuit)
140if ($cmdopts{stage} eq 'c' || ($cmdopts{stage} =~ /[ilabs]/ && $cmdopts{short} ne 'y')) {
141 build();
142}
143# -> install if -.[ilabs]
144#if ($cmdopts{stage} eq 'i' || ($cmdopts{stage} =~ /[labs]/ && $cmdopts{short} ne 'y')) {
145if ($cmdopts{stage} =~ /[ilabs]/) {
146 install();
147}
148# -> binpkg and srcpkg if -.a
149if ($cmdopts{stage} eq 'a') {
150 binpackage();
151 srcpackage();
152}
153# -> binpkg if -.b
154if ($cmdopts{stage} eq 'b') {
155 binpackage();
156}
157# -> srcpkg if -.s
158if ($cmdopts{stage} eq 's') {
159 srcpackage();
160}
161
162# Just in case.
163exit 0;
164
165
166## load_userconfig()
167# Loads user configuration (if any)
168# Currently only handles .debmacros
169# Needs to handle "other files"
170sub load_userconfig {
171 my (undef,undef,undef,undef,undef,undef,undef,$homedir,undef) = getpwuid($<);
172 if (-e "$homedir/.debmacros") {
173 open USERMACROS,"<$homedir/.debmacros";
174 while (<USERMACROS>) {
175 # And we also only handle a few macros at the moment.
176 if (/^\%_topdir/) {
177 my (undef,$tmp) = split /\s+/, $_;
178 $topdir = $tmp;
179 }
180 }
181 }
182} # end load_userconfig()
183
184
185## parse_cmd()
186# Parses command line into global hash %cmdopts, other globals
187# Options based on rpmbuild's options
188sub parse_cmd {
189 # Don't feel like coding my own option parser...
190 #use Getopt::Long;
191 # ... but I may have to: (OTOH, rpm uses popt, so maybe we can too.)
192 #use Getopt::Popt qw(:all);
193 # Or not. >:( Stupid Debian lack of findable Perl module names in packages.
194
195 # Stuff it.
196 my $prevopt = '';
197 foreach (@ARGV) {
198 chomp;
199
200 # Is it an option?
201 if (/^-/) {
202
203 # Is it a long option?
204 if (/^--/) {
205 if (/^--short-circuit/) {
206 $cmdopts{short} = 'y';
207 } elsif (/^--rebuild/) {
208 $cmdopts{type} = 's';
209 } else {
210 print "Long opt $_\n";
211 }
212 } else {
213 # Not a long option
214 if (/^-[bt]/) {
215 if ($cmdopts{stage} eq 's') {
216 # Mutually exclusive options.
217 die "Can't use $_ with --rebuild\n";
218 } else {
219 # Capture the type (from "bare" files or tarball) and the stage (prep, build, etc)
220 ($cmdopts{stage}) = (/^-[bt]([pcilabs])/);
221 ($cmdopts{type}) = (/^-([bt])[pcilabs]/);
222 }
223 } elsif (/^-v/) {
224 # bump verbosity. Not sure what I'll actually do here...
225 } else {
226 die "Bad option $_\n";
227 }
228 }
229
230 } else { # Not an option argument
231
232 # --buildroot is the only option that takes an argument
233 # Therefore, any *other* bare arguments are the spec file,
234 # tarball, or source package we're operating on - depending
235 # on which one we meet.
236 if ($prevopt eq '--buildroot') {
237 $cmdbuildroot = $_;
238 } else {
239 if ($cmdopts{type} eq 's') {
240 # Source package
241 if (!/\.src\.(deb|rpm)$/) {
242 die "Can't --rebuild with $_\n";
243 }
244 } elsif ($cmdopts{type} eq 'b') {
245 $specfile = $_;
246 # Spec file
247 } else {
248 # Tarball
249 }
250 }
251 }
252 $prevopt = $_;
253 } # foreach @ARGV
254
255 # Some cross-checks. rpmbuild limits --short-circuit to just
256 # the "compile" and "install" targets - with good reason IMO.
257 # Note that --short-circuit with -.p is not really an error, just redundant.
258 # NB - this is NOT fatal, just ignored!
259 if ($cmdopts{short} eq 'y' && $cmdopts{stage} =~ /[labs]/) {
260 warn "Can't use --short-circuit for $targets{$cmdopts{stage}} stage. Ignoring.\n";
261 $cmdopts{short} = 'n';
262 }
263
264 # Valid options, with example arguments (if any):
265# Build from .spec file; mutually exclusive:
266 # -bp
267 # -bc
268 # -bi
269 # -bl
270 # -ba
271 # -bb
272 # -bs
273# Build from tarball; mutually exclusive:
274 # -tp
275 # -tc
276 # -ti
277 # -ta
278 # -tb
279 # -ts
280# Build from .src.(deb|rpm)
281 # --rebuild
282 # --recompile
283
284# General options
285 # --buildroot=DIRECTORY
286 # --clean
287 # --nobuild
288 # --nodeps
289 # --nodirtokens
290 # --rmsource
291 # --rmspec
292 # --short-circuit
293 # --target=CPU-VENDOR-OS
294
295 #my $popt = new Getopt::Popt(argv => \@ARGV, options => \@optionsTable);
296
297} # end parse_cmd()
298
299
300## parse_spec()
301# Parse the .spec file.
302sub parse_spec {
303 open SPECFILE,"<$specfile";
304
305LINE: while (<SPECFILE>) {
306 next if /^#/; # Ignore comments...
307 next if /^\s+$/; # ... and blank lines.
308
309 if (/^\%/) {
310 # A macro that needs further processing.
311
312 if (/^\%define\s+([^\s]+)\s+([^\s]+)/) {
313 $specglobals{$1} = expandmacros($2,'g');
314 }
315
316 if (/^\%description(?:\s+(?:-n\s+)?([a-zA-Z0-9_.-]+))?/) {
317 my $subname = "main";
318 if ($1) {
319 if (/-n/) { $subname = $1; } else { $subname = "$pkgdata{main}{name}-$1"; }
320 }
321 while (<SPECFILE>) {
322 redo LINE if /^\%/;
323 $pkgdata{$subname}{desc} .= " $_";
324 }
325 }
326 if (/^\%package\s+(?:-n\s+)?([a-zA-Z0-9_.-]+)/) {
327 my $subname;
328 if (/-n/) { $subname = $1; } else { $subname = "$pkgdata{main}{name}-$1"; }
329 push @pkglist, $subname;
330 $pkgdata{$subname}{name} = $subname;
331 $pkgdata{$subname}{version} = $pkgdata{main}{version};
332 while (<SPECFILE>) {
333 redo LINE if /^\%/;
334 if (my ($dname,$dvalue) = (/^(Summary|Group|Version):\s+(.+)$/i)) {
335 $dname =~ tr/[A-Z]/[a-z]/;
336 $pkgdata{$subname}{$dname} = $dvalue;
337 }
338 }
339 }
340
341 if (/^\%prep/) {
342 # %prep section. May have %setup macro; may include %patch tags,
343 # may be just a bare shell script.
344
345 # This really should be local-ish, but we need just the filename for the source
346 $pkgdata{main}{source} =~ s|.+/([^/]+)$|$1|;
347
348 # Replace some core macros
349 $pkgdata{main}{source} = expandmacros($pkgdata{main}{source},'gp');
350
351PREPSCRIPT: while (<SPECFILE>) {
352 if (/^\%setup/) {
353 # Parse out the %setup macro. Note that we aren't supporting
354 # many of RPM's %setup features.
355 $prepscript .= "cd $topdir/BUILD\n";
356 if ( /\s+-n\s+([^\s]+)\s+/ ) {
357 $tarballdir = $1;
358 } else {
359 $tarballdir = "$pkgdata{main}{name}-$pkgdata{main}{version}";
360 }
361 $prepscript .= "rm -rf $tarballdir\ntar -".
362 ( $pkgdata{main}{source} =~ /\.tar\.gz$/ ? "z" : "" ).
363 ( $pkgdata{main}{source} =~ /\.tar\.bz2$/ ? "j" : "" ).
364 ( /\s+-q\s+/ ? '' : 'vv' )."xf ".
365 "$topdir/SOURCES/$pkgdata{main}{source}\n".
366 qq(STATUS=\$?\nif [ \$STATUS -ne 0 ]; then\n exit \$STATUS\nfi\n).
367 ( /\s+-n\s+([^\s]+)\s+/ ?
368 "cd $1\n" : "cd $pkgdata{main}{name}-$pkgdata{main}{version}\n" ).
369 qq([ `/usr/bin/id -u` = '0' ] && /bin/chown -Rhf root .\n).
370 qq([ `/usr/bin/id -u` = '0' ] && /bin/chgrp -Rhf root .\n).
371 qq(/bin/chmod -Rf a+rX,g-w,o-w .\n);
372 } elsif (/^\%patch([^:]+)\s+(.+)$/) {
373 $prepscript .= "patch $2 <$topdir/SOURCES/".$pkgdata{main}{"patch$1"}."\n";
374 } else {
375 last PREPSCRIPT if /^\%/;
376 $prepscript .= $_;
377 }
378 }
379 redo LINE;
380 }
381 if (/^\%build/) {
382 # %build. This is pretty much just a shell script. There
383 # *are* a few macros, but we're not going to deal with them yet.
384 $buildscript .= "cd $tarballdir\n";
385BUILDSCRIPT: while (<SPECFILE>) {
386 if (/^\%configure/) {
387 $buildscript .= expandmacros($_,'cgbp');
388 } elsif (/^\%\{__make\}/) {
389 $buildscript .= expandmacros($_,'mgbp');
390 } else {
391 last BUILDSCRIPT if /^\%[^{]/;
392 $buildscript .= $_;
393 }
394 }
395 redo LINE;
396 }
397 if (/^\%install/) {
398 $installscript .= "cd $tarballdir\n";
399INSTALLSCRIPT: while (<SPECFILE>) {
400 if (/^\%makeinstall/) {
401 $installscript .= expandmacros($_,'igbp');
402 } else {
403 last INSTALLSCRIPT if /^\%/;
404 $installscript .= $_;
405 }
406 }
407 redo LINE;
408 }
409 if (/^\%clean/) {
410 while (<SPECFILE>) {
411 redo LINE if /^\%/;
412 $cleanscript .= $_;
413 }
414print "before:\n$cleanscript\n";
415 $cleanscript = expandmacros($cleanscript,'gp');
416print "\nafter:\n$cleanscript\n";
417exit 0;
418 }
419
420 # pre/post (un)install scripts
421 if (/^\%pre\b/) {
422 while (<SPECFILE>) {
423 redo LINE if /^\%/;
424 $preinstscript .= $_;
425 }
426 }
427 if (/^\%post\b/) {
428 while (<SPECFILE>) {
429 redo LINE if /^\%/;
430 $postinstscript .= $_;
431 }
432 }
433 if (/^\%preun\b/) {
434 while (<SPECFILE>) {
435 redo LINE if /^\%/;
436 $preuninstscript .= $_;
437 }
438 }
439 if (/^\%postun\b/) {
440 while (<SPECFILE>) {
441 redo LINE if /^\%/;
442 $postuninstscript .= $_;
443 }
444 }
445 # done %pre/%post scripts
446
447 if (/^\%files(?:\s+(?:-n\s+)?([a-zA-z0-9]+))?/) {
448 my $pkgname = 'main';
449 if ($1) { # Magic to add entries to the right list of files
450 if (/-n/) { $pkgname = $1; } else { $pkgname = "$pkgdata{main}{name}-$1"; }
451 }
452 while (<SPECFILE>) {
453 chomp;
454 # need to update this to deal (properly) with %dir, %attr, etc
455 next if /^\%dir/;
456 next if /^\%attr/;
457 next if /^\%defattr/;
458
459 # and finally we can fall through %{_<FHS>}-prefixed locations...
460 $filelist{$pkgname} .= " $_" if /^\%\{_/;
461
462 # ... unknown or "next section" % directives ...
463 redo LINE if /^\%/;
464
465 # ... and "normal" files
466 $filelist{$pkgname} .= " $_";
467 }
468 } # done %file section
469
470 if (/^\%changelog/) {
471 $pkgdata{main}{changelog} = '';
472 while (<SPECFILE>) {
473 redo LINE if /^\%/;
474 $pkgdata{main}{changelog} .= $_;
475 }
476 }
477
478 } else { # Data from the spec file "header"
479
480 if (/^summary:\s+(.+)/i) {
481 $pkgdata{main}{summary} = $1;
482 } elsif (/^name:\s+(.+)/i) {
483 $pkgdata{main}{name} = expandmacros($1,'g');
484 } elsif (/^version:\s+(.+)/i) {
485 $pkgdata{main}{version} = expandmacros($1,'g');
486 } elsif (/^release:\s+(.+)/i) {
487 $pkgdata{main}{release} = expandmacros($1,'g');
488 } elsif (/^group:\s+(.+)/i) {
489 $pkgdata{main}{group} = $1;
490 } elsif (/^copyright:\s+(.+)/i) {
491 $pkgdata{main}{copyright} = $1;
492 } elsif (/^url:\s+(.+)/i) {
493 $pkgdata{main}{url} = $1;
494 } elsif (/^packager:\s+(.+)/i) {
495 $pkgdata{main}{packager} = $1;
496 } elsif (/^buildroot:\s+(.+)/i) {
497 $buildroot = $1;
498 } elsif (/^source:\s+(.+)/i) {
499 $pkgdata{main}{source} = $1;
500 die "Unknown tarball format $1\n" if $1 !~ /\.tar\.(?:gz|bz2)$/;
501 } elsif (/^source([0-9]+):\s+(.+)/i) {
502 $pkgdata{sources}{$1} = $2;
503 } elsif (/^patch([^:]+):\s+(.+)$/i) {
504 my $patchname = "patch$1";
505 $pkgdata{main}{$patchname} = $2;
506 if ($pkgdata{main}{$patchname} =~ /\//) {
507 # URL-style patch. Rare but not unheard-of.
508 my @patchbits = split '/', $pkgdata{main}{$patchname};
509 $pkgdata{main}{$patchname} = $patchbits[$#patchbits];
510 }
511 }
512#Name: suwrap
513#Version: 0.04
514#Release: 3
515#Group: Applications/System
516#Copyright: WebHart internal ONLY. :(
517#BuildArchitectures: i386
518#BuildRoot: /tmp/%{name}-%{version}
519#Url: http://virtual.webhart.net
520#Packager: Kris Deugau <kdeugau@deepnet.cx>
521#Source: ftp://virtual.webhart.net/%{name}-%{version}.tar.gz
522
523 }
524 }
525
526 # Parse and replace some more macros. More will be replaced even later.
527
528 # Expand macros as necessary.
529 $scriptletbase = expandmacros($scriptletbase,'gp');
530
531 $buildroot = $cmdbuildroot if $cmdbuildroot;
532 $buildroot = expandmacros($buildroot,'gp');
533
534 close SPECFILE;
535} # end parse_spec()
536
537
538## prep()
539# Writes and executes the %prep script (mostly) built while reading the spec file.
540sub prep {
541 # Replace some things here just to make sure.
542 $prepscript = expandmacros($prepscript,'gp');
543
544#print $prepscript; exit 0;
545
546 # create script filename
547 my $prepscriptfile = "$tmpdir/deb-tmp.prep.".int(rand(99998)+1);
548 sysopen(PREPSCRIPT, $prepscriptfile, O_RDWR | O_CREAT | O_EXCL | O_NOFOLLOW)
549 or die $!;
550 print PREPSCRIPT $scriptletbase;
551 print PREPSCRIPT $prepscript;
552 close PREPSCRIPT;
553
554 # execute
555 print "Calling \%prep script $prepscriptfile...\n";
556 system("/bin/sh -e $prepscriptfile") == 0
557 or die "Can't exec: $!\n";
558
559 # and clean up
560 unlink $prepscriptfile;
561} # end prep()
562
563
564## build()
565# Writes and executes the %build script (mostly) built while reading the spec file.
566sub build {
567 # Expand the macros
568 $buildscript = expandmacros($buildscript,'cgbp');
569
570 # create script filename
571 my $buildscriptfile = "$tmpdir/deb-tmp.build.".int(rand(99998)+1);
572 sysopen(BUILDSCRIPT, $buildscriptfile, O_RDWR | O_CREAT | O_EXCL | O_NOFOLLOW)
573 or die $!;
574 print BUILDSCRIPT $scriptletbase;
575 print BUILDSCRIPT $buildscript;
576 close BUILDSCRIPT;
577
578 # execute
579 print "Calling \%build script $buildscriptfile...\n";
580 system("/bin/sh -e $buildscriptfile") == 0
581 or die "Can't exec: $!\n";
582
583 # and clean up
584 unlink $buildscriptfile;
585} # end build()
586
587
588## install()
589# Writes and executes the %install script (mostly) built while reading the spec file.
590sub install {
591 # Expand the macros
592 $installscript = expandmacros($installscript,'igbp');
593
594 # create script filename
595 my $installscriptfile = "$tmpdir/deb-tmp.inst.".int(rand(99998)+1);
596 sysopen(INSTSCRIPT, $installscriptfile, O_RDWR | O_CREAT | O_EXCL | O_NOFOLLOW)
597 or die $!;
598 print INSTSCRIPT $scriptletbase;
599# print INSTSCRIPT $cleanscript; # Clean up our install target before installing into it.
600 print INSTSCRIPT $installscript;
601 close INSTSCRIPT;
602
603 # execute
604 print "Calling \%install script $installscriptfile...\n";
605 system("/bin/sh -e $installscriptfile") == 0
606 or die "Can't exec: $!\n";
607
608 # and clean up
609 unlink $installscriptfile;
610} # end install()
611
612
613## binpackage()
614# Creates the binary .deb package from the installed tree in $buildroot.
615# Writes and executes a shell script to do so.
616# Creates miscellaneous files required by dpkg-deb to actually build the package file.
617# Should handle simple subpackages
618sub binpackage {
619 # Make sure we have somewhere to write the .deb file
620 if (!-e "$topdir/DEBS/i386") {
621# "if [ -e $topdir/DEBS/i386 ]; then\n\tmkdir $topdir/DEBS/i386\nfi\n".
622 mkdir "$topdir/DEBS/i386";
623 }
624
625##work
626 foreach my $pkg (@pkglist) {
627
628 # Gotta do this first, otherwise we don't have a place to move files from %files
629 mkdir "$buildroot/$pkg";
630
631 my @pkgfilelist = split ' ', $filelist{$pkg};
632 foreach my $pkgfile (@pkgfilelist) {
633 my @filepath = ($pkgfile =~ /(.+)\/([a-zA-Z0-9_\.\+\-]+)$/);
634 qx { mkdir -p $buildroot/$pkg$filepath[0] }
635 if $filepath[0] ne '';
636 qx { mv $buildroot$pkgfile $buildroot/$pkg$filepath[0] };
637 }
638
639 # Gotta do this next, otherwise the control file has nowhere to go. >:(
640 mkdir "$buildroot/$pkg/DEBIAN";
641
642 # create script filename
643 my $debscriptfile = "$tmpdir/deb-tmp.pkg.".int(rand(99998)+1);
644 sysopen(DEBSCRIPT, $debscriptfile, O_RDWR | O_CREAT | O_EXCL | O_NOFOLLOW)
645 or die $!;
646 print DEBSCRIPT $scriptletbase;
647 print DEBSCRIPT "fakeroot dpkg-deb -b $buildroot/$pkg $topdir/DEBS/i386/".
648 "$pkgdata{$pkg}{name}_$pkgdata{$pkg}{version}-$pkgdata{main}{release}_i386.deb\n";
649 # %$&$%@#@@#%@@@ Debian and their horrible ugly package names. >:(
650 close DEBSCRIPT;
651
652 my $control = "Package: $pkgdata{$pkg}{name}\n".
653 "Version: $pkgdata{$pkg}{version}-$pkgdata{main}{release}\n".
654 "Section: $pkgdata{$pkg}{group}\n".
655 "Priority: optional\n".
656 "Architecture: i386\n".
657 "Maintainer: $pkgdata{main}{packager}\n".
658 "Description: $pkgdata{$pkg}{summary}\n";
659 $control .= "$pkgdata{$pkg}{desc}\n";
660
661 open CONTROL, ">$buildroot/$pkg/DEBIAN/control";
662 print CONTROL $control;
663 close CONTROL;
664
665 if ($preinstscript ne '') {
666 open PREINST, ">$buildroot/$pkg/DEBIAN/preinst";
667 print PREINST "#!/bin/sh\nset -e\n\n";
668 print PREINST $preinstscript;
669 close PREINST;
670 `chmod 0755 $buildroot/$pkg/DEBIAN/preinst`;
671 }
672 if ($postinstscript ne '') {
673 open POSTINST, ">$buildroot/$pkg/DEBIAN/postinst";
674 print POSTINST "#!/bin/sh\nset -e\n\n";
675 print POSTINST $postinstscript;
676 close POSTINST;
677 `chmod 0755 $buildroot/$pkg/DEBIAN/postinst`;
678 }
679 if ($preuninstscript ne '') {
680 open PREUNINST, ">$buildroot/$pkg/DEBIAN/prerm";
681 print PREUNINST "#!/bin/sh\nset -e\n\n";
682 print PREUNINST $preuninstscript;
683 close PREUNINST;
684 `chmod 0755 $buildroot/$pkg/DEBIAN/prerm`;
685 }
686 if ($postuninstscript ne '') {
687 open POSTUNINST, ">$buildroot/$pkg/DEBIAN/postrm";
688 print POSTUNINST "#!/bin/sh\nset -e\n\n";
689 print POSTUNINST $postuninstscript;
690 close POSTUNINST;
691 `chmod 0755 $buildroot/$pkg/DEBIAN/postrm`;
692 }
693
694#print `ls -l $buildroot/DEBIAN`;
695
696#Package: httpd
697#Version: 2.0.54-7via
698#Section: unknown
699#Priority: optional
700#Architecture: i386
701#Depends: libc6 (>= 2.3.2.ds1-21), libdb4.2, libexpat1 (>= 1.95.8), libssl0.9.7, libapr0
702#Replaces: apache2
703#Installed-Size: 3076
704#Maintainer: Kris Deugau <kdeugau@vianet.ca>
705#Description: apache2 for ViaNet
706# apache2 for ViaNet. Includes per-vhost setuid patches from
707# http://home.samfundet.no/~sesse/mpm-itk/.
708
709 # execute
710 print "Calling package creation script $debscriptfile for $pkgdata{$pkg}{name}...\n";
711 system("/bin/sh -e $debscriptfile") == 0
712 or die "Can't exec: $!\n";
713
714 # and clean up
715 unlink $debscriptfile;
716
717 } # subpackage loop
718
719} # end binpackage()
720
721
722sub srcpackage {}
723
724
725## expandmacros()
726# Expands all %{blah} macros in the passed string
727# Split up a bit with some sections so we don't spend time trying to
728# expand macros that are only used in a few specific places.
729sub expandmacros {
730 my $macrostring = shift;
731 my $section = shift;
732
733 # To allow the FHS-ish %configure and %makeinstall to work The Right Way.
734 # (Without clobbering the global $buildroot.)
735 my $prefix = '';
736
737 if ($section =~ /c/) {
738 # %configure macro
739# Don't know what it's for, don't have a useful default replacement
740# --program-prefix=%{_program_prefix} \
741 $macrostring =~ s'%configure'./configure --host=$DEB_HOST_GNU_TYPE \
742 --build=$DEB_BUILD_GNU_TYPE \
743 --prefix=%{_prefix} \
744 --exec-prefix=%{_exec_prefix} \
745 --bindir=%{_bindir} \
746 --sbindir=%{_sbindir} \
747 --sysconfdir=%{_sysconfdir} \
748 --datadir=%{_datadir} \
749 --includedir=%{_includedir} \
750 --libdir=%{_libdir} \
751 --libexecdir=%{_libexecdir} \
752 --localstatedir=%{_localstatedir} \
753 --sharedstatedir=%{_sharedstatedir} \
754 --mandir=%{_mandir} \
755 --infodir=%{_infodir} ';
756 } # done %configure
757
758 if ($section =~ /m/) {
759 $macrostring =~ s'%{__make}'make ';
760 } # done make
761
762 if ($section =~ /i/) {
763 # This is where we need to mangle $prefix.
764 $macrostring =~ s'%makeinstall'make %{fhs} install';
765 $prefix = $buildroot;
766 } # done %install and/or %makeinstall
767
768 # Build data
769 # Note that these are processed in reverse order to get the substitution order right
770 if ($section =~ /b/) {
771# $macrostring =~ s'%{fhs}'host=$DEB_HOST_GNU_TYPE \
772# build=$DEB_BUILD_GNU_TYPE \
773 $macrostring =~ s'%{fhs}'prefix=%{_prefix} \
774 exec-prefix=%{_exec_prefix} \
775 bindir=%{_bindir} \
776 sbindir=%{_sbindir} \
777 sysconfdir=%{_sysconfdir} \
778 datadir=%{_datadir} \
779 includedir=%{_includedir} \
780 libdir=%{_libdir} \
781 libexecdir=%{_libexecdir} \
782 localstatedir=%{_localstatedir} \
783 sharedstatedir=%{_sharedstatedir} \
784 mandir=%{_mandir} \
785 infodir=%{_infodir} \
786';
787
788 # Note that the above regex terminates with the extra space
789 # "Just In Case" of user additions, which will then get neatly
790 # tagged on the end where they take precedence (supposedly)
791 # over the "default" ones.
792
793 # Now we cascade the macros introduced above. >_<
794 # Wot ot to go theah:
795 $macrostring =~ s|%{_mandir}|%{_datadir}/man|g; #/usr/share/man
796 $macrostring =~ s|%{_infodir}|%{_datadir}/info|g; #/usr/share/info
797 $macrostring =~ s|%{_oldincludedir}|/usr/include|g; #/usr/include
798 $macrostring =~ s|%{_includedir}|%{_prefix\}/include|g; #/usr/include
799 $macrostring =~ s|%{_libdir}|%{_exec_prefix}/%{_lib}|g; #/usr/lib
800 $macrostring =~ s|%{_lib}|lib|g; #?
801 $macrostring =~ s|%{_localstatedir}|/var|g; #/var
802 $macrostring =~ s|%{_sharedstatedir}|%{_prefix}/com|g; #/usr/com WTF?
803 $macrostring =~ s|%{_sysconfdir}|/etc|g; #/etc
804 $macrostring =~ s|%{_datadir}|%{_prefix}/share|g; #/usr/share
805 $macrostring =~ s|%{_libexecdir}|%{_exec_prefix}/libexec|g; #/usr/libexec
806 $macrostring =~ s|%{_sbindir}|%{_exec_prefix}/sbin|g; #/usr/sbin
807 $macrostring =~ s|%{_bindir}|%{_exec_prefix}/bin|g; #/usr/bin
808 $macrostring =~ s|%{_exec_prefix}|%{_prefix}|g; #/usr
809 $macrostring =~ s|%{_prefix}|/usr|g; #/usr
810 } # done with config section
811
812 # Package data
813 if ($section =~ /p/) {
814 $macrostring =~ s/\%\{buildroot\}/$buildroot/gi;
815 foreach my $source (keys %{$pkgdata{sources}}) {
816 $macrostring =~ s/\%\{source$source\}/$topdir\/SOURCES\/$pkgdata{sources}{$source}/gi;
817 }
818 $macrostring =~ s/\%\{name\}/$pkgdata{main}{name}/gi;
819 $macrostring =~ s/\%\{version\}/$pkgdata{main}{version}/gi;
820 $macrostring =~ s/\%\{release\}/$pkgdata{main}{release}/gi;
821 }
822
823 # Globals, and not-so-globals
824 if ($section =~ /g/) {
825 $macrostring =~ s|%{_builddir}|%{_topdir}/BUILD|g;
826 $macrostring =~ s|%{_topdir}|$topdir|g;
827 $macrostring =~ s|%{_tmppath}|$tmpdir|g;
828 $macrostring =~ s'%{_docdir}'/usr/share/doc'g;
829
830 # %define's
831 foreach my $key (keys %specglobals) {
832 $macrostring =~ s|%{$key}|$specglobals{$key}|g;
833 }
834
835 # system programs. RPM uses a global config file for these; we'll just
836 # ASS-U-ME and make life a little simpler.
837 if ($macrostring =~ /\%\{\_\_([a-z0-9_-]+)\}/) {
838 $macrostring =~ s|%{__([a-z0-9_-]+)}|$1|g;
839 }
840 } # done with globals section
841
842 return $macrostring;
843} # end expandmacros()
844
845
846
847=head1 NAME
848
849debbuild - Build Debian-compatible packages from RPM spec files
850
851=head1 SYNOPSIS
852
853 debbuild {-ba|-bb|-bp|-bc|-bi|-bl|-bs} [build-options] file.spec
854
855 debbuild {-ta|-tb|-tp|-tc|-ti|-tl|-ts} [build-options] file.tar.{gz|bz2}
856
857 debbuild --rebuild file.src.{rpm|deb}
858
859=head1 DESCRIPTION
860
861This script attempts to build Debian-friendly semi-native packages
862from RPM spec files, RPM-friendly tarballs, and RPM source packages
863(.src.rpm). It accepts I<most> of the options rpmbuild does, and
864should be able to interpret most spec files usefully. Perl modules
865should be handled via CPAN+dh-make-perl instead; Debian's conventions
866for such things do not lend themselves to automated conversion.
867
868As far as possible, the command-line options are identical to those
869from rpmbuild, although several rpmbuild options are not supported.
870
871=cut
Note: See TracBrowser for help on using the repository browser.