File: debian-matlab-mexhelper

package info (click to toggle)
matlab-support 0.0.21
  • links: PTS, VCS
  • area: main
  • in suites: buster, sid, stretch
  • size: 240 kB
  • ctags: 4
  • sloc: sh: 418; makefile: 12
file content (320 lines) | stat: -rwxr-xr-x 9,256 bytes parent folder | download | duplicates (3)
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.18'
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 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