Fix mac osx deploy scripts.

This commit is contained in:
vertoe 2015-01-16 10:19:59 +01:00
parent 9a18c01433
commit 0745120cfa
4 changed files with 87 additions and 76 deletions

17
INSTALL
View File

@ -1,5 +1,16 @@
Building Bitcoin
Building Darkcoin
See doc/build-*.md for instructions on building bitcoind,
Use the autogen script to prepare the build environment.
./autogen.sh
./configure
make
Precompiled binaries are available at github, see
https://github.com/darkcoinproject/darkcoin-binaries
Always verify the signatures and checksums.
See doc/build-*.md for instructions on building darkcoind,
the intended-for-services, no-graphical-interface, reference
implementation of Bitcoin.
implementation of Darkcoin.

View File

@ -5,7 +5,7 @@ You will need the appscript package for the fancy disk image creation to work:
sudo easy_install appscript
For Snow Leopard (which uses [Python 2.6](http://www.python.org/download/releases/2.6/)), you will need the param_parser package:
sudo easy_install argparse
This script should not be run manually, instead, after building as usual:
@ -15,5 +15,5 @@ This script should not be run manually, instead, after building as usual:
During the process, the disk image window will pop up briefly where the fancy
settings are applied. This is normal, please do not interfere.
When finished, it will produce `Bitcoin-Qt.dmg`.
When finished, it will produce `Darkcoin-Qt.dmg`.

View File

@ -22,7 +22,7 @@
<integer>370</integer>
<integer>156</integer>
</array>
<key>Bitcoin-Qt.app</key>
<key>Darkcoin-Qt.app</key>
<array>
<integer>128</integer>
<integer>156</integer>

View File

@ -42,13 +42,13 @@ class FrameworkInfo(object):
self.sourceContentsDirectory = ""
self.destinationResourcesDirectory = ""
self.destinationVersionContentsDirectory = ""
def __eq__(self, other):
if self.__class__ == other.__class__:
return self.__dict__ == other.__dict__
else:
return False
def __str__(self):
return """ Framework name: %s
Framework directory: %s
@ -72,51 +72,51 @@ class FrameworkInfo(object):
self.deployedInstallName,
self.sourceFilePath,
self.destinationDirectory)
def isDylib(self):
return self.frameworkName.endswith(".dylib")
def isQtFramework(self):
if self.isDylib():
return self.frameworkName.startswith("libQt")
else:
return self.frameworkName.startswith("Qt")
reOLine = re.compile(r'^(.+) \(compatibility version [0-9.]+, current version [0-9.]+\)$')
bundleFrameworkDirectory = "Contents/Frameworks"
bundleBinaryDirectory = "Contents/MacOS"
@classmethod
def fromOtoolLibraryLine(cls, line):
# Note: line must be trimmed
if line == "":
return None
# Don't deploy system libraries (exception for libQtuitools and libQtlucene).
if line.startswith("/System/Library/") or line.startswith("@executable_path") or (line.startswith("/usr/lib/") and "libQt" not in line):
return None
m = cls.reOLine.match(line)
if m is None:
raise RuntimeError("otool line could not be parsed: " + line)
path = m.group(1)
info = cls()
info.sourceFilePath = path
info.installName = path
if path.endswith(".dylib"):
dirname, filename = os.path.split(path)
info.frameworkName = filename
info.frameworkDirectory = dirname
info.frameworkPath = path
info.binaryDirectory = dirname
info.binaryName = filename
info.binaryPath = path
info.version = "-"
info.installName = path
info.deployedInstallName = "@executable_path/../Frameworks/" + info.binaryName
info.sourceFilePath = path
@ -131,26 +131,26 @@ class FrameworkInfo(object):
i += 1
if i == len(parts):
raise RuntimeError("Could not find .framework or .dylib in otool line: " + line)
info.frameworkName = parts[i]
info.frameworkDirectory = "/".join(parts[:i])
info.frameworkPath = os.path.join(info.frameworkDirectory, info.frameworkName)
info.binaryName = parts[i+3]
info.binaryDirectory = "/".join(parts[i+1:i+3])
info.binaryPath = os.path.join(info.binaryDirectory, info.binaryName)
info.version = parts[i+2]
info.deployedInstallName = "@executable_path/../Frameworks/" + os.path.join(info.frameworkName, info.binaryPath)
info.destinationDirectory = os.path.join(cls.bundleFrameworkDirectory, info.frameworkName, info.binaryDirectory)
info.sourceResourcesDirectory = os.path.join(info.frameworkPath, "Resources")
info.sourceContentsDirectory = os.path.join(info.frameworkPath, "Contents")
info.sourceVersionContentsDirectory = os.path.join(info.frameworkPath, "Versions", info.version, "Contents")
info.destinationResourcesDirectory = os.path.join(cls.bundleFrameworkDirectory, info.frameworkName, "Resources")
info.destinationContentsDirectory = os.path.join(cls.bundleFrameworkDirectory, info.frameworkName, "Contents")
info.destinationVersionContentsDirectory = os.path.join(cls.bundleFrameworkDirectory, info.frameworkName, "Versions", info.version, "Contents")
return info
class ApplicationBundleInfo(object):
@ -168,7 +168,7 @@ class DeploymentInfo(object):
self.qtPath = None
self.pluginPath = None
self.deployedFrameworks = []
def detectQtPath(self, frameworkDirectory):
parentDir = os.path.dirname(frameworkDirectory)
if os.path.exists(os.path.join(parentDir, "translations")):
@ -187,7 +187,7 @@ class DeploymentInfo(object):
pluginPath = os.path.join(self.qtPath, "plugins")
if os.path.exists(pluginPath):
self.pluginPath = pluginPath
def usesFramework(self, name):
nameDot = "%s." % name
libNameDot = "lib%s." % name
@ -211,12 +211,12 @@ def getFrameworks(binaryPath, verbose):
sys.stderr.write(o_stderr)
sys.stderr.flush()
raise RuntimeError("otool failed with return code %d" % otool.returncode)
otoolLines = o_stdout.split("\n")
otoolLines.pop(0) # First line is the inspected binary
if ".framework" in binaryPath or binaryPath.endswith(".dylib"):
otoolLines.pop(0) # Frameworks and dylibs list themselves as a dependency.
libraries = []
for line in otoolLines:
info = FrameworkInfo.fromOtoolLibraryLine(line.strip())
@ -225,7 +225,7 @@ def getFrameworks(binaryPath, verbose):
print "Found framework:"
print info
libraries.append(info)
return libraries
def runInstallNameTool(action, *args):
@ -262,16 +262,16 @@ def copyFramework(framework, path, verbose):
fromPath = framework.sourceFilePath
toDir = os.path.join(path, framework.destinationDirectory)
toPath = os.path.join(toDir, framework.binaryName)
if not os.path.exists(fromPath):
raise RuntimeError("No file at " + fromPath)
if os.path.exists(toPath):
return None # Already there
if not os.path.exists(toDir):
os.makedirs(toDir)
shutil.copy2(fromPath, toPath)
if verbose >= 3:
print "Copied:", fromPath
@ -314,53 +314,53 @@ def copyFramework(framework, path, verbose):
if verbose >= 3:
print "Copied for libQtGui:", qtMenuNibSourcePath
print " to:", qtMenuNibDestinationPath
return toPath
def deployFrameworks(frameworks, bundlePath, binaryPath, strip, verbose, deploymentInfo=None):
if deploymentInfo is None:
deploymentInfo = DeploymentInfo()
while len(frameworks) > 0:
framework = frameworks.pop(0)
deploymentInfo.deployedFrameworks.append(framework.frameworkName)
if verbose >= 2:
print "Processing", framework.frameworkName, "..."
# Get the Qt path from one of the Qt frameworks
if deploymentInfo.qtPath is None and framework.isQtFramework():
deploymentInfo.detectQtPath(framework.frameworkDirectory)
if framework.installName.startswith("@executable_path"):
if verbose >= 2:
print framework.frameworkName, "already deployed, skipping."
continue
# install_name_tool the new id into the binary
changeInstallName(framework.installName, framework.deployedInstallName, binaryPath, verbose)
# Copy farmework to app bundle.
deployedBinaryPath = copyFramework(framework, bundlePath, verbose)
# Skip the rest if already was deployed.
if deployedBinaryPath is None:
continue
if strip:
runStrip(deployedBinaryPath, verbose)
# install_name_tool it a new id.
changeIdentification(framework.deployedInstallName, deployedBinaryPath, verbose)
# Check for framework dependencies
dependencies = getFrameworks(deployedBinaryPath, verbose)
for dependency in dependencies:
changeInstallName(dependency.installName, dependency.deployedInstallName, deployedBinaryPath, verbose)
# Deploy framework if necessary.
if dependency.frameworkName not in deploymentInfo.deployedFrameworks and dependency not in frameworks:
frameworks.append(dependency)
return deploymentInfo
def deployFrameworksForAppBundle(applicationBundle, strip, verbose):
@ -401,7 +401,7 @@ def deployPlugins(appBundleInfo, deploymentInfo, strip, verbose):
# Deploy the bearer plugins only if QtNetwork is in use
if not deploymentInfo.usesFramework("QtNetwork"):
continue
for pluginName in filenames:
pluginPath = os.path.join(pluginDirectory, pluginName)
if pluginName.endswith("_debug.dylib"):
@ -419,32 +419,32 @@ def deployPlugins(appBundleInfo, deploymentInfo, strip, verbose):
# Deploy the opengl graphicssystem plugin only if QtOpenGL is in use
if not deploymentInfo.usesFramework("QtOpenGL"):
continue
plugins.append((pluginDirectory, pluginName))
for pluginDirectory, pluginName in plugins:
if verbose >= 2:
print "Processing plugin", os.path.join(pluginDirectory, pluginName), "..."
sourcePath = os.path.join(deploymentInfo.pluginPath, pluginDirectory, pluginName)
destinationDirectory = os.path.join(appBundleInfo.pluginPath, pluginDirectory)
if not os.path.exists(destinationDirectory):
os.makedirs(destinationDirectory)
destinationPath = os.path.join(destinationDirectory, pluginName)
shutil.copy2(sourcePath, destinationPath)
if verbose >= 3:
print "Copied:", sourcePath
print " to:", destinationPath
if strip:
runStrip(destinationPath, verbose)
dependencies = getFrameworks(destinationPath, verbose)
for dependency in dependencies:
changeInstallName(dependency.installName, dependency.deployedInstallName, destinationPath, verbose)
# Deploy framework if necessary.
if dependency.frameworkName not in deploymentInfo.deployedFrameworks:
deployFrameworks([dependency], appBundleInfo.path, destinationPath, strip, verbose, deploymentInfo)
@ -511,7 +511,7 @@ if len(config.fancy) == 1:
if verbose >= 1:
sys.stderr.write("Error: Could not import plistlib which is required for fancy disk images.\n")
sys.exit(1)
if verbose >= 3:
print "Fancy: Importing appscript..."
try:
@ -521,7 +521,7 @@ if len(config.fancy) == 1:
sys.stderr.write("Error: Could not import appscript which is required for fancy disk images.\n")
sys.stderr.write("Please install it e.g. with \"sudo easy_install appscript\".\n")
sys.exit(1)
p = config.fancy[0]
if verbose >= 3:
print "Fancy: Loading \"%s\"..." % p
@ -529,14 +529,14 @@ if len(config.fancy) == 1:
if verbose >= 1:
sys.stderr.write("Error: Could not find fancy disk image plist at \"%s\"\n" % (p))
sys.exit(1)
try:
fancy = plistlib.readPlist(p)
except:
if verbose >= 1:
sys.stderr.write("Error: Could not parse fancy disk image plist at \"%s\"\n" % (p))
sys.exit(1)
try:
assert not fancy.has_key("window_bounds") or (isinstance(fancy["window_bounds"], list) and len(fancy["window_bounds"]) == 4)
assert not fancy.has_key("background_picture") or isinstance(fancy["background_picture"], str)
@ -550,7 +550,7 @@ if len(config.fancy) == 1:
if verbose >= 1:
sys.stderr.write("Error: Bad format of fancy disk image plist at \"%s\"\n" % (p))
sys.exit(1)
if fancy.has_key("background_picture"):
bp = fancy["background_picture"]
if verbose >= 3:
@ -571,7 +571,7 @@ else:
if os.path.exists("dist"):
if verbose >= 2:
print "+ Removing old dist folder +"
shutil.rmtree("dist")
# ------------------------------------------------
@ -611,7 +611,7 @@ except RuntimeError as e:
if config.plugins:
if verbose >= 2:
print "+ Deploying plugins +"
try:
deployPlugins(applicationBundle, deploymentInfo, config.strip, verbose)
except RuntimeError as e:
@ -708,26 +708,26 @@ if config.dmg is not None:
elif verbose >= 3:
hdiutil_args.append("-verbose")
run = subprocess.check_call
for key, value in kwargs.iteritems():
hdiutil_args.append("-" + key)
if not value is True:
hdiutil_args.append(str(value))
return run(hdiutil_args)
if verbose >= 2:
if fancy is None:
print "+ Creating .dmg disk image +"
else:
print "+ Preparing .dmg disk image +"
if config.dmg != "":
dmg_name = config.dmg
else:
spl = app_bundle_name.split(" ")
dmg_name = spl[0] + "".join(p.capitalize() for p in spl[1:])
if fancy is None:
try:
runHDIUtil("create", dmg_name, srcfolder="dist", format="UDBZ", volname=app_bundle_name, ov=True)
@ -741,28 +741,28 @@ if config.dmg is not None:
for file in files:
size += os.path.getsize(os.path.join(path, file))
size += int(size * 0.1)
if verbose >= 3:
print "Creating temp image for modification..."
try:
runHDIUtil("create", dmg_name + ".temp", srcfolder="dist", format="UDRW", size=size, volname=app_bundle_name, ov=True)
except subprocess.CalledProcessError as e:
sys.exit(e.returncode)
if verbose >= 3:
print "Attaching temp image..."
try:
output = runHDIUtil("attach", dmg_name + ".temp", readwrite=True, noverify=True, noautoopen=True, capture_stdout=True)
except subprocess.CalledProcessError as e:
sys.exit(e.returncode)
m = re.search("/Volumes/(.+$)", output)
disk_root = m.group(0)
disk_name = m.group(1)
if verbose >= 2:
print "+ Applying fancy settings +"
if fancy.has_key("background_picture"):
bg_path = os.path.join(disk_root, os.path.basename(fancy["background_picture"]))
if verbose >= 3:
@ -770,10 +770,10 @@ if config.dmg is not None:
shutil.copy2(fancy["background_picture"], bg_path)
else:
bg_path = None
if fancy.get("applications_symlink", False):
os.symlink("/Applications", os.path.join(disk_root, "Applications"))
# The Python appscript package broke with OSX 10.8 and isn't being fixed.
# So we now build up an AppleScript string and use the osascript command
# to make the .dmg file pretty:
@ -809,7 +809,7 @@ if config.dmg is not None:
items_positions.append(itemscript.substitute(params))
params = {
"disk" : "Bitcoin-Qt",
"disk" : "Darkcoin-Qt",
"window_bounds" : "300,300,800,620",
"icon_size" : "96",
"background_commands" : "",
@ -838,12 +838,12 @@ if config.dmg is not None:
if verbose >= 2:
print "+ Finalizing .dmg disk image +"
try:
runHDIUtil("convert", dmg_name + ".temp", format="UDBZ", o=dmg_name + ".dmg", ov=True)
except subprocess.CalledProcessError as e:
sys.exit(e.returncode)
os.unlink(dmg_name + ".temp.dmg")
# ------------------------------------------------