Mercurial > hg > easyhg
changeset 699:646e48a0d3a5
Some work on macOS packaging
author | Chris Cannam |
---|---|
date | Tue, 11 Dec 2018 16:40:57 +0000 |
parents | 52b8a499f379 |
children | 21e4df9865af |
files | deploy/osx/copy-qt.sh deploy/osx/deploy.sh deploy/osx/paths.sh deploy/osx/qt.conf deploy/osx/sign.sh src/fswatcher.cpp src/hgrunner.cpp |
diffstat | 7 files changed, 157 insertions(+), 42 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/deploy/osx/copy-qt.sh Tue Dec 11 16:40:57 2018 +0000 @@ -0,0 +1,59 @@ +#!/bin/bash + +set -eu + +app="$1" +if [ -z "$app" ]; then + echo "Usage: $0 <appname>" + echo "Provide appname without the .app extension, please" + exit 2 +fi + +frameworks="QtCore QtNetwork QtGui QtWidgets QtPrintSupport QtDBus" + +plugins="gif icns ico jpeg tga tiff wbmp webp cocoa macstyle minimal offscreen" + +qtdir=$(grep "Command:" Makefile | head -1 | awk '{ print $3; }' | sed s,/bin/.*,,) + +if [ ! -d "$qtdir" ]; then + echo "Failed to discover Qt installation directory from Makefile, exiting" + exit 2 +fi + +fdir="$app.app/Contents/Frameworks" +pdir="$app.app/Contents/plugins" + +mkdir -p "$fdir" +mkdir -p "$pdir" + +echo +echo "Copying frameworks..." +for fwk in $frameworks; do + if [ ! -d "$qtdir/lib/$fwk.framework" ]; then + if [ "$fwk" = "QtDBus" ]; then + echo "QtDBus.framework not found, assuming Qt was built without DBus support" + continue + fi + fi + cp -v "$qtdir/lib/$fwk.framework/$fwk" "$fdir" || exit 2 +done + +echo "Done" + +echo +echo "Copying plugins..." +for plug in $plugins; do + pfile=$(ls "$qtdir"/plugins/*/libq"$plug".dylib) + if [ ! -f "$pfile" ]; then + echo "Failed to find plugin $plug, exiting" + exit 2 + fi + target="$pdir"/${pfile##?*plugins/} + tdir=`dirname "$target"` + mkdir -p "$tdir" + cp -v "$pfile" "$target" || exit 2 +done + +echo "Done" + +
--- a/deploy/osx/deploy.sh Mon Dec 10 17:52:27 2018 +0000 +++ b/deploy/osx/deploy.sh Tue Dec 11 16:40:57 2018 +0000 @@ -16,15 +16,17 @@ echo " but the .app name must include .app" exit 2 fi -app=EasyMercurial +app=`basename "$source" .app` set -u version=`perl -p -e 's/^[^"]*"([^"]*)".*$/$1/' src/version.h` -case "$version" in - [0-9].[0-9]) bundleVersion="$version".0 ;; - [0-9].[0-9].[0-9]) bundleVersion="$version" ;; - *) echo "Error: Version $version is neither two- nor three-part number" ;; +stem=${version%%-*} +stem=${stem%%pre*} +case "$stem" in + [0-9].[0-9]) bundleVersion="$stem".0 ;; + [0-9].[0-9].[0-9]) bundleVersion="$stem" ;; + *) echo "Error: Version stem $stem (of version $version) is neither two- nor three-part number" ;; esac echo @@ -70,14 +72,27 @@ cp COPYING "$volume/COPYING.txt" cp -rp "$source" "$target" +# update file timestamps so as to make the build date apparent +find "$volume" -exec touch \{\} \; + echo "Done" +echo +echo "Code-signing volume..." + deploy/osx/sign.sh "$volume" || exit 1 +echo "Done" + echo echo "Making dmg..." -hdiutil create -srcfolder "$volume" "$dmg" -volname "$volume" && +hdiutil create -srcfolder "$volume" "$dmg" -volname "$volume" -fs HFS+ && rm -r "$volume" +echo +echo "Signing dmg..." + +codesign -s "Developer ID Application: Chris Cannam" -fv "$dmg" + echo "Done"
--- a/deploy/osx/paths.sh Mon Dec 10 17:52:27 2018 +0000 +++ b/deploy/osx/paths.sh Tue Dec 11 16:40:57 2018 +0000 @@ -31,45 +31,48 @@ for fwk in $frameworks; do find "$app.app" -type f -print | while read x; do - - current=$(otool -L "$x" | - grep "$fwk" | grep amework | grep -v ':$' | - awk '{ print $1; }') + if [ -x "$x" ]; then + current=$(otool -L "$x" | + grep "$fwk" | grep amework | grep -v ':$' | + awk '{ print $1; }') - [ -z "$current" ] && continue + [ -z "$current" ] && continue - echo "$x has $current" + echo "$x has $current" - case "$x" in - *PyQt4*) - # These are "special" Qt4 libraries used by - # the PyQt module. They need to refer to their - # own local neighbours. Ugh, but let's handle - # those manually here. - relative="$fwk.so" - ;; - *) - # The normal Qt5 case - relative=$(echo "$x" | - sed -e "s,$app.app/Contents/,," \ - -e 's,[^/]*/,../,g' \ - -e 's,/[^/]*$,/Frameworks/'"$fwk"',' ) - ;; - esac + case "$x" in +# *PyQt*) + # These are "special" Qt libraries used by + # the PyQt module. They need to refer to their + # own local neighbours. Ugh, but let's handle + # those manually here. +# relative="$fwk.so" +# ;; + *) + # The normal Qt case + relative=$(echo "$x" | + sed -e "s,$app.app/Contents/,," \ + -e 's,[^/]*/,../,g' \ + -e 's,/[^/]*$,/Frameworks/'"$fwk"',' ) + ;; + esac - echo "replacing with relative path $relative" - install_name_tool -change \ - "$current" "@loader_path/$relative" "$x" + echo "replacing with relative path $relative" + install_name_tool -change \ + "$current" "@loader_path/$relative" "$x" + fi done done find "$app.app" -type f -print | while read x; do - qtdep=$(otool -L "$x" | grep Qt | grep amework | grep -v ':$' | grep -v '@loader_path' | awk '{ print $1; }') - if [ -n "$qtdep" ]; then - echo - echo "ERROR: File $x depends on Qt framework(s) not apparently present in the bundle:" - echo $qtdep - exit 1 + if [ -x "$x" ]; then + qtdep=$(otool -L "$x" | grep Qt | grep amework | grep -v ':$' | grep -v '@loader_path' | awk '{ print $1; }') + if [ -n "$qtdep" ]; then + echo + echo "ERROR: File $x depends on Qt framework(s) not apparently present in the bundle:" + echo $qtdep + exit 1 + fi fi done
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/deploy/osx/qt.conf Tue Dec 11 16:40:57 2018 +0000 @@ -0,0 +1,2 @@ +[Paths] +Plugins = plugins
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/deploy/osx/sign.sh Tue Dec 11 16:40:57 2018 +0000 @@ -0,0 +1,31 @@ +#!/bin/bash + +set -eu + +# Execute this from the top-level directory of the project (the one +# that contains the .app bundle). Supply the name of the .app bundle +# as argument +dir="$1" +if [ -z "$dir" ] || [ ! -d "$dir" ]; then + echo "Usage: $0 <pkgdir>" + echo "Where pkgdir is the directory containing <MyApplication>.app" + echo "All .app bundles in pkgdir will be signed" + exit 2 +fi + +for app in "$dir"/*.app; do + find "$app" -name Qt\* -print | while read fr; do + codesign -s "Developer ID Application: Chris Cannam" -fv --deep "$fr" + done + find "$app" -name \*.dylib -print | while read fr; do + codesign -s "Developer ID Application: Chris Cannam" -fv --deep "$fr" + done + find "$app" -name \*.so -print | while read fr; do + codesign -s "Developer ID Application: Chris Cannam" -fv --deep "$fr" + done + codesign -s "Developer ID Application: Chris Cannam" -fv --deep "$app" +# codesign -s "Developer ID Application: Chris Cannam" -fv \ +# --requirements '=designated => identifier "org.easymercurial.EasyMercurial" and ( (anchor apple generic and certificate leaf[field.1.2.840.113635.100.6.1.9] ) or (anchor apple generic and certificate 1[field.1.2.840.113635.100.6.2.6] and certificate leaf[field.1.2.840.113635.100.6.1.13] and certificate leaf[subject.OU] = "M2H8666U82"))' \ +# "$app" +done +
--- a/src/fswatcher.cpp Mon Dec 10 17:52:27 2018 +0000 +++ b/src/fswatcher.cpp Tue Dec 11 16:40:57 2018 +0000 @@ -144,12 +144,12 @@ #ifdef Q_OS_MAC static void -fsEventsCallback(ConstFSEventStreamRef streamRef, +fsEventsCallback(ConstFSEventStreamRef /* streamRef */, void *clientCallBackInfo, size_t numEvents, void *paths, - const FSEventStreamEventFlags eventFlags[], - const FSEventStreamEventId eventIDs[]) + const FSEventStreamEventFlags /* eventFlags */[], + const FSEventStreamEventId /*eventIDs */[]) { FsWatcher *watcher = reinterpret_cast<FsWatcher *>(clientCallBackInfo); const char *const *cpaths = reinterpret_cast<const char *const *>(paths);
--- a/src/hgrunner.cpp Mon Dec 10 17:52:27 2018 +0000 +++ b/src/hgrunner.cpp Tue Dec 11 16:40:57 2018 +0000 @@ -28,6 +28,7 @@ #include <QProgressBar> #include <QPushButton> #include <QGridLayout> +#include <QCoreApplication> #include <iostream> #include <errno.h> @@ -44,8 +45,9 @@ HgRunner::HgRunner(QString myDirPath, QWidget *parent) : QWidget(parent), - m_myDirPath(myDirPath), - m_ptyFile(0) + m_ptyFile(0), + m_proc(0), + m_myDirPath(myDirPath) { QGridLayout *layout = new QGridLayout(this); layout->setMargin(0); @@ -586,6 +588,9 @@ if (QSettings().value("python32", false).toBool()) { env.insert("VERSIONER_PYTHON_PREFER_32_BIT", "1"); } + QDir pluginDir(QCoreApplication::applicationDirPath()); + pluginDir.cd("../plugins"); + env.insert("QT_PLUGIN_PATH", pluginDir.canonicalPath()); #endif env.insert("LANG", "en_US.utf8");