Port macdeployqtplus to OSX 10.8
Use 'osascript' to run AppleScript, instead of using (broken-in-10.8) python appscript package. And added support for code-signing the .app bundle, to make OSX's GateKeeper happy.
This commit is contained in:
parent
2c7847349d
commit
33b377a016
2 changed files with 77 additions and 24 deletions
|
@ -18,6 +18,7 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
import subprocess, sys, re, os, shutil, stat, os.path
|
import subprocess, sys, re, os, shutil, stat, os.path
|
||||||
|
from string import Template
|
||||||
from time import sleep
|
from time import sleep
|
||||||
from argparse import ArgumentParser
|
from argparse import ArgumentParser
|
||||||
|
|
||||||
|
@ -429,12 +430,17 @@ ap = ArgumentParser(description="""Improved version of macdeployqt.
|
||||||
Outputs a ready-to-deploy app in a folder "dist" and optionally wraps it in a .dmg file.
|
Outputs a ready-to-deploy app in a folder "dist" and optionally wraps it in a .dmg file.
|
||||||
Note, that the "dist" folder will be deleted before deploying on each run.
|
Note, that the "dist" folder will be deleted before deploying on each run.
|
||||||
|
|
||||||
Optionally, Qt translation files (.qm) and additional resources can be added to the bundle.""")
|
Optionally, Qt translation files (.qm) and additional resources can be added to the bundle.
|
||||||
|
|
||||||
|
Also optionally signs the .app bundle; set the CODESIGNARGS environment variable to pass arguments
|
||||||
|
to the codesign tool.
|
||||||
|
E.g. CODESIGNARGS='--sign "Developer ID Application: ..." --keychain /encrypted/foo.keychain'""")
|
||||||
|
|
||||||
ap.add_argument("app_bundle", nargs=1, metavar="app-bundle", help="application bundle to be deployed")
|
ap.add_argument("app_bundle", nargs=1, metavar="app-bundle", help="application bundle to be deployed")
|
||||||
ap.add_argument("-verbose", type=int, nargs=1, default=[1], metavar="<0-3>", help="0 = no output, 1 = error/warning (default), 2 = normal, 3 = debug")
|
ap.add_argument("-verbose", type=int, nargs=1, default=[1], metavar="<0-3>", help="0 = no output, 1 = error/warning (default), 2 = normal, 3 = debug")
|
||||||
ap.add_argument("-no-plugins", dest="plugins", action="store_false", default=True, help="skip plugin deployment")
|
ap.add_argument("-no-plugins", dest="plugins", action="store_false", default=True, help="skip plugin deployment")
|
||||||
ap.add_argument("-no-strip", dest="strip", action="store_false", default=True, help="don't run 'strip' on the binaries")
|
ap.add_argument("-no-strip", dest="strip", action="store_false", default=True, help="don't run 'strip' on the binaries")
|
||||||
|
ap.add_argument("-sign", dest="sign", action="store_true", default=False, help="sign .app bundle with codesign tool")
|
||||||
ap.add_argument("-dmg", nargs="?", const="", metavar="basename", help="create a .dmg disk image; if basename is not specified, a camel-cased version of the app name is used")
|
ap.add_argument("-dmg", nargs="?", const="", metavar="basename", help="create a .dmg disk image; if basename is not specified, a camel-cased version of the app name is used")
|
||||||
ap.add_argument("-fancy", nargs=1, metavar="plist", default=[], help="make a fancy looking disk image using the given plist file with instructions; requires -dmg to work")
|
ap.add_argument("-fancy", nargs=1, metavar="plist", default=[], help="make a fancy looking disk image using the given plist file with instructions; requires -dmg to work")
|
||||||
ap.add_argument("-add-qt-tr", nargs=1, metavar="languages", default=[], help="add Qt translation files to the bundle's ressources; the language list must be separated with commas, not with whitespace")
|
ap.add_argument("-add-qt-tr", nargs=1, metavar="languages", default=[], help="add Qt translation files to the bundle's ressources; the language list must be separated with commas, not with whitespace")
|
||||||
|
@ -635,6 +641,15 @@ for p in config.add_resources:
|
||||||
|
|
||||||
# ------------------------------------------------
|
# ------------------------------------------------
|
||||||
|
|
||||||
|
if config.sign and 'CODESIGNARGS' not in os.environ:
|
||||||
|
print "You must set the CODESIGNARGS environment variable. Skipping signing."
|
||||||
|
elif config.sign:
|
||||||
|
if verbose >= 1:
|
||||||
|
print "Code-signing app bundle %s"%(target,)
|
||||||
|
subprocess.check_call("codesign --force %s %s"%(os.environ['CODESIGNARGS'], target), shell=True)
|
||||||
|
|
||||||
|
# ------------------------------------------------
|
||||||
|
|
||||||
if config.dmg is not None:
|
if config.dmg is not None:
|
||||||
def runHDIUtil(verb, image_basename, **kwargs):
|
def runHDIUtil(verb, image_basename, **kwargs):
|
||||||
hdiutil_args = ["hdiutil", verb, image_basename + ".dmg"]
|
hdiutil_args = ["hdiutil", verb, image_basename + ".dmg"]
|
||||||
|
@ -713,30 +728,67 @@ if config.dmg is not None:
|
||||||
if fancy.get("applications_symlink", False):
|
if fancy.get("applications_symlink", False):
|
||||||
os.symlink("/Applications", os.path.join(disk_root, "Applications"))
|
os.symlink("/Applications", os.path.join(disk_root, "Applications"))
|
||||||
|
|
||||||
finder = appscript.app("Finder")
|
# The Python appscript package broke with OSX 10.8 and isn't being fixed.
|
||||||
disk = finder.disks[disk_name]
|
# So we now build up an AppleScript string and use the osascript command
|
||||||
disk.open()
|
# to make the .dmg file pretty:
|
||||||
window = disk.container_window
|
appscript = Template( """
|
||||||
window.current_view.set(appscript.k.icon_view)
|
on run argv
|
||||||
window.toolbar_visible.set(False)
|
tell application "Finder"
|
||||||
window.statusbar_visible.set(False)
|
tell disk "$disk"
|
||||||
if fancy.has_key("window_bounds"):
|
open
|
||||||
window.bounds.set(fancy["window_bounds"])
|
set current view of container window to icon view
|
||||||
view_options = window.icon_view_options
|
set toolbar visible of container window to false
|
||||||
view_options.arrangement.set(appscript.k.not_arranged)
|
set statusbar visible of container window to false
|
||||||
if fancy.has_key("icon_size"):
|
set the bounds of container window to {$window_bounds}
|
||||||
view_options.icon_size.set(fancy["icon_size"])
|
set theViewOptions to the icon view options of container window
|
||||||
if bg_path is not None:
|
set arrangement of theViewOptions to not arranged
|
||||||
view_options.background_picture.set(disk.files[os.path.basename(bg_path)])
|
set icon size of theViewOptions to $icon_size
|
||||||
|
$background_commands
|
||||||
|
$items_positions
|
||||||
|
close -- close/reopen works around a bug...
|
||||||
|
open
|
||||||
|
update without registering applications
|
||||||
|
delay 5
|
||||||
|
eject
|
||||||
|
end tell
|
||||||
|
end tell
|
||||||
|
end run
|
||||||
|
""")
|
||||||
|
|
||||||
|
itemscript = Template('set position of item "${item}" of container window to {${position}}')
|
||||||
|
items_positions = []
|
||||||
if fancy.has_key("items_position"):
|
if fancy.has_key("items_position"):
|
||||||
for name, position in fancy["items_position"].iteritems():
|
for name, position in fancy["items_position"].iteritems():
|
||||||
window.items[name].position.set(position)
|
params = { "item" : name, "position" : ",".join([str(p) for p in position]) }
|
||||||
disk.close()
|
items_positions.append(itemscript.substitute(params))
|
||||||
|
|
||||||
|
params = {
|
||||||
|
"disk" : "Bitcoin-Qt",
|
||||||
|
"window_bounds" : "300,300,800,620",
|
||||||
|
"icon_size" : "96",
|
||||||
|
"background_commands" : "",
|
||||||
|
"items_positions" : "\n ".join(items_positions)
|
||||||
|
}
|
||||||
|
if fancy.has_key("window_bounds"):
|
||||||
|
params["window.bounds"] = ",".join([str(p) for p in fancy["window_bounds"]])
|
||||||
|
if fancy.has_key("icon_size"):
|
||||||
|
params["icon_size"] = str(fancy["icon_size"])
|
||||||
if bg_path is not None:
|
if bg_path is not None:
|
||||||
subprocess.call(["SetFile", "-a", "V", bg_path])
|
# Set background file, then call SetFile to make it invisible.
|
||||||
# disk.update(registering_applications=False)
|
# (note: making it invisible first makes set background picture fail)
|
||||||
sleep(2)
|
bgscript = Template("""set background picture of theViewOptions to file "$bgpic"
|
||||||
disk.eject()
|
do shell script "SetFile -a V /Volumes/$disk/$bgpic" """)
|
||||||
|
params["background_commands"] = bgscript.substitute({"bgpic" : os.path.basename(bg_path), "disk" : params["disk"]})
|
||||||
|
|
||||||
|
s = appscript.substitute(params)
|
||||||
|
if verbose >= 2:
|
||||||
|
print("Running AppleScript:")
|
||||||
|
print(s)
|
||||||
|
|
||||||
|
p = subprocess.Popen(['osascript', '-'], stdin=subprocess.PIPE)
|
||||||
|
p.communicate(input=s)
|
||||||
|
if p.returncode:
|
||||||
|
print("Error running osascript.")
|
||||||
|
|
||||||
if verbose >= 2:
|
if verbose >= 2:
|
||||||
print "+ Finalizing .dmg disk image +"
|
print "+ Finalizing .dmg disk image +"
|
||||||
|
|
|
@ -83,7 +83,8 @@
|
||||||
make
|
make
|
||||||
export QTDIR=/opt/local/share/qt4 # needed to find translations/qt_*.qm files
|
export QTDIR=/opt/local/share/qt4 # needed to find translations/qt_*.qm files
|
||||||
T=$(contrib/qt_translations.py $QTDIR/translations src/qt/locale)
|
T=$(contrib/qt_translations.py $QTDIR/translations src/qt/locale)
|
||||||
python2.7 contrib/macdeploy/macdeployqtplus Bitcoin-Qt.app -add-qt-tr $T -dmg -fancy contrib/macdeploy/fancy.plist
|
export CODESIGNARGS='--sign "Developer ID Application: BITCOIN FOUNDATION, INC., THE"'
|
||||||
|
python2.7 contrib/macdeploy/macdeployqtplus Bitcoin-Qt.app -sign -add-qt-tr $T -dmg -fancy contrib/macdeploy/fancy.plist
|
||||||
|
|
||||||
Build output expected:
|
Build output expected:
|
||||||
Bitcoin-Qt.dmg
|
Bitcoin-Qt.dmg
|
||||||
|
|
Loading…
Reference in a new issue