LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Slackware (http://www.linuxquestions.org/questions/slackware-14/)
-   -   a generic SlackBuild (http://www.linuxquestions.org/questions/slackware-14/a-generic-slackbuild-365655/)

shilo 09-21-2005 02:32 PM

a generic SlackBuild
 
Sometimes, I want to build a package from source. I like to make a Slackware package, so that it is easy to upgrade/remove the package in the future. checkinstall works for this most of the time, but not always. I have found it easier to create a SlackBuild for the package.

Since most software compiles fairly similar, I decided to create a SlackBuild template. I have tried to keep it as simliar to the SlackBuild scripts that the official packages use as possible.

Please feel free to use this if it is useful to you.

Any recommended changes/critiques are welcome.

Code:

#!/bin/sh

########################
# NOTES:
#
########################
#
#
#
#
#
#
#
########################

# Set initial variables:

NAME=                        # Program name
PNAME=                        # Package name (Useful for changing case, removing "-"s, etc.)
VERSION=                # Program version
PVERSION=                # Package version (Useful for removing "-"s, CVS builds, etc.)
ARCH=${ARCH:-i686}        # Package architecture
BUILD=${BUILD:-1seb}        # Build number plus packager initials (use your own)

CWD=`pwd`
TMP=${TMP:-/tmp}        # Location to compile the source
PKG=$TMP/package-$NAME        # Location to build the package (use "package-$NAME" to avoid poss. conflicts)

# Define compiler flags based on intended architecture:
# Can easily expand this for alternate compilations

if [ "$ARCH" = "i386" ]; then
  SLKCFLAGS="-O2 -march=i386 -mcpu=i686"
elif [ "$ARCH" = "i486" ]; then
  SLKCFLAGS="-O2 -march=i486 -mcpu=i686"
elif [ "$ARCH" = "i686" ]; then
  SLKCFLAGS="-O2 -march=i686 -mcpu=i686"
elif [ "$ARCH" = "s390" ]; then
  SLKCFLAGS="-O2"
elif [ "$ARCH" = "x86_64" ]; then
  SLKCFLAGS="-O2"
fi

rm -rf $PKG                # Get rid of any leftovers
mkdir -p $PKG                # Make sure $PKG and $TMP (-p switch) exist

########################
#
# Why use this?  Already covered above, right?
#
########################
#
#if [ ! -d $TMP ]; then
#  mkdir -p $TMP                # location to build the source
#fi
#
########################

########################
#
# Why use this?  Already covered above, right?
#
########################
#
#if [ ! -d $PKG ]; then
#  mkdir -p $PKG                # place for the package to be built
#fi
#
########################

cd $TMP
rm -rf $NAME-$VERSION
tar xvzf $CWD/$NAME-$VERSION.tar.gz # Should consider changing to check for tar.gz or tar.bz2
cd $NAME-$VERSION

# Correct general permissions/ownership:

chown -R root.root .
find . -perm 777 -exec chmod 755 {} \;
find . -perm 775 -exec chmod 755 {} \;
find . -perm 711 -exec chmod 755 {} \;
find . -perm 666 -exec chmod 644 {} \;
find . -perm 664 -exec chmod 644 {} \;
find . -perm 600 -exec chmod 644 {} \;
find . -perm 555 -exec chmod 755 {} \;
find . -perm 511 -exec chmod 755 {} \;
find . -perm 444 -exec chmod 644 {} \;
find . -perm 440 -exec chmod 644 {} \;
find . -perm 400 -exec chmod 644 {} \;

# Classic "./configure && make && make install":

CFLAGS="$SLKCFLAGS" \
./configure \
  --prefix=/usr \
  --sysconfdir=/etc \
  --localstatedir=/var/lib \
  $ARCH-slackware-linux
make -j3
make install DESTDIR=$PKG

# Correct binaries ownership:

if ls $PKG/bin &> /dev/null; then
  chown -R root.bin $PKG/bin
fi

if ls $PKG/usr/bin &> /dev/null; then
  chown -R root.bin $PKG/usr/bin
fi

if ls $PKG/sbin &> /dev/null; then
  chown -R root.bin $PKG/sbin
fi

if ls $PKG/usr/sbin &> /dev/null; then
  chown -R root.bin $PKG/usr/sbin
fi

if ls $PKG/usr/X11R6/bin &> /dev/null; then
  chown -R root.bin $PKG/usr/X11R6/bin
fi

# Strip binaries and libs:

( cd $PKG
  find . | xargs file | grep "executable" | grep ELF | cut -f 1 -d : | xargs strip --strip-unneeded 2> /dev/null
  find . | xargs file | grep "shared object" | grep ELF | cut -f 1 -d : | xargs strip --strip-unneeded 2> /dev/null
)

# Compress man pages:

find $PKG/usr/man -type f -exec gzip -9 {} \;

# Create package docs:
# Probably should define the package documentation with
# a variable ($PDOCS) up top and replace the names with it

mkdir -p $PKG/usr/doc/$PNAME-$PVERSION
cp -a \
  AUTHORS BUGS COPYING ChangeLog INSTALL NEWS README TODO TROUBLESHOOTING \
  $PKG/usr/doc/$PNAME-$PVERSION
chmod 644 $PKG/usr/doc/$PNAME-$PVERSION/*

# Add package description:

if [ -e $CWD/slack-desc ]; then
  mkdir -p $PKG/install
  cat $CWD/slack-desc > $PKG/install/slack-desc
fi

# Add install script:

if [ -e $CWD/doinst.sh ]; then
  cat $CWD/doinst.sh > $PKG/install/doinst.sh
fi

# Add desktop file:

if [ -e $CWD/$PNAME.desktop ]; then
  mkdir -p $PKG/usr/share/applications
  cat $CWD/$PNAME.desktop > $PKG/usr/share/applications/$PNAME.desktop
fi

# Build the package:

cd $PKG
makepkg -l y -c n $TMP/$PNAME-$PVERSION-$ARCH-$BUILD.tgz

# Clean up the extra stuff:

if [ "$1" = "--cleanup" ]; then
  rm -rf $PKG
fi


XavierP 09-21-2005 02:58 PM

Shilo - thanks for this. I am sure that at least one of our members will be able to use it. Keep the ideas coming!

vicye6 03-19-2006 02:14 PM

Good work shilo, I will try to build my own package shortly!

Alien Bob 03-19-2006 03:00 PM

Hi Shilo
Nice one, this. Some positive feedback:

Quote:

TMP=${TMP:-/tmp} # Location to compile the source

......

########################
#
# Why use this? Already covered above, right?
#
########################
#
#if [ ! -d $TMP ]; then
# mkdir -p $TMP # location to build the source
#fi
#
########################
The first line is just the definition of the environment variable "TMP", but that does not mean it exists as a directory already. If I run the SlackBuild script as
Code:

TMP=/home/alien/temp ./template.SlackBuild
then execution would fail if the directory /home/alien/temp does not exist.
So the commented-out lines really should be uncommented.

Quote:

# Correct binaries ownership:

if ls $PKG/bin &> /dev/null; then
chown -R root.bin $PKG/bin
fi
To be complete, you should add a check for $PKG/opt/kde/bin too in case someone builds a KDE package.
Quote:

# Add package description:

if [ -e $CWD/slack-desc ]; then
mkdir -p $PKG/install
cat $CWD/slack-desc > $PKG/install/slack-desc
fi

# Add install script:

if [ -e $CWD/doinst.sh ]; then
cat $CWD/doinst.sh > $PKG/install/doinst.sh
fi
Now, if the "$CWD/slack-desc" file is not found, then the "$PKG/install" directory is not created and the "cat $CWD/doinst.sh" command will fail.

Cheers, Eric

danieldk 03-19-2006 03:44 PM

I built something similar, but it bit more extensive a while ago. It can be found at:

http://danieldk.org/buildpkg/

Some example buildfiles can be found at:

http://builds.slackbasics.org/newsource/

buildpkg is practically the generic SlackBuild script plus some checksum validation stuff.

BTW. it is not a serious attempt to build a 'generic package builder', just some script that I use to build own personal packages.

win32sux 03-19-2006 04:23 PM

Quote:

Originally Posted by shilo
Code:

find $PKG/usr/man -type f -exec gzip -9 {} \;

this would gzip man pages even if they were already gzipped, no?? i think something like this would be better (no need to use find):
Code:

gzip -9 $PKG/usr/man/man?/*.?
just my :twocents:...

Alien Bob 03-19-2006 04:36 PM

Quote:

Originally Posted by win32sux
this would gzip man pages even if they were already gzipped, no?? i think something like this would be better (no need to use find):
Code:

gzip -9 $PKG/usr/man/man?/*.?

No not really. You would not catch all possible man pages without a "find", since there could be internationalized man pages too, that will be installed into $PKG/usr/jp/man/ for instance (japanese).

Eric

win32sux 03-19-2006 04:47 PM

Quote:

Originally Posted by Alien Bob
No not really. You would not catch all possible man pages without a "find", since there could be internationalized man pages too, that will be installed into $PKG/usr/jp/man/ for instance (japanese).

the original find command wouldn't find the japanese man pages either, since it doesn't look in /usr/*/man... then again, being a *generic* script perhaps it doesn't need to cover any international possibilities... either way, the method i posted is what patrick usually uses, which is something to keep in mind...

maybe you could post a find command that would search through all the possible locations??

danieldk 03-19-2006 05:32 PM

Code:

find $PKG/usr/man -name "*.?" -type f 2> /dev/null | xargs gzip -9 2> /dev/null
find $PKG/usr/X11R6/man -name "*.?" -type f 2> /dev/null | xargs gzip -9 2> /dev/null

Seems sensible to me. Some programs have internationalized manual pages, and the number will probably only increase. So I don't see a problem with doing things the right way ;). You may want to take out the redirections of stderr to /dev/null.

win32sux 03-19-2006 05:46 PM

Quote:

Originally Posted by danieldk
Code:

find $PKG/usr/man -name "*.?" -type f 2> /dev/null | xargs gzip -9 2> /dev/null
find $PKG/usr/X11R6/man -name "*.?" -type f 2> /dev/null | xargs gzip -9 2> /dev/null

Seems sensible to me. Some programs have internationalized manual pages, and the number will probably only increase. So I don't see a problem with doing things the right way ;). You may want to take out the redirections of stderr to /dev/null.

yeah that looks much better... kinda like a hybrid of the find and the direct gzip... :)

so i take it that the internationalized man pages are stored in the /usr/man directory and not in a directory such as the /usr/jp/man/ example above, right?? cool...

danieldk 03-19-2006 06:12 PM

Quote:

Originally Posted by win32sux
so i take it that the internationalized man pages are stored in the /usr/man directory and not in a directory such as the /usr/jp/man/ example above, right??

Yeah, e.g. /usr/man/ko/man[0-9]

win32sux 03-19-2006 06:14 PM

that's what i suspected... thanks for clearing that up, and thanks for the nice tweak you did to the find... :)

J.W. 03-19-2006 07:25 PM

Excellent thread, all. Thanks for contributing

gnashley 03-20-2006 04:01 AM

I've written a package build system which can use a template as simple as this:

#!/bin/sh
BUILD="1"
NAME="PkgName"
VERSION="0.0.1"
SRC_SUFFIX=".tar.bz2"
source /usr/share/Amigo/PkgBuild/FUNCTIONS
do_all_processes

A more flexible template looks like this:

#!/bin/sh
## Advanced.PkgBuild script for: PkgName
##
## Amigo PkgBuild-0.4 - Gilbert Ashley <amigo@ibiblio.org>
##
##### ------------Standard Package Variables-------------------
# Most source code only needs these 4 variables set.
# Set SRC_SUFFIX to ".tar.gz" ".tgz" ".tar.bz2" or ".tbz"

BUILD="1"
NAME="PkgName"
VERSION="0.0.1"
SRC_SUFFIX=".tar.bz2"

#####--------Common Overrides and Options----------------------
# PRE_FIX=""
# EXTRA_CONFIGS=""
# DOCLIST=""
# GROUP_NAME=""
#######----------------Processing------------------------------
# Get functions and read in configuration files
source /usr/share/Amigo/PkgBuild/FUNCTIONS ;
# This template calls each process individually so you can add
# extra instructions between processes, or even leave out steps.

pre_process ;
find_source ;
make_dirs ;
unpack_source ;
fix_source_perms ;
configure_source ;
compile_source ;
fake_install ;
fix_pkg_perms ;
strip_bins ;
create_docs ;
compress_man_pages ;
make_description ;
make_doinst ;
make_package ;
post_process ;
exit 0

All the code for these functions are in the FUNCTIONS file. A couple of config files let you set up global prefs as to where to unpack, build and leave the created packages.

The first example works for anything that will compile using autoconf and make:
./configure
make
make install

The second example can be made to work for anything -multi-packages from one source, no configure, imake compiles, noarch packages, etc.

The point is that the build script only has information about what is unique to compiling and building only that package. All other information is either part of the functions, or is a variable which can be always be easily overridden.

It supports source/package grouping and regrouping, never actually installs the package unless you tell it to, works for suid programs. It also has a lot of extar features for generating dependency information and package reports, or for creating 'non-standard' packages with extra compression, culling of language files and other features.

It's not perfect, but I turned it loose the other day on 83 source packages. A few hours later I had 83 binary packages, with temp directories all cleaned up.

The really nice thing is that someone who can't code BASH at all, can write a build script for probably 80% of the stuff they want compile.
The long form gives me an excellent way to *easily* see the details of anything that needs custonization.

elyk 03-27-2006 04:00 AM

I have a similar script that I use when packaging programs. When I use it to package mplayer, gzipping the man pages will break a symlink. It looks like this script will have the same problem.

If I remember correctly...
mencoder.1 -> mplayer.1

After gzipping mplayer.1, the mencoder.1 symlink is broken (it should point to mplayer.1.gz instead). Does anyone have a good solution for detecting and fixing this type of problem, rather than explicitly removing and recreating that specific symlink?


All times are GMT -5. The time now is 10:25 PM.