Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
95 changes: 56 additions & 39 deletions scripts/fix_app_bundle_paths.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,49 +10,38 @@

class AppBundleChecker:

def __init__(self):
# Get command line arguments
args = self.parse_args()
self.app_path = os.path.join(os.getcwd(), args.app)

# Determine the exectutable to check
files = os.listdir(os.path.join(self.app_path, 'Contents/MacOS'))
# assumes only one executable in MacOS dir, which I think is standard
# for mac apps
self.executable_path = os.path.join(self.app_path, 'Contents/MacOS',
files[0])
# Set the frameworks path
self.frameworks_path = os.path.join(self.app_path,
"Contents/Frameworks")
# Set the plugins path
self.plugins_path = os.path.join(self.app_path,
"Contents/PlugIns")
def __init__(self, app, brew_prefix=None, app_path_override=False):
if app_path_override:
# supply exact app path to check, and use its directory directly
# for all dependencies.
app_path = os.path.dirname(app)
self.app_path = app_path
self.frameworks_path = app_path
self.plugins_path = app_path
# assuming only file present yet is the executable
self.executable_path = app
else:
self.app_path = os.path.join(os.getcwd(), app)
# Determine the exectutable to check
files = os.listdir(os.path.join(self.app_path, 'Contents/MacOS'))
# assumes only one executable in MacOS dir, which I think is standard
# for mac apps
self.executable_path = os.path.join(self.app_path, 'Contents/MacOS',
files[0])
# Set the frameworks path
self.frameworks_path = os.path.join(self.app_path,
"Contents/Frameworks")
# Set the plugins path
self.plugins_path = os.path.join(self.app_path,
"Contents/PlugIns")

# Find the homebrew path
brew_prefix = args.brew_prefix
if not brew_prefix:
brew_prefix = "/opt/homebrew"
if not (os.path.exists(brew_prefix)):
brew_prefix = "/usr/local"
self.homebrew_path = brew_prefix + '/opt'

def parse_args(self):
""" Instantiate a command line argument parser """

# Define command line arguments which can be provided
parser = argparse.ArgumentParser(
description="Check for Library paths missed by macdeployqt in" +
"MAC .app bundles")
parser.add_argument(
'--app', type=str, required=True,
help='relative path to .app bundle')
parser.add_argument('--brew_prefix', type=str, default=None, help="homebrew prefix")

# Parse the command line arguments
args = parser.parse_args()

return args

def check(self):
# check app itself
self.check_executable(self.executable_path)
Expand Down Expand Up @@ -122,8 +111,9 @@ def fix_library_path(self, library_path, referenced_from):
self.add_library_to_app(library_name)
# always need to update reference
print("Updating reference: ", library_name)
new_library_path = self.get_new_library_path()
subprocess.run(["install_name_tool", "-change", library_path,
"@executable_path/../Frameworks/" + library_name,
new_library_path + library_name,
referenced_from])

def exists_in_app(self, lib):
Expand All @@ -141,6 +131,8 @@ def add_library_to_app(self, library_name):
print(src, " is a framework")
new_library_path = self.frameworks_path + "/" + library_name
self.update_self_references(library_name, new_library_path, src)
# if this library just got added, run check_executable on it too
self.check_executable(new_library_path)

def add_framework_to_app(self, framework_name):
framework_dir = Path(framework_name).parts[0]
Expand All @@ -167,17 +159,42 @@ def update_self_references(self, name, new_path, old_path):
# update ID and self-reference of a file that has just been added to
# the app bundle
# update ID of file just copied
new_library_path = self.get_new_library_path()
subprocess.run(["install_name_tool", "-id",
"@executable_path/../Frameworks/" + name,
new_library_path + name,
new_path])
# update self-reference of file just copied
subprocess.run(["install_name_tool", "-change", old_path,
"@executable_path/../Frameworks/" + name,
new_library_path + name,
new_path])

def get_new_library_path(self):
new_library_path = "@executable_path/../Frameworks/"
if self.frameworks_path == self.app_path: # no app bundle structure
new_library_path = "@executable_path/"
return new_library_path

def parse_args():
""" Instantiate a command line argument parser """

# Define command line arguments which can be provided
parser = argparse.ArgumentParser(
description="Check for Library paths missed by macdeployqt in" +
"MAC .app bundles")
parser.add_argument(
'--app', type=str, required=True,
help='relative path to .app bundle')
parser.add_argument('--brew_prefix', type=str, default=None, help="homebrew prefix")

# Parse the command line arguments
args = parser.parse_args()

return args


def main():
checker = AppBundleChecker()
args = parse_args()
checker = AppBundleChecker(args.app, args.brew_prefix)
checker.check()


Expand Down
Loading