2021-04-16 00:59:52 +00:00
|
|
|
#!/usr/bin/env python3
|
2012-08-13 10:08:22 +00:00
|
|
|
import os
|
|
|
|
import shutil
|
2014-12-13 00:29:57 +00:00
|
|
|
import fileinput
|
2024-02-22 18:38:46 +00:00
|
|
|
import dylib_unhell
|
2024-04-13 10:42:32 +00:00
|
|
|
import subprocess
|
2013-04-08 19:44:46 +00:00
|
|
|
from optparse import OptionParser
|
2012-08-13 10:08:22 +00:00
|
|
|
|
2013-07-16 11:28:28 +00:00
|
|
|
def bundle_path(binary_name):
|
2012-08-13 10:08:22 +00:00
|
|
|
return "%s.app" % binary_name
|
|
|
|
|
2013-07-16 11:28:28 +00:00
|
|
|
def bundle_name(binary_name):
|
|
|
|
return os.path.basename(bundle_path(binary_name))
|
|
|
|
|
2013-04-08 19:44:46 +00:00
|
|
|
def target_plist(binary_name):
|
2013-07-16 11:28:28 +00:00
|
|
|
return os.path.join(bundle_path(binary_name), 'Contents', 'Info.plist')
|
2012-08-13 10:08:22 +00:00
|
|
|
|
2013-04-08 19:44:46 +00:00
|
|
|
def target_directory(binary_name):
|
2013-07-16 11:28:28 +00:00
|
|
|
return os.path.join(bundle_path(binary_name), 'Contents', 'MacOS')
|
2012-08-13 10:08:22 +00:00
|
|
|
|
2013-04-08 19:44:46 +00:00
|
|
|
def target_binary(binary_name):
|
2013-07-16 11:28:28 +00:00
|
|
|
return os.path.join(target_directory(binary_name),
|
|
|
|
os.path.basename(binary_name))
|
2012-08-13 10:08:22 +00:00
|
|
|
|
2024-02-17 21:40:46 +00:00
|
|
|
def copy_bundle(binary_name, src_path):
|
2013-07-16 11:28:28 +00:00
|
|
|
if os.path.isdir(bundle_path(binary_name)):
|
|
|
|
shutil.rmtree(bundle_path(binary_name))
|
2012-08-13 10:08:22 +00:00
|
|
|
shutil.copytree(
|
2024-02-17 21:40:46 +00:00
|
|
|
os.path.join(src_path, 'TOOLS', 'osxbundle', bundle_name(binary_name)),
|
2013-07-16 11:28:28 +00:00
|
|
|
bundle_path(binary_name))
|
2012-08-13 10:08:22 +00:00
|
|
|
|
2013-04-08 19:44:46 +00:00
|
|
|
def copy_binary(binary_name):
|
|
|
|
shutil.copy(binary_name, target_binary(binary_name))
|
2012-08-13 10:08:22 +00:00
|
|
|
|
|
|
|
def apply_plist_template(plist_file, version):
|
2014-12-13 00:29:57 +00:00
|
|
|
for line in fileinput.input(plist_file, inplace=1):
|
2020-02-27 19:46:42 +00:00
|
|
|
print(line.rstrip().replace('${VERSION}', version))
|
2012-08-13 10:08:22 +00:00
|
|
|
|
2023-11-13 22:47:16 +00:00
|
|
|
def sign_bundle(binary_name):
|
2024-03-02 13:03:48 +00:00
|
|
|
sign_directories = ['Contents/Frameworks', 'Contents/MacOS']
|
|
|
|
for dir in sign_directories:
|
|
|
|
resolved_dir = os.path.join(bundle_path(binary_name), dir)
|
|
|
|
for root, _dirs, files in os.walk(resolved_dir):
|
|
|
|
for f in files:
|
2024-04-13 10:42:32 +00:00
|
|
|
subprocess.run(['codesign', '--force', '-s', '-', os.path.join(root, f)])
|
|
|
|
subprocess.run(['codesign', '--force', '-s', '-', bundle_path(binary_name)])
|
2023-11-13 22:47:16 +00:00
|
|
|
|
2024-02-17 21:40:46 +00:00
|
|
|
def bundle_version(src_path):
|
2024-02-17 21:38:24 +00:00
|
|
|
version = 'UNKNOWN'
|
2024-02-17 21:40:46 +00:00
|
|
|
version_path = os.path.join(src_path, 'VERSION')
|
|
|
|
if os.path.exists(version_path):
|
|
|
|
x = open(version_path)
|
2016-01-05 11:24:50 +00:00
|
|
|
version = x.read()
|
|
|
|
x.close()
|
|
|
|
return version
|
|
|
|
|
2013-04-08 19:44:46 +00:00
|
|
|
def main():
|
|
|
|
usage = "usage: %prog [options] arg"
|
|
|
|
parser = OptionParser(usage)
|
|
|
|
parser.add_option("-s", "--skip-deps", action="store_false", dest="deps",
|
|
|
|
default=True,
|
|
|
|
help="don't bundle the dependencies")
|
|
|
|
|
|
|
|
(options, args) = parser.parse_args()
|
|
|
|
|
2024-02-17 21:40:46 +00:00
|
|
|
if len(args) < 1 or len(args) > 2:
|
2013-04-08 19:44:46 +00:00
|
|
|
parser.error("incorrect number of arguments")
|
|
|
|
else:
|
|
|
|
binary_name = args[0]
|
2024-02-17 21:40:46 +00:00
|
|
|
src_path = args[1] if len(args) > 1 else "."
|
2013-04-08 19:44:46 +00:00
|
|
|
|
2024-02-17 21:40:46 +00:00
|
|
|
version = bundle_version(src_path).rstrip()
|
2024-02-17 21:38:24 +00:00
|
|
|
|
2024-02-20 20:24:54 +00:00
|
|
|
print("Creating macOS application bundle (version: %s)..." % version)
|
2013-04-08 19:44:46 +00:00
|
|
|
print("> copying bundle skeleton")
|
2024-02-17 21:40:46 +00:00
|
|
|
copy_bundle(binary_name, src_path)
|
2013-04-08 19:44:46 +00:00
|
|
|
print("> copying binary")
|
|
|
|
copy_binary(binary_name)
|
|
|
|
print("> generating Info.plist")
|
|
|
|
apply_plist_template(target_plist(binary_name), version)
|
|
|
|
|
|
|
|
if options.deps:
|
|
|
|
print("> bundling dependencies")
|
2024-02-22 18:38:46 +00:00
|
|
|
dylib_unhell.process(target_binary(binary_name))
|
2013-04-08 19:44:46 +00:00
|
|
|
|
2023-11-13 22:47:16 +00:00
|
|
|
print("> signing bundle with ad-hoc pseudo identity")
|
|
|
|
sign_bundle(binary_name)
|
|
|
|
|
2013-04-08 19:44:46 +00:00
|
|
|
print("done.")
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
main()
|