source: trunk/debbuild@ 5

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

/trunk

checkpoint

  • Property svn:executable set to *
  • Property svn:keywords set to Date Rev Author
File size: 7.7 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-28 22:04:31 +0000 (Fri, 28 Oct 2005) $
9# SVN revision $Rev: 5 $
10# Last update by $Author: kdeugau $
11###
12
13use strict;
14
15# Program flow:
16# -> Parse/execute "system" config/macros (if any - should be rare)
17# -> Parse/execute "user" config/macros (if any - *my* requirement is %_topdir)
18# -> Parse command line for options, spec file/tarball/.src.deb (NB - also accept .src.rpm)
19
20# User's prefs for dirs, environment, etc,etc,etc.
21# config file ~/.debmacros
22# Default ordered search paths for config/macros:
23# /usr/lib/rpm/rpmrc /usr/lib/rpm/redhat/rpmrc /etc/rpmrc ~/.rpmrc
24# /usr/lib/rpm/macros /usr/lib/rpm/redhat/macros /etc/rpm/macros ~/.rpmmacros
25# **NOTE: May be possible to (ab)use bits of debhelper
26
27# Build tree
28# default is /usr/src/debian/{BUILD,SOURCES,SPECS,DEBS,SDEBS}
29
30# Globals
31my $specfile;
32my $tarball;
33my $srcpkg;
34my $verbosity = 0;
35my %cmdopts = (type => '',
36 stage => 'a',
37 short => 'n'
38 );
39my %targets = ('p' => 'Prep',
40 'c' => 'Compile',
41 'i' => 'Install',
42 'l' => 'Verify %files',
43 'a' => 'Build binary and source',
44 'b' => 'Build binary',
45 's' => 'Build source'
46 );
47my $topdir = "/usr/src/debian";
48
49# Package data
50# This is the form of $pkgdata{pkgname}{meta}
51# meta includes Summary, Name, Version, Release, Group, Copyright,
52# Source, URL, Packager, BuildRoot, Description
53my %pkgdata;
54
55# Functions
56sub prep;
57sub parse_spec;
58
59die "Not enough arguments\n" if #$argv == 0;
60
61load_userconfig();
62parse_cmd();
63
64# Hokay. Need to:
65# Execute prep if *not* --short-circuit
66prep() if ($cmdopts{short} ne 'y');
67
68if ($cmdopts{stage} =~ /ciab/) {
69 # Execute build if bc
70 # Execute build if bi, ba, bb and NOT --short-circuit
71 build() if ( ($cmdopts{stage} eq 'c') ||
72 (($cmdopts{stage} =~ /iab/) && ($cmdopts{short} ne 'y'))
73 );
74
75 # -> Execute
76 install() if ($cmdopts{short} ne 'y');
77 binpackage();
78}
79
80srcpackage();
81
82
83
84# Just in case.
85exit 0;
86
87
88## load_userconfig()
89# Loads user configuration (if any)
90# Currently only handles .debmacros
91# Needs to handle "other files"
92sub load_userconfig {
93 my (undef,undef,undef,undef,undef,undef,undef,$homedir,undef) = getpwuid($<);
94 if (-e "$homedir/.debmacros") {
95 open USERMACROS,"<$homedir/.debmacros";
96 while (<USERMACROS>) {
97 # And we also only handle the %_topdir macro at the moment.
98 if (/^\%_topdir/) {
99 my (undef,$tmp) = split /\s+/, $_;
100 $topdir = $tmp;
101 }
102 }
103 }
104} # end load_userconfig()
105
106
107## parse_cmd()
108# Parses command line into global hash %cmdopts, other globals
109# Options based on rpmbuild's options
110sub parse_cmd {
111 # Don't feel like coding my own option parser...
112 #use Getopt::Long;
113 # ... but I may have to: (OTOH, rpm uses popt, so maybe we can too.)
114 #use Getopt::Popt qw(:all);
115 # Or not. >:( Stupid Debian lack of findable Perl module names in packages.
116
117 # Stuff it.
118 my $prevopt = '';
119 foreach (@ARGV) {
120 chomp;
121 $prevopt = $_;
122 # Is it an option?
123 if (/^-/) {
124 # Is it a long option?
125 if (/^--/) {
126 if (/^--short-circuit/) {
127 $cmdopts{short} = 'y';
128 } elsif (/^--rebuild/) {
129 $cmdopts{type} = 's';
130 } else {
131 print "Long opt $_\n";
132 }
133 } else {
134 if (/^-[bt]/) {
135 if ($cmdopts{stage} eq 's') {
136 # Mutually exclusive options.
137 die "Can't use $_ with --rebuild\n";
138 } else {
139 ($cmdopts{stage}) = (/^-[bt]([pcilabs])/);
140 ($cmdopts{type}) = (/^-([bt])[pcilabs]/);
141 }
142 } elsif (/^-v/) {
143 # bump verbosity. Not sure what I'll actually do here...
144 } else {
145 die "Bad option $_\n";
146 }
147 }
148 } else {
149 # --buildroot is the only option that takes an argument
150 # Therefore, any *other* bare arguments are the spec file,
151 # tarball, or source package we're operating on - depending
152 # on which one we meet.
153 if ($prevopt eq '--buildroot') {
154 # Set buildroot
155 } else {
156 if ($cmdopts{type} eq 's') {
157 # Source package
158 if (!/\.src\.(deb|rpm)$/) {
159 die "Can't --rebuild with $_\n";
160 }
161 } elsif ($cmdopts{type} eq 'b') {
162 $specfile = $_;
163 # Spec file
164 } else {
165 # Tarball
166 }
167 }
168 }
169 }
170
171 # Some cross-checks. rpmbuild limits --short-circuit to just
172 # the "compile" and "install" targets - with good reason IMO.
173 # NB - this is NOT fatal, just ignored!
174 if ($cmdopts{short} eq 'y') {
175 warn "Can't use --short-circuit for $targets{$cmdopts{stage}} stage. Ignoring.\n";
176 $cmdopts{short} = 'n';
177 }
178 # Valid options, with example arguments (if any):
179# Build from .spec file; mutually exclusive:
180 # -bp
181 # -bc
182 # -bi
183 # -bl
184 # -ba
185 # -bb
186 # -bs
187# Build from tarball; mutually exclusive:
188 # -tp
189 # -tc
190 # -ti
191 # -ta
192 # -tb
193 # -ts
194# Build from .src.(deb|rpm)
195 # --rebuild
196 # --recompile
197
198# General options
199 # --buildroot=DIRECTORY
200 # --clean
201 # --nobuild
202 # --nodeps
203 # --nodirtokens
204 # --rmsource
205 # --rmspec
206 # --short-circuit
207 # --target=CPU-VENDOR-OS
208
209 #my $popt = new Getopt::Popt(argv => \@ARGV, options => \@optionsTable);
210
211} # end parse_cmd()
212
213
214## prep()
215# Unpacks the tarball from the SOURCES directory to the BUILD directory.
216# Speaks gzip and bzip2.
217# Finishes by applying patches in %prep section of spec file
218sub prep {
219 if ($cmdopts{type} eq 'b') {
220 # Need to read the spec file to find the tarball
221 parse_spec();
222
223 # Need to find the filename part of the tarball. In theory, we
224 # could go out to the URL and retrieve it, but that's Messy.
225# want to make this local
226 $pkgdata{main}{source} =~ s|.+/([^/]+)$|$1|;
227
228 if ($pkgdata{main}{source} =~ /(.+)\.tar\.gz$/) {
229 -e "$topdir/BUILD/$1" && system "rm -rf $topdir/BUILD/$1";
230 system "cd $topdir/BUILD;tar -zxvf $topdir/SOURCES/$pkgdata{main}{source}";
231 } elsif ($pkgdata{main}{source} =~ /(.+)\.tar\.bz2$/) {
232 -e "$topdir/BUILD/$1" && system "rm -rf $topdir/BUILD/$1";
233 system "cd $topdir/BUILD;tar -jxvf $topdir/SOURCES/$pkgdata{main}{source}";
234 } else {
235 die "Unknown source tarball format\n";
236 }
237 # And now for patches. (not)
238 }
239} # end prep()
240
241
242## parse_spec()
243# Parse the .spec file once we've.... uh....
244sub parse_spec {
245 open SPECFILE,"<$specfile";
246
247 while (<SPECFILE>) {
248 next if /^#/;
249 next if /^\s+$/;
250 if (/^\%/) {
251 # A macro that needs further processing.
252 if (/^\%build/) {
253 # %build. This is pretty much just a shell script.
254 }
255 } else {
256 if (/^summary:\s+(.+)/i) {
257 $pkgdata{main}{summary} = $1;
258 } elsif (/^name:\s+(.+)/i) {
259 $pkgdata{main}{name} = $1;
260 } elsif (/^version:\s+(.+)/i) {
261 $pkgdata{main}{version} = $1;
262 } elsif (/^release:\s+(.+)/i) {
263 $pkgdata{main}{release} = $1;
264 } elsif (/^group:\s+(.+)/i) {
265 $pkgdata{main}{group} = $1;
266 } elsif (/^copyright:\s+(.+)/i) {
267 $pkgdata{main}{copyright} = $1;
268 } elsif (/^url:\s+(.+)/i) {
269 $pkgdata{main}{url} = $1;
270 } elsif (/^packager:\s+(.+)/i) {
271 $pkgdata{main}{packager} = $1;
272 } elsif (/^source:\s+(.+)/i) {
273 $pkgdata{main}{source} = $1;
274 }
275#Name: suwrap
276#Version: 0.04
277#Release: 3
278#Group: Applications/System
279#Copyright: WebHart internal ONLY. :(
280#BuildArchitectures: i386
281#BuildRoot: /tmp/%{name}-%{version}
282#Url: http://virtual.webhart.net
283#Packager: Kris Deugau <kdeugau@deepnet.cx>
284#Source: ftp://virtual.webhart.net/%{name}-%{version}.tar.gz
285
286 }
287 }
288 # Parse and replace macros in $pkgdata{}{}
289 # Start with the ones I use
290 $pkgdata{main}{source} =~ s/\%\{name\}/$pkgdata{main}{name}/;
291 $pkgdata{main}{source} =~ s/\%\{version\}/$pkgdata{main}{version}/;
292} # end parse_spec()
293
294
295## build()
296# Execute commands provided as a shell script. It may prove simpler
297# to do as rpm does and actually create a little shell script.
298sub build {
299} # end build()
300
301
302sub install {}
303sub binpackage {}
304sub srcpackage {}
Note: See TracBrowser for help on using the repository browser.