0

I would like to automate the generation of an installer in my build process, with some control over when it gets built. How do I set up a make target to generate an installer using qmake?

I have a subdirs project with multiple components. The installer configuration is in a subdirectory (“installer-qt”). Files need to be copied to the installer packages’ data directories, then run the installer generator automatically. In addition to the built binaries I’d like to install documentation, headers, and other resources.

Yuriy
  • 61
  • 4

1 Answers1

0

This is what I've come up with.

Step 1: Copy files to the installer packages

Using make install: Add this to the subprojects:

package_build {
    INSTALLER_PACKAGE=$$PWD/installer-qt/packages
    INSTALL_PREFIX=$$INSTALLER_PACKAGE/com.example.component1/data
} else {
    isEmpty(INSTALL_PREFIX): INSTALL_PREFIX="/opt/ExampleCorp"
}
message("Install to $$INSTALL_PREFIX")
unix {
    target.path = "$$INSTALL_PREFIX/bin"
    documentation.path = "$$INSTALL_PREFIX/doc"
    includes.path = "$$INSTALL_PREFIX/include"
    testcase|staticlib {
        INSTALLS -= target
    } else {
        INSTALLS += target
        INSTALLS += documentation
        INSTALLS += includes
    }
}
documentation.files += readme.txt
includes.files += header.h

Now you can use the default /opt install when you run qmake, specify the prefix when you run qmake using qmake INSTALL_PREFIX=/my/prefix, or specify copying to the installer package when you run qmake using qmake CONFIG+=package_build

(Open question: How best to copy everything to the installer data without overriding the normal ‘make install’?)

Step 2: Build installer package

Add a qmake .pro project in installer-qt:

TEMPLATE = subdirs # Empty project

CONFIG(release, debug|release) {
    unix: INSTALLER_OFFLINE = $$PWD/MYPROJECT-linux-x64.run
    win32: INSTALLER_OFFLINE = $$PWD/MYPROJECT-win32-x64.exe
}
CONFIG(debug, debug|release) {
    unix: INSTALLER_OFFLINE = $$PWD/MYPROJECT-linux-x64-debug.run
    win32: INSTALLER_OFFLINE = $$PWD/MYPROJECT-win32-x64-debug.exe
}
OTHER_FILES += $$PWD/config/config.xml \
    $$PWD/packages/com.example.component1/meta/package.xml
# Create the target assembly Offline Installer
QTIFWDIR = $$(HOME)/Qt/QtIFW2.0.5
offlineInstaller.target = $$INSTALLER_OFFLINE
offlineInstaller.commands = $$QTIFWDIR/bin/binarycreator --offline-only \
    -c $$PWD/config/config.xml -p $$PWD/packages $$offlineInstaller.target
offlineInstaller.depends = install
offlineInstallerTarget.target = package # This is the real name of the target
offlineInstallerTarget.depends = offlineInstaller
QMAKE_EXTRA_TARGETS += offlineInstaller offlineInstallerTarget

This is enough to run ‘make package’ in the subdirectory, but we want to run it from the top level build directory. To do that, add this to the top level subdirs project:

SUBDIRS += installer-qt
offlineInstaller.target = package
offlineInstaller.depends = installer-qt mysubproject install
offlineInstaller.CONFIG = recursive
offlineInstaller.recurse = installer-qt
offlineInstaller.recurse_target = package
QMAKE_EXTRA_TARGETS += offlineInstaller

Now you can run ‘qmake CONFIG+= package_build /path/to/project.pro && make package’ from the build directory to build the installer. Add this to the QtCreator deploy configuration by going to Add Deploy Step > Make and putting in “package” for the “Make arguments.”

Resources:

https://evileg.com/en/post/164/

http://doc.qt.io/qt-5/qmake-advanced-usage.html#adding-custom-targets

Yuriy
  • 61
  • 4