source: trunk/debbuild@ 6

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

/trunk

Checkpoint

  • Property svn:executable set to *
  • Property svn:keywords set to Date Rev Author
File size: 10.2 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-10-31 22:58:40 +0000 (Mon, 31 Oct 2005) $
9# SVN revision $Rev: 6 $
10# Last update by $Author: kdeugau $
11###
12
13use strict;
14use warnings;
15
16# Program flow:
17# -> Parse/execute "system" config/macros (if any - should be rare)
18# -> Parse/execute "user" config/macros (if any - *my* requirement is %_topdir)
19# -> Parse command line for options, spec file/tarball/.src.deb (NB - also accept .src.rpm)
20
21# User's prefs for dirs, environment, etc,etc,etc.
22# config file ~/.debmacros
23# Default ordered search paths for config/macros:
24# /usr/lib/rpm/rpmrc /usr/lib/rpm/redhat/rpmrc /etc/rpmrc ~/.rpmrc
25# /usr/lib/rpm/macros /usr/lib/rpm/redhat/macros /etc/rpm/macros ~/.rpmmacros
26# **NOTE: May be possible to (ab)use bits of debhelper
27
28# Build tree
29# default is /usr/src/debian/{BUILD,SOURCES,SPECS,DEBS,SDEBS}
30
31# Globals
32my $specfile;
33my $tarball;
34my $srcpkg;
35
36# Initialized globals
37my $verbosity = 0;
38my %cmdopts = (type => '',
39 stage => 'a',
40 short => 'n'
41 );
42my $topdir = "/usr/src/debian";
43
44# "Constants"
45my %targets = ('p' => 'Prep',
46 'c' => 'Compile',
47 'i' => 'Install',
48 'l' => 'Verify %files',
49 'a' => 'Build binary and source',
50 'b' => 'Build binary',
51 's' => 'Build source'
52 );
53my $scriptletbase =
54q(#!/bin/sh
55
56 RPM_SOURCE_DIR="%{_topdir}/SOURCES"
57 RPM_BUILD_DIR="%{_topdir}/BUILD"
58 RPM_OPT_FLAGS="-O2 -g -march=i386 -mcpu=i686"
59 RPM_ARCH="i386"
60 RPM_OS="linux"
61 export RPM_SOURCE_DIR RPM_BUILD_DIR RPM_OPT_FLAGS RPM_ARCH RPM_OS
62 RPM_DOC_DIR="/usr/share/doc"
63 export RPM_DOC_DIR
64 RPM_PACKAGE_NAME="%{name}"
65 RPM_PACKAGE_VERSION="%{version}"
66 RPM_PACKAGE_RELEASE="%{release}"
67 export RPM_PACKAGE_NAME RPM_PACKAGE_VERSION RPM_PACKAGE_RELEASE
68 RPM_BUILD_ROOT="%{buildroot}"
69 export RPM_BUILD_ROOT
70
71 set -x
72 umask 022
73 cd %{_topdir}/BUILD
74);
75
76# Package data
77# This is the form of $pkgdata{pkgname}{meta}
78# meta includes Summary, Name, Version, Release, Group, Copyright,
79# Source, URL, Packager, BuildRoot, Description
80# 10/31/2005 Maybe this should be flatter? -kgd
81my %pkgdata;
82
83# Scriptlets
84my $prepscript;
85my $buildscript;
86my $installscript;
87
88# Functions
89sub prep;
90sub parse_spec;
91
92die "Not enough arguments\n" if #$argv == 0;
93
94load_userconfig();
95parse_cmd();
96
97# Hokay. Need to:
98# Execute prep if *not* --short-circuit
99prep() if ($cmdopts{short} ne 'y');
100
101if ($cmdopts{stage} =~ /ciab/) {
102 # Execute build if bc
103 # Execute build if bi, ba, bb and NOT --short-circuit
104 build() if ( ($cmdopts{stage} eq 'c') ||
105 (($cmdopts{stage} =~ /iab/) && ($cmdopts{short} ne 'y'))
106 );
107
108 # -> Execute
109 install() if ($cmdopts{short} ne 'y');
110 binpackage();
111}
112
113srcpackage();
114
115
116
117# Just in case.
118exit 0;
119
120
121## load_userconfig()
122# Loads user configuration (if any)
123# Currently only handles .debmacros
124# Needs to handle "other files"
125sub load_userconfig {
126 my (undef,undef,undef,undef,undef,undef,undef,$homedir,undef) = getpwuid($<);
127 if (-e "$homedir/.debmacros") {
128 open USERMACROS,"<$homedir/.debmacros";
129 while (<USERMACROS>) {
130 # And we also only handle the %_topdir macro at the moment.
131 if (/^\%_topdir/) {
132 my (undef,$tmp) = split /\s+/, $_;
133 $topdir = $tmp;
134 }
135 }
136 }
137} # end load_userconfig()
138
139
140## parse_cmd()
141# Parses command line into global hash %cmdopts, other globals
142# Options based on rpmbuild's options
143sub parse_cmd {
144 # Don't feel like coding my own option parser...
145 #use Getopt::Long;
146 # ... but I may have to: (OTOH, rpm uses popt, so maybe we can too.)
147 #use Getopt::Popt qw(:all);
148 # Or not. >:( Stupid Debian lack of findable Perl module names in packages.
149
150 # Stuff it.
151 my $prevopt = '';
152 foreach (@ARGV) {
153 chomp;
154 $prevopt = $_;
155 # Is it an option?
156 if (/^-/) {
157 # Is it a long option?
158 if (/^--/) {
159 if (/^--short-circuit/) {
160 $cmdopts{short} = 'y';
161 } elsif (/^--rebuild/) {
162 $cmdopts{type} = 's';
163 } else {
164 print "Long opt $_\n";
165 }
166 } else {
167 if (/^-[bt]/) {
168 if ($cmdopts{stage} eq 's') {
169 # Mutually exclusive options.
170 die "Can't use $_ with --rebuild\n";
171 } else {
172 ($cmdopts{stage}) = (/^-[bt]([pcilabs])/);
173 ($cmdopts{type}) = (/^-([bt])[pcilabs]/);
174 }
175 } elsif (/^-v/) {
176 # bump verbosity. Not sure what I'll actually do here...
177 } else {
178 die "Bad option $_\n";
179 }
180 }
181 } else {
182 # --buildroot is the only option that takes an argument
183 # Therefore, any *other* bare arguments are the spec file,
184 # tarball, or source package we're operating on - depending
185 # on which one we meet.
186 if ($prevopt eq '--buildroot') {
187 # Set buildroot
188 } else {
189 if ($cmdopts{type} eq 's') {
190 # Source package
191 if (!/\.src\.(deb|rpm)$/) {
192 die "Can't --rebuild with $_\n";
193 }
194 } elsif ($cmdopts{type} eq 'b') {
195 $specfile = $_;
196 # Spec file
197 } else {
198 # Tarball
199 }
200 }
201 }
202 }
203
204 # Some cross-checks. rpmbuild limits --short-circuit to just
205 # the "compile" and "install" targets - with good reason IMO.
206 # NB - this is NOT fatal, just ignored!
207 if ($cmdopts{short} eq 'y') {
208 warn "Can't use --short-circuit for $targets{$cmdopts{stage}} stage. Ignoring.\n";
209 $cmdopts{short} = 'n';
210 }
211 # Valid options, with example arguments (if any):
212# Build from .spec file; mutually exclusive:
213 # -bp
214 # -bc
215 # -bi
216 # -bl
217 # -ba
218 # -bb
219 # -bs
220# Build from tarball; mutually exclusive:
221 # -tp
222 # -tc
223 # -ti
224 # -ta
225 # -tb
226 # -ts
227# Build from .src.(deb|rpm)
228 # --rebuild
229 # --recompile
230
231# General options
232 # --buildroot=DIRECTORY
233 # --clean
234 # --nobuild
235 # --nodeps
236 # --nodirtokens
237 # --rmsource
238 # --rmspec
239 # --short-circuit
240 # --target=CPU-VENDOR-OS
241
242 #my $popt = new Getopt::Popt(argv => \@ARGV, options => \@optionsTable);
243
244} # end parse_cmd()
245
246
247## prep()
248# Unpacks the tarball from the SOURCES directory to the BUILD directory.
249# Speaks gzip and bzip2.
250# Finishes by applying patches in %prep section of spec file
251sub prep {
252 if ($cmdopts{type} eq 'b') {
253 # Need to read the spec file to find the tarball
254 parse_spec();
255
256 # Need to find the filename part of the tarball. In theory, we
257 # could go out to the URL and retrieve it, but that's Messy.
258# want to make this local
259 $pkgdata{main}{source} =~ s|.+/([^/]+)$|$1|;
260
261 if ($pkgdata{main}{source} =~ /(.+)\.tar\.gz$/) {
262 -e "$topdir/BUILD/$1" && system "rm -rf $topdir/BUILD/$1";
263# system "cd $topdir/BUILD;tar -zxvvf $topdir/SOURCES/$pkgdata{main}{source}";
264 } elsif ($pkgdata{main}{source} =~ /(.+)\.tar\.bz2$/) {
265 -e "$topdir/BUILD/$1" && system "rm -rf $topdir/BUILD/$1";
266 system "cd $topdir/BUILD;tar -jxvvf $topdir/SOURCES/$pkgdata{main}{source}";
267 } else {
268 die "Unknown source tarball format\n";
269 }
270 # And now for patches. (not)
271 }
272} # end prep()
273
274
275## parse_spec()
276# Parse the .spec file once we've.... uh....
277sub parse_spec {
278 open SPECFILE,"<$specfile";
279
280LINE: while (<SPECFILE>) {
281 next if /^#/;
282 next if /^\s+$/;
283 if (/^\%/) {
284 # A macro that needs further processing.
285 if (/^\%prep/) {
286 # %prep section. May have %setup macro; may include %patch tags,
287 # may be just a bare shell script.
288
289 # This really should be local-ish, but we need just the filename for the source
290 $pkgdata{main}{source} =~ s|.+/([^/]+)$|$1|;
291
292 # Replace some core macros
293 $pkgdata{main}{source} =~ s/\%\{name\}/$pkgdata{main}{name}/;
294 $pkgdata{main}{source} =~ s/\%\{version\}/$pkgdata{main}{version}/;
295
296PREPSCRIPT: while (<SPECFILE>) {
297 if (/^\%setup/) {
298 # Parse out the %setup macro. Note that we aren't supporting
299 # most of RPM's %setup features.
300 $prepscript .= "cd $topdir/BUILD\n".
301 ( /\s+-n\s+([^\s]+)\s+/ ?
302 "rm -rf $1\n" : "rm -rf $pkgdata{main}{name}-$pkgdata{main}{version}\n" ).
303 "tar -".
304 ( $pkgdata{main}{source} =~ /\.tar\.gz$/ ? "z" : "" ).
305 ( $pkgdata{main}{source} =~ /\.tar\.bz2$/ ? "j" : "" ).
306 "x".( /\s+-q\s+/ ? '' : 'vv' )."f ".
307 "$topdir/SOURCES/$pkgdata{main}{source}\n".
308 qq(STATUS=\$?\nif [ \$STATUS -ne 0 ]; then\n exit \$STATUS\nfi\n).
309 ( /\s+-n\s+([^\s]+)\s+/ ?
310 "cd $1\n" : "cd $pkgdata{main}{name}-$pkgdata{main}{version}\n" ).
311 qq([ `/usr/bin/id -u` = '0' ] && /bin/chown -Rhf root .\n).
312 qq([ `/usr/bin/id -u` = '0' ] && /bin/chgrp -Rhf root .\n).
313 qq(/bin/chmod -Rf a+rX,g-w,o-w .\n);
314 } elsif (/^\%patch/) {
315 print "patch macro\n";
316 } else {
317 last PREPSCRIPT if /^\%/;
318 $prepscript .= $_;
319 }
320 }
321 redo LINE;
322 }
323 if (/^\%build/) {
324 # %build. This is pretty much just a shell script. There
325 # *are* a few macros, but we're not going to deal with them yet.
326 while (<SPECFILE>) {
327 redo LINE if /^\%/;
328 $buildscript .= $_;
329 }
330 }
331 if (/^\%install/) {
332 while (<SPECFILE>) {
333 redo LINE if /^\%/;
334 $installscript .= $_;
335 }
336 }
337 if (/^\%clean/) {
338 }
339 if (/^\%post/) {
340 }
341 if (/^\%preun/) {
342 }
343 if (/^\%files/) {
344 # Danger! Danger!
345 }
346 } else {
347 if (/^summary:\s+(.+)/i) {
348 $pkgdata{main}{summary} = $1;
349 } elsif (/^name:\s+(.+)/i) {
350 $pkgdata{main}{name} = $1;
351 } elsif (/^version:\s+(.+)/i) {
352 $pkgdata{main}{version} = $1;
353 } elsif (/^release:\s+(.+)/i) {
354 $pkgdata{main}{release} = $1;
355 } elsif (/^group:\s+(.+)/i) {
356 $pkgdata{main}{group} = $1;
357 } elsif (/^copyright:\s+(.+)/i) {
358 $pkgdata{main}{copyright} = $1;
359 } elsif (/^url:\s+(.+)/i) {
360 $pkgdata{main}{url} = $1;
361 } elsif (/^packager:\s+(.+)/i) {
362 $pkgdata{main}{packager} = $1;
363 } elsif (/^source:\s+(.+)/i) {
364 $pkgdata{main}{source} = $1;
365 die "Unknown tarball format $1\n" if $1 !~ /\.tar\.(?:gz|bz2)$/;
366 }
367#Name: suwrap
368#Version: 0.04
369#Release: 3
370#Group: Applications/System
371#Copyright: WebHart internal ONLY. :(
372#BuildArchitectures: i386
373#BuildRoot: /tmp/%{name}-%{version}
374#Url: http://virtual.webhart.net
375#Packager: Kris Deugau <kdeugau@deepnet.cx>
376#Source: ftp://virtual.webhart.net/%{name}-%{version}.tar.gz
377
378 }
379 }
380 # Parse and replace macros in $pkgdata{}{}
381 # Start with the ones I use
382 $pkgdata{main}{source} =~ s/\%\{name\}/$pkgdata{main}{name}/;
383 $pkgdata{main}{source} =~ s/\%\{version\}/$pkgdata{main}{version}/;
384} # end parse_spec()
385
386
387## build()
388# Execute commands provided as a shell script. It may prove simpler
389# to do as rpm does and actually create a little shell script.
390sub build {
391} # end build()
392
393
394sub install {}
395sub binpackage {}
396sub srcpackage {}
Note: See TracBrowser for help on using the repository browser.