source: trunk/debbuild@ 28

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

/trunk

Checkpoint
Tweaks to %files handling, cruft cleanup

  • Property svn:executable set to *
  • Property svn:keywords set to Date Rev Author
File size: 24.8 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-12 23:10:42 +0000 (Mon, 12 Dec 2005) $
9# SVN revision $Rev: 28 $
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 # pre/post (un)install scripts
420 if (/^\%pre\b/) {
421 while (<SPECFILE>) {
422 redo LINE if /^\%/;
423 $preinstscript .= $_;
424 }
425 }
426 if (/^\%post\b/) {
427 while (<SPECFILE>) {
428 redo LINE if /^\%/;
429 $postinstscript .= $_;
430 }
431 }
432 if (/^\%preun\b/) {
433 while (<SPECFILE>) {
434 redo LINE if /^\%/;
435 $preuninstscript .= $_;
436 }
437 }
438 if (/^\%postun\b/) {
439 while (<SPECFILE>) {
440 redo LINE if /^\%/;
441 $postuninstscript .= $_;
442 }
443 }
444 if (/^\%files(?:\s+(?:-n\s+)?([a-zA-z0-9]+))?/) {
445 my $pkgname = 'main';
446 if ($1) {
447 if (/-n/) { $pkgname = $1; } else { $pkgname = "$pkgdata{main}{name}-$1"; }
448 }
449 # subpackage not based on "main" package
450#print "$pkgname\n";
451 while (<SPECFILE>) {
452 # need to update this to deal with %dir, %attr, etc
453 redo LINE if /^\%/;
454chomp;
455#print; print "\n";
456 $filelist{$pkgname} .= " $_";
457#print $pkgdata{$pkgname}{files}; print "\n";
458 }
459 # do we replace \n's with \s in $filelist{$pkgname}?
460 # Danger! Danger!
461 }
462 if (/^\%changelog/) {
463 $pkgdata{main}{changelog} = '';
464 while (<SPECFILE>) {
465 redo LINE if /^\%/;
466 $pkgdata{main}{changelog} .= $_;
467 }
468 }
469
470 } else { # Data from the spec file "header"
471
472 if (/^summary:\s+(.+)/i) {
473 $pkgdata{main}{summary} = $1;
474 } elsif (/^name:\s+(.+)/i) {
475 $pkgdata{main}{name} = expandmacros($1,'g');
476 } elsif (/^version:\s+(.+)/i) {
477 $pkgdata{main}{version} = expandmacros($1,'g');
478 } elsif (/^release:\s+(.+)/i) {
479 $pkgdata{main}{release} = expandmacros($1,'g');
480 } elsif (/^group:\s+(.+)/i) {
481 $pkgdata{main}{group} = $1;
482 } elsif (/^copyright:\s+(.+)/i) {
483 $pkgdata{main}{copyright} = $1;
484 } elsif (/^url:\s+(.+)/i) {
485 $pkgdata{main}{url} = $1;
486 } elsif (/^packager:\s+(.+)/i) {
487 $pkgdata{main}{packager} = $1;
488 } elsif (/^buildroot:\s+(.+)/i) {
489 $buildroot = $1;
490 } elsif (/^source:\s+(.+)/i) {
491 $pkgdata{main}{source} = $1;
492 die "Unknown tarball format $1\n" if $1 !~ /\.tar\.(?:gz|bz2)$/;
493 } elsif (/^source([0-9]+):\s+(.+)/i) {
494 $pkgdata{sources}{$1} = $2;
495 } elsif (/^patch([^:]+):\s+(.+)$/i) {
496 my $patchname = "patch$1";
497 $pkgdata{main}{$patchname} = $2;
498 if ($pkgdata{main}{$patchname} =~ /\//) {
499 # URL-style patch. Rare but not unheard-of.
500 my @patchbits = split '/', $pkgdata{main}{$patchname};
501 $pkgdata{main}{$patchname} = $patchbits[$#patchbits];
502 }
503 }
504#Name: suwrap
505#Version: 0.04
506#Release: 3
507#Group: Applications/System
508#Copyright: WebHart internal ONLY. :(
509#BuildArchitectures: i386
510#BuildRoot: /tmp/%{name}-%{version}
511#Url: http://virtual.webhart.net
512#Packager: Kris Deugau <kdeugau@deepnet.cx>
513#Source: ftp://virtual.webhart.net/%{name}-%{version}.tar.gz
514
515 }
516 }
517
518 # Parse and replace some more macros. More will be replaced even later.
519
520 # Expand macros as necessary.
521 $scriptletbase = expandmacros($scriptletbase,'gp');
522
523 $buildroot = $cmdbuildroot if $cmdbuildroot;
524 $buildroot = expandmacros($buildroot,'gp');
525
526 close SPECFILE;
527} # end parse_spec()
528
529
530## prep()
531# Writes and executes the %prep script (mostly) built while reading the spec file.
532sub prep {
533 # Replace some things here just to make sure.
534 $prepscript = expandmacros($prepscript,'gp');
535
536#print $prepscript; exit 0;
537
538 # create script filename
539 my $prepscriptfile = "$tmpdir/deb-tmp.prep.".int(rand(99998)+1);
540 sysopen(PREPSCRIPT, $prepscriptfile, O_RDWR | O_CREAT | O_EXCL | O_NOFOLLOW)
541 or die $!;
542 print PREPSCRIPT $scriptletbase;
543 print PREPSCRIPT $prepscript;
544 close PREPSCRIPT;
545
546 # execute
547 print "Calling \%prep script $prepscriptfile...\n";
548 system("/bin/sh -e $prepscriptfile") == 0
549 or die "Can't exec: $!\n";
550
551 # and clean up
552 unlink $prepscriptfile;
553} # end prep()
554
555
556## build()
557# Writes and executes the %build script (mostly) built while reading the spec file.
558sub build {
559 # Expand the macros
560 $buildscript = expandmacros($buildscript,'cgbp');
561
562 # create script filename
563 my $buildscriptfile = "$tmpdir/deb-tmp.build.".int(rand(99998)+1);
564 sysopen(BUILDSCRIPT, $buildscriptfile, O_RDWR | O_CREAT | O_EXCL | O_NOFOLLOW)
565 or die $!;
566 print BUILDSCRIPT $scriptletbase;
567 print BUILDSCRIPT $buildscript;
568 close BUILDSCRIPT;
569
570 # execute
571 print "Calling \%build script $buildscriptfile...\n";
572 system("/bin/sh -e $buildscriptfile") == 0
573 or die "Can't exec: $!\n";
574
575 # and clean up
576 unlink $buildscriptfile;
577} # end build()
578
579
580## install()
581# Writes and executes the %install script (mostly) built while reading the spec file.
582sub install {
583 # Expand the macros
584 $installscript = expandmacros($installscript,'igbp');
585
586 # create script filename
587 my $installscriptfile = "$tmpdir/deb-tmp.inst.".int(rand(99998)+1);
588 sysopen(INSTSCRIPT, $installscriptfile, O_RDWR | O_CREAT | O_EXCL | O_NOFOLLOW)
589 or die $!;
590 print INSTSCRIPT $scriptletbase;
591# print INSTSCRIPT $cleanscript; # Clean up our install target before installing into it.
592 print INSTSCRIPT $installscript;
593 close INSTSCRIPT;
594
595 # execute
596 print "Calling \%install script $installscriptfile...\n";
597 system("/bin/sh -e $installscriptfile") == 0
598 or die "Can't exec: $!\n";
599
600 # and clean up
601 unlink $installscriptfile;
602} # end install()
603
604
605## binpackage()
606# Creates the binary .deb package from the installed tree in $buildroot.
607# Writes and executes a shell script to do so.
608# Creates miscellaneous files required by dpkg-deb to actually build the package file.
609# Should handle simple subpackages
610sub binpackage {
611 # Make sure we have somewhere to write the .deb file
612 if (!-e "$topdir/DEBS/i386") {
613# "if [ -e $topdir/DEBS/i386 ]; then\n\tmkdir $topdir/DEBS/i386\nfi\n".
614 mkdir "$topdir/DEBS/i386";
615 }
616
617##work
618 foreach my $pkg (@pkglist) {
619
620 # Gotta do this first, otherwise we don't have a place to move files from %files
621 mkdir "$buildroot/$pkg";
622
623 my @pkgfilelist = split ' ', $filelist{$pkg};
624 foreach my $pkgfile (@pkgfilelist) {
625 my @filepath = ($pkgfile =~ /(.+)\/([a-zA-Z0-9_\.\+\-]+)$/);
626 qx { mkdir -p $buildroot/$pkg$filepath[0] }
627 if $filepath[0] ne '';
628 qx { mv $buildroot$pkgfile $buildroot/$pkg$filepath[0] };
629 }
630
631 # Gotta do this next, otherwise the control file has nowhere to go. >:(
632 mkdir "$buildroot/$pkg/DEBIAN";
633
634 # create script filename
635 my $debscriptfile = "$tmpdir/deb-tmp.pkg.".int(rand(99998)+1);
636 sysopen(DEBSCRIPT, $debscriptfile, O_RDWR | O_CREAT | O_EXCL | O_NOFOLLOW)
637 or die $!;
638 print DEBSCRIPT $scriptletbase;
639 print DEBSCRIPT "fakeroot dpkg-deb -b $buildroot/$pkg $topdir/DEBS/i386/".
640 "$pkgdata{$pkg}{name}_$pkgdata{$pkg}{version}-$pkgdata{main}{release}_i386.deb\n";
641 # %$&$%@#@@#%@@@ Debian and their horrible ugly package names. >:(
642 close DEBSCRIPT;
643
644 my $control = "Package: $pkgdata{$pkg}{name}\n".
645 "Version: $pkgdata{$pkg}{version}-$pkgdata{main}{release}\n".
646 "Section: $pkgdata{$pkg}{group}\n".
647 "Priority: optional\n".
648 "Architecture: i386\n".
649 "Maintainer: $pkgdata{main}{packager}\n".
650 "Description: $pkgdata{$pkg}{summary}\n";
651 $control .= "$pkgdata{$pkg}{desc}\n";
652
653 open CONTROL, ">$buildroot/$pkg/DEBIAN/control";
654 print CONTROL $control;
655 close CONTROL;
656
657 if ($preinstscript ne '') {
658 open PREINST, ">$buildroot/$pkg/DEBIAN/preinst";
659 print PREINST "#!/bin/sh\nset -e\n\n";
660 print PREINST $preinstscript;
661 close PREINST;
662 `chmod 0755 $buildroot/$pkg/DEBIAN/preinst`;
663 }
664 if ($postinstscript ne '') {
665 open POSTINST, ">$buildroot/$pkg/DEBIAN/postinst";
666 print POSTINST "#!/bin/sh\nset -e\n\n";
667 print POSTINST $postinstscript;
668 close POSTINST;
669 `chmod 0755 $buildroot/$pkg/DEBIAN/postinst`;
670 }
671 if ($preuninstscript ne '') {
672 open PREUNINST, ">$buildroot/$pkg/DEBIAN/prerm";
673 print PREUNINST "#!/bin/sh\nset -e\n\n";
674 print PREUNINST $preuninstscript;
675 close PREUNINST;
676 `chmod 0755 $buildroot/$pkg/DEBIAN/prerm`;
677 }
678 if ($postuninstscript ne '') {
679 open POSTUNINST, ">$buildroot/$pkg/DEBIAN/postrm";
680 print POSTUNINST "#!/bin/sh\nset -e\n\n";
681 print POSTUNINST $postuninstscript;
682 close POSTUNINST;
683 `chmod 0755 $buildroot/$pkg/DEBIAN/postrm`;
684 }
685
686#print `ls -l $buildroot/DEBIAN`;
687
688#Package: httpd
689#Version: 2.0.54-7via
690#Section: unknown
691#Priority: optional
692#Architecture: i386
693#Depends: libc6 (>= 2.3.2.ds1-21), libdb4.2, libexpat1 (>= 1.95.8), libssl0.9.7, libapr0
694#Replaces: apache2
695#Installed-Size: 3076
696#Maintainer: Kris Deugau <kdeugau@vianet.ca>
697#Description: apache2 for ViaNet
698# apache2 for ViaNet. Includes per-vhost setuid patches from
699# http://home.samfundet.no/~sesse/mpm-itk/.
700
701 # execute
702 print "Calling package creation script $debscriptfile for $pkgdata{$pkg}{name}...\n";
703 system("/bin/sh -e $debscriptfile") == 0
704 or die "Can't exec: $!\n";
705
706 # and clean up
707 unlink $debscriptfile;
708
709 } # subpackage loop
710
711} # end binpackage()
712
713
714sub srcpackage {}
715
716
717## expandmacros()
718# Expands all %{blah} macros in the passed string
719# Split up a bit with some sections so we don't spend time trying to
720# expand macros that are only used in a few specific places.
721sub expandmacros {
722 my $macrostring = shift;
723 my $section = shift;
724
725 # To allow the FHS-ish %configure and %makeinstall to work The Right Way.
726 # (Without clobbering the global $buildroot.)
727 my $prefix = '';
728
729 if ($section =~ /c/) {
730 # %configure macro
731# Don't know what it's for, don't have a useful default replacement
732# --program-prefix=%{_program_prefix} \
733 $macrostring =~ s'%configure'./configure --host=$DEB_HOST_GNU_TYPE \
734 --build=$DEB_BUILD_GNU_TYPE \
735 --prefix=%{_prefix} \
736 --exec-prefix=%{_exec_prefix} \
737 --bindir=%{_bindir} \
738 --sbindir=%{_sbindir} \
739 --sysconfdir=%{_sysconfdir} \
740 --datadir=%{_datadir} \
741 --includedir=%{_includedir} \
742 --libdir=%{_libdir} \
743 --libexecdir=%{_libexecdir} \
744 --localstatedir=%{_localstatedir} \
745 --sharedstatedir=%{_sharedstatedir} \
746 --mandir=%{_mandir} \
747 --infodir=%{_infodir} ';
748 } # done %configure
749
750 if ($section =~ /m/) {
751 $macrostring =~ s'%{__make}'make ';
752 } # done make
753
754 if ($section =~ /i/) {
755 # This is where we need to mangle $prefix.
756 $macrostring =~ s'%makeinstall'make %{fhs} install';
757 $prefix = $buildroot;
758 } # done %install and/or %makeinstall
759
760 # Build data
761 # Note that these are processed in reverse order to get the substitution order right
762 if ($section =~ /b/) {
763# $macrostring =~ s'%{fhs}'host=$DEB_HOST_GNU_TYPE \
764# build=$DEB_BUILD_GNU_TYPE \
765 $macrostring =~ s'%{fhs}'prefix=%{_prefix} \
766 exec-prefix=%{_exec_prefix} \
767 bindir=%{_bindir} \
768 sbindir=%{_sbindir} \
769 sysconfdir=%{_sysconfdir} \
770 datadir=%{_datadir} \
771 includedir=%{_includedir} \
772 libdir=%{_libdir} \
773 libexecdir=%{_libexecdir} \
774 localstatedir=%{_localstatedir} \
775 sharedstatedir=%{_sharedstatedir} \
776 mandir=%{_mandir} \
777 infodir=%{_infodir} \
778';
779
780 # Note that the above regex terminates with the extra space
781 # "Just In Case" of user additions, which will then get neatly
782 # tagged on the end where they take precedence (supposedly)
783 # over the "default" ones.
784
785 # Now we cascade the macros introduced above. >_<
786 # Wot ot to go theah:
787 $macrostring =~ s|%{_mandir}|%{_datadir}/man|g; #/usr/share/man
788 $macrostring =~ s|%{_infodir}|%{_datadir}/info|g; #/usr/share/info
789 $macrostring =~ s|%{_oldincludedir}|/usr/include|g; #/usr/include
790 $macrostring =~ s|%{_includedir}|%{_prefix\}/include|g; #/usr/include
791 $macrostring =~ s|%{_libdir}|%{_exec_prefix}/%{_lib}|g; #/usr/lib
792 $macrostring =~ s|%{_lib}|lib|g; #?
793 $macrostring =~ s|%{_localstatedir}|/var|g; #/var
794 $macrostring =~ s|%{_sharedstatedir}|%{_prefix}/com|g; #/usr/com WTF?
795 $macrostring =~ s|%{_sysconfdir}|/etc|g; #/etc
796 $macrostring =~ s|%{_datadir}|%{_prefix}/share|g; #/usr/share
797 $macrostring =~ s|%{_libexecdir}|%{_exec_prefix}/libexec|g; #/usr/libexec
798 $macrostring =~ s|%{_sbindir}|%{_exec_prefix}/sbin|g; #/usr/sbin
799 $macrostring =~ s|%{_bindir}|%{_exec_prefix}/bin|g; #/usr/bin
800 $macrostring =~ s|%{_exec_prefix}|%{_prefix}|g; #/usr
801 $macrostring =~ s|%{_prefix}|/usr|g; #/usr
802 } # done with config section
803
804 # Package data
805 if ($section =~ /p/) {
806 $macrostring =~ s/\%\{buildroot\}/$buildroot/gi;
807 foreach my $source (keys %{$pkgdata{sources}}) {
808 $macrostring =~ s/\%\{source$source\}/$topdir\/SOURCES\/$pkgdata{sources}{$source}/gi;
809 }
810 $macrostring =~ s/\%\{name\}/$pkgdata{main}{name}/gi;
811 $macrostring =~ s/\%\{version\}/$pkgdata{main}{version}/gi;
812 $macrostring =~ s/\%\{release\}/$pkgdata{main}{release}/gi;
813 }
814
815 # Globals, and not-so-globals
816 if ($section =~ /g/) {
817 $macrostring =~ s/\%\{_topdir\}/$topdir/g;
818 $macrostring =~ s|%{_tmppath}|$tmpdir|g;
819 $macrostring =~ s'%{_docdir}'/usr/share/doc'g;
820
821 # %define's
822 foreach my $key (keys %specglobals) {
823 $macrostring =~ s|%{$key}|$specglobals{$key}|g;
824 }
825
826 # system programs. RPM uses a global config file for these; we'll just
827 # ASS-U-ME and make life a little simpler.
828 if ($macrostring =~ /\%\{\_\_([a-z0-9_-]+)\}/) {
829 $macrostring =~ s|%{__([a-z0-9_-]+)}|$1|g;
830 }
831 } # done with globals section
832
833 return $macrostring;
834} # end expandmacros()
835
836
837
838=head1 NAME
839
840debbuild - Build Debian-compatible packages from RPM spec files
841
842=head1 SYNOPSIS
843
844 debbuild {-ba|-bb|-bp|-bc|-bi|-bl|-bs} [build-options] file.spec
845
846 debbuild {-ta|-tb|-tp|-tc|-ti|-tl|-ts} [build-options] file.tar.{gz|bz2}
847
848 debbuild --rebuild file.src.{rpm|deb}
849
850=head1 DESCRIPTION
851
852This script attempts to build Debian-friendly semi-native packages
853from RPM spec files, RPM-friendly tarballs, and RPM source packages
854(.src.rpm). It accepts I<most> of the options rpmbuild does, and
855should be able to interpret most spec files usefully. Perl modules
856should be handled via CPAN+dh-make-perl instead; Debian's conventions
857for such things do not lend themselves to automated conversion.
858
859As far as possible, the command-line options are identical to those
860from rpmbuild, although several rpmbuild options are not supported.
861
862=cut
Note: See TracBrowser for help on using the repository browser.