1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320
|
#!/bin/sh
set -e
set -u
# init
version='0.0.21.1'
scriptname=$(basename $0)
mode=""
build_cmd=""
install_cmd=""
clean_cmd=""
src_dir=""
mex_dir=""
m_dir=""
makefile_mode=0
print_description()
{
cat << EOT
The is a small helper that eases building and installing MEX extensions for
Matlab toolbox packages in Debian binary packages. Because these packages
cannot build-depend on Matlab (for obvious reasons) they need to compile their
extensions at installation time using a local Matlab installation. The helper
is somewhat flexible by supporting custom build, install and clean commands, as
well as source and destination directories. It also deals with moving
extensions into library directories and automatically symlinks them into the
toolbox directory.
There are two major modes: 'install' to build, install and symlink extensions
(useful in postinst) and 'clean' to remove installed extensions and symlinks
(useful in prerm).
The command to build the extensions is invoked in the source directory. By
default, this is /usr/src/matlab/<package name>, but can be overridden with
the --src-dir option. Any optional 'install' (--install-cmd) and 'clean'
(--clean-cmd) are invoked in the source directory too.
Moreover, this helper will also take any installed extensions from a default
installation path /usr/share/matlab/site/m/<package name>, move them into
/usr/lib/matlab/site/<package name> and symlink back to the original location.
These locations can be configured with the --m-dir and --mex-dir options
respectively. Again, this step is optional and is only performed if a package
actually installs extensions inot this location.
EOT
}
print_version()
{
cat << EOT
$scriptname $version
Copyright (C) 2010-2011 Michael Hanke <michael.hanke@gmail.com>
Licensed under GNU General Public License version 3 or later.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Written by Michael Hanke.
EOT
}
print_help()
{
cat << EOT
Usage: $scriptname [OPTIONS] <package name> <mode>
Options:
-h
Print usage summary and option list.
--help
Print full help.
--version
Print version information and exit.
--build-cmd
Command to build the extensions in the source directory
--install-cmd
Command to install the extensions after building
--clean-cmd
Command to clean the source tree after installation. This is not the command
that is executed in 'clean' mode.
--src-dir
Directory with the extension sources. This is also the directory in which
build, install and clean commands get invoked.
--mex-dir
Target directory into which binary extensions get moved.
--m-dir
Target directory in which symlinks to binary extensions get created.
--make
Set default commands for 'build-cmd' (make), 'install-cmd'
(make install DESTDIR=\$m_dir) and 'clean-cmd' (make distclean) if no
specific command has been provided via the respective options.
EOT
}
print_examples()
{
cat << EOT
Examples:
The following call can be used in a package's postinst script if it comes with
a Matlab script 'build_matlab.m' that builds and installs its extension into
the desired locations. The --src-dir option is used to point to a non-standard
location of the extension sources.
debian-matlab-mexhelper somepackagename install \
--src-dir /usr/src/dynare-matlab/mex/sources \
--build-cmd 'matlab -nodesktop -nodisplay -nojvm -r build_matlab'
If a package installs extension sources into the standard location and builds
its extensions using a Makefile that support the DESTDIR for installing the
built extensions and a 'distclean' target it is sufficient to run the
following.
debian-matlab-mexhelper somepackagename install --make
Otherwise it is also possible to fully customize all commands.
debian-matlab-mexhelper difficultpackage install \
--build-cmd 'make -C src all toolbox MEXBIN="matlab-mex"' \
--install-cmd 'make -C src install && find . ! -wholename "./src" -name "*.mex?*" -print0 | xargs -0 -I {} cp -v --parent {} /usr/share/difficultpackage' \
--clean-cmd 'make -C src distclean toolbox-distclean && find . -name "*.mex?*" -delete'
If a package uses $scriptname to install extensions into the standard location
it can also be used to remove all MEX extensions and created symlinks when a
package is removed from a system. To achieve this simply put the following call
into a package's prerm script.
debian-matlab-mexhelper packagename clean
EOT
}
# Parse commandline options (taken from the getopt examples from the Debian util-linux package)
# Note that we use `"$@"' to let each command-line parameter expand to a
# separate word. The quotes around `$@' are essential!
# We need CLOPTS as the `eval set --' would nuke the return value of getopt.
CLOPTS=`getopt -o h --long help,version,build-cmd:,install-cmd:,clean-cmd:,src-dir:,mex-dir:,m-dir: -n "$scriptname" -- "$@"`
if [ $? != 0 ] ; then
echo "Terminating..." >&2
exit 1
fi
# Note the quotes around `$CLOPTS': they are essential!
eval set -- "$CLOPTS"
while true ; do
case "$1" in
-h) print_help; exit 0;;
--help) print_description; print_help; print_examples; exit 0;;
--version) print_version; exit 0;;
--build-cmd) shift; build_cmd=$1; shift;;
--install-cmd) shift; install_cmd=$1; shift;;
--clean-cmd) shift; clean_cmd=$1; shift;;
--src-dir) shift; src_dir=$1; shift;;
--mex-dir) shift; mex_dir=$1; shift;;
--m-dir) shift; m_dir=$1; shift;;
--make) shift; makefile_mode=1;;
--) shift ; break ;;
*) echo "Internal error! ($1)"; exit 1;;
esac
done
if [ ! $# -eq 2 ]; then
printf "Need exactly two arguments.\n\n"
print_help
exit 1
fi
pkg=$1
mode=$2
if [ -z "$pkg" ]; then
echo "No package name given."
print_help
exit 1
fi
if [ -z "$mode" ]; then
echo "No mode specified -- can be either 'install' or 'clean'."
print_help
exit 1
fi
# we have a default idea of where the sources are
if [ -z "$src_dir" ]; then
src_dir="/usr/src/matlab/$pkg"
fi
# we have a default idea of where compile extensions shall live
if [ -z "$mex_dir" ]; then
mex_dir="/usr/lib/matlab/site/$pkg"
fi
# we have a default idea of where extensions shall be symlinked to
if [ -z "$m_dir" ]; then
m_dir="/usr/share/matlab/site/m/$pkg"
fi
# if in makefile mode set defaults
if [ $makefile_mode -eq 1 ]; then
if [ -z "$build_cmd" ]; then
build_cmd="make"
fi
if [ -z "$install_cmd" ]; then
install_cmd="make install DESTDIR=$m_dir"
fi
if [ -z "$clean_cmd" ]; then
clean_cmd="make distclean"
fi
fi
# handle clean mode first
if [ "$mode" = "clean" ]; then
# find MEX extension symlinks and remove
[ -d $m_dir ] && find $m_dir/ -type l -name '*.mex?*' -delete
# wipe out mexdir
[ -d $mex_dir ] && rm -rf $mex_dir
# done
exit 0
fi
# unknown mode
if [ ! "$mode" = 'install' ]; then
echo "Got unknown mode: $mode"
exit 1
fi
# get the config
. /etc/matlab/debconf
# create logfile
logfile=$(mktemp ${TMPDIR:-/tmp}/${pkg}-mexbuild-$(date -u +%s).XXXXXXX)
cat << EOT >> $logfile
$(print_version)
Attempt to build Matlab extensions
Package name: $pkg
Source directory: $src_dir
MEX dir: $mex_dir
M dir: $m_dir
Build user (if any): $MATLAB_MEXBUILD_USER
Build command: $build_cmd
Install command: $install_cmd
Clean command: $clean_cmd
EOT
echo "Attempt to build Matlab extensions:" >> $logfile
# go into the source dir
cd $src_dir
echo "Building Matlab extensions (logfile at $logfile)"
# if we need to use a dedicated user
# (strip whitespace from the user name -- necessary to avoid failure
# if the user name is basically empty but not length zero -- seems to happen
# when retrieving the value from debconf under some weired non-reproducible
# conditions)
if [ -n "$(echo ${MATLAB_MEXBUILD_USER} | tr -d ' ')" ]; then
chown -R $MATLAB_MEXBUILD_USER $src_dir
echo "sudo -H -u $MATLAB_MEXBUILD_USER sh -c \"$build_cmd\"" >> $logfile
sudo -H -u $MATLAB_MEXBUILD_USER sh -c "$build_cmd" 2>&1 >> $logfile
chown -R root:root $src_dir
else
echo "$build_cmd" >> $logfile
sh -c "$build_cmd" 2>&1 >> $logfile
fi
# now install if desired
if [ -n "$install_cmd" ]; then
echo "$install_cmd" >> $logfile
sh -c "$install_cmd" 2>&1 >> $logfile
fi
# now clean if desired
if [ -n "$clean_cmd" ]; then
echo "$clean_cmd" >> $logfile
sh -c "$clean_cmd" 2>&1 >> $logfile
fi
# look if installing created the m-path directory -- if so
# move binary extensions out of the m-path and symlink back
# However, if nothing got installed there we do not want to fail
# in case a specific setup is required or intended
[ ! -d $m_dir ] && exit 0
for ext in $(find $m_dir/ -type f -name '*.mex?*'); do
# relative path to m-dir
relpath=${ext#$m_dir/*}
# extension location within the m-dir tree
reldir=$(dirname $relpath)
# create path in mex-dir
mkdir -p $mex_dir/$reldir
# move extension
echo "mv $ext $mex_dir/$relpath" >> $logfile
mv $ext $mex_dir/$relpath
# might want to have nice function to figure out common prefix and to relative
# symlinks
echo "ln -s $mex_dir/$relpath $ext" >> $logfile
ln -s $mex_dir/$relpath $ext
done
exit 0
|