1 | #!/bin/sh |
---|
2 | |
---|
3 | # Build a standard Athena package into a Solaris package. |
---|
4 | |
---|
5 | usage="build-package [-s srcdir] [-d destdir] [-v version] [-r release]" |
---|
6 | usage="$usage source pkgname" |
---|
7 | |
---|
8 | sourcedir=/mit/source |
---|
9 | destdir=/build |
---|
10 | |
---|
11 | while getopts s:d:v:r: opt; do |
---|
12 | case "$opt" in |
---|
13 | s) |
---|
14 | sourcedir="$OPTARG" |
---|
15 | ;; |
---|
16 | d) |
---|
17 | destdir="$OPTARG" |
---|
18 | ;; |
---|
19 | v) |
---|
20 | version="$OPTARG" |
---|
21 | ;; |
---|
22 | r) |
---|
23 | release="$OPTARG" |
---|
24 | ;; |
---|
25 | \?) |
---|
26 | echo "$usage" 1>&2 |
---|
27 | exit 1 |
---|
28 | ;; |
---|
29 | esac |
---|
30 | done |
---|
31 | shift `expr $OPTIND - 1` |
---|
32 | |
---|
33 | if [ $# -ne 2 ]; then |
---|
34 | echo "$usage" 1>&2 |
---|
35 | exit 1 |
---|
36 | fi |
---|
37 | |
---|
38 | athena_dir=$1 |
---|
39 | # Sun package names cannot contain underscore, so we change those to |
---|
40 | # hyphen. |
---|
41 | package_name=`echo $2 | tr '_' '-'` |
---|
42 | |
---|
43 | # XXX sigh. |
---|
44 | if [ third/krb5/src/appl = "$athena_dir" ]; then |
---|
45 | athena_dir=third/krb5 |
---|
46 | fi |
---|
47 | |
---|
48 | . $sourcedir/packs/build/version |
---|
49 | if [ "${version+set}" != set ]; then |
---|
50 | version=$major.$minor |
---|
51 | fi |
---|
52 | if [ "${release+set}" != set ]; then |
---|
53 | release="${ATHENA_PATCH_VERSION-$patch}" |
---|
54 | fi |
---|
55 | pkg_version=$version.$release |
---|
56 | |
---|
57 | source_name=$package_name-$pkg_version |
---|
58 | pkgdir=$destdir/PKG/$pkg_version |
---|
59 | |
---|
60 | # Check that we are where we ought to be, and set up the environment. |
---|
61 | case `uname -s` in |
---|
62 | SunOS) |
---|
63 | OS=solaris |
---|
64 | PATH=/usr/xpg4/bin:/usr/ccs/bin:/usr/bin:/usr/ucb:/usr/openwin/bin |
---|
65 | arch=sparc |
---|
66 | ;; |
---|
67 | *) |
---|
68 | echo "build-package must be run on a Solaris machine" 1>&2 |
---|
69 | exit 1 |
---|
70 | ;; |
---|
71 | esac |
---|
72 | PATH=/usr/athena/bin:$PATH |
---|
73 | export PATH OS |
---|
74 | |
---|
75 | |
---|
76 | echo "==== create top-level build directories" |
---|
77 | |
---|
78 | mkdir -p \ |
---|
79 | $destdir/BUILD \ |
---|
80 | $destdir/INSTALL \ |
---|
81 | $pkgdir \ |
---|
82 | $destdir/athtools |
---|
83 | |
---|
84 | |
---|
85 | echo "==== prepare sources" |
---|
86 | |
---|
87 | # Copy in the sources. |
---|
88 | rm -rf $destdir/BUILD/$source_name |
---|
89 | mkdir $destdir/BUILD/$source_name |
---|
90 | cd $destdir/BUILD |
---|
91 | (cd $sourcedir/$athena_dir; tar cf - .) | (cd $source_name; tar xfpo -) |
---|
92 | |
---|
93 | |
---|
94 | echo "==== build package objects from source" |
---|
95 | |
---|
96 | rm -rf $destdir/INSTALL/$source_name |
---|
97 | mkdir $destdir/INSTALL/$source_name |
---|
98 | |
---|
99 | # Hack: create any needed directory symlinks in the target, so that |
---|
100 | # package files that are installed under those directories end up |
---|
101 | # living in the right place. |
---|
102 | mkdir -p $destdir/INSTALL/$source_name/usr/bin |
---|
103 | ln -s ./usr/bin $destdir/INSTALL/$source_name/bin |
---|
104 | |
---|
105 | for op in dist prepare all install ; do |
---|
106 | (cd $source_name && \ |
---|
107 | $sourcedir/packs/build/do.sh -s $sourcedir \ |
---|
108 | -d $destdir/INSTALL/$source_name $op) || exit 1 |
---|
109 | done |
---|
110 | |
---|
111 | # Install any "extra" files (config files, etc.) that belong to this package. |
---|
112 | if [ -f $sourcedir/packs/build/sunpkg/extra/$package_name ]; then |
---|
113 | echo "==== build \"extra\" package objects" |
---|
114 | (cd $source_name && \ |
---|
115 | sh -e $sourcedir/packs/build/sunpkg/extra/$package_name \ |
---|
116 | $sourcedir $destdir/INSTALL/$source_name) || exit 1 |
---|
117 | fi |
---|
118 | |
---|
119 | # Hack: clean up any symlinks created above in the target, and the |
---|
120 | # directories they link to (if empty). |
---|
121 | rmdir -p $destdir/INSTALL/$source_name/usr/bin > /dev/null 2>&1 |
---|
122 | rm $destdir/INSTALL/$source_name/bin |
---|
123 | |
---|
124 | # Do not install any info dir file generated by the build. The dir |
---|
125 | # file will be managed by putting info files into their own class |
---|
126 | # below. |
---|
127 | rm -f $destdir/INSTALL/$source_name/usr/athena/info/dir |
---|
128 | |
---|
129 | # Hack: only install the charset.alias file belonging to the libiconv |
---|
130 | # package; otherwise, the last package installed which generated the |
---|
131 | # file will install its own (possibly abbreviated) version. (The |
---|
132 | # libcharset mechanism assumes that the build target file is shared |
---|
133 | # between packages). |
---|
134 | if [ "$package_name" != MIT-libiconv ]; then |
---|
135 | rm -f $destdir/INSTALL/$source_name/usr/athena/lib/charset.alias |
---|
136 | fi |
---|
137 | |
---|
138 | # Copy the built package into athtools now. |
---|
139 | echo "==== save tools" |
---|
140 | (cd $destdir/INSTALL/$source_name; tar cf - .) | \ |
---|
141 | (cd $destdir/athtools; tar xfp - .) |
---|
142 | |
---|
143 | echo "==== create the package prototype" |
---|
144 | |
---|
145 | # Generate the prototype file. The awk hack changes the mode, owner, |
---|
146 | # and group fields for all directories which properly belong to the |
---|
147 | # OS, to indicate that they should be left unchanged when the package |
---|
148 | # is installed (implying that those directories will already exist). |
---|
149 | # Otherwise, those values will get reset to whatever gets generated |
---|
150 | # here. |
---|
151 | # Also, change all files in /usr/athena/info to class info, whose |
---|
152 | # action scripts will update the info dir file. |
---|
153 | prototype=/tmp/prototype$$ |
---|
154 | rm -f $prototype |
---|
155 | (cd $destdir/INSTALL/$source_name && pkgproto . | nawk '{ |
---|
156 | if ($1 == "d" && ($3 !~ "/athena(/|$)" && |
---|
157 | $3 !~ "^usr/afsws(/|$)" && |
---|
158 | $3 !~ "^usr/gcc(/|$)" && |
---|
159 | $3 !~ "^usr/prototype_user(/|$)" && |
---|
160 | $3 !~ "^usr/vice(/|$)")) |
---|
161 | print $1, $2, $3, "?", "?", "?"; |
---|
162 | else if ($1 == "f" && $3 ~ "^usr/athena/info/") |
---|
163 | print "f", "info", $3, $4, $5, $6; |
---|
164 | else |
---|
165 | print $0; |
---|
166 | }' > $prototype) || exit 1 |
---|
167 | |
---|
168 | # If this package has a filter for editing the prototype, run it. |
---|
169 | if [ -f $sourcedir/packs/build/sunpkg/prototype/$package_name ]; then |
---|
170 | echo "==== edit the generated prototype" |
---|
171 | sh -e $sourcedir/packs/build/sunpkg/prototype/$package_name < $prototype \ |
---|
172 | > $prototype.new |
---|
173 | if [ -s $prototype.new ]; then |
---|
174 | if cmp -s $prototype $prototype.new ; then |
---|
175 | echo "Warning: prototype filter for $package_name made no changes" |
---|
176 | else |
---|
177 | mv $prototype.new $prototype |
---|
178 | fi |
---|
179 | else |
---|
180 | echo "prototype filter failed for $package_name" |
---|
181 | exit 1 |
---|
182 | fi |
---|
183 | fi |
---|
184 | |
---|
185 | echo "==== create pkginfo" |
---|
186 | |
---|
187 | # Create the pkginfo file. |
---|
188 | pkginfo_source=$sourcedir/packs/build/sunpkg/pkginfo/$package_name |
---|
189 | |
---|
190 | # Prepend the pkginfo stub from the source tree. |
---|
191 | # The stub must contain settings for PKG and NAME; others are defaulted |
---|
192 | # as follows. |
---|
193 | cp $pkginfo_source $destdir/INSTALL/$source_name/pkginfo |
---|
194 | |
---|
195 | grep -q '^ARCH=' $pkginfo_source || \ |
---|
196 | echo "ARCH=$arch" >> $destdir/INSTALL/$source_name/pkginfo |
---|
197 | |
---|
198 | grep -q '^VERSION=' $pkginfo_source || \ |
---|
199 | echo "VERSION=$pkg_version" >> $destdir/INSTALL/$source_name/pkginfo |
---|
200 | |
---|
201 | grep -q '^CATEGORY=' $pkginfo_source || \ |
---|
202 | echo "CATEGORY=system" >> $destdir/INSTALL/$source_name/pkginfo |
---|
203 | |
---|
204 | grep -q '^BASEDIR=' $pkginfo_source || \ |
---|
205 | echo "BASEDIR=/" >> $destdir/INSTALL/$source_name/pkginfo |
---|
206 | |
---|
207 | # Get the CLASSES setting. The order here defines the order in which |
---|
208 | # the class is processed at install time. If the stub does not set |
---|
209 | # CLASSES, we find all classes specified in the prototype. |
---|
210 | # "none" is the default class, and must be listed in pkginfo. |
---|
211 | grep -q '^CLASSES=' $pkginfo_source || { |
---|
212 | # Find the non-default classes in the prototype. Note that the following |
---|
213 | # assumes that the prototype does not contain a "part number" field. |
---|
214 | classes=`awk '$1 != "i" && $2 != "none" { print $2; }' $prototype | sort -u` |
---|
215 | # Always list class "none" first. |
---|
216 | echo CLASSES=none $classes >> $destdir/INSTALL/$source_name/pkginfo |
---|
217 | } |
---|
218 | |
---|
219 | # The following three settings are used in creating a compressed |
---|
220 | # archive for the "none" class in the package, speeding install time. |
---|
221 | # We assume that no package requires any other kind of processing for |
---|
222 | # this default class. |
---|
223 | |
---|
224 | # At install time, do not check for files in the package's reloc directory. |
---|
225 | grep -q '^PKG_SRC_NOVERIFY=' $pkginfo_source || \ |
---|
226 | echo "PKG_SRC_NOVERIFY=none" >> $destdir/INSTALL/$source_name/pkginfo |
---|
227 | |
---|
228 | # Do a "quick" verify after installation, i.e. skip the checksum check. |
---|
229 | grep -q '^PKG_DST_QKVERIFY=' $pkginfo_source || \ |
---|
230 | echo "PKG_DST_QKVERIFY=none" >> $destdir/INSTALL/$source_name/pkginfo |
---|
231 | |
---|
232 | # Pass package location and destination paths to the class action script, |
---|
233 | # instead of source/destination path pairs. |
---|
234 | grep -q '^PKG_CAS_PASSRELATIVE=' $pkginfo_source || \ |
---|
235 | echo "PKG_CAS_PASSRELATIVE=none" >> $destdir/INSTALL/$source_name/pkginfo |
---|
236 | |
---|
237 | echo "i pkginfo" >> $prototype |
---|
238 | |
---|
239 | echo "==== add other package files" |
---|
240 | |
---|
241 | # Add any other package files to the prototype. |
---|
242 | |
---|
243 | # If this package has a copyright file, copy it in. The copyright is |
---|
244 | # apparently displayed only at install time by pkgadd. |
---|
245 | if [ -f $sourcedir/packs/build/sunpkg/copyright/$package_name ]; then |
---|
246 | cp $sourcedir/packs/build/sunpkg/copyright/$package_name \ |
---|
247 | $destdir/INSTALL/$source_name/copyright |
---|
248 | echo "i copyright" >> $prototype |
---|
249 | fi |
---|
250 | |
---|
251 | # Create the depend file; every package depends on MIT-base, except |
---|
252 | # MIT-base itself. |
---|
253 | if [ "$package_name" = MIT-base ]; then |
---|
254 | rm -f $destdir/INSTALL/$source_name/depend |
---|
255 | else |
---|
256 | echo "P MIT-base A few base files needed by any Athena package" \ |
---|
257 | > $destdir/INSTALL/$source_name/depend |
---|
258 | fi |
---|
259 | if [ -f $sourcedir/packs/build/sunpkg/depend/$package_name ]; then |
---|
260 | # Append this package's other dependencies. |
---|
261 | cat $sourcedir/packs/build/sunpkg/depend/$package_name \ |
---|
262 | >> $destdir/INSTALL/$source_name/depend |
---|
263 | fi |
---|
264 | |
---|
265 | if [ -f $destdir/INSTALL/$source_name/depend ]; then |
---|
266 | echo "i depend" >> $prototype |
---|
267 | fi |
---|
268 | |
---|
269 | # Copy in any procedure scripts (postinstall, etc.) |
---|
270 | for proc in checkinstall preinstall postinstall preremove postremove ; do |
---|
271 | if [ -f $sourcedir/packs/build/sunpkg/$proc/$package_name ]; then |
---|
272 | cp $sourcedir/packs/build/sunpkg/$proc/$package_name \ |
---|
273 | $destdir/INSTALL/$source_name/$proc |
---|
274 | echo "i $proc" >> $prototype |
---|
275 | fi |
---|
276 | done |
---|
277 | |
---|
278 | # Copy in the class action scripts. Every package should have at |
---|
279 | # least class "none". |
---|
280 | classes=`grep '^CLASSES=' $destdir/INSTALL/$source_name/pkginfo | \ |
---|
281 | sed -e 's|^CLASSES=||'` |
---|
282 | for class in $classes ; do |
---|
283 | for type in i r ; do |
---|
284 | if [ -f $sourcedir/packs/build/sunpkg/class/$type.$class ]; then |
---|
285 | cp $sourcedir/packs/build/sunpkg/class/$type.$class \ |
---|
286 | $destdir/INSTALL/$source_name |
---|
287 | echo "i $type.$class" >> $prototype |
---|
288 | fi |
---|
289 | done |
---|
290 | done |
---|
291 | |
---|
292 | # We have completed the prototype, so copy it in. |
---|
293 | cp $prototype $destdir/INSTALL/$source_name/prototype |
---|
294 | |
---|
295 | |
---|
296 | echo "==== generate the installable package" |
---|
297 | |
---|
298 | # Make the package. |
---|
299 | rm -rf $pkgdir/$package_name |
---|
300 | (cd $destdir/INSTALL/$source_name && \ |
---|
301 | pkgmk -d $pkgdir -b $destdir/INSTALL/$source_name) || exit 1 |
---|
302 | |
---|
303 | echo "==== build a compressed archive of the package files" |
---|
304 | |
---|
305 | # Build a compressed cpio archive of the package's files in class "none". |
---|
306 | filelist=/tmp/filelist$$ |
---|
307 | mkdir -p $pkgdir/$package_name/archive |
---|
308 | rm -rf $filelist |
---|
309 | awk '(($2 == "f" || $2 == "v" || $2 == "e") && $3 == "none") { print $4; }' \ |
---|
310 | $pkgdir/$package_name/pkgmap > $filelist |
---|
311 | if [ -s $filelist ]; then |
---|
312 | (cd $pkgdir/$package_name/reloc && cpio -oc -C 512 < $filelist) | \ |
---|
313 | bzip2 -c > $pkgdir/$package_name/archive/none.bz2 || exit 1 |
---|
314 | if [ ! -s $pkgdir/$package_name/archive/none.bz2 ]; then |
---|
315 | echo "Failed to create compressed archive" 1>&2 |
---|
316 | exit 1 |
---|
317 | fi |
---|
318 | # The archived files are no longer needed in the package reloc directory. |
---|
319 | (cd $pkgdir/$package_name/reloc && cat $filelist | xargs rm -f) |
---|
320 | fi |
---|
321 | |
---|
322 | # Clean up. |
---|
323 | rm -f $prototype |
---|
324 | rm -f $filelist |
---|
325 | |
---|
326 | exit 0 |
---|