Published:

Jarle Aase

How to make a dmg package for macos for a QT Application

bookmark 1 min read

Recently I made a Jenkins Pipeline to build a QT Application for multiple Linux distributions, Windows and macOS. In the process I had to figure out how to package a macOS Application.

I ended up building it with a script similar to what I did for Linux.

 1#!/bin/bash
 2
 3# Compile and prepare a signed .dmg package for distribution
 4# Assumes the environment-variable QTDIR to point to the
 5# Qt installation
 6#
 7# Example:
 8#     Jarles-Mac-mini:scripts jgaa$ QTDIR=/Users/jgaa/Qt/5.10.0/clang_64 ./package-macos.sh
 9
10if [ -z "$WHID_VERSION" ]; then
11    WHID_VERSION="2.0.0"
12    echo "Warning: Missing WHID_VERSION variable!"
13fi
14
15if [ -z ${DIST_DIR:-} ];
16then
17    DIST_DIR=`pwd`/dist/macos
18fi
19
20if [ -z ${SIGN_CERT:-} ];
21then
22    SIGN_CERT="Developer ID Application"
23fi
24
25if [ -z ${BUILD_DIR:-} ]; then
26    BUILD_DIR=`pwd`/build
27fi
28
29if [ -z ${SRC_DIR:-} ];
30then
31# Just assume we are run from the scipts directory
32    SRC_DIR=`pwd`/..
33fi
34
35echo "Building whid for macos into ${DIST_DIR} from ${SRC_DIR}"
36
37rm -rf $DIST_DIR $BUILD_DIR
38
39mkdir -p $DIST_DIR && cd $DIST_DIR
40mkdir -p $BUILD_DIR
41
42pushd $BUILD_DIR
43
44$QTDIR/bin/qmake \
45    -spec macx-clang \
46    "CONFIG += release x86_64" \
47    $SRC_DIR/whid.pro
48
49make -j4
50
51popd
52
53pushd $DIST_DIR
54
55mv $BUILD_DIR/whid.app $BUILD_DIR/whid-${WHID_VERSION}.app
56
57echo "Making dmg package with $QTDIR/bin/macdeployqt"
58$QTDIR/bin/macdeployqt $BUILD_DIR/whid-${WHID_VERSION}.app -dmg -appstore-compliant -codesign="$SIGN_CERT"
59
60mv  $BUILD_DIR/whid-${WHID_VERSION}.dmg .
61
62popd
63

As you can see, I use qmake and make to build the application. That is great, because it can be done from a script, and scripts can be started from Jenkins.

1$QTDIR/bin/qmake \
2    -spec macx-clang \
3    "CONFIG += release x86_64" \
4    $SRC_DIR/whid.pro
5
6make -j4

To build the actual dmg package, I use a utility shipped with QT, macdeployqt. This makes sure that all the required libraries are properly packaged into the bundle. My first attempt worked fine on my local machine, but when I downloaded the package from the build machine, I was unable to install it because it was unsigned.

Signing

It turned out that macdeployqt can sign the package. However I needed to create a certificate signed by Apple, of the correct type, issued to the correct entity.

In order to do that, you must be a registered Apple Developer. Then you must go to xcode, open preferences and accounts. I have enrolled my company, rather than myself, in the Apple Developer program, so I had to select the "The Last Viking LTD" team (rather than the personal, team), click on "Manage Certificates", and then create a "Developer ID Application" certificate.

Screenshot

The name of the certificate is then given to macdeployqt after the -codesign option.

1$QTDIR/bin/macdeployqt $BUILD_DIR/whid-${WHID_VERSION}.app -dmg -appstore-compliant -codesign="$SIGN_CERT"

So with this in place, I can build a deployable package for macOS directly from Jenkins.