Fix mac osx deploy scripts.
This commit is contained in:
parent
9a18c01433
commit
0745120cfa
17
INSTALL
17
INSTALL
@ -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.
|
||||
|
@ -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`.
|
||||
|
||||
|
@ -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>
|
||||
|
@ -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")
|
||||
|
||||
# ------------------------------------------------
|
||||
|
Loading…
Reference in New Issue
Block a user