source: trunk/debbuild@ 25

Last change on this file since 25 was 25, checked in by kdeugau, 19 years ago

/trunk

Checkpoint

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