package.sh 13.8 KB
Newer Older
1
#!/bin/bash
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
# --------------------------------------------------------------------
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
# ---------------------------------------------------------------------

17
# ----------------------------------------------------------------------------
18
# Packaging script for OpenBoard, for Debian-compatible distributions. 
19 20
#
# This should be run after `build.sh`.
21 22 23 24 25 26 27 28 29 30
#
# The generated package structure is as follows : 
#
#    DEBIAN/
#    | control
#    | md5sums
#    | prerm
#    | postinst
#    usr/
#    | bin/
31
#    | | openboard <-- actually a symlink to run.sh or OpenBoard
32 33
#    | share/
#    | | applications/
34
#    | | | openboard.desktop
35 36 37 38 39
#    opt/
#    | openboard/
#    | | importer/
#    | | library/
#    | | etc/
40 41
#    | | qtlib/ (*)
#    | | plugins/ (*)
42 43
#    | | OpenBoard
#    | | OpenBoard.png
44
#    | | run.sh (*)
45
#
46 47
# (*) Only included if Qt libs and plugins are bundled. It is necessary to
# bundle these if the target system doesn't provide Qt 5.5.1, for example.
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
initializeVariables()
{
  # This script's path
  SCRIPT_PATH="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

  PROJECT_ROOT="$SCRIPT_PATH/../.."

  # Where the application was built (see build.sh)
  BUILD_DIR="$PROJECT_ROOT/build/linux/release"
  PRODUCT_PATH="$BUILD_DIR/product"
  IMPORTER_DIR="$PROJECT_ROOT/../OpenBoard-Importer/"
  IMPORTER_NAME="OpenBoardImporter"

  # Where the package is built to
  PACKAGE_BUILD_DIR="$PROJECT_ROOT/install"

  # Temporary folder, where we put all the files that will be built into the
  # package
  BASE_WORKING_DIR="debianPackage"

  APPLICATION_NAME="OpenBoard"
  APPLICATION_CODE="openboard"
  APPLICATION_PATH="opt"

  PACKAGE_DIRECTORY=$BASE_WORKING_DIR/$APPLICATION_PATH/$APPLICATION_CODE
  QT_PLUGINS_DEST_PATH="$PACKAGE_DIRECTORY/plugins"
  QT_LIBRARY_DEST_PATH="$PACKAGE_DIRECTORY/qtlib"

  DESKTOP_FILE_PATH="$BASE_WORKING_DIR/usr/share/applications"
  APPLICATION_SHORTCUT="$DESKTOP_FILE_PATH/${APPLICATION_CODE}.desktop"

  DESCRIPTION="OpenBoard, an interactive white board application"
  VERSION=`cat $BUILD_DIR/version`
  ARCHITECTURE=`cat buildContext`


  # Include Qt libraries and plugins in the package, or not
  # (this is necessary if the target system doesn't provide Qt 5.5.1)
  BUNDLE_QT=false

  # Qt installation path. This may vary across machines
  QT_PATH="/usr/lib/x86_64-linux-gnu/qt5"
  QT_PLUGINS_SOURCE_PATH="$QT_PATH/plugins"
  GUI_TRANSLATIONS_DIRECTORY_PATH="/usr/share/qt5/translations"
  QT_LIBRARY_SOURCE_PATH="$QT_PATH/.."

  NOTIFY_CMD=`which notify-send`
  ZIP_PATH=`which zip`
}

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
checkUser()
{
  if [ `id -u` -ne 0 ]; then
    echo "Please run the script as root" 
    exit 1
  fi
}

checkBuild() 
{
  if [ -z "$ARCHITECTURE" ]; then
    echo "Make sure you have built the software first using ./build.sh"
    exit 1
  fi
}

notifyError(){
    if [ -e "$NOTIFY_CMD" ]; then
        $NOTIFY_CMD -t 0 -i "/usr/share/icons/oxygen/64x64/status/dialog-error.png" "$1"
    fi
    printf "\033[31merror:\033[0m $1\n"
    exit 1
}

notifyProgress(){
    if [ -e "$NOTIFY_CMD" ]; then
        $NOTIFY_CMD "$1" "$2"
    fi
    printf "\033[32m--> \033[0m $1:\n\t$2\n"
}

