mirror of
https://github.com/space-wizards/RobustToolbox.git
synced 2026-02-14 19:29:36 +01:00
Avoid needing to get executable path from MainModule, which broke the game when run with the dotnet command instead of the bin's apphost. Fixes tests.
119 lines
4.1 KiB
Python
Executable File
119 lines
4.1 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
|
|
import argparse
|
|
import os
|
|
import re
|
|
import shutil
|
|
import plistlib
|
|
|
|
p = os.path.join
|
|
|
|
symlinkable_re = re.compile(r"(?:runtimes|.+\.(?:dll|pdb|json))$", re.IGNORECASE)
|
|
|
|
def main():
|
|
parser = argparse.ArgumentParser()
|
|
parser.add_argument("--webview", action="store_true")
|
|
parser.add_argument("--name", required=True)
|
|
parser.add_argument("--directory", required=True)
|
|
parser.add_argument("--apphost", required=True)
|
|
parser.add_argument("--identifier", required=True)
|
|
parser.add_argument("--icon")
|
|
|
|
args = parser.parse_args()
|
|
dir: str = args.directory
|
|
name: str = args.name
|
|
|
|
# Create base app directory structure.
|
|
os.makedirs(p(dir, f"{name}.app", "Contents", "MacOS"), exist_ok=True)
|
|
os.makedirs(p(dir, f"{name}.app", "Contents", "Resources"), exist_ok=True)
|
|
os.makedirs(p(dir, f"{name}.app", "Contents", "Frameworks"), exist_ok=True)
|
|
|
|
# Copy apphost
|
|
dest_apphost = p(dir, f"{name}.app", "Contents", "MacOS", name)
|
|
shutil.copy(p(dir, args.apphost), dest_apphost)
|
|
|
|
# Symlink most files in the bin dir.
|
|
symlink_files(args.directory, p(dir, f"{name}.app", "Contents", "MacOS"), "")
|
|
|
|
# Copy icon
|
|
if args.icon:
|
|
shutil.copy(args.icon, p(dir, f"{name}.app", "Contents", "Resources", "icon.icns"))
|
|
|
|
# Write plist
|
|
plist_dat = {
|
|
"CFBundleName": name,
|
|
"CFBundleDisplayName": name,
|
|
"CFBundleIdentifier": args.identifier,
|
|
"CFBundleIconFile": "icon",
|
|
"CFBundleExecutable": name,
|
|
"LSApplicationCategoryType": "public.app-category.games"
|
|
}
|
|
|
|
with open(p(dir, f"{name}.app", "Contents", "Info.plist"), "wb") as f:
|
|
plistlib.dump(plist_dat, f)
|
|
|
|
if args.webview:
|
|
chromium_framework_path = p(dir, f"{name}.app", "Contents", "Frameworks", "Chromium Embedded Framework.framework")
|
|
if not os.path.exists(chromium_framework_path):
|
|
os.symlink("../../../Chromium Embedded Framework.framework", chromium_framework_path)
|
|
|
|
create_webview_helper(dir, name, args.identifier, None, None)
|
|
create_webview_helper(dir, name, args.identifier, "GPU", "gpu")
|
|
create_webview_helper(dir, name, args.identifier, "Renderer", "renderer")
|
|
create_webview_helper(dir, name, args.identifier, "Alerts", "alerts")
|
|
|
|
def create_webview_helper(dir: str, name: str, identifier: str, suffix: str | None, identifier_suffix: str | None):
|
|
helper_name = f"{name} helper"
|
|
if suffix is not None:
|
|
helper_name += f" ({suffix})"
|
|
|
|
sub_app_path = p(dir, f"{name}.app", "Contents", "Frameworks", f"{helper_name}.app")
|
|
|
|
os.makedirs(p(sub_app_path, "Contents", "MacOS"), exist_ok=True)
|
|
os.makedirs(p(sub_app_path, "Contents", "Resources"), exist_ok=True)
|
|
|
|
# Copy apphost for Robust.Client.WebView
|
|
shutil.copy(p(dir, "Robust.Client.WebView"), p(sub_app_path, "Contents", "MacOS", helper_name))
|
|
|
|
# Symlink files
|
|
symlink_files(dir, p(sub_app_path, "Contents", "MacOS"), "../../../")
|
|
|
|
helper_identifier = f"{identifier}.cef.{identifier_suffix}"
|
|
|
|
if identifier_suffix is not None:
|
|
helper_identifier += "." + identifier_suffix
|
|
|
|
plist_dat = {
|
|
"CFBundleName": f"{name} helper",
|
|
"CFBundleDisplayName": f"{name} helper",
|
|
"CFBundleIdentifier": f"{identifier}.cef.{identifier_suffix}",
|
|
"CFBundleExecutable": helper_name
|
|
}
|
|
|
|
with open(p(sub_app_path, "Contents", "Info.plist"), "wb") as f:
|
|
plistlib.dump(plist_dat, f)
|
|
|
|
def symlink_files(src_dir: str, dest_dir: str, relative: str):
|
|
for file in os.listdir(src_dir):
|
|
if not symlinkable_re.match(file):
|
|
continue
|
|
|
|
src_path = p(src_dir, file)
|
|
dest_symlink = p(dest_dir, file)
|
|
if os.path.isdir(src_path):
|
|
# Symlink directories
|
|
if not os.path.islink(dest_symlink):
|
|
os.symlink(f"../../../{relative}{file}", dest_symlink)
|
|
else:
|
|
# Hardlink files
|
|
# (so that .NET doesn't report the real file path for assembly locations)
|
|
try:
|
|
os.remove(dest_symlink)
|
|
except FileNotFoundError:
|
|
pass # Fine
|
|
|
|
os.link(src_path, dest_symlink)
|
|
|
|
|
|
main()
|