source: trunk/debbuild@ 57

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

/trunk

Update POD again. I think it's actually in sync with the code...

  • Property svn:executable set to *
  • Property svn:keywords set to Date Rev Author
File size: 39.1 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: 2006-04-20 19:03:11 +0000 (Thu, 20 Apr 2006) $
9# SVN revision $Rev: 57 $
10# Last update by $Author: kdeugau $
11###
12# Copyright 2005,2006 Kris Deugau <kdeugau@deepnet.cx>
13#
14# This program is free software; you can redistribute it and/or modify
15# it under the terms of the GNU General Public License as published by
16# the Free Software Foundation; either version 2 of the License, or
17# (at your option) any later version.
18#
19# This program is distributed in the hope that it will be useful,
20# but WITHOUT ANY WARRANTY; without even the implied warranty of
21# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22# GNU General Public License for more details.
23#
24# You should have received a copy of the GNU General Public License
25# along with this program; if not, write to the Free Software
26# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
27
28use strict;
29use warnings;
30use Fcntl; # for sysopen flags
31use Cwd 'abs_path'; # for finding where files really are
32
33# regex debugger
34#use re "debug";
35
36# Program flow:
37# -> Parse/execute "system" config/macros (if any - should be rare)
38# -> Parse/execute "user" config/macros (if any - *my* requirement is %_topdir)
39# -> Parse command line for options, spec file/tarball/.src.deb (NB - also accept .src.rpm)
40
41sub expandmacros;
42
43# User's prefs for dirs, environment, etc,etc,etc.
44# config file ~/.debmacros
45# Default ordered search paths for config/macros:
46# /usr/lib/rpm/rpmrc /usr/lib/rpm/redhat/rpmrc /etc/rpmrc ~/.rpmrc
47# /usr/lib/rpm/macros /usr/lib/rpm/redhat/macros /etc/rpm/macros ~/.rpmmacros
48# **NOTE: May be possible to (ab)use bits of debhelper
49
50# Build tree
51# default is /usr/src/debian/{BUILD,SOURCES,SPECS,DEBS,SDEBS}
52
53# Globals
54my $specfile;
55my $tarball;
56my $srcpkg;
57my $cmdbuildroot;
58my $tarballdir; # This should really be initialized, but the coding makes it, um, ugly.
59my %specglobals; # For %define's in specfile, among other things.
60
61# Initialized globals
62my $verbosity = 0;
63my %cmdopts = (type => '',
64 stage => 'a',
65 short => 'n'
66 );
67my $topdir = "/usr/src/debian";
68my $buildroot = "%{_tmppath}/%{name}-%{version}-%{release}.root".int(rand(99998)+1);
69
70# "Constants"
71my %targets = ('p' => 'Prep',
72 'c' => 'Compile',
73 'i' => 'Install',
74 'l' => 'Verify %files',
75 'a' => 'Build binary and source',
76 'b' => 'Build binary',
77 's' => 'Build source'
78 );
79my $scriptletbase =
80q(#!/bin/sh
81
82 RPM_SOURCE_DIR="%{_topdir}/SOURCES"
83 RPM_BUILD_DIR="%{_topdir}/BUILD"
84 RPM_OPT_FLAGS="-O2 -g -march=i386 -mcpu=i686"
85 RPM_ARCH="i386"
86 RPM_OS="linux"
87 export RPM_SOURCE_DIR RPM_BUILD_DIR RPM_OPT_FLAGS RPM_ARCH RPM_OS
88 RPM_DOC_DIR="/usr/share/doc"
89 export RPM_DOC_DIR
90 RPM_PACKAGE_NAME="%{name}"
91 RPM_PACKAGE_VERSION="%{version}"
92 RPM_PACKAGE_RELEASE="%{release}"
93 export RPM_PACKAGE_NAME RPM_PACKAGE_VERSION RPM_PACKAGE_RELEASE
94 RPM_BUILD_ROOT="%{buildroot}"
95 export RPM_BUILD_ROOT
96);
97foreach (`dpkg-architecture`) {
98 s/=(.+)/="$1"/;
99 $scriptletbase .= " $_";
100}
101$scriptletbase .=
102q(
103 set -x
104 umask 022
105 cd %{_topdir}/BUILD
106);
107
108# Package data
109# This is the form of $pkgdata{pkgname}{meta}
110# meta includes Summary, Name, Version, Release, Group, Copyright,
111# Source, URL, Packager, BuildRoot, Description, BuildReq(uires),
112# Requires, Provides
113# 10/31/2005 Maybe this should be flatter? -kgd
114my %pkgdata;
115my @pkglist = ('main'); #sigh
116# Files listing. Embedding this in %pkgdata would be, um, messy.
117my %filelist;
118my $buildreq = '';
119
120# Scriptlets
121my $prepscript = '';
122my $buildscript = '';
123# %install doesn't need the full treatment from %clean; just an empty place to install to.
124# NB - rpm doesn't do this; is it really necessary?
125my $installscript = '[ "$RPM_BUILD_ROOT" != "/" ] && rm -rf $RPM_BUILD_ROOT'."\n";
126my $cleanscript = '';
127# pre/post (un)install scripts. Note that these will likely barf as-is. :/
128my $preinstscript = '';
129my $postinstscript = '';
130my $preuninstscript = '';
131my $postuninstscript = '';
132
133die "Not enough arguments\n" if #$argv == 0;
134
135# Snag some environment data
136my $tmpdir;
137if (defined $ENV{TMP} && $ENV{TMP} =~ /^(\/var)?\/tmp$/) {
138 $tmpdir = $ENV{TMP};
139} else {
140 $tmpdir = "/var/tmp";
141}
142
143##main
144
145load_userconfig();
146parse_cmd();
147
148if ($cmdopts{install}) {
149 install_sdeb();
150 exit 0;
151}
152
153# Stick --rebuild handling in here - basically install_sdeb()
154# followed by tweaking options to run with -ba
155if ($cmdopts{type} eq 's') {
156 if ($srcpkg =~ /\.src\.rpm$/) {
157 @srclist = qx { rpm -qlp $srcpkg };
158 foreach (@srclist) {
159 chomp;
160 $specfile = "$topdir/SPECS/$_" if /\.spec$/;
161 }
162 qx { rpm -i $srcpkg };
163 } else {
164 install_sdeb();
165 my @srclist = qx { pax < $srcpkg };
166 foreach (@srclist) {
167 chomp;
168 $specfile = "$topdir/$_" if /SPECS/;
169 }
170 }
171 $cmdopts{type} = 'b';
172 $cmdopts{stage} = 'a';
173}
174
175if ($cmdopts{type} eq 'b') {
176 # Need to read the spec file to find the tarball. Note that
177 # this also generates most of the shell script required.
178 parse_spec();
179 die "Can't build $pkgdata{main}{name}: build requirements not met.\n"
180 if !checkbuildreq();
181}
182
183# -> srcpkg if -.s
184if ($cmdopts{stage} eq 's') {
185 srcpackage();
186 exit 0;
187}
188
189# Hokay. Need to:
190# -> prep if -.p OR (-.[cilabs] AND !--short-circuit)
191if ($cmdopts{stage} eq 'p' || ($cmdopts{stage} =~ /[cilabs]/ && $cmdopts{short} ne 'y')) {
192 prep();
193}
194# -> build if -.c OR (-.[ilabs] AND !--short-circuit)
195if ($cmdopts{stage} eq 'c' || ($cmdopts{stage} =~ /[ilabs]/ && $cmdopts{short} ne 'y')) {
196 build();
197}
198# -> install if -.[ilabs]
199#if ($cmdopts{stage} eq 'i' || ($cmdopts{stage} =~ /[labs]/ && $cmdopts{short} ne 'y')) {
200if ($cmdopts{stage} =~ /[ilabs]/) {
201 install();
202#foreach my $pkg (@pkglist) {
203# print "files in $pkg:\n ".$filelist{$pkg}."\n";
204#}
205
206}
207# -> binpkg and srcpkg if -.a
208if ($cmdopts{stage} eq 'a') {
209 binpackage();
210 srcpackage();
211}
212# -> binpkg if -.b
213if ($cmdopts{stage} eq 'b') {
214 binpackage();
215}
216
217# Just in case.
218exit 0;
219
220
221## load_userconfig()
222# Loads user configuration (if any)
223# Currently only handles .debmacros
224# Needs to handle "other files"
225sub load_userconfig {
226 my (undef,undef,undef,undef,undef,undef,undef,$homedir,undef) = getpwuid($<);
227 if (-e "$homedir/.debmacros") {
228 open USERMACROS,"<$homedir/.debmacros";
229 while (<USERMACROS>) {
230 # And we also only handle a few macros at the moment.
231 if (/^\%_topdir/) {
232 my (undef,$tmp) = split /\s+/, $_;
233 $topdir = $tmp;
234 }
235 }
236 }
237} # end load_userconfig()
238
239
240## parse_cmd()
241# Parses command line into global hash %cmdopts, other globals
242# Options based on rpmbuild's options
243sub parse_cmd {
244 # Don't feel like coding my own option parser...
245 #use Getopt::Long;
246 # ... but I may have to: (OTOH, rpm uses popt, so maybe we can too.)
247 #use Getopt::Popt qw(:all);
248 # Or not. >:( Stupid Debian lack of findable Perl module names in packages.
249
250 # Stuff it.
251 my $prevopt = '';
252 foreach (@ARGV) {
253 chomp;
254
255 # Is it an option?
256 if (/^-/) {
257
258 # Is it a long option?
259 if (/^--/) {
260 if (/^--short-circuit/) {
261 $cmdopts{short} = 'y';
262 } elsif (/^--rebuild/) {
263 $cmdopts{type} = 's';
264 } else {
265 print "Long opt $_\n";
266 }
267 } else {
268 # Not a long option
269 if (/^-[bt]/) {
270 if ($cmdopts{stage} eq 's') {
271 # Mutually exclusive options.
272 die "Can't use $_ with --rebuild\n";
273 } else {
274 # Capture the type (from "bare" files or tarball) and the stage (prep, build, etc)
275 ($cmdopts{stage}) = (/^-[bt]([pcilabs])/);
276 ($cmdopts{type}) = (/^-([bt])[pcilabs]/);
277 }
278 } elsif (/^-v/) {
279 # bump verbosity. Not sure what I'll actually do here...
280 } elsif (/^-i/) {
281 $cmdopts{install} = 1;
282 $prevopt = '-i';
283 } else {
284 die "Bad option $_\n";
285 }
286 }
287
288 } else { # Not an option argument
289
290 # --buildroot is the only option that takes an argument
291 # Therefore, any *other* bare arguments are the spec file,
292 # tarball, or source package we're operating on - depending
293 # on which one we meet.
294 if ($prevopt eq '--buildroot') {
295 $cmdbuildroot = $_;
296 } elsif ($prevopt eq '-i') {
297 $srcpkg = $_;
298 } else {
299 if ($cmdopts{type} eq 's') {
300 # Source package
301 if (!/(sdeb|\.src\.rpm)$/) {
302 die "Can't --rebuild with $_\n";
303 }
304 $srcpkg = $_;
305 } elsif ($cmdopts{type} eq 'b') {
306 $specfile = $_;
307 # Spec file
308 } else {
309 # Tarball
310 }
311 }
312 }
313 $prevopt = $_;
314 } # foreach @ARGV
315
316 # Some cross-checks. rpmbuild limits --short-circuit to just
317 # the "compile" and "install" targets - with good reason IMO.
318 # Note that --short-circuit with -.p is not really an error, just redundant.
319 # NB - this is NOT fatal, just ignored!
320 if ($cmdopts{short} eq 'y' && $cmdopts{stage} =~ /[labs]/) {
321 warn "Can't use --short-circuit for $targets{$cmdopts{stage}} stage. Ignoring.\n";
322 $cmdopts{short} = 'n';
323 }
324
325 # Valid options, with example arguments (if any):
326# Build from .spec file; mutually exclusive:
327 # -bp
328 # -bc
329 # -bi
330 # -bl
331 # -ba
332 # -bb
333 # -bs
334# Build from tarball; mutually exclusive:
335 # -tp
336 # -tc
337 # -ti
338 # -ta
339 # -tb
340 # -ts
341# Build from .src.(deb|rpm)
342 # --rebuild
343 # --recompile
344
345# General options
346 # --buildroot=DIRECTORY
347 # --clean
348 # --nobuild
349 # --nodeps
350 # --nodirtokens
351 # --rmsource
352 # --rmspec
353 # --short-circuit
354 # --target=CPU-VENDOR-OS
355
356 #my $popt = new Getopt::Popt(argv => \@ARGV, options => \@optionsTable);
357
358} # end parse_cmd()
359
360
361## parse_spec()
362# Parse the .spec file.
363sub parse_spec {
364 open SPECFILE,"<$specfile";
365
366LINE: while (<SPECFILE>) {
367 next if /^#/; # Ignore comments...
368 next if /^\s+$/; # ... and blank lines.
369
370 if (/^\%/) {
371 # A macro that needs further processing.
372
373 if (/^\%define\s+([^\s]+)\s+([^\s]+)/) {
374 $specglobals{$1} = expandmacros($2,'g');
375 }
376
377 if (/^\%description(?:\s+(?:-n\s+)?([a-zA-Z0-9_.-]+))?/) {
378 my $subname = "main";
379 if ($1) {
380 my $tmp = $1;
381 if (/-n/) { $subname = $tmp; } else { $subname = "$pkgdata{main}{name}-$tmp"; }
382 }
383 while (<SPECFILE>) {
384 next if /^#/; # Messy. Should be possible to do better. :/
385 redo LINE if /^\%/;
386 $pkgdata{$subname}{desc} .= " $_";
387 }
388 }
389 if (/^\%package\s+(?:-n\s+)?([a-zA-Z0-9_.-]+)/) {
390 my $subname = $1;
391 if (! /-n/) { $subname = "$pkgdata{main}{name}-$1"; }
392 push @pkglist, $subname;
393 $pkgdata{$subname}{name} = $subname;
394 $pkgdata{$subname}{version} = $pkgdata{main}{version};
395 while (<SPECFILE>) {
396 redo LINE if /^\%/;
397 if (my ($dname,$dvalue) = (/^(Summary|Group|Version|Requires|Provides):\s+(.+)$/i)) {
398 $dname =~ tr/[A-Z]/[a-z]/;
399 $pkgdata{$subname}{$dname} = $dvalue;
400 }
401 }
402 }
403
404 if (/^\%prep/) {
405 # %prep section. May have %setup macro; may include %patch tags,
406 # may be just a bare shell script.
407
408 # This really should be local-ish, but we need just the filename for the source
409 $pkgdata{main}{source} =~ s|.+/([^/]+)$|$1|;
410
411 # Replace some core macros
412 $pkgdata{main}{source} = expandmacros($pkgdata{main}{source},'gp');
413
414PREPSCRIPT: while (<SPECFILE>) {
415 if (/^\%setup/) {
416 # Parse out the %setup macro. Note that we aren't supporting
417 # many of RPM's %setup features.
418 $prepscript .= "cd $topdir/BUILD\n";
419 if ( /\s+-n\s+([^\s]+)\s+/ ) {
420 $tarballdir = $1;
421 } else {
422 $tarballdir = "$pkgdata{main}{name}-$pkgdata{main}{version}";
423 }
424 $prepscript .= "rm -rf $tarballdir\ntar -".
425 ( $pkgdata{main}{source} =~ /\.tar\.gz$/ ? "z" : "" ).
426 ( $pkgdata{main}{source} =~ /\.tar\.bz2$/ ? "j" : "" ).
427 ( /\s+-q\s+/ ? '' : 'vv' )."xf ".
428 "$topdir/SOURCES/$pkgdata{main}{source}\n".
429 qq(STATUS=\$?\nif [ \$STATUS -ne 0 ]; then\n exit \$STATUS\nfi\n).
430 ( /\s+-n\s+([^\s]+)\s+/ ?
431 "cd $1\n" : "cd $pkgdata{main}{name}-$pkgdata{main}{version}\n" ).
432 qq([ `/usr/bin/id -u` = '0' ] && /bin/chown -Rhf root .\n).
433 qq([ `/usr/bin/id -u` = '0' ] && /bin/chgrp -Rhf root .\n).
434 qq(/bin/chmod -Rf a+rX,g-w,o-w .\n);
435 } elsif (/^\%patch([^:]+)\s+(.+)$/) {
436 $prepscript .= "patch $2 <$topdir/SOURCES/".$pkgdata{main}{"patch$1"}."\n";
437 } else {
438 last PREPSCRIPT if /^\%/;
439 $prepscript .= $_;
440 }
441 }
442 redo LINE;
443 }
444 if (/^\%build/) {
445 # %build. This is pretty much just a shell script. There
446 # *are* a few macros, but we're not going to deal with them yet.
447 $buildscript .= "cd $tarballdir\n";
448BUILDSCRIPT: while (<SPECFILE>) {
449 if (/^\%configure/) {
450 $buildscript .= expandmacros($_,'cgbp');
451 } elsif (/^\%\{__make\}/) {
452 $buildscript .= expandmacros($_,'mgbp');
453 } else {
454 last BUILDSCRIPT if /^\%[^{]/;
455 $buildscript .= $_;
456 }
457 }
458 redo LINE;
459 }
460 if (/^\%install/) {
461 $installscript .= "cd $tarballdir\n";
462INSTALLSCRIPT: while (<SPECFILE>) {
463 if (/^\%makeinstall/) {
464 $installscript .= expandmacros($_,'igbp');
465 } else {
466 last INSTALLSCRIPT if /^\%/;
467 $installscript .= $_;
468 }
469 }
470 redo LINE;
471 }
472 if (/^\%clean/) {
473 while (<SPECFILE>) {
474 redo LINE if /^\%/;
475 $cleanscript .= $_;
476 }
477 $cleanscript = expandmacros($cleanscript,'gp');
478 }
479
480 # pre/post (un)install scripts
481 if (/^\%pre\b/) {
482 while (<SPECFILE>) {
483 redo LINE if /^\%/;
484 $preinstscript .= $_;
485 }
486 }
487 if (/^\%post\b/) {
488 while (<SPECFILE>) {
489 redo LINE if /^\%/;
490 $postinstscript .= $_;
491 }
492 }
493 if (/^\%preun\b/) {
494 while (<SPECFILE>) {
495 redo LINE if /^\%/;
496 $preuninstscript .= $_;
497 }
498 }
499 if (/^\%postun\b/) {
500 while (<SPECFILE>) {
501 redo LINE if /^\%/;
502 $postuninstscript .= $_;
503 }
504 }
505 # done %pre/%post scripts
506
507 if (/^\%files(?:\s+(?:-n\s+)?([a-zA-z0-9]+))?/) {
508 my $pkgname = 'main';
509 if ($1) { # Magic to add entries to the right list of files
510 my $tmp = $1;
511 if (/-n/) { $pkgname = $tmp; } else { $pkgname = "$pkgdata{main}{name}-$tmp"; }
512 }
513
514 # Set this now, so it can be flipped a bit later, and used much later.
515 #$pkgdata{$pkgname}{conffiles} = 0;
516
517 while (<SPECFILE>) {
518 chomp;
519 next if /^#/;
520 # need to update this to deal (properly) with %dir, %attr, etc
521 next if /^\%dir/;
522 next if /^\%attr/;
523 next if /^\%defattr/;
524
525 # Debian dpkg doesn't speak "%docdir". Meh.
526 next if /^\%docdir/;
527
528 # Conffiles. Note that Debian and RH have similar, but not
529 # *quite* identical ideas of what constitutes a conffile. Nrgh.
530 if (/^\%config\s+(.+)$/) {
531 $pkgdata{$pkgname}{conffiles} = 1; # Flag it for later
532 my $tmp = $1; # Now we can mangleificationate it. And we probably need to. :/
533 $tmp = expandmacros($tmp, 'gp'); # Expand common macros
534 if ($tmp !~ /\s+/) {
535 # Simplest case, just a file. Whew.
536 push @{$pkgdata{$pkgname}{conflist}}, $tmp;
537 $filelist{$pkgname} .= " $tmp";
538 } else {
539 # Wot? Spaces? That means extra %-macros. Which, for the most part, can be ignored.
540 ($tmp) = ($tmp =~ /.+\s([^\s]+)/); # Strip everything before the last space
541 push @{$pkgdata{$pkgname}{conflist}}, $tmp;
542 $filelist{$pkgname} .= " $tmp";
543 }
544 next;
545 }
546
547 # and finally we can fall through %{_<FHS>}-prefixed locations...
548 if (/^\%\{_/) {
549 $filelist{$pkgname} .= " $_";
550 next;
551 }
552 # EW. Necessary to clear up %define expansions before we exit with redo.
553 $_ = expandmacros $_, 'g';
554
555 # ... unknown or "next section" % directives ...
556 redo LINE if /^\%/;
557
558 # ... and "normal" files
559 $filelist{$pkgname} .= " $_";
560 }
561 $filelist{$pkgname} = expandmacros($filelist{$pkgname}, 'gp');
562 } # done %file section
563
564 if (/^\%changelog/) {
565 $pkgdata{main}{changelog} = '';
566 while (<SPECFILE>) {
567 redo LINE if /^\%/;
568 $pkgdata{main}{changelog} .= $_;
569 }
570 }
571
572 } else { # Data from the spec file "header"
573
574 if (/^summary:\s+(.+)/i) {
575 $pkgdata{main}{summary} = $1;
576 } elsif (/^name:\s+(.+)/i) {
577 $pkgdata{main}{name} = expandmacros($1,'g');
578 } elsif (/^version:\s+(.+)/i) {
579 $pkgdata{main}{version} = expandmacros($1,'g');
580 } elsif (/^release:\s+(.+)/i) {
581 $pkgdata{main}{release} = expandmacros($1,'g');
582 } elsif (/^group:\s+(.+)/i) {
583 $pkgdata{main}{group} = $1;
584 } elsif (/^copyright:\s+(.+)/i) {
585 $pkgdata{main}{copyright} = $1;
586 } elsif (/^url:\s+(.+)/i) {
587 $pkgdata{main}{url} = $1;
588 } elsif (/^packager:\s+(.+)/i) {
589 $pkgdata{main}{packager} = $1;
590 } elsif (/^buildroot:\s+(.+)/i) {
591 $buildroot = $1;
592 } elsif (/^source:\s+(.+)/i) {
593 $pkgdata{main}{source} = $1;
594 die "Unknown tarball format $1\n" if $1 !~ /\.tar\.(?:gz|bz2)$/;
595 } elsif (/^source([0-9]+):\s+(.+)/i) {
596 $pkgdata{sources}{$1} = $2;
597 } elsif (/^patch([^:]+):\s+(.+)$/i) {
598 my $patchname = "patch$1";
599 $pkgdata{main}{$patchname} = $2;
600 if ($pkgdata{main}{$patchname} =~ /\//) {
601 # URL-style patch. Rare but not unheard-of.
602 my @patchbits = split '/', $pkgdata{main}{$patchname};
603 $pkgdata{main}{$patchname} = $patchbits[$#patchbits];
604 }
605 } elsif (/^buildreq(?:uires)?:\s+(.+)/i) {
606 $buildreq .= ", $1";
607 } elsif (/^requires:\s+(.+)/i) {
608 $pkgdata{main}{requires} .= ", $1";
609 } elsif (/^provides:\s+(.+)/i) {
610 $pkgdata{main}{provides} .= ", $1";
611 } elsif (/^conflicts:\s+(.+)/i) {
612 $pkgdata{main}{conflicts} .= ", $1";
613 }
614#Name: suwrap
615#Version: 0.04
616#Release: 3
617#Group: Applications/System
618#Copyright: WebHart internal ONLY. :(
619#BuildArchitectures: i386
620#BuildRoot: /tmp/%{name}-%{version}
621#Url: http://virtual.webhart.net
622#Packager: Kris Deugau <kdeugau@deepnet.cx>
623#Source: ftp://virtual.webhart.net/%{name}-%{version}.tar.gz
624
625 }
626 }
627
628 # Parse and replace some more macros. More will be replaced even later.
629
630 # Expand macros as necessary.
631 $scriptletbase = expandmacros($scriptletbase,'gp');
632
633 $buildroot = $cmdbuildroot if $cmdbuildroot;
634 $buildroot = expandmacros($buildroot,'gp');
635
636 close SPECFILE;
637} # end parse_spec()
638
639
640## prep()
641# Writes and executes the %prep script (mostly) built while reading the spec file.
642sub prep {
643 # Replace some things here just to make sure.
644 $prepscript = expandmacros($prepscript,'gp');
645
646#print $prepscript; exit 0;
647
648 # create script filename
649 my $prepscriptfile = "$tmpdir/deb-tmp.prep.".int(rand(99998)+1);
650 sysopen(PREPSCRIPT, $prepscriptfile, O_RDWR | O_CREAT | O_EXCL | O_NOFOLLOW)
651 or die $!;
652 print PREPSCRIPT $scriptletbase;
653 print PREPSCRIPT $prepscript;
654 close PREPSCRIPT;
655
656 # execute
657 print "Calling \%prep script $prepscriptfile...\n";
658 system("/bin/sh -e $prepscriptfile") == 0
659 or die "Can't exec: $!\n";
660
661 # and clean up
662 unlink $prepscriptfile;
663} # end prep()
664
665
666## build()
667# Writes and executes the %build script (mostly) built while reading the spec file.
668sub build {
669 # Expand the macros
670 $buildscript = expandmacros($buildscript,'cgbp');
671
672 # create script filename
673 my $buildscriptfile = "$tmpdir/deb-tmp.build.".int(rand(99998)+1);
674 sysopen(BUILDSCRIPT, $buildscriptfile, O_RDWR | O_CREAT | O_EXCL | O_NOFOLLOW)
675 or die $!;
676 print BUILDSCRIPT $scriptletbase;
677 print BUILDSCRIPT $buildscript;
678 close BUILDSCRIPT;
679
680 # execute
681 print "Calling \%build script $buildscriptfile...\n";
682 system("/bin/sh -e $buildscriptfile") == 0
683 or die "Can't exec: $!\n";
684
685 # and clean up
686 unlink $buildscriptfile;
687} # end build()
688
689
690## install()
691# Writes and executes the %install script (mostly) built while reading the spec file.
692sub install {
693 # Expand the macros
694 $installscript = expandmacros($installscript,'igbp');
695
696 # create script filename
697 my $installscriptfile = "$tmpdir/deb-tmp.inst.".int(rand(99998)+1);
698 sysopen(INSTSCRIPT, $installscriptfile, O_RDWR | O_CREAT | O_EXCL | O_NOFOLLOW)
699 or die $!;
700 print INSTSCRIPT $scriptletbase;
701# print INSTSCRIPT $cleanscript; # Clean up our install target before installing into it.
702 print INSTSCRIPT $installscript;
703 close INSTSCRIPT;
704
705 # execute
706 print "Calling \%install script $installscriptfile...\n";
707 system("/bin/sh -e $installscriptfile") == 0
708 or die "Can't exec: $!\n";
709
710 # and clean up
711 unlink $installscriptfile;
712} # end install()
713
714
715## binpackage()
716# Creates the binary .deb package from the installed tree in $buildroot.
717# Writes and executes a shell script to do so.
718# Creates miscellaneous files required by dpkg-deb to actually build the package file.
719# Should handle simple subpackages
720sub binpackage {
721 # Make sure we have somewhere to write the .deb file
722 if (!-e "$topdir/DEBS/i386") {
723 mkdir "$topdir/DEBS/i386";
724 }
725
726 foreach my $pkg (@pkglist) {
727
728 # Gotta do this first, otherwise we don't have a place to move files from %files
729 mkdir "$buildroot/$pkg";
730
731 # Eliminate any lingering % macros
732 $filelist{$pkg} = expandmacros $filelist{$pkg}, 'g';
733
734 my @pkgfilelist = split ' ', $filelist{$pkg};
735 foreach my $pkgfile (@pkgfilelist) {
736 $pkgfile = expandmacros($pkgfile, 'gp');
737 my ($fpath,$fname) = ($pkgfile =~ m|(.+?/?)?([^/]+)$|); # We don't need $fname now, but we might.
738 qx { mkdir -p $buildroot/$pkg$fpath }
739 if $fpath && $fpath ne '';
740 qx { mv $buildroot$pkgfile $buildroot/$pkg$fpath };
741 }
742
743 # Get the "Depends" (Requires) a la RPM. Ish. We strip the leading
744 # comma and space here (if needed) in case there were "Requires" specified
745 # in the spec file - those would precede these.
746 ($pkgdata{$pkg}{requires} .= getreqs("$buildroot/$pkg")) =~ s/^, //;
747
748 # Do this here since we're doing {depends}...
749 if (defined($pkgdata{$pkg}{provides})) {
750 $pkgdata{$pkg}{provides} =~ s/^, //;
751 $pkgdata{$pkg}{provides} = expandmacros($pkgdata{$pkg}{provides},'gp');
752 }
753 if (defined($pkgdata{$pkg}{conflicts})) {
754 $pkgdata{$pkg}{conflicts} =~ s/^, //;
755 $pkgdata{$pkg}{conflicts} = expandmacros($pkgdata{$pkg}{conflicts},'gp');
756 }
757
758 # Gotta do this next, otherwise the control file has nowhere to go. >:(
759 mkdir "$buildroot/$pkg/DEBIAN";
760
761 # Hack the filename for the package into a Debian-tool-compatible format. GRRRRRR!!!!!
762 # Have I mentioned I hate Debian Policy?
763 $pkgdata{$pkg}{name} =~ tr/_/-/;
764
765 # create script filename
766 my $debscriptfile = "$tmpdir/deb-tmp.pkg.".int(rand(99998)+1);
767 sysopen(DEBSCRIPT, $debscriptfile, O_RDWR | O_CREAT | O_EXCL | O_NOFOLLOW)
768 or die $!;
769 print DEBSCRIPT $scriptletbase;
770 print DEBSCRIPT "fakeroot dpkg-deb -b $buildroot/$pkg $topdir/DEBS/i386/".
771 "$pkgdata{$pkg}{name}_$pkgdata{$pkg}{version}-$pkgdata{main}{release}_i386.deb\n";
772 # %$&$%@#@@#%@@@ Debian and their horrible ugly package names. >:(
773 close DEBSCRIPT;
774
775 my $control = "Package: $pkgdata{$pkg}{name}\n".
776 "Version: $pkgdata{$pkg}{version}-$pkgdata{main}{release}\n".
777 "Section: $pkgdata{$pkg}{group}\n".
778 "Priority: optional\n".
779 "Architecture: i386\n".
780 "Maintainer: $pkgdata{main}{packager}\n".
781 ( $pkgdata{$pkg}{requires} ne '' ? "Depends: $pkgdata{$pkg}{requires}\n" : '' ).
782 ( defined($pkgdata{$pkg}{provides}) ? "Provides: $pkgdata{$pkg}{provides}\n" : '' ).
783 ( defined($pkgdata{$pkg}{conflicts}) ? "Conflicts: $pkgdata{$pkg}{conflicts}\n" : '' ).
784 "Description: $pkgdata{$pkg}{summary}\n";
785 $control .= "$pkgdata{$pkg}{desc}\n";
786
787 open CONTROL, ">$buildroot/$pkg/DEBIAN/control";
788 print CONTROL $control;
789 close CONTROL;
790
791 # Iff there are conffiles (as specified in the %files list(s), add'em
792 # in so dpkg-deb can tag them.
793 if ($pkgdata{$pkg}{conffiles}) {
794 open CONFLIST, ">$buildroot/$pkg/DEBIAN/conffiles";
795 foreach my $conffile (@{$pkgdata{$pkg}{conflist}}) {
796 print CONFLIST "$conffile\n";
797 }
798 close CONFLIST;
799 }
800
801 # Can't see much point in scripts on subpackages... although since
802 # it's *possible* I should support it at some point.
803 if ($pkg eq 'main') {
804 if ($preinstscript ne '') {
805 $preinstscript = expandmacros($preinstscript,'g');
806 open PREINST, ">$buildroot/$pkg/DEBIAN/preinst";
807 print PREINST "#!/bin/sh\nset -e\n\n";
808 print PREINST $preinstscript;
809 close PREINST;
810 `chmod 0755 $buildroot/$pkg/DEBIAN/preinst`;
811 }
812 if ($postinstscript ne '') {
813 $postinstscript = expandmacros($postinstscript,'g');
814 open POSTINST, ">$buildroot/$pkg/DEBIAN/postinst";
815 print POSTINST "#!/bin/sh\nset -e\n\n";
816 print POSTINST $postinstscript;
817 close POSTINST;
818 `chmod 0755 $buildroot/$pkg/DEBIAN/postinst`;
819 }
820 if ($preuninstscript ne '') {
821 $preuninstscript = expandmacros($preuninstscript,'g');
822 open PREUNINST, ">$buildroot/$pkg/DEBIAN/prerm";
823 print PREUNINST "#!/bin/sh\nset -e\n\n";
824 print PREUNINST $preuninstscript;
825 close PREUNINST;
826 `chmod 0755 $buildroot/$pkg/DEBIAN/prerm`;
827 }
828 if ($postuninstscript ne '') {
829 $postuninstscript = expandmacros($postuninstscript,'g');
830 open POSTUNINST, ">$buildroot/$pkg/DEBIAN/postrm";
831 print POSTUNINST "#!/bin/sh\nset -e\n\n";
832 print POSTUNINST $postuninstscript;
833 close POSTUNINST;
834 `chmod 0755 $buildroot/$pkg/DEBIAN/postrm`;
835 }
836 }
837
838 # execute
839 print "Calling package creation script $debscriptfile for $pkgdata{$pkg}{name}...\n";
840 system("/bin/sh -e $debscriptfile") == 0
841 or die "Can't exec: $!\n";
842
843 # and clean up
844 unlink $debscriptfile;
845
846 } # subpackage loop
847
848} # end binpackage()
849
850
851## srcpackage()
852# Builds a .src.deb source package. Note that Debian's idea of
853# a "source package" is seriously flawed IMO, because you can't
854# easily copy it as-is.
855# Not quite identical to RPM, but Good Enough (TM).
856sub srcpackage {
857 # In case we were called with -bs.
858 $pkgdata{main}{name} =~ tr/_/-/;
859 my $pkgsrcname = "$pkgdata{main}{name}-$pkgdata{main}{version}-$pkgdata{main}{release}.sdeb";
860
861 my $paxcmd;
862
863 # We'll definitely need this later, and *may* need it sooner.
864 (my $barespec = $specfile) =~ s|.+/([^/]+)$|$1|;
865
866 # Copy the specfile to the build tree, but only if it's not there already.
867##buglet: need to deal with silly case where silly user has put the spec
868# file in a subdir of %{_topdir}/SPECS. Ewww. Silly user!
869 if (abs_path($specfile) !~ /^$topdir\/SPECS/) {
870 $paxcmd .= "cp $specfile %{_topdir}/SPECS/; \n"
871 }
872
873 # use pax -w [file] [file] ... >outfile.sdeb
874 $paxcmd = "cd $topdir; pax -w ";
875
876# tweak source entry into usable form. Need it locally somewhere along the line.
877 (my $pkgsrc = $pkgdata{main}{source}) =~ s|.+/([^/]+)$|$1|;
878 $paxcmd .= "SOURCES/$pkgsrc ";
879
880 # create file list: Source[nn], Patch[nn]
881 foreach my $specbit (keys %{$pkgdata{main}} ) {
882 next if $specbit eq 'source';
883 $paxcmd .= "SOURCES/$pkgdata{main}{$specbit} " if $specbit =~ /^patch/;
884##buglet: need to deal with case where patches are listed as URLs?
885# or other extended pathnames? Silly !@$%^&!%%!%!! user!
886 }
887
888 foreach my $source (keys %{$pkgdata{sources}}) {
889 $paxcmd .= "SOURCES/$pkgdata{sources}{$source} ";
890 }
891
892 # add the spec file, source package destination, and cd back where we came from.
893 $paxcmd .= "SPECS/$barespec > $topdir/SDEBS/$pkgsrcname; cd -";
894
895 # In case of %-macros...
896 $paxcmd = expandmacros($paxcmd,'gp');
897
898 system "$paxcmd";
899 print "Wrote source package $pkgsrcname in $topdir/SDEBS.\n";
900}
901
902
903## checkbuildreq()
904# Checks the build requirements (if any)
905# Spits out a rude warning and returns a true-false error if any
906# requirements are not met.
907sub checkbuildreq {
908 return 1 if $buildreq eq ''; # No use doing extra work.
909
910 if ( ! -e "/usr/bin/dpkg-query" ) {
911 print "**WARNING** dpkg-query not found. Can't check build-deps.\n".
912 " Required for sucessful build:\n".$buildreq."\n".
913 " Continuing anyway.\n";
914 return 1;
915 }
916
917 my $reqflag = 1; # unset iff a buildreq is missing
918
919 $buildreq =~ s/^, //; # Strip the leading comma and space
920 my @reqlist = split /,\s+/, $buildreq;
921
922 foreach my $req (@reqlist) {
923 my ($pkg,$rel,$ver);
924
925 # We have two classes of requirements - versioned and unversioned.
926 if ($req =~ /[><=]/) {
927 # Pick up the details of versioned buildreqs
928 ($pkg,$rel,$ver) = ($req =~ /([a-z0-9._-]+)\s+([><=]+)\s+([a-z0-9._-]+)/);
929 } else {
930 # And the unversioned ones.
931 $pkg = $req;
932 $rel = '>=';
933 $ver = 0;
934 }
935
936 my @pkglist = qx { dpkg-query --showformat '\${status}\t\${version}\n' -W $pkg };
937# need to check if no lines returned - means a bad buildreq
938 my ($reqstat,undef,undef,$reqver) = split /\s+/, $pkglist[0];
939 if ($reqstat !~ /install/) {
940 print " * Missing build-dependency $pkg!\n";
941 $reqflag = 0;
942 } else {
943# gotta be a better way to do this... :/
944 if ($rel eq '>=' && !($reqver ge $ver)) {
945 print " * Buildreq $pkg is installed, but wrong version ($reqver): Need $ver\n";
946 $reqflag = 0;
947 }
948 if ($rel eq '>' && !($reqver gt $ver)) {
949 print " * Buildreq $pkg is installed, but wrong version ($reqver): Need $ver\n";
950 $reqflag = 0;
951 }
952 if ($rel eq '<=' && !($reqver le $ver)) {
953 print " * Buildreq $pkg is installed, but wrong version ($reqver): Need $ver\n";
954 $reqflag = 0;
955 }
956 if ($rel eq '<' && !($reqver lt $ver)) {
957 print " * Buildreq $pkg is installed, but wrong version ($reqver): Need $ver\n";
958 $reqflag = 0;
959 }
960 if ($rel eq '=' && !($reqver eq $ver)) {
961 print " * Buildreq $pkg is installed, but wrong version ($reqver): Need $ver\n";
962 $reqflag = 0;
963 }
964 } # end not installed/installed check
965 } # end req loop
966
967 return $reqflag;
968} # end checkbuildreq()
969
970
971## getreqs()
972# Find out which libraries/packages are required for any
973# executables and libs in a given file tree.
974# (Debian doesn't have soname-level deps; just package-level)
975# Returns an empty string if the tree contains no binaries.
976# Doesn't work well on shell scripts. but those *should* be
977# fine anyway. (Yeah, right...)
978sub getreqs() {
979 my $pkgtree = $_[0];
980
981 print "Checking library requirements...\n";
982 my @binlist = qx { find $pkgtree -type f -perm 755 };
983
984 if (scalar(@binlist) == 0) {
985 return '';
986 }
987
988 my @reqlist;
989 foreach (@binlist) {
990 push @reqlist, qx { ldd $_ };
991 }
992
993 # Get the list of libs provided by this package. Still doesn't
994 # handle the case where the lib gets stuffed into a subpackage. :/
995 my @intprovlist = qx { find $pkgtree -type f -name "*.so*" };
996 my $provlist = '';
997 foreach (@intprovlist) {
998 s/$pkgtree//;
999 $provlist .= "$_";
1000 }
1001
1002 my %reqs;
1003 my $reqlibs = '';
1004
1005 foreach (@reqlist) {
1006 next if /^$pkgtree/;
1007 next if /not a dynamic executable/;
1008 next if m|/lib/ld-linux.so|; # Hack! Hack! PTHBTT! (libc suxx0rz)
1009
1010 my ($req) = (/^\s+([a-z0-9._-]+)/); # dig out the actual library (so)name
1011
1012 # Ignore libs provided by this package. Note that we don't match
1013 # on word-boundary at the *end* of the lib we're looking for, as the
1014 # looked-for lib may not have the full soname version. (ie, it may
1015 # "just" point to one of the symlinks that get created somewhere.)
1016 next if $provlist =~ /\b$req/;
1017
1018 $reqlibs .= " $req";
1019 }
1020
1021 if ($reqlibs ne '') {
1022 foreach (qx { dpkg -S $reqlibs }) {
1023 my ($libpkg,undef) = split /:\s+/;
1024 $reqs{$libpkg} = 1;
1025 }
1026 }
1027
1028 my $deplist = '';
1029 foreach (keys %reqs) {
1030 $deplist .= ", $_";
1031 }
1032
1033# For now, we're done. We're not going to meddle with versions yet.
1034# Among other things, it's messier than handling "simple" yes/no "do
1035# we have this lib?" deps. >:(
1036
1037 return $deplist;
1038} # end getreqs()
1039
1040
1041## install_sdeb()
1042# Extracts .sdeb contents to %_topdir as appropriate
1043sub install_sdeb {
1044 my $paxcmd = "cd $topdir; pax -r <$srcpkg; cd -";
1045
1046 # In case of %-macros...
1047 $paxcmd = expandmacros($paxcmd,'gp');
1048
1049 system "$paxcmd";
1050 print "Extracted source package $srcpkg to $topdir.\n";
1051} # end install_sdeb()
1052
1053
1054## expandmacros()
1055# Expands all %{blah} macros in the passed string
1056# Split up a bit with some sections so we don't spend time trying to
1057# expand macros that are only used in a few specific places.
1058sub expandmacros {
1059 my $macrostring = shift;
1060 my $section = shift;
1061
1062 # To allow the FHS-ish %configure and %makeinstall to work The Right Way.
1063 # (Without clobbering the global $buildroot.)
1064 my $prefix = '';
1065
1066 if ($section =~ /c/) {
1067 # %configure macro
1068# Don't know what it's for, don't have a useful default replacement
1069# --program-prefix=%{_program_prefix} \
1070 $macrostring =~ s'%configure'./configure --host=$DEB_HOST_GNU_TYPE \
1071 --build=$DEB_BUILD_GNU_TYPE \
1072 --prefix=%{_prefix} \
1073 --exec-prefix=%{_exec_prefix} \
1074 --bindir=%{_bindir} \
1075 --sbindir=%{_sbindir} \
1076 --sysconfdir=%{_sysconfdir} \
1077 --datadir=%{_datadir} \
1078 --includedir=%{_includedir} \
1079 --libdir=%{_libdir} \
1080 --libexecdir=%{_libexecdir} \
1081 --localstatedir=%{_localstatedir} \
1082 --sharedstatedir=%{_sharedstatedir} \
1083 --mandir=%{_mandir} \
1084 --infodir=%{_infodir} ';
1085 } # done %configure
1086
1087 if ($section =~ /m/) {
1088 $macrostring =~ s'%{__make}'make ';
1089 } # done make
1090
1091 if ($section =~ /i/) {
1092 # This is where we need to mangle $prefix.
1093 $macrostring =~ s'%makeinstall'make %{fhs} install';
1094 $prefix = $buildroot;
1095 } # done %install and/or %makeinstall
1096
1097 # Build data
1098 # Note that these are processed in reverse order to get the substitution order right
1099 if ($section =~ /b/) {
1100# $macrostring =~ s'%{fhs}'host=$DEB_HOST_GNU_TYPE \
1101# build=$DEB_BUILD_GNU_TYPE \
1102 $macrostring =~ s'%{fhs}'prefix=%{_prefix} \
1103 exec-prefix=%{_exec_prefix} \
1104 bindir=%{_bindir} \
1105 sbindir=%{_sbindir} \
1106 sysconfdir=%{_sysconfdir} \
1107 datadir=%{_datadir} \
1108 includedir=%{_includedir} \
1109 libdir=%{_libdir} \
1110 libexecdir=%{_libexecdir} \
1111 localstatedir=%{_localstatedir} \
1112 sharedstatedir=%{_sharedstatedir} \
1113 mandir=%{_mandir} \
1114 infodir=%{_infodir} \
1115';
1116
1117 # Note that the above regex terminates with the extra space
1118 # "Just In Case" of user additions, which will then get neatly
1119 # tagged on the end where they take precedence (supposedly)
1120 # over the "default" ones.
1121
1122 # Now we cascade the macros introduced above. >_<
1123 # Wot ot to go theah:
1124 $macrostring =~ s|%{_mandir}|%{_datadir}/man|g; #/usr/share/man
1125 $macrostring =~ s|%{_infodir}|%{_datadir}/info|g; #/usr/share/info
1126 $macrostring =~ s|%{_oldincludedir}|/usr/include|g; #/usr/include
1127 $macrostring =~ s|%{_includedir}|%{_prefix\}/include|g; #/usr/include
1128 $macrostring =~ s|%{_libdir}|%{_exec_prefix}/%{_lib}|g; #/usr/lib
1129 $macrostring =~ s|%{_lib}|lib|g; #?
1130 $macrostring =~ s|%{_localstatedir}|/var|g; #/var
1131 $macrostring =~ s|%{_sharedstatedir}|%{_prefix}/com|g; #/usr/com WTF?
1132 $macrostring =~ s|%{_sysconfdir}|/etc|g; #/etc
1133 $macrostring =~ s|%{_datadir}|%{_prefix}/share|g; #/usr/share
1134 $macrostring =~ s|%{_libexecdir}|%{_exec_prefix}/libexec|g; #/usr/libexec
1135 $macrostring =~ s|%{_sbindir}|%{_exec_prefix}/sbin|g; #/usr/sbin
1136 $macrostring =~ s|%{_bindir}|%{_exec_prefix}/bin|g; #/usr/bin
1137 $macrostring =~ s|%{_exec_prefix}|%{_prefix}|g; #/usr
1138 $macrostring =~ s|%{_prefix}|/usr|g; #/usr
1139 } # done with config section
1140
1141 # Package data
1142 if ($section =~ /p/) {
1143 $macrostring =~ s/\%\{buildroot\}/$buildroot/gi;
1144 foreach my $source (keys %{$pkgdata{sources}}) {
1145 $macrostring =~ s/\%\{source$source\}/$topdir\/SOURCES\/$pkgdata{sources}{$source}/gi;
1146 }
1147 $macrostring =~ s/\%\{name\}/$pkgdata{main}{name}/gi;
1148 $macrostring =~ s/\%\{version\}/$pkgdata{main}{version}/gi;
1149 $macrostring =~ s/\%\{release\}/$pkgdata{main}{release}/gi;
1150 }
1151
1152 # Globals, and not-so-globals
1153 if ($section =~ /g/) {
1154 $macrostring =~ s|%{_builddir}|%{_topdir}/BUILD|g;
1155 $macrostring =~ s|%{_topdir}|$topdir|g;
1156 $macrostring =~ s|%{_tmppath}|$tmpdir|g;
1157 $macrostring =~ s'%{_docdir}'/usr/share/doc'g;
1158
1159 # Standard FHS locations. More or less.
1160 $macrostring =~ s'%{_bindir}'/usr/bin'g;
1161 $macrostring =~ s'%{_sbindir}'/usr/sbin'g;
1162 $macrostring =~ s'%{_mandir}'/usr/share/man'g;
1163 $macrostring =~ s'%{_includedir}'/usr/include'g;
1164 $macrostring =~ s'%{_libdir}'/usr/lib'g;
1165 $macrostring =~ s'%{_sysconfdir}'/etc'g;
1166 $macrostring =~ s'%{_localstatedir}'/var'g;
1167
1168 # %define's
1169 foreach my $key (keys %specglobals) {
1170 $macrostring =~ s|%{$key}|$specglobals{$key}|g;
1171 }
1172
1173 # system programs. RPM uses a global config file for these; we'll just
1174 # ASS-U-ME and make life a little simpler.
1175 if ($macrostring =~ /\%\{\_\_([a-z0-9_-]+)\}/) {
1176 $macrostring =~ s|%{__([a-z0-9_-]+)}|$1|g;
1177 }
1178 } # done with globals section
1179
1180 return $macrostring;
1181} # end expandmacros()
1182
1183
1184
1185__END__
1186
1187
1188
1189=head1 NAME
1190
1191debbuild - Build Debian-compatible packages from RPM spec files
1192
1193=head1 SYNOPSIS
1194
1195 debbuild {-ba|-bb|-bp|-bc|-bi|-bl|-bs} [build-options] file.spec
1196
1197 debbuild {-ta|-tb|-tp|-tc|-ti|-tl|-ts} [build-options] file.tar.{gz|bz2}
1198
1199 debbuild --rebuild file.{src.rpm|sdeb}
1200
1201=head1 DESCRIPTION
1202
1203This script attempts to build Debian-friendly semi-native packages from RPM spec files,
1204RPM-friendly tarballs, and RPM source packages (.src.rpm files). It accepts I<most> of the
1205options rpmbuild does, and should be able to interpret most spec files usefully. Perl
1206modules should be handled via CPAN+dh-make-perl instead; Debian's conventions for such
1207things do not lend themselves to automated conversion.
1208
1209As far as possible, the command-line options are identical to those from rpmbuild, although
1210several rpmbuild options are not supported:
1211
1212 --recompile
1213 --showrc
1214 --buildroot
1215 --clean
1216 --nobuild
1217 --rmsource
1218 --rmspec
1219 --sign
1220 --target
1221
1222Some of these could probably be trivially added. Feel free to send me a patch. ;)
1223
1224Complex spec files will most likely not work well, if at all. Rewrite them from scratch -
1225you'll have to make heavy modifications anyway.
1226
1227If you see something you don't like, mail me. Send a patch if you feel inspired. I don't
1228promise I'll do anything other than say "Yup, that's broken" or "Got your message".
1229
1230=head1 ASSUMPTIONS
1231
1232As with rpmbuild, debbuild makes some assumptions about your system.
1233
1234=over 4
1235
1236=item *
1237
1238Either you have rights to do as you please under /usr/src/debian, or you have created a file
1239~/.debmacros containing a suitable %_topdir definition.
1240
1241Both rpmbuild and debbuild require the directories %_topdir/{BUILD,SOURCES,SPECS}. However,
1242where rpmbuild requires the %_topdir/{RPMS,SRPMS} directories, debbuild
1243requires %_topdir/{DEBS,SDEBS} instead. Create them in advance;
1244some subdirectories are created automatically as needed, but most are not.
1245
1246=item *
1247
1248/var/tmp must allow script execution - rpmbuild and debbuild both rely on creating and
1249executing shell scripts for much of their functionality. By default, debbuild also creates
1250install trees under /var/tmp - however this is (almost) entirely under the control of the
1251package's .spec file.
1252
1253=item *
1254
1255If you wish to --rebuild a .src.rpm, your %_topdir for both debbuild and rpmbuild must either
1256match, or be suitably symlinked one direction or another so that both programs are effectively
1257working in the same tree. (Or you could just manually wrestle files around your system.)
1258
1259You could symlink ~/.rpmmacros to ~/.debmacros (or vice versa) and save yourself some hassle
1260if you need to rebuild .src.rpm packages on a regular basis. Currently debbuild only uses the
1261%_topdir macro definition, although there are many more things that rpmbuild can use from
1262~/.rpmmacros.
1263
1264=back
1265
1266=head1 AUTHOR
1267
1268debbuild was written by Kris Deugau <kdeugau@deepnet.cx>. A version that approximates
1269current is available at http://www.deepnet.cx/debbuild/.
1270
1271=head1 BUGS
1272
1273Funky Things Happen if you forget a command-line option or two. I've been too lazy to bother
1274fixing this.
1275
1276Many macro expansions are unsupported or incompletely supported.
1277
1278The generated scriptlets don't quite match those from rpmbuild exactly. There are extra
1279environment variables and preprocessing that I haven't needed (yet).
1280
1281Dcumentation, such as it is, will likely remain perpetually out of date.
1282
1283%_topdir and the five "working" directories under %_topdir could arguably be created by
1284debbuild. However, rpmbuild doesn't create these directories either.
1285
1286=head1 SEE ALSO
1287
1288rpm(8), rpmbuild(8), and pretty much any document describing how to write a .spec file.
1289
1290=cut
Note: See TracBrowser for help on using the repository browser.