source: pkgtools/makepkg-0.2

Last change on this file was becab57, checked in by Paweł Foremski <pjf@…>, 10 years ago

new env var names

  • Property mode set to 100755
File size: 12.2 KB
Line 
1#!/bin/bash
2#
3# makepkg - Lintrack package build tool
4# stripped down, cleaned up and feature enhanced version for Lintrack
5#
6# Copyright (C):
7#       2002-2004 by Judd Vinet <jvinet@zeroflux.org> (Arch Linux)
8#       2005 by Dawid Ciezarkiewicz <dpc@asn.pl> (Lintrack)
9#       2005-2006 by Pawel Foremski <pjf@asn.pl> (Lintrack)
10#
11# This program is free software; you can redistribute it and/or modify it under
12# the terms of the GNU General Public License as published by the Free Software
13# Foundation; either version 2 of the License, or (at your option) any later
14# version.
15#
16# This program is distributed in the hope that it will be useful, but WITHOUT
17# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18# FOR A PARTICULAR PURPOSE.     See the GNU General Public License for more details.
19#
20# You should have received a copy of the GNU General Public License along with
21# this program; if not, write to the Free Software Foundation, Inc., 59 Temple
22# Place - Suite 330, Boston, MA 02111-1307, USA.
23#
24
25myver='0.2-lt1'
26startdir="`pwd`"
27PKGDEST=$startdir
28
29### SUBROUTINES ###
30plain() { echo "  $1" >&2; }
31msg() { echo "==> $1" >&2; }
32warning() { echo "==> WARNING: $1" >&2; }
33error() { echo "==> ERROR: $1" >&2; msg "Aborting..."; exit ${2:-1}; }
34
35strip_url() { echo $1 | sed 's|^.*://.*/||g'; }
36
37function usage()
38{
39        cat <<-EOF
40        Usage: makepkg [options]
41
42        Options:
43          -e, --noextract  Do not extract source files (use existing src/ dir)
44          -d, --delsrc     Delete existing src/ dir
45          -o, --nobuild    Download and extract files only
46          -P, --pack       Just make a package of existing pkg/ dir
47          -p <buildscript> Use an alternate build script (instead of PKGBUILD)
48          -w <destdir>     Write package to <destdir> (instead of PKGDEST)
49          -C <confscript>  Specify configuration file path instead of
50                           /etc/makepkg.conf
51          -h, --help       This help
52          -v, --version    Show version information and exit
53       
54          If -p is not specified, makepkg will look for a PKGBUILD
55          file in the current directory.
56        EOF
57}
58
59function version()
60{
61        cat <<-EOF
62        makepkg (Lintrack) $myver
63       
64        Copyright (C) 2005-2006 by Pawel Foremski <pjf@asn.pl> (Lintrack)
65        Copyright (C) 2005 by Dawid Ciezarkiewicz <dpc@asn.pl> (Lintrack)
66        Copyright (C) 2002-2004 by Judd Vinet <jvinet@zeroflux.org> (Arch Linux)
67       
68        This is free software; see the source for copying conditions. There is NO
69        warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
70        EOF
71}
72
73# some useful functions imported from dqd installer
74function name_base() { echo $1 | sed -e 's/\/$//' -e 's/.*\///'; }
75function name_dir() { echo $1 | sed -e 's/\/$//' -e 's/\/[^\/]*$//'; }
76
77function realpath()
78{
79        # this parses '~' symbols
80        eval "path=\"\`echo $1\`\""
81
82        if [ "${path:0:1}" = '/' ]; then
83                        curdir=
84        else
85                        curdir="`pwd`"
86        fi
87
88        for part in `echo "$path" | sed -e 's/\// /g'`; do
89                if [ "$part" = '.' ]; then
90                        continue
91                elif [ "$part" = '..' ]; then
92                        curdir="`name_dir $curdir`"
93                elif [ -n "$part" ]; then
94                        curdir="$curdir/$part"
95                fi
96        done
97
98        if [ -z "$curdir" ]; then
99                echo '/'
100        else
101                echo $curdir
102        fi
103}
104
105# commonly used operations
106function patches()
107{
108        if [ "$NOEXTRACT" = "1" ]; then
109                warning "Skipping source patchning - using existing src/ tree"
110                return
111        fi
112
113        for file in ${1:-$startdir/patches/*.diff.bz2}; do
114                msg "patching with `basename $file`"
115                bunzip2 -c $file | patch -p1 || return 1
116        done
117}
118
119function files()
120{
121        cp -a ${1:-$startdir/files/*} ${2:-$startdir/pkg/} || return 1
122}
123
124## builds a package from current dir
125function build_package()
126{
127        local pkgdst files perm ppath pmode puser pgroup file
128
129        case "$1" in
130                "big")
131                        msg "Building big package"; suffix="-big" ;;
132                "small")
133                        msg "Building a stripped-down version of package"; suffix="" ;;
134                *)
135                        warning "Don't know how to build \"$1\" package"; return ;;
136        esac
137
138        msg "  Generating .FILELIST file..."
139        tar cvf /dev/null * | sort > .FILELIST
140
141        # size and time changes, so do it here
142        msg "  Generating .PKGINFO file..."
143        (
144                LC_ALL=; LANG=;
145
146                echo "# Generated by makepkg $myver (Lintrack)"
147                echo "# `date`"
148                echo "pkgname=\"$pkgname\""
149                echo "pkgver=\"$pkgver-$pkgrel${suffix}\""
150                echo "builddate=\"`date -u '+%a %b %e %H:%M:%S %Y'`\""
151                echo "packager=\"${PACKAGER:-Lintrack (http://www.lintrack.org/)}\""
152                echo "size=\"`du -cb . | tail -n 1 | awk '{print \$1}'`\""
153
154                [ -n "$CARCH" ] && echo "arch=\"$CARCH\""
155        ) > .PKGINFO
156
157        msg "  Compressing..."
158        pkgdst="$FB_PKGDEST/$pkgname-$pkgver-$pkgrel${suffix}.pkg.tar"
159        files="* .PKGINFO .FILELIST"
160        [ -f .INSTALL ] && files="$files .INSTALL"
161
162        #
163        # Below we implement flexible way to define final file permissions and ownership by passing us the
164        # $perms array which each element is of the following format: 'path mode user group'
165        #
166        # Implementation is hackish, but this is caused by no option/way in GNU tar to specify a list for
167        # file permissions and ownership.
168        #
169
170        # tar all files except listed ones, as root:root
171        for perm in "${perms[@]}"; do
172                set $perm
173                echo "${1%%/}"
174                [ -d "$1" ] && echo "${1%%/}/*"
175        done \
176                | tr ' ' '\n' \
177                | tar -c --owner 0 --group 0 -f "$pkgdst" -X - $files \
178                2> /dev/null
179
180        # now add the rest with requested perms
181        for perm in "${perms[@]}"; do
182                set $perm
183                ppath="$1"; pmode="$2"; puser="$3"; pgroup="$4"
184                tar -r --mode "$pmode" --owner "$puser" --group "$pgroup" -f "$pkgdst" $ppath
185        done
186
187        # finally, gzip
188        gzip -9f "$pkgdst"
189}
190
191
192### MAIN ###
193# options
194NOEXTRACT=0
195NOBUILD=0
196BUILDSCRIPT="./PKGBUILD"
197DELSRC=0
198JUSTPACK=0
199#CONFIGFILE=/etc/makepkg.conf
200
201ARGLIST=$@
202while [ "$#" -ne "0" ]; do
203        case $1 in
204                --delsrc)    DELSRC=1 ;;
205                --noextract) NOEXTRACT=1 ;;
206                --nobuild)   NOBUILD=1 ;;
207                --pack)      JUSTPACK=1 ;;
208                --help)      usage; exit 0 ;;
209                --version)   version; exit 0 ;;
210                --*)         usage; exit 1 ;;
211                -*)
212                        while getopts "dehoPp:w:vC:-" opt; do
213                                case $opt in
214                                        d) DELSRC=1 ;;
215                                        e) NOEXTRACT=1 ;;
216                                        h) usage; exit 0 ;;
217                                        v) version; exit 0 ;;
218                                        o) NOBUILD=1 ;;
219                                        p) BUILDSCRIPT=$OPTARG ;;
220                                        P) JUSTPACK=1 ;;
221                                        w) PKGDEST=$OPTARG ;;
222                                        C) CONFIGFILE=$OPTARG ;;
223                                        -) OPTIND=0; break ;;
224                                        *) usage; exit 1 ;;
225                                esac
226                        done
227                        ;;
228                *) true ;;
229        esac
230        shift
231done
232
233# makepkg configuration
234[ -f $CONFIGFILE ] || error "Configuration file not found: $CONFIGFILE"
235msg "Loading configuration file: $CONFIGFILE"
236source $CONFIGFILE
237
238# convert a (possibly) relative path to absolute
239PKGDEST="`realpath $FB_PKGDEST`"
240mkdir -p $FB_PKGDEST
241
242# unset special variables
243unset pkgname pkgver pkgrel md5sums source install build smalldel perms
244umask 0022
245
246### prepare to build
247[ ! -f $BUILDSCRIPT ] && error "$BUILDSCRIPT does not exist."
248source $BUILDSCRIPT
249
250[ `echo $pkgver | grep '-'` ] && error "pkgver is not allowed to contain hyphens."
251[ `echo $pkgrel | grep '-'` ] && error "pkgrel is not allowed to contain hyphens."
252
253msg "Making package: $pkgname   (`date`)"
254cd $startdir
255
256if [ "$JUSTPACK" = "1" ]; then
257        cd pkg/
258        build_package small
259        msg "Done"
260        exit 0
261fi
262
263# retrieve sources
264msg "Retrieving sources..."
265mkdir -p $FB_PKGDW
266cd $FB_PKGDW
267
268for netfile in ${source[@]}; do
269        file=`strip_url $netfile`
270
271        if [ -f $file ]; then
272                msg "    Found $file in sources dir"
273        else
274                [ -z "$FB_FTPAGENT" ] && error "FTPAGENT is not configured."
275                ftpclient=`echo $FB_FTPAGENT | awk {'print $1'}`
276                [ -z "`which $ftpclient 2> /dev/null`" ] && error "ftpclient `basename $ftpclient` is not installed."
277
278                proto=`echo $netfile | sed 's|://.*||'`
279                [ "$proto" != "ftp" -a "$proto" != "http" -a "$proto" != "https" ] && \
280                        error "$netfile was not found in the build directory and is not a proper URL."
281
282                msg "    Downloading $file"
283                $FB_FTPAGENT $netfile 2>&1
284                [ ! -f $file ] && error "Failed to download $file"
285        fi
286done
287
288if [ "$DELSRC" = "1" ]; then
289        warning "Deleting existing src/ dir"
290        rm -fr $startdir/src
291fi
292
293mkdir -p $startdir/src
294
295if [ "$NOEXTRACT" = "1" ]; then
296        warning "Skipping source extraction -- using existing src/ dir"
297        warning "Skipping source integrity checks -- using existing src/ dir"
298else
299        # MD5 validation
300        if [ ${#md5sums[@]} -ne ${#source[@]} ]; then
301                error "MD5 sums are missing or incomplete. Cannot verify source integrity."
302        elif [ `type -p md5sum` ]; then
303                msg "Validating source files with MD5 sums"
304                errors=0
305                idx=0
306                for netfile in ${source[@]}; do
307                        file=`strip_url $netfile`
308                        echo -n "    $file ... "
309                        echo "${md5sums[$idx]}  $file" | md5sum -c - >/dev/null
310                        if [ $? -ne 0 ]; then
311                                echo "FAILED"
312                                errors=1
313                        else
314                                echo "Passed"
315                        fi
316                        let idx++
317                done
318
319                [ $errors -gt 0 ] && error "One or more files did not pass the validity check!"
320        else
321                warning "The md5sum program is missing. Cannot verify source files!"
322                sleep 1
323        fi
324
325        msg "Extracting sources..."
326        cd $startdir/src
327
328        for netfile in ${source[@]}; do
329                unziphack=0
330                file=`strip_url $netfile`
331                unset cmd
332                case $file in
333                        *.tar.gz|*.tar.Z|*.tgz)
334                                cmd="tar --use-compress-program=gzip -xf $FB_PKGDW/$file" ;;
335                        *.tar.bz2)
336                                cmd="tar --use-compress-program=bzip2 -xf $FB_PKGDW/$file" ;;
337                        *.tar)  cmd="tar -xf $FB_PKGDW/$file" ;;
338                        *.zip)  unziphack=1; cmd="unzip -qqo $FB_PKGDW/$file" ;;
339                        *.gz)   cmd="zcat $FB_PKGDW/$file > ${file%.gz}" ;;
340                        *.bz2)  cmd="bzcat $FB_PKGDW/$file > ${file%.bz2}" ;;
341                        *)      cmd="cp $FB_PKGDW/$file ${file}" ;;
342                esac
343
344                if [ "$cmd" != "" ]; then
345                        msg "    $cmd"
346                        $cmd || {
347                                # unzip will return a 1 as a warning, it is not an error
348                                [ "$unziphack" != "1" -o $? -ne 1 ] && error "Failed to extract $file"
349                        }
350                fi
351        done
352fi
353
354# check for existing pkg directory
355[ -d $startdir/pkg ] && { msg "Removing existing pkg/ directory..."; rm -rf $startdir/pkg; }
356mkdir -p $startdir/pkg
357
358[ "$NOBUILD" = "1" ] && { msg "Sources are ready."; exit 0; }
359
360
361### build
362msg "Starting build()..."
363cd $startdir/src
364build 2>&1
365[ $? -gt 0 ] && error "Build failed" 2
366
367### let's package it
368cd $startdir/pkg
369
370
371# check for an install script
372[ -f ../INSTALL ] && { msg "Copying install script..."; cp ../INSTALL .INSTALL; }
373
374
375### do tasks for big and small packages
376msg "Fixing permissions"
377chmod -R u+w .
378
379if [ -d usr/share/man ]; then
380        msg "Moving usr/share/man files to usr/man"
381        mkdir -p usr/man
382        cp -a usr/share/man/* usr/man/
383        rm -rf usr/share/man
384fi
385
386msg "Compressing man pages..."
387find ./{usr{,/local,/share},opt/*}/man -type f 2>/dev/null | while read i ; do
388        ext="${i##*.}"
389        fn="${i##*/}"
390
391        if [ "$ext" != "gz" -a "$ext" != "bz2" ]; then
392                # update symlinks to this manpage
393                find ./{usr{,/local,/share},opt/*}/man -lname "$fn" 2> /dev/null | while read ln ; do
394                        rm -f "$ln"
395                        ln -sf "${fn}.gz" "${ln}.gz"
396                done
397                # compress the original
398                gzip -9 "$i"
399        fi
400done
401
402# remove empty directories, if needed
403[ -d usr/share ] && [ -z "`ls -1 usr/share`" ] && rm -r usr/share
404[ -d usr/lib ] && [ -z "`ls -1 usr/lib`" ] && rm -r usr/lib
405
406msg "Removing CVS and .svn dirs..."
407find . -type d -name "CVS" -exec rm -rf {} \; 2> /dev/null
408find . -type d -name ".svn" -exec rm -rf {} \; 2> /dev/null
409
410### build big package
411build_package big
412
413### build normal package
414msg "Removing unnecessary files"
415rm -rf usr/info usr/share/info
416rm -rf usr/doc usr/share/doc
417rm -rf usr/docs usr/share/docs
418rm -rf usr/share/locale
419rm -fr usr/man
420rm -rf usr/lib/pkgconfig
421rm -fr usr/include
422
423msg "Removing static libraries"
424find -name '*.a' -exec rm {} \;
425
426# remove empty dir, if needed
427[ -d usr/lib ] && [ -z "`ls -1 usr/lib`" ] && rm -r usr/lib
428
429msg "Stripping debugging symbols from kernel modules..."
430find ./lib/modules -type f -name "*.o" -or -name "*.ko" \
431        -exec /usr/bin/strip -g '{}' \; 2>&1 \
432        | grep -v "No such file" | grep -v "format not recognized"
433
434msg "Stripping debugging symbols from libraries..."
435find ./{,usr,usr/local,opt/*}/lib -type f \
436        -not -name "*.dll" -not -name "*.exe" -not -name "*.o" -not -name "*.ko" \
437        -exec /usr/bin/strip -s '{}' \; 2>&1 \
438        | grep -v "No such file" | grep -v "format not recognized"
439
440msg "Stripping symbols from binaries..."
441find ./{,usr,usr/local,opt/*}/{bin,sbin} -type f -not -name "*.dll" -not -name "*.exe" \
442        -exec /usr/bin/strip -s '{}' \; 2>&1 \
443        | grep -v "No such file" | grep -v "format not recognized"
444
445# remove requested files and dirs
446for delme in "${smalldel[@]}"; do
447        if echo "$delme" | egrep -q '^/'; then
448                warning "Not deleting '$delme', as it's given as an absolute path and can harm your system"
449                continue
450        fi
451        msg "Removing $delme"
452        rm -fr $delme
453done
454
455build_package small
456
457
458### DONE
459cd $startdir
460
461msg "Finished making: $pkgname (`date`)"
462
463exit 0
464
465# vim: tabstop=2 textwidth=100
Note: See TracBrowser for help on using the repository browser.