Files
brave-core/script/ios_bootstrap.py
T
2025-08-25 17:16:52 -07:00

101 lines
4.0 KiB
Python
Executable File

#!/usr/bin/env vpython3
# Copyright (c) 2024 The Brave Authors. All rights reserved.
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
# You can obtain one at https://mozilla.org/MPL/2.0/.
import argparse
import inspect
import os
import shutil
import sys
from distutils.dir_util import copy_tree
from brave_chromium_utils import wspath
from lib.config import PLATFORM, enable_verbose_mode, is_verbose_mode
from lib.util import execute_stdout
from pathlib import Path
def main():
if PLATFORM != 'darwin':
# Only applicable to macOS
sys.exit(0)
args = parse_args()
if args.verbose:
enable_verbose_mode()
create_required_spm_resources(force=args.force)
generate_lldbinit(force=args.force)
def parse_args():
parser = argparse.ArgumentParser(description='Bootstrap the iOS project')
parser.add_argument('-v',
'--verbose',
action='store_true',
help='Prints the output of the subprocesses')
parser.add_argument('-f',
'--force',
action='store_true',
help='Always rewrite the symlink/directory entirely')
return parser.parse_args()
def create_required_spm_resources(force=False):
# Runs webpack on the JS files that are generated in iOS. This is so that
# Package.swift/SPM resolves with the resources available
execute_stdout(['npm', 'run', 'ios_pack_js'])
# Creates the expected out/ios_current_link directory and places placeholder
# xcframeworks inside to ensure Package.swift/SPM validates the manifest
# correctly.
ios_current_link = Path(wspath("//out/ios_current_link"))
if ios_current_link.is_symlink():
# Check if the symlink is valid and unlink if its not, (or in the case
# of --force, unlink anyways so it can be removed)
if force or not os.path.exists(os.readlink(ios_current_link)):
ios_current_link.unlink()
if force and ios_current_link.exists():
# Remove the directory entirely
shutil.rmtree(ios_current_link)
ios_current_link.mkdir(parents=True, exist_ok=True)
# Make xcframework placeholders for targets exported by the iOS GN target
# These are essentially the bare-essential requirements for SPM to validate
# the Package.swift manifest: The existence of the xcframework directory
# itself, plus a valid Info.plist inside it.
frameworks = ['BraveCore', 'MaterialComponents', 'NalaAssets']
for frmk in frameworks:
framework_dir = os.path.join(ios_current_link, f'{frmk}.xcframework')
if force and os.path.exists(framework_dir):
shutil.rmtree(framework_dir)
if not os.path.exists(framework_dir):
Path(framework_dir).mkdir(parents=True)
info_plist = wspath(
"//brave/ios/brave-ios/BraveCore/placeholders/xcframework.plist"
)
shutil.copyfile(info_plist, os.path.join(framework_dir,
'Info.plist'))
# Creates an empty args.xcconfig due to a race in Xcode which seems to fail
# to find the xcconfig after its generated during the build preaction script
args_config_path = os.path.join(ios_current_link, 'args.xcconfig')
if force or not os.path.exists(args_config_path):
Path(args_config_path).touch()
def generate_lldbinit(force=False):
contents = inspect.cleandoc(f"""
# This file is generated by ios_bootstrap.py
#
# This allows proper source mapping to builds made with the GN arg
# strip_absolute_paths_from_debug_symbols set to true.
settings set target.source-map "../.." "{wspath("//")}"
""")
lldbinit_file = wspath("//brave/ios/brave-ios/App/Configuration/LLDBInit")
if force or not os.path.exists(lldbinit_file):
with open(lldbinit_file, 'w') as f:
f.write(contents)
if __name__ == '__main__':
main()