copyQtLibrary(){
132
    echo -e "\t $1"
133 134 135 136
    if ls "$QT_LIBRARY_SOURCE_PATH/$1.so" &> /dev/null; then
        cp -P $QT_LIBRARY_SOURCE_PATH/$1.so.? "$QT_LIBRARY_DEST_PATH/"
        cp -P $QT_LIBRARY_SOURCE_PATH/$1.so.?.? "$QT_LIBRARY_DEST_PATH/"
        cp -P $QT_LIBRARY_SOURCE_PATH/$1.so.?.?.? "$QT_LIBRARY_DEST_PATH/"
137

138
        strip $QT_LIBRARY_DEST_PATH/$1.so.?.?.?
139
        chmod 644 $QT_LIBRARY_DEST_PATH/$1.so.?.?.? # 644 = rw-r-r
140 141 142 143 144 145
    else
        notifyError "$1 library not found in path: $QT_LIBRARY_SOURCE_PATH"
    fi
}

copyQtPlugin(){
146
    echo -e "\t $1"
147 148
    if ls "$QT_PLUGINS_SOURCE_PATH/$1" &> /dev/null; then
        cp -r $QT_PLUGINS_SOURCE_PATH/$1 $QT_PLUGINS_DEST_PATH/
149

150
        strip $QT_PLUGINS_DEST_PATH/$1/*
151
        chmod 644 $QT_PLUGINS_DEST_PATH/$1/* # 644 = rw-r-r
152
        chmod +rx $QT_PLUGINS_DEST_PATH/$1
153 154 155 156 157 158 159 160

    else
        notifyError "$1 plugin not found in path: $QT_PLUGINS_SOURCE_PATH"
    fi
}


# ----------------------------------------------------------------------------
161
# Copying the application, libs etc. to the temporary working directory
162 163
# ----------------------------------------------------------------------------

164

165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182
initializeVariables

checkBuild
checkUser

cd $PROJECT_ROOT

rm -rf $PACKAGE_DIRECTORY
mkdir -p $PACKAGE_DIRECTORY

rm -rf $PACKAGE_BUILD_DIR


notifyProgress "Copying product directory and resources"
cp -R $PRODUCT_PATH/* $PACKAGE_DIRECTORY
chown -R root:root $PACKAGE_DIRECTORY

cp -R resources/customizations $PACKAGE_DIRECTORY/
183
cp resources/linux/openboard-ubz.xml $PACKAGE_DIRECTORY/etc/
184

185 186 187 188 189
if $BUNDLE_QT; then
    cp -R resources/linux/run.sh $PACKAGE_DIRECTORY/
    chmod a+x $PACKAGE_DIRECTORY/run.sh
fi

190
notifyProgress "Copying importer"
191 192
mkdir -p $PACKAGE_DIRECTORY/importer
cp -R "$IMPORTER_DIR/$IMPORTER_NAME" "$PACKAGE_DIRECTORY/importer"
193 194 195

notifyProgress "Stripping importer and main executable"
strip $PACKAGE_DIRECTORY/$APPLICATION_NAME
196
strip $PACKAGE_DIRECTORY/importer/$IMPORTER_NAME
197

198 199 200 201
if $BUNDLE_QT; then
    notifyProgress "Copying and stripping Qt plugins"
    mkdir -p $QT_PLUGINS_DEST_PATH
    copyQtPlugin audio
202
    copyQtPlugin bearer
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
    copyQtPlugin generic
    copyQtPlugin iconengines
    copyQtPlugin imageformats
    copyQtPlugin mediaservice
    copyQtPlugin platforminputcontexts
    copyQtPlugin platforms
    copyQtPlugin platformthemes
    copyQtPlugin position
    copyQtPlugin printsupport
    copyQtPlugin qtwebengine
    copyQtPlugin sceneparsers
    copyQtPlugin xcbglintegrations

    notifyProgress "Copying and stripping Qt libraries"
    mkdir -p $QT_LIBRARY_DEST_PATH
    copyQtLibrary libQt5Core
    copyQtLibrary libQt5DBus
    copyQtLibrary libQt5Gui
    copyQtLibrary libQt5Multimedia
    copyQtLibrary libQt5MultimediaWidgets
    copyQtLibrary libQt5Network
    copyQtLibrary libQt5OpenGL
    copyQtLibrary libQt5Positioning
    copyQtLibrary libQt5PrintSupport
    copyQtLibrary libQt5Qml
    copyQtLibrary libQt5Quick
    copyQtLibrary libQt5Script
    copyQtLibrary libQt5Sensors
    copyQtLibrary libQt5Sql
    copyQtLibrary libQt5Svg
    copyQtLibrary libQt5WebChannel
    copyQtLibrary libQt5WebKit
    copyQtLibrary libQt5WebKitWidgets
236
    copyQtLibrary libQt5WebSockets
237 238 239 240 241 242
    copyQtLibrary libQt5Widgets
    copyQtLibrary libQt5XcbQpa
    copyQtLibrary libQt5Xml
    copyQtLibrary libQt5XmlPatterns
    copyQtLibrary libqgsttools_p
fi
243 244 245 246 247 248 249 250 251

notifyProgress "Copying Qt translations"
mkdir -p $PACKAGE_DIRECTORY/i18n
cp $GUI_TRANSLATIONS_DIRECTORY_PATH/qt_??.qm $PACKAGE_DIRECTORY/i18n/


# ----------------------------------------------------------------------------
# DEBIAN directory of package (control, md5sums, postinst etc)
# ----------------------------------------------------------------------------
252 253
notifyProgress "Generating control files for package"

254 255
mkdir -p "$BASE_WORKING_DIR/DEBIAN"

256
# Copy prerm script
257 258
cp -r "$SCRIPT_PATH/debian_package_files/prerm" "$BASE_WORKING_DIR/DEBIAN/"
chmod 755 "$BASE_WORKING_DIR/DEBIAN/prerm"
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

# Generate postinst script (can't copy it like prerm because some paths vary depending on
# the values of the variables in this script)

SYMLINK_TARGET="/$APPLICATION_PATH/$APPLICATION_CODE/$APPLICATION_NAME"
if $BUNDLE_QT ; then
    SYMLINK_TARGET="/$APPLICATION_PATH/$APPLICATION_CODE/run.sh"
fi

cat > "$BASE_WORKING_DIR/DEBIAN/postinst" << EOF
#!/bin/bash
# --------------------------------------------------------------------
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
# ---------------------------------------------------------------------

xdg-desktop-menu install --novendor /usr/share/applications/${APPLICATION_CODE}.desktop
xdg-mime install --mode system /$APPLICATION_PATH/$APPLICATION_CODE/etc/openboard-ubz.xml
xdg-mime default /usr/share/applications/${APPLICATION_CODE}.desktop application/ubz

ln -s $SYMLINK_TARGET /usr/bin/$APPLICATION_CODE

exit 0
EOF

294 295
chmod 755 "$BASE_WORKING_DIR/DEBIAN/postinst"

296

297
# Generate md5 sums of everything in the application path (e.g /opt) and the desktop entry
298 299 300 301
cd $BASE_WORKING_DIR
find $APPLICATION_PATH/ -exec md5sum {} > DEBIAN/md5sums 2>/dev/null \;
find $DESKTOP_FILE_PATH/ -exec md5sum {} >> DEBIAN/md5sums 2>/dev/null \;
cd $PROJECT_ROOT
302 303 304 305

# Generate control file
CONTROL_FILE="$BASE_WORKING_DIR/DEBIAN/control"

306
echo "Package: ${APPLICATION_CODE}" > "$CONTROL_FILE"
307 308 309 310 311 312 313 314 315 316 317
echo "Version: $VERSION" >> "$CONTROL_FILE"
echo "Section: education" >> "$CONTROL_FILE"
echo "Priority: optional" >> "$CONTROL_FILE"
echo "Architecture: $ARCHITECTURE" >> "$CONTROL_FILE"
echo "Essential: no" >> "$CONTROL_FILE"
echo "Installed-Size: `du -s $PACKAGE_DIRECTORY | awk '{ print $1 }'`" >> "$CONTROL_FILE"
echo "Maintainer: ${APPLICATION_NAME} Developers team <dev@openboard.ch>" >> "$CONTROL_FILE"
echo "Homepage: https://github.com/DIP-SEM/OpenBoard" >> "$CONTROL_FILE"

# Generate dependency list
echo -n "Depends: " >> "$CONTROL_FILE"
318 319 320 321

unset tab
declare -a tab
let count=0
322 323 324 325 326 327 328 329 330 331

if $BUNDLE_QT; then
    for l in `objdump -p $PACKAGE_DIRECTORY/${APPLICATION_NAME} | grep NEEDED | awk '{ print $2 }'`; do
        for lib in `dpkg -S  $l | grep -v "libqt5" | grep -v "qt55" | awk -F":" '{ print $1 }'`; do
            presence=`echo ${tab[*]} | grep -c "$lib"`;
            if [ "$presence" == "0" ]; then
                tab[$count]=$lib;
                ((count++));
            fi;
        done;
332
    done;
333 334 335 336 337 338 339 340 341 342 343 344
else
    for l in `objdump -p $PACKAGE_DIRECTORY/${APPLICATION_NAME} | grep NEEDED | awk '{ print $2 }'`; do
        for lib in `dpkg -S  $l | awk -F":" '{ print $1 }'`; do
            presence=`echo ${tab[*]} | grep -c "$lib"`;
            if [ "$presence" == "0" ]; then
                tab[$count]=$lib;
                ((count++));
            fi;
        done;
    done;
fi

345 346 347

for ((i=0;i<${#tab[@]};i++)); do
    if [ $i -ne "0" ]; then
G3rb's avatar
G3rb committed
348 349 350
        echo -n ", " >> "$CONTROL_FILE"
    fi
    # conditional dependency when libavcodec-ffmpeg56 or libavcodec-ffmpeg-extra56 is found
351
    depdVer=$(apt-cache show ${tab[$i]} | grep "Version: " | head -1 | awk '{ print $2 }' | sed -e 's/\([~:. 0-9?]*\).*/\1/g' | sed -e 's/\.$//')
G3rb's avatar
G3rb committed
352 353
    if [ "${tab[$i]}" == "libavcodec-ffmpeg56" ] || [ "${tab[$i]}" == "libavcodec-ffmpeg-extra56" ]; then
      echo -n "libavcodec-ffmpeg56 (>= ${depdVer}) | libavcodec-ffmpeg-extra56 (>= ${depdVer})" >> "$CONTROL_FILE"
354 355
    elif [ "${tab[$i]}" == "libavcodec-ffmpeg57" ] || [ "${tab[$i]}" == "libavcodec-ffmpeg-extra57" ]; then
      echo -n "libavcodec-ffmpeg57 (>= ${depdVer}) | libavcodec-ffmpeg-extra57 (>= ${depdVer})" >> "$CONTROL_FILE"
G3rb's avatar
G3rb committed
356 357
    else
      echo -n "${tab[$i]} (>= ${depdVer})" >> "$CONTROL_FILE"
358 359 360
    fi
done
echo -n ",  onboard" >> "$CONTROL_FILE"
361

362 363 364
if $BUNDLE_QT; then
    # Listing some dependencies manually; ideally we should use dpkg -p recursively 
    # to get the dependencies of the bundled shared libs & plugins. Or use static libs.
365
    echo -n ",  libxcb1" >> "$CONTROL_FILE"
366 367
    echo -n ",  libxcb-icccm4" >> "$CONTROL_FILE"
    echo -n ",  libxcb-xkb1" >> "$CONTROL_FILE"
368 369
    echo -n ",  libxcb-image0" >> "$CONTROL_FILE"
    echo -n ",  libxcb-render-util0" >> "$CONTROL_FILE"
370 371 372 373
else
    echo -n ",  libqt5multimedia5-plugins" >> "$CONTROL_FILE"
fi

374 375 376 377 378 379 380 381 382 383
echo "" >> "$CONTROL_FILE"
echo "Description: $DESCRIPTION" >> "$CONTROL_FILE"

# ----------------------------------------------------------------------------
# .desktop file
# ----------------------------------------------------------------------------
mkdir -p $DESKTOP_FILE_PATH
echo "[Desktop Entry]" > $APPLICATION_SHORTCUT
echo "Version=$VERSION" >> $APPLICATION_SHORTCUT
echo "Encoding=UTF-8" >> $APPLICATION_SHORTCUT
384
echo "Name=${APPLICATION_NAME}" >> $APPLICATION_SHORTCUT
385 386
echo "Comment=$DESCRIPTION" >> $APPLICATION_SHORTCUT
echo "Exec=$APPLICATION_CODE %f" >> $APPLICATION_SHORTCUT
387
echo "Icon=/$APPLICATION_PATH/$APPLICATION_CODE/${APPLICATION_NAME}.png" >> $APPLICATION_SHORTCUT
388 389 390
echo "StartupNotify=true" >> $APPLICATION_SHORTCUT
echo "Terminal=false" >> $APPLICATION_SHORTCUT
echo "Type=Application" >> $APPLICATION_SHORTCUT
Craig Watson's avatar
Craig Watson committed
391
echo "MimeType=application/ubz" >> $APPLICATION_SHORTCUT
392 393 394 395 396 397 398 399 400 401
echo "Categories=Education;" >> $APPLICATION_SHORTCUT
cp "resources/images/${APPLICATION_NAME}.png" "$PACKAGE_DIRECTORY/${APPLICATION_NAME}.png"



# ----------------------------------------------------------------------------
# Building the package
# ----------------------------------------------------------------------------
notifyProgress "Building package"
mkdir -p "$PACKAGE_BUILD_DIR/linux"
Craig's avatar
Craig committed
402 403
PACKAGE_NAME="${APPLICATION_NAME}_`lsb_release -is`_`lsb_release -rs`_${VERSION}_$ARCHITECTURE.deb"
PACKAGE_NAME=`echo "$PACKAGE_NAME" | awk '{print tolower($0)}'`
404

Craig's avatar
Craig committed
405
dpkg -b "$BASE_WORKING_DIR" "$PACKAGE_BUILD_DIR/linux/$PACKAGE_NAME"
406 407

#clean up mess
408
rm -rf $BASE_WORKING_DIR
409 410 411 412 413

notifyProgress "${APPLICATION_NAME}" "Package built"


exit 0