2017-12-12 16:47:24 -03:00
#!/usr/bin/env python3
2011-11-02 10:58:50 -03:00
#
# Copyright (C) 2011 Patrick "p2k" Schneider <me@p2k-network.org>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
2021-07-25 11:29:57 -04:00
import sys, re, os, platform, shutil, stat, subprocess, os.path
2011-11-02 10:58:50 -03:00
from argparse import ArgumentParser
2020-11-08 03:43:58 -03:00
from pathlib import Path
2020-11-11 04:29:00 -03:00
from subprocess import PIPE, run
2023-10-24 19:55:17 -03:00
from typing import Optional
2011-11-02 10:58:50 -03:00
2012-01-19 17:45:49 -03:00
# This is ported from the original macdeployqt with modifications
class FrameworkInfo(object):
def __init__(self):
self.frameworkDirectory = ""
self.frameworkName = ""
self.frameworkPath = ""
self.binaryDirectory = ""
self.binaryName = ""
self.binaryPath = ""
self.version = ""
self.installName = ""
self.deployedInstallName = ""
self.sourceFilePath = ""
self.destinationDirectory = ""
self.sourceResourcesDirectory = ""
2014-05-30 19:14:01 -04:00
self.sourceVersionContentsDirectory = ""
self.sourceContentsDirectory = ""
2012-01-19 17:45:49 -03:00
self.destinationResourcesDirectory = ""
2014-05-30 19:14:01 -04:00
self.destinationVersionContentsDirectory = ""
2012-01-19 17:45:49 -03:00
def __eq__(self, other):
if self.__class__ == other.__class__:
return self.__dict__ == other.__dict__
else:
return False
def __str__(self):
2021-05-31 04:31:51 -04:00
return f""" Framework name: {self.frameworkName}
2020-11-13 04:38:03 -03:00
Framework directory: {self.frameworkDirectory}
Framework path: {self.frameworkPath}
Binary name: {self.binaryName}
Binary directory: {self.binaryDirectory}
Binary path: {self.binaryPath}
Version: {self.version}
Install name: {self.installName}
Deployed install name: {self.deployedInstallName}
Source file Path: {self.sourceFilePath}
Deployed Directory (relative to bundle): {self.destinationDirectory}
"""
2012-01-19 17:45:49 -03:00
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
2024-01-30 06:37:37 -03:00
def fromLibraryLine(cls, line: str) -> Optional['FrameworkInfo']:
2012-01-19 17:45:49 -03:00
# Note: line must be trimmed
if line == "":
return None
2021-06-02 00:15:15 -04:00
# Don't deploy system libraries
if line.startswith("/System/Library/") or line.startswith("@executable_path") or line.startswith("/usr/lib/"):
2012-01-19 17:45:49 -03:00
return None
m = cls.reOLine.match(line)
if m is None:
2024-01-30 06:37:37 -03:00
raise RuntimeError(f"Line could not be parsed: {line}")
2012-01-19 17:45:49 -03:00
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
2020-11-13 04:38:03 -03:00
info.deployedInstallName = f"@executable_path/../Frameworks/{info.binaryName}"
2012-01-19 17:45:49 -03:00
info.sourceFilePath = path
info.destinationDirectory = cls.bundleFrameworkDirectory
else:
parts = path.split("/")
i = 0
# Search for the .framework directory
for part in parts:
if part.endswith(".framework"):
break
i += 1
if i == len(parts):
2024-01-30 06:37:37 -03:00
raise RuntimeError(f"Could not find .framework or .dylib in line: {line}")
2012-01-19 17:45:49 -03:00
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]
2020-11-13 04:38:03 -03:00
info.deployedInstallName = f"@executable_path/../Frameworks/{os.path.join(info.frameworkName, info.binaryPath)}"
2012-01-19 17:45:49 -03:00
info.destinationDirectory = os.path.join(cls.bundleFrameworkDirectory, info.frameworkName, info.binaryDirectory)
info.sourceResourcesDirectory = os.path.join(info.frameworkPath, "Resources")
2014-05-30 19:14:01 -04:00
info.sourceContentsDirectory = os.path.join(info.frameworkPath, "Contents")
info.sourceVersionContentsDirectory = os.path.join(info.frameworkPath, "Versions", info.version, "Contents")
2012-01-19 17:45:49 -03:00
info.destinationResourcesDirectory = os.path.join(cls.bundleFrameworkDirectory, info.frameworkName, "Resources")
2014-05-30 19:14:01 -04:00
info.destinationVersionContentsDirectory = os.path.join(cls.bundleFrameworkDirectory, info.frameworkName, "Versions", info.version, "Contents")
2012-01-19 17:45:49 -03:00
return info
class ApplicationBundleInfo(object):
2019-07-15 22:40:31 -04:00
def __init__(self, path: str):
2012-01-19 17:45:49 -03:00
self.path = path
2020-11-13 04:38:03 -03:00
# for backwards compatibility reasons, this must remain as Bitcoin-Qt
self.binaryPath = os.path.join(path, "Contents", "MacOS", "Bitcoin-Qt")
2012-01-19 17:45:49 -03:00
if not os.path.exists(self.binaryPath):
2020-11-13 04:38:03 -03:00
raise RuntimeError(f"Could not find bundle binary for {path}")
2012-01-19 17:45:49 -03:00
self.resourcesPath = os.path.join(path, "Contents", "Resources")
self.pluginPath = os.path.join(path, "Contents", "PlugIns")
class DeploymentInfo(object):
def __init__(self):
self.qtPath = None
self.pluginPath = None
self.deployedFrameworks = []
2019-07-15 22:40:31 -04:00
def detectQtPath(self, frameworkDirectory: str):
2012-01-19 17:45:49 -03:00
parentDir = os.path.dirname(frameworkDirectory)
if os.path.exists(os.path.join(parentDir, "translations")):
# Classic layout, e.g. "/usr/local/Trolltech/Qt-4.x.x"
self.qtPath = parentDir
2012-11-21 16:38:56 -03:00
else:
self.qtPath = os.getenv("QTDIR", None)
2012-01-19 17:45:49 -03:00
if self.qtPath is not None:
pluginPath = os.path.join(self.qtPath, "plugins")
if os.path.exists(pluginPath):
self.pluginPath = pluginPath
2019-07-15 22:40:31 -04:00
def usesFramework(self, name: str) -> bool:
2012-01-19 17:45:49 -03:00
for framework in self.deployedFrameworks:
if framework.endswith(".framework"):
2020-11-13 04:38:03 -03:00
if framework.startswith(f"{name}."):
2012-01-19 17:45:49 -03:00
return True
elif framework.endswith(".dylib"):
2020-11-13 04:38:03 -03:00
if framework.startswith(f"lib{name}."):
2012-01-19 17:45:49 -03:00
return True
return False
2023-10-24 19:55:17 -03:00
def getFrameworks(binaryPath: str, verbose: int) -> list[FrameworkInfo]:
2024-01-30 06:37:37 -03:00
objdump = os.getenv("OBJDUMP", "objdump")
2020-11-09 00:10:39 -03:00
if verbose:
2024-01-30 06:37:37 -03:00
print(f"Inspecting with {objdump}: {binaryPath}")
output = run([objdump, "--macho", "--dylibs-used", binaryPath], stdout=PIPE, stderr=PIPE, text=True)
if output.returncode != 0:
sys.stderr.write(output.stderr)
2020-11-09 00:10:39 -03:00
sys.stderr.flush()
2024-01-30 06:37:37 -03:00
raise RuntimeError(f"{objdump} failed with return code {output.returncode}")
2016-04-02 11:45:26 -03:00
2024-01-30 06:37:37 -03:00
lines = output.stdout.split("\n")
lines.pop(0) # First line is the inspected binary
2012-01-19 17:45:49 -03:00
if ".framework" in binaryPath or binaryPath.endswith(".dylib"):
2024-01-30 06:37:37 -03:00
lines.pop(0) # Frameworks and dylibs list themselves as a dependency.
2012-01-19 17:45:49 -03:00
libraries = []
2024-01-30 06:37:37 -03:00
for line in lines:
2014-07-09 19:50:30 -04:00
line = line.replace("@loader_path", os.path.dirname(binaryPath))
2024-01-30 06:37:37 -03:00
info = FrameworkInfo.fromLibraryLine(line.strip())
2012-01-19 17:45:49 -03:00
if info is not None:
2020-11-09 00:10:39 -03:00
if verbose:
2016-03-20 14:51:52 -03:00
print("Found framework:")
print(info)
2012-01-19 17:45:49 -03:00
libraries.append(info)
return libraries
2019-07-15 22:40:31 -04:00
def runInstallNameTool(action: str, *args):
2022-04-15 12:39:17 -04:00
installnametoolbin=os.getenv("INSTALL_NAME_TOOL", "install_name_tool")
2020-11-11 04:29:00 -03:00
run([installnametoolbin, "-"+action] + list(args), check=True)
2012-01-19 17:45:49 -03:00
2019-07-15 22:40:31 -04:00
def changeInstallName(oldName: str, newName: str, binaryPath: str, verbose: int):
2020-11-09 00:10:39 -03:00
if verbose:
2016-03-20 14:51:52 -03:00
print("Using install_name_tool:")
print(" in", binaryPath)
print(" change reference", oldName)
print(" to", newName)
2012-01-19 17:45:49 -03:00
runInstallNameTool("change", oldName, newName, binaryPath)
2019-07-15 22:40:31 -04:00
def changeIdentification(id: str, binaryPath: str, verbose: int):
2020-11-09 00:10:39 -03:00
if verbose:
2016-03-20 14:51:52 -03:00
print("Using install_name_tool:")
print(" change identification in", binaryPath)
print(" to", id)
2012-01-19 17:45:49 -03:00
runInstallNameTool("id", id, binaryPath)
2019-07-15 22:40:31 -04:00
def runStrip(binaryPath: str, verbose: int):
2013-12-06 20:08:53 -03:00
stripbin=os.getenv("STRIP", "strip")
2020-11-09 00:10:39 -03:00
if verbose:
2016-03-20 14:51:52 -03:00
print("Using strip:")
print(" stripped", binaryPath)
2020-11-11 04:29:00 -03:00
run([stripbin, "-x", binaryPath], check=True)
2012-01-19 17:45:49 -03:00
2019-07-15 22:40:31 -04:00
def copyFramework(framework: FrameworkInfo, path: str, verbose: int) -> Optional[str]:
2012-11-21 16:38:56 -03:00
if framework.sourceFilePath.startswith("Qt"):
#standard place for Nokia Qt installer's frameworks
2020-11-13 04:38:03 -03:00
fromPath = f"/Library/Frameworks/{framework.sourceFilePath}"
2012-11-21 16:38:56 -03:00
else:
fromPath = framework.sourceFilePath
2012-01-19 17:45:49 -03:00
toDir = os.path.join(path, framework.destinationDirectory)
toPath = os.path.join(toDir, framework.binaryName)
2021-07-25 11:17:15 -04:00
if framework.isDylib():
if not os.path.exists(fromPath):
raise RuntimeError(f"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:
print("Copied:", fromPath)
print(" to:", toPath)
else:
to_dir = os.path.join(path, "Contents", "Frameworks", framework.frameworkName)
if os.path.exists(to_dir):
return None # Already there
from_dir = framework.frameworkPath
if not os.path.exists(from_dir):
raise RuntimeError(f"No directory at {from_dir}")
shutil.copytree(from_dir, to_dir, symlinks=True)
if verbose:
print("Copied:", from_dir)
print(" to:", to_dir)
headers_link = os.path.join(to_dir, "Headers")
if os.path.exists(headers_link):
os.unlink(headers_link)
headers_dir = os.path.join(to_dir, framework.binaryDirectory, "Headers")
if os.path.exists(headers_dir):
shutil.rmtree(headers_dir)
2012-02-06 11:32:35 -03:00
permissions = os.stat(toPath)
if not permissions.st_mode & stat.S_IWRITE:
os.chmod(toPath, permissions.st_mode | stat.S_IWRITE)
2012-01-19 17:45:49 -03:00
return toPath
2023-10-24 19:55:17 -03:00
def deployFrameworks(frameworks: list[FrameworkInfo], bundlePath: str, binaryPath: str, strip: bool, verbose: int, deploymentInfo: Optional[DeploymentInfo] = None) -> DeploymentInfo:
2012-01-19 17:45:49 -03:00
if deploymentInfo is None:
deploymentInfo = DeploymentInfo()
while len(frameworks) > 0:
framework = frameworks.pop(0)
deploymentInfo.deployedFrameworks.append(framework.frameworkName)
2020-11-09 00:10:39 -03:00
print("Processing", framework.frameworkName, "...")
2012-01-19 17:45:49 -03:00
# Get the Qt path from one of the Qt frameworks
if deploymentInfo.qtPath is None and framework.isQtFramework():
deploymentInfo.detectQtPath(framework.frameworkDirectory)
2014-07-09 19:50:30 -04:00
if framework.installName.startswith("@executable_path") or framework.installName.startswith(bundlePath):
2020-11-09 00:10:39 -03:00
print(framework.frameworkName, "already deployed, skipping.")
2012-01-19 17:45:49 -03:00
continue
# install_name_tool the new id into the binary
changeInstallName(framework.installName, framework.deployedInstallName, binaryPath, verbose)
2017-01-29 14:19:55 -03:00
# Copy framework to app bundle.
2012-01-19 17:45:49 -03:00
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
2019-07-15 22:40:31 -04:00
def deployFrameworksForAppBundle(applicationBundle: ApplicationBundleInfo, strip: bool, verbose: int) -> DeploymentInfo:
2012-01-19 17:45:49 -03:00
frameworks = getFrameworks(applicationBundle.binaryPath, verbose)
2020-11-09 00:10:39 -03:00
if len(frameworks) == 0:
2020-11-13 04:38:03 -03:00
print(f"Warning: Could not find any external frameworks to deploy in {applicationBundle.path}.")
2012-01-19 17:45:49 -03:00
return DeploymentInfo()
else:
return deployFrameworks(frameworks, applicationBundle.path, applicationBundle.binaryPath, strip, verbose)
2019-07-15 22:40:31 -04:00
def deployPlugins(appBundleInfo: ApplicationBundleInfo, deploymentInfo: DeploymentInfo, strip: bool, verbose: int):
2012-01-19 17:45:49 -03:00
plugins = []
2013-12-06 20:08:53 -03:00
if deploymentInfo.pluginPath is None:
return
2012-01-19 17:45:49 -03:00
for dirpath, dirnames, filenames in os.walk(deploymentInfo.pluginPath):
pluginDirectory = os.path.relpath(dirpath, deploymentInfo.pluginPath)
2021-05-31 21:20:16 -04:00
if pluginDirectory not in ['styles', 'platforms']:
2019-07-15 22:48:19 -04:00
continue
2014-10-01 20:22:20 -03:00
2012-01-19 17:45:49 -03:00
for pluginName in filenames:
pluginPath = os.path.join(pluginDirectory, pluginName)
2021-05-31 21:20:16 -04:00
if pluginName.split('.')[0] not in ['libqminimal', 'libqcocoa', 'libqmacstyle']:
2012-01-19 17:45:49 -03:00
continue
2014-10-01 20:22:20 -03:00
2012-01-19 17:45:49 -03:00
plugins.append((pluginDirectory, pluginName))
for pluginDirectory, pluginName in plugins:
2020-11-09 00:10:39 -03:00
print("Processing plugin", os.path.join(pluginDirectory, pluginName), "...")
2012-01-19 17:45:49 -03:00
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)
2020-11-09 00:10:39 -03:00
if verbose:
2016-03-20 14:51:52 -03:00
print("Copied:", sourcePath)
print(" to:", destinationPath)
2012-01-19 17:45:49 -03:00
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)
ap = ArgumentParser(description="""Improved version of macdeployqt.
2011-11-02 10:58:50 -03:00
2022-11-18 09:04:51 -03:00
Outputs a ready-to-deploy app in a folder "dist" and optionally wraps it in a .zip file.
2011-11-02 10:58:50 -03:00
Note, that the "dist" folder will be deleted before deploying on each run.
2020-11-08 23:51:20 -03:00
Optionally, Qt translation files (.qm) can be added to the bundle.""")
2011-11-02 10:58:50 -03:00
ap.add_argument("app_bundle", nargs=1, metavar="app-bundle", help="application bundle to be deployed")
2020-11-09 06:47:21 -03:00
ap.add_argument("appname", nargs=1, metavar="appname", help="name of the app being deployed")
2020-11-09 00:10:39 -03:00
ap.add_argument("-verbose", nargs="?", const=True, help="Output additional debugging information")
2011-11-02 10:58:50 -03:00
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")
2020-11-08 03:43:58 -03:00
ap.add_argument("-translations-dir", nargs=1, metavar="path", default=None, help="Path to Qt's translations. Base translations will automatically be added to the bundle's resources.")
2020-05-25 21:11:05 -04:00
ap.add_argument("-zip", nargs="?", const="", metavar="zip", help="create a .zip containing the app bundle")
2011-11-02 10:58:50 -03:00
config = ap.parse_args()
2020-11-09 00:10:39 -03:00
verbose = config.verbose
2011-11-02 10:58:50 -03:00
# ------------------------------------------------
app_bundle = config.app_bundle[0]
2020-11-11 02:16:27 -03:00
appname = config.appname[0]
2011-11-02 10:58:50 -03:00
if not os.path.exists(app_bundle):
2020-11-13 04:38:03 -03:00
sys.stderr.write(f"Error: Could not find app bundle \"{app_bundle}\"\n")
2011-11-02 10:58:50 -03:00
sys.exit(1)
# ------------------------------------------------
if os.path.exists("dist"):
2020-11-11 02:16:27 -03:00
print("+ Removing existing dist folder +")
2011-11-02 10:58:50 -03:00
shutil.rmtree("dist")
2022-11-18 09:04:51 -03:00
if os.path.exists(appname + ".zip"):
print("+ Removing existing .zip +")
os.unlink(appname + ".zip")
2021-06-09 00:16:39 -04:00
2015-12-10 18:49:27 -03:00
# ------------------------------------------------
2015-06-01 10:42:34 -03:00
target = os.path.join("dist", "Bitcoin-Qt.app")
2011-11-02 10:58:50 -03:00
2020-11-09 00:10:39 -03:00
print("+ Copying source bundle +")
if verbose:
2016-03-20 14:51:52 -03:00
print(app_bundle, "->", target)
2011-11-02 10:58:50 -03:00
os.mkdir("dist")
2014-09-29 13:09:46 -03:00
shutil.copytree(app_bundle, target, symlinks=True)
2011-11-02 10:58:50 -03:00
2012-01-19 17:45:49 -03:00
applicationBundle = ApplicationBundleInfo(target)
2011-11-02 10:58:50 -03:00
2012-01-19 17:45:49 -03:00
# ------------------------------------------------
2011-11-02 10:58:50 -03:00
2020-11-09 00:10:39 -03:00
print("+ Deploying frameworks +")
2011-11-02 10:58:50 -03:00
2012-01-19 17:45:49 -03:00
try:
deploymentInfo = deployFrameworksForAppBundle(applicationBundle, config.strip, verbose)
if deploymentInfo.qtPath is None:
deploymentInfo.qtPath = os.getenv("QTDIR", None)
if deploymentInfo.qtPath is None:
2020-11-09 00:10:39 -03:00
sys.stderr.write("Warning: Could not detect Qt's path, skipping plugin deployment!\n")
2012-01-19 17:45:49 -03:00
config.plugins = False
except RuntimeError as e:
2020-11-13 04:38:03 -03:00
sys.stderr.write(f"Error: {str(e)}\n")
2014-05-15 02:27:35 -04:00
sys.exit(1)
2011-11-02 10:58:50 -03:00
# ------------------------------------------------
2012-01-19 17:45:49 -03:00
if config.plugins:
2020-11-09 00:10:39 -03:00
print("+ Deploying plugins +")
2012-01-19 17:45:49 -03:00
try:
deployPlugins(applicationBundle, deploymentInfo, config.strip, verbose)
except RuntimeError as e:
2020-11-13 04:38:03 -03:00
sys.stderr.write(f"Error: {str(e)}\n")
2014-05-15 02:27:35 -04:00
sys.exit(1)
2012-01-19 17:45:49 -03:00
# ------------------------------------------------
2020-11-08 03:43:58 -03:00
if config.translations_dir:
if not Path(config.translations_dir[0]).exists():
2020-11-13 04:38:03 -03:00
sys.stderr.write(f"Error: Could not find translation dir \"{config.translations_dir[0]}\"\n")
2020-11-08 03:43:58 -03:00
sys.exit(1)
2020-11-09 00:10:39 -03:00
print("+ Adding Qt translations +")
2020-11-08 03:43:58 -03:00
translations = Path(config.translations_dir[0])
regex = re.compile('qt_[a-z]*(.qm|_[A-Z]*.qm)')
lang_files = [x for x in translations.iterdir() if regex.match(x.name)]
for file in lang_files:
2020-11-09 00:10:39 -03:00
if verbose:
2020-11-08 03:43:58 -03:00
print(file.as_posix(), "->", os.path.join(applicationBundle.resourcesPath, file.name))
shutil.copy2(file.as_posix(), os.path.join(applicationBundle.resourcesPath, file.name))
2012-01-19 17:45:49 -03:00
# ------------------------------------------------
2020-11-09 00:10:39 -03:00
print("+ Installing qt.conf +")
2011-11-02 10:58:50 -03:00
2020-11-09 06:49:11 -03:00
qt_conf="""[Paths]
Translations=Resources
Plugins=PlugIns
"""
2017-04-25 05:14:57 -03:00
with open(os.path.join(applicationBundle.resourcesPath, "qt.conf"), "wb") as f:
f.write(qt_conf.encode())
2011-11-02 10:58:50 -03:00
# ------------------------------------------------
2021-07-25 11:29:57 -04:00
if platform.system() == "Darwin":
subprocess.check_call(f"codesign --deep --force --sign - {target}", shell=True)
2011-11-02 10:58:50 -03:00
# ------------------------------------------------
2020-05-25 21:11:05 -04:00
if config.zip is not None:
shutil.make_archive('{}'.format(appname), format='zip', root_dir='dist', base_dir='Bitcoin-Qt.app')
# ------------------------------------------------
2020-11-09 00:10:39 -03:00
print("+ Done +")
2011-11-02 10:58:50 -03:00
sys.exit(0)