mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
WIP
This commit is contained in:
parent
2555ac00bd
commit
f89e30b17f
@ -1,3 +1,7 @@
|
||||
load("@bazel_skylib//rules:common_settings.bzl",
|
||||
"bool_flag"
|
||||
)
|
||||
|
||||
load("@build_bazel_rules_apple//apple:ios.bzl",
|
||||
"ios_application",
|
||||
"ios_extension",
|
||||
@ -24,7 +28,6 @@ load(
|
||||
"telegram_bundle_id",
|
||||
"telegram_aps_environment",
|
||||
"telegram_team_id",
|
||||
"telegram_disable_extensions",
|
||||
)
|
||||
|
||||
config_setting(
|
||||
@ -34,6 +37,19 @@ config_setting(
|
||||
},
|
||||
)
|
||||
|
||||
bool_flag(
|
||||
name = "disableExtensions",
|
||||
build_setting_default = False,
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
||||
config_setting(
|
||||
name = "disableExtensionsSetting",
|
||||
flag_values = {
|
||||
":disableExtensions": "True",
|
||||
},
|
||||
)
|
||||
|
||||
genrule(
|
||||
name = "empty",
|
||||
outs = ["empty.swift"],
|
||||
@ -482,7 +498,7 @@ watchos_extension(
|
||||
":WatchExtensionNSExtensionInfoPlist",
|
||||
],
|
||||
minimum_os_version = "5.0",
|
||||
provisioning_profile = "@build_configuration//data/provisioning-profiles:WatchExtension.mobileprovision",
|
||||
provisioning_profile = "@build_configuration//provisioning:WatchExtension.mobileprovision",
|
||||
resources = [
|
||||
":TelegramWatchExtensionResources",
|
||||
],
|
||||
@ -509,7 +525,7 @@ watchos_application(
|
||||
":WatchAppCompanionInfoPlist",
|
||||
],
|
||||
minimum_os_version = "5.0",
|
||||
provisioning_profile = "@build_configuration//data/provisioning-profiles:WatchApp.mobileprovision",
|
||||
provisioning_profile = "@build_configuration//provisioning:WatchApp.mobileprovision",
|
||||
resources = [
|
||||
":TelegramWatchAppResources",
|
||||
":TelegramWatchAppAssets",
|
||||
@ -1055,7 +1071,7 @@ ios_extension(
|
||||
":AppNameInfoPlist",
|
||||
],
|
||||
minimum_os_version = "9.0",
|
||||
provisioning_profile = "@build_configuration//data/provisioning-profiles:Share.mobileprovision",
|
||||
provisioning_profile = "@build_configuration//provisioning:Share.mobileprovision",
|
||||
deps = [":ShareExtensionLib"],
|
||||
frameworks = [
|
||||
":TelegramUIFramework"
|
||||
@ -1123,7 +1139,7 @@ ios_extension(
|
||||
":AppNameInfoPlist",
|
||||
],
|
||||
minimum_os_version = "10.0",
|
||||
provisioning_profile = "@build_configuration//data/provisioning-profiles:NotificationContent.mobileprovision",
|
||||
provisioning_profile = "@build_configuration//provisioning:NotificationContent.mobileprovision",
|
||||
deps = [":NotificationContentExtensionLib"],
|
||||
frameworks = [
|
||||
":TelegramUIFramework"
|
||||
@ -1195,7 +1211,7 @@ ios_extension(
|
||||
],
|
||||
minimum_os_version = "14.0",
|
||||
provides_main = True,
|
||||
provisioning_profile = "@build_configuration//data/provisioning-profiles:Widget.mobileprovision",
|
||||
provisioning_profile = "@build_configuration//provisioning:Widget.mobileprovision",
|
||||
deps = [":WidgetExtensionLib"],
|
||||
frameworks = [
|
||||
":SwiftSignalKitFramework",
|
||||
@ -1283,7 +1299,7 @@ ios_extension(
|
||||
":AppNameInfoPlist",
|
||||
],
|
||||
minimum_os_version = "10.0",
|
||||
provisioning_profile = "@build_configuration//data/provisioning-profiles:Intents.mobileprovision",
|
||||
provisioning_profile = "@build_configuration//provisioning:Intents.mobileprovision",
|
||||
deps = [":IntentsExtensionLib"],
|
||||
frameworks = [
|
||||
":SwiftSignalKitFramework",
|
||||
@ -1334,7 +1350,7 @@ ios_extension(
|
||||
":AppNameInfoPlist",
|
||||
],
|
||||
minimum_os_version = "10.0",
|
||||
provisioning_profile = "@build_configuration//data/provisioning-profiles:NotificationService.mobileprovision",
|
||||
provisioning_profile = "@build_configuration//provisioning:NotificationService.mobileprovision",
|
||||
deps = ["//Telegram/NotificationService:NotificationServiceExtensionLib"],
|
||||
frameworks = [
|
||||
":MtProtoKitFramework",
|
||||
@ -1522,7 +1538,7 @@ ios_application(
|
||||
),
|
||||
families = ["iphone", "ipad"],
|
||||
minimum_os_version = "9.0",
|
||||
provisioning_profile = "@build_configuration//data/provisioning-profiles:Telegram.mobileprovision",
|
||||
provisioning_profile = "@build_configuration//provisioning:Telegram.mobileprovision",
|
||||
entitlements = ":TelegramEntitlements.entitlements",
|
||||
infoplists = [
|
||||
":TelegramInfoPlist",
|
||||
@ -1547,14 +1563,16 @@ ios_application(
|
||||
strings = [
|
||||
":AppStringResources",
|
||||
],
|
||||
extensions = [
|
||||
] if telegram_disable_extensions else [
|
||||
":ShareExtension",
|
||||
":NotificationContentExtension",
|
||||
":NotificationServiceExtension",
|
||||
":IntentsExtension",
|
||||
":WidgetExtension",
|
||||
],
|
||||
extensions = select({
|
||||
":disableExtensionsSetting": [],
|
||||
"//conditions:default": [
|
||||
":ShareExtension",
|
||||
":NotificationContentExtension",
|
||||
":NotificationServiceExtension",
|
||||
":IntentsExtension",
|
||||
":WidgetExtension",
|
||||
],
|
||||
}),
|
||||
watch_application = ":TelegramWatchApp",
|
||||
deps = [
|
||||
":Main",
|
||||
|
112
build-system/Make/BuildEnvironment.py
Normal file
112
build-system/Make/BuildEnvironment.py
Normal file
@ -0,0 +1,112 @@
|
||||
import json
|
||||
import os
|
||||
import platform
|
||||
import subprocess
|
||||
|
||||
|
||||
def is_apple_silicon():
|
||||
if platform.processor() == 'arm':
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
|
||||
def get_clean_env():
|
||||
clean_env = os.environ.copy()
|
||||
clean_env['PATH'] = '/usr/bin:/bin:/usr/sbin:/sbin'
|
||||
return clean_env
|
||||
|
||||
|
||||
def run_executable_with_output(path, arguments):
|
||||
process = subprocess.Popen(
|
||||
[path] + arguments,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.STDOUT,
|
||||
env=get_clean_env()
|
||||
)
|
||||
output_data, _ = process.communicate()
|
||||
output_string = output_data.decode('utf-8')
|
||||
return output_string
|
||||
|
||||
|
||||
def call_executable(arguments):
|
||||
subprocess.check_call(arguments, env=get_clean_env())
|
||||
|
||||
|
||||
def get_bazel_version(bazel_path):
|
||||
command_result = run_executable_with_output(bazel_path, ['--version']).strip('\n')
|
||||
if not command_result.startswith('bazel '):
|
||||
raise Exception('{} is not a valid bazel binary'.format(bazel_path))
|
||||
command_result.replace('bazel ', '')
|
||||
return command_result
|
||||
|
||||
|
||||
def get_xcode_version():
|
||||
xcode_path = run_executable_with_output('xcode-select', ['-p']).strip('\n')
|
||||
if not os.path.isdir(xcode_path):
|
||||
print('The path reported by \'xcode-select -p\' does not exist')
|
||||
exit(1)
|
||||
|
||||
plist_path = '{}/../Info.plist'.format(xcode_path)
|
||||
|
||||
info_plist_lines = run_executable_with_output('plutil', [
|
||||
'-p', plist_path
|
||||
]).split('\n')
|
||||
|
||||
pattern = 'CFBundleShortVersionString" => '
|
||||
for line in info_plist_lines:
|
||||
index = line.find(pattern)
|
||||
if index != -1:
|
||||
version = line[index + len(pattern):].strip('"')
|
||||
return version
|
||||
|
||||
print('Could not parse the Xcode version from {}'.format(plist_path))
|
||||
exit(1)
|
||||
|
||||
|
||||
class BuildEnvironment:
|
||||
def __init__(
|
||||
self,
|
||||
base_path,
|
||||
bazel_path,
|
||||
bazel_x86_64_path,
|
||||
override_bazel_version,
|
||||
override_xcode_version
|
||||
):
|
||||
self.base_path = base_path
|
||||
self.bazel_path = bazel_path
|
||||
self.bazel_x86_64_path = bazel_x86_64_path
|
||||
|
||||
configuration_path = os.path.join(base_path, 'versions.json')
|
||||
with open(configuration_path) as file:
|
||||
configuration_dict = json.load(file)
|
||||
if configuration_dict['bazel'] is None:
|
||||
raise Exception('Missing bazel version in {}'.format(configuration_path))
|
||||
else:
|
||||
self.bazel_version = configuration_dict['bazel']
|
||||
if configuration_dict['xcode'] is None:
|
||||
raise Exception('Missing xcode version in {}'.format(configuration_path))
|
||||
else:
|
||||
self.xcode_version = configuration_dict['xcode']
|
||||
|
||||
actual_bazel_version = get_bazel_version(self.bazel_path)
|
||||
if actual_bazel_version != self.bazel_version:
|
||||
if override_bazel_version:
|
||||
print('Overriding the required bazel version {} with {} as reported by {}'.format(
|
||||
self.bazel_version, actual_bazel_version, self.bazel_path))
|
||||
self.bazel_version = actual_bazel_version
|
||||
else:
|
||||
print('Required bazel version is {}, but {} is reported by {}'.format(
|
||||
self.bazel_version, actual_bazel_version, self.bazel_path))
|
||||
exit(1)
|
||||
|
||||
actual_xcode_version = get_xcode_version()
|
||||
if actual_xcode_version != self.xcode_version:
|
||||
if override_xcode_version:
|
||||
print('Overriding the required Xcode version {} with {} as reported by \'xcode-select -p\''.format(
|
||||
self.xcode_version, actual_xcode_version, self.bazel_path))
|
||||
self.xcode_version = actual_xcode_version
|
||||
else:
|
||||
print('Required Xcode version is {}, but {} is reported by \'xcode-select -p\''.format(
|
||||
self.xcode_version, actual_xcode_version, self.bazel_path))
|
||||
exit(1)
|
446
build-system/Make/Make.py
Normal file
446
build-system/Make/Make.py
Normal file
@ -0,0 +1,446 @@
|
||||
#!/bin/python3
|
||||
|
||||
import argparse
|
||||
import os
|
||||
import sys
|
||||
import tempfile
|
||||
|
||||
from BuildEnvironment import is_apple_silicon, call_executable, BuildEnvironment
|
||||
from ProjectGeneration import generate
|
||||
|
||||
|
||||
class BazelCommandLine:
|
||||
def __init__(self, bazel_path, bazel_x86_64_path, override_bazel_version, override_xcode_version):
|
||||
self.build_environment = BuildEnvironment(
|
||||
base_path=os.getcwd(),
|
||||
bazel_path=bazel_path,
|
||||
bazel_x86_64_path=bazel_x86_64_path,
|
||||
override_bazel_version=override_bazel_version,
|
||||
override_xcode_version=override_xcode_version
|
||||
)
|
||||
self.remote_cache = None
|
||||
self.cache_dir = None
|
||||
self.additional_args = None
|
||||
self.configuration_args = None
|
||||
self.configuration_path = None
|
||||
|
||||
self.common_args = [
|
||||
# https://docs.bazel.build/versions/master/command-line-reference.html
|
||||
# Ask bazel to print the actual resolved command line options.
|
||||
'--announce_rc',
|
||||
|
||||
# https://github.com/bazelbuild/rules_swift
|
||||
# If enabled, Swift compilation actions will use the same global Clang module
|
||||
# cache used by Objective-C compilation actions. This is disabled by default
|
||||
# because under some circumstances Clang module cache corruption can cause the
|
||||
# Swift compiler to crash (sometimes when switching configurations or syncing a
|
||||
# repository), but disabling it also causes a noticeable build time regression
|
||||
# so it can be explicitly re-enabled by users who are not affected by those
|
||||
# crashes.
|
||||
'--features=swift.use_global_module_cache',
|
||||
|
||||
# https://docs.bazel.build/versions/master/command-line-reference.html
|
||||
# Print the subcommand details in case of failure.
|
||||
'--verbose_failures',
|
||||
]
|
||||
|
||||
self.common_build_args = [
|
||||
# https://github.com/bazelbuild/rules_swift
|
||||
# If enabled and whole module optimisation is being used, the `*.swiftdoc`,
|
||||
# `*.swiftmodule` and `*-Swift.h` are generated with a separate action
|
||||
# rather than as part of the compilation.
|
||||
'--features=swift.split_derived_files_generation',
|
||||
|
||||
# https://github.com/bazelbuild/rules_swift
|
||||
# If enabled the skip function bodies frontend flag is passed when using derived
|
||||
# files generation.
|
||||
'--features=swift.skip_function_bodies_for_derived_files',
|
||||
|
||||
# Set the number of parallel processes to match the available CPU core count.
|
||||
'--jobs={}'.format(os.cpu_count()),
|
||||
]
|
||||
|
||||
self.common_debug_args = [
|
||||
# https://github.com/bazelbuild/rules_swift
|
||||
# If enabled, Swift compilation actions will use batch mode by passing
|
||||
# `-enable-batch-mode` to `swiftc`. This is a new compilation mode as of
|
||||
# Swift 4.2 that is intended to speed up non-incremental non-WMO builds by
|
||||
# invoking a smaller number of frontend processes and passing them batches of
|
||||
# source files.
|
||||
'--features=swift.enable_batch_mode',
|
||||
|
||||
# https://docs.bazel.build/versions/master/command-line-reference.html
|
||||
# Set the number of parallel jobs per module to saturate the available CPU resources.
|
||||
'--swiftcopt=-j{}'.format(os.cpu_count() - 1),
|
||||
]
|
||||
|
||||
self.common_release_args = [
|
||||
# https://github.com/bazelbuild/rules_swift
|
||||
# Enable whole module optimization.
|
||||
'--features=swift.opt_uses_wmo',
|
||||
|
||||
# https://github.com/bazelbuild/rules_swift
|
||||
# Use -Osize instead of -O when building swift modules.
|
||||
'--features=swift.opt_uses_osize',
|
||||
|
||||
# --num-threads 0 forces swiftc to generate one object file per module; it:
|
||||
# 1. resolves issues with the linker caused by the swift-objc mixing.
|
||||
# 2. makes the resulting binaries significantly smaller (up to 9% for this project).
|
||||
'--swiftcopt=-num-threads', '--swiftcopt=0',
|
||||
|
||||
# Strip unsused code.
|
||||
'--features=dead_strip',
|
||||
'--objc_enable_binary_stripping',
|
||||
|
||||
# Always embed bitcode into Watch binaries. This is required by the App Store.
|
||||
'--apple_bitcode=watchos=embedded',
|
||||
]
|
||||
|
||||
def add_remote_cache(self, host):
|
||||
self.remote_cache = host
|
||||
|
||||
def add_cache_dir(self, path):
|
||||
self.cache_dir = path
|
||||
|
||||
def add_additional_args(self, additional_args):
|
||||
self.additional_args = additional_args
|
||||
|
||||
def set_configuration_path(self, path):
|
||||
self.configuration_path = path
|
||||
|
||||
def set_configuration(self, configuration):
|
||||
if configuration == 'debug_arm64':
|
||||
self.configuration_args = [
|
||||
# bazel debug build configuration
|
||||
'-c', 'dbg',
|
||||
|
||||
# Build single-architecture binaries. It is almost 2 times faster is 32-bit support is not required.
|
||||
'--ios_multi_cpus=arm64',
|
||||
|
||||
# Always build universal Watch binaries.
|
||||
'--watchos_cpus=armv7k,arm64_32'
|
||||
] + self.common_debug_args
|
||||
elif configuration == 'release_arm64':
|
||||
self.configuration_args = [
|
||||
# bazel optimized build configuration
|
||||
'-c', 'opt',
|
||||
|
||||
# Build single-architecture binaries. It is almost 2 times faster is 32-bit support is not required.
|
||||
'--ios_multi_cpus=arm64',
|
||||
|
||||
# Always build universal Watch binaries.
|
||||
'--watchos_cpus=armv7k,arm64_32'
|
||||
] + self.common_release_args
|
||||
elif configuration == 'release':
|
||||
self.configuration_args = [
|
||||
# bazel optimized build configuration
|
||||
'-c', 'opt',
|
||||
|
||||
# Build universal binaries.
|
||||
'--ios_multi_cpus=armv7,arm64',
|
||||
|
||||
# Always build universal Watch binaries.
|
||||
'--watchos_cpus=armv7k,arm64_32'
|
||||
|
||||
# Generate DSYM files when building.
|
||||
'--apple_generate_dsym',
|
||||
|
||||
# Require DSYM files as build output.
|
||||
'--output_groups=+dsyms'
|
||||
] + self.common_release_args
|
||||
else:
|
||||
raise Exception('Unknown configuration {}'.format(configuration))
|
||||
|
||||
def invoke_clean(self):
|
||||
combined_arguments = [
|
||||
self.build_environment.bazel_path,
|
||||
'clean',
|
||||
'--expunge'
|
||||
]
|
||||
|
||||
print('TelegramBuild: running {}'.format(combined_arguments))
|
||||
call_executable(combined_arguments)
|
||||
|
||||
def get_project_generation_arguments(self):
|
||||
combined_arguments = []
|
||||
combined_arguments += self.common_args
|
||||
combined_arguments += self.common_debug_args
|
||||
|
||||
if self.remote_cache is not None:
|
||||
combined_arguments += [
|
||||
'--remote_cache={}'.format(self.remote_cache),
|
||||
'--experimental_remote_downloader="{}"'.format(self.remote_cache)
|
||||
]
|
||||
elif self.cache_dir is not None:
|
||||
combined_arguments += [
|
||||
'--disk_cache={path}'.format(path=self.cache_dir)
|
||||
]
|
||||
|
||||
return combined_arguments
|
||||
|
||||
def invoke_build(self):
|
||||
combined_arguments = [
|
||||
self.build_environment.bazel_path,
|
||||
'build',
|
||||
'Telegram/Telegram'
|
||||
]
|
||||
|
||||
if self.configuration_path is None:
|
||||
raise Exception('configuration_path is not defined')
|
||||
|
||||
combined_arguments += [
|
||||
'--override_repository=build_configuration={}'.format(self.configuration_path)
|
||||
]
|
||||
|
||||
combined_arguments += self.common_args
|
||||
combined_arguments += self.common_build_args
|
||||
|
||||
if self.remote_cache is not None:
|
||||
combined_arguments += [
|
||||
'--remote_cache={}'.format(self.remote_cache),
|
||||
'--experimental_remote_downloader="{}"'.format(self.remote_cache)
|
||||
]
|
||||
elif self.cache_dir is not None:
|
||||
combined_arguments += [
|
||||
'--disk_cache={path}'.format(path=self.cache_dir)
|
||||
]
|
||||
|
||||
combined_arguments += self.configuration_args
|
||||
|
||||
print('TelegramBuild: running {}'.format(combined_arguments))
|
||||
call_executable(combined_arguments)
|
||||
|
||||
|
||||
def clean(arguments):
|
||||
bazel_command_line = BazelCommandLine(
|
||||
bazel_path=arguments.bazel,
|
||||
bazel_x86_64_path=None,
|
||||
override_bazel_version=arguments.overrideBazelVersion,
|
||||
override_xcode_version=arguments.overrideXcodeVersion
|
||||
)
|
||||
|
||||
bazel_command_line.invoke_clean()
|
||||
|
||||
|
||||
def resolve_configuration(bazel_command_line: BazelCommandLine, arguments):
|
||||
if arguments.configurationGenerator is not None:
|
||||
if not os.path.isfile(arguments.configurationGenerator):
|
||||
print('{} is not a valid executable'.format(arguments.configurationGenerator))
|
||||
exit(1)
|
||||
|
||||
temp_configuration_path = tempfile.mkdtemp()
|
||||
call_executable([
|
||||
arguments.configurationGenerator,
|
||||
temp_configuration_path
|
||||
])
|
||||
|
||||
print('TelegramBuild: using generated configuration in {}'.format(temp_configuration_path))
|
||||
bazel_command_line.set_configuration_path(temp_configuration_path)
|
||||
elif arguments.configurationPath is not None:
|
||||
absolute_configuration_path = os.path.abspath(arguments.configurationPath)
|
||||
if not os.path.isdir(absolute_configuration_path):
|
||||
print('Error: {} does not exist'.format(absolute_configuration_path))
|
||||
exit(1)
|
||||
bazel_command_line.set_configuration_path(absolute_configuration_path)
|
||||
else:
|
||||
raise Exception('Neither configurationPath nor configurationGenerator are set')
|
||||
|
||||
|
||||
def generate_project(arguments):
|
||||
bazel_command_line = BazelCommandLine(
|
||||
bazel_path=arguments.bazel,
|
||||
bazel_x86_64_path=arguments.bazel_x86_64,
|
||||
override_bazel_version=arguments.overrideBazelVersion,
|
||||
override_xcode_version=arguments.overrideXcodeVersion
|
||||
)
|
||||
|
||||
if arguments.cacheDir is not None:
|
||||
bazel_command_line.add_cache_dir(arguments.cacheDir)
|
||||
elif arguments.cacheHost is not None:
|
||||
bazel_command_line.add_remote_cache(arguments.cacheDir)
|
||||
|
||||
resolve_configuration(bazel_command_line, arguments)
|
||||
|
||||
disable_extensions = False
|
||||
if arguments.disableExtensions is not None:
|
||||
disable_extensions = arguments.disableExtensions
|
||||
|
||||
generate(
|
||||
build_environment=bazel_command_line.build_environment,
|
||||
disable_extensions=disable_extensions,
|
||||
configuration_path=bazel_command_line.configuration_path,
|
||||
bazel_app_arguments=bazel_command_line.get_project_generation_arguments()
|
||||
)
|
||||
|
||||
|
||||
def build(arguments):
|
||||
bazel_command_line = BazelCommandLine(
|
||||
bazel_path=arguments.bazel,
|
||||
bazel_x86_64_path=None,
|
||||
override_bazel_version=arguments.overrideBazelVersion,
|
||||
override_xcode_version=arguments.overrideXcodeVersion
|
||||
)
|
||||
|
||||
if arguments.cacheDir is not None:
|
||||
bazel_command_line.add_cache_dir(arguments.cacheDir)
|
||||
elif arguments.cacheHost is not None:
|
||||
bazel_command_line.add_remote_cache(arguments.cacheDir)
|
||||
|
||||
resolve_configuration(bazel_command_line, arguments)
|
||||
|
||||
bazel_command_line.set_configuration(arguments.configuration)
|
||||
|
||||
bazel_command_line.invoke_build()
|
||||
|
||||
|
||||
def add_project_and_build_common_arguments(current_parser: argparse.ArgumentParser):
|
||||
group = current_parser.add_mutually_exclusive_group(required=True)
|
||||
group.add_argument(
|
||||
'--configurationPath',
|
||||
help='''
|
||||
Path to a folder containing build configuration and provisioning profiles.
|
||||
See build-system/example-configuration for an example.
|
||||
''',
|
||||
metavar='path'
|
||||
)
|
||||
group.add_argument(
|
||||
'--configurationGenerator',
|
||||
help='''
|
||||
Path to an executable that will generate configuration data
|
||||
(project constants and provisioning profiles).
|
||||
The executable will be invoked with one parameter — path to the destination directory.
|
||||
See build-system/generate-configuration.sh for an example.
|
||||
''',
|
||||
metavar='path'
|
||||
)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
parser = argparse.ArgumentParser(prog='Make')
|
||||
|
||||
parser.add_argument(
|
||||
'--verbose',
|
||||
action='store_true',
|
||||
default=False,
|
||||
help='Print debug info'
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
'--bazel',
|
||||
required=True,
|
||||
help='Use custom bazel binary',
|
||||
metavar='path'
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
'--overrideBazelVersion',
|
||||
action='store_true',
|
||||
help='Override bazel version with the actual version reported by the bazel binary'
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
'--overrideXcodeVersion',
|
||||
action='store_true',
|
||||
help='Override xcode version with the actual version reported by \'xcode-select -p\''
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
'--bazelArguments',
|
||||
required=False,
|
||||
help='Add additional arguments to all bazel invocations.',
|
||||
metavar='arguments'
|
||||
)
|
||||
|
||||
cacheTypeGroup = parser.add_mutually_exclusive_group()
|
||||
cacheTypeGroup.add_argument(
|
||||
'--cacheHost',
|
||||
required=False,
|
||||
help='Use remote build artifact cache to speed up rebuilds (See https://github.com/buchgr/bazel-remote).',
|
||||
metavar='http://host:9092'
|
||||
)
|
||||
cacheTypeGroup.add_argument(
|
||||
'--cacheDir',
|
||||
required=False,
|
||||
help='Cache build artifacts in a local directory to speed up rebuilds.',
|
||||
metavar='path'
|
||||
)
|
||||
|
||||
subparsers = parser.add_subparsers(dest='commandName', help='Commands')
|
||||
|
||||
cleanParser = subparsers.add_parser(
|
||||
'clean', help='''
|
||||
Clean local bazel cache. Does not affect files cached remotely (via --cacheHost=...) or
|
||||
locally in an external directory ('--cacheDir=...')
|
||||
'''
|
||||
)
|
||||
|
||||
generateProjectParser = subparsers.add_parser('generateProject', help='Generate Xcode project')
|
||||
if is_apple_silicon():
|
||||
generateProjectParser.add_argument(
|
||||
'--bazel_x86_64',
|
||||
required=True,
|
||||
help='A standalone bazel x86_64 binary is required to generate a project on Apple Silicon.',
|
||||
metavar='path'
|
||||
)
|
||||
generateProjectParser.add_argument(
|
||||
'--buildNumber',
|
||||
required=False,
|
||||
type=int,
|
||||
default=10000,
|
||||
help='Build number.',
|
||||
metavar='number'
|
||||
)
|
||||
add_project_and_build_common_arguments(generateProjectParser)
|
||||
generateProjectParser.add_argument(
|
||||
'--disableExtensions',
|
||||
action='store_true',
|
||||
default=False,
|
||||
help='''
|
||||
The generated project will not include app extensions.
|
||||
This allows Xcode to properly index the source code.
|
||||
'''
|
||||
)
|
||||
|
||||
buildParser = subparsers.add_parser('build', help='Build the app')
|
||||
buildParser.add_argument(
|
||||
'--buildNumber',
|
||||
required=True,
|
||||
type=int,
|
||||
help='Build number.',
|
||||
metavar='number'
|
||||
)
|
||||
add_project_and_build_common_arguments(buildParser)
|
||||
buildParser.add_argument(
|
||||
'--configuration',
|
||||
choices=[
|
||||
'debug_arm64',
|
||||
'release_arm64',
|
||||
'release_universal'
|
||||
],
|
||||
required=True,
|
||||
help='Build configuration'
|
||||
)
|
||||
|
||||
if len(sys.argv) < 2:
|
||||
parser.print_help()
|
||||
sys.exit(1)
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.verbose:
|
||||
print(args)
|
||||
|
||||
if args.commandName is None:
|
||||
exit(0)
|
||||
|
||||
try:
|
||||
if args.commandName == 'clean':
|
||||
clean(arguments=args)
|
||||
elif args.commandName == 'generateProject':
|
||||
generate_project(arguments=args)
|
||||
elif args.commandName == 'build':
|
||||
build(arguments=args)
|
||||
else:
|
||||
raise Exception('Unknown command')
|
||||
except KeyboardInterrupt:
|
||||
pass
|
155
build-system/Make/ProjectGeneration.py
Normal file
155
build-system/Make/ProjectGeneration.py
Normal file
@ -0,0 +1,155 @@
|
||||
import json
|
||||
import os
|
||||
import shutil
|
||||
|
||||
from BuildEnvironment import is_apple_silicon, call_executable, BuildEnvironment
|
||||
|
||||
|
||||
def remove_directory(path):
|
||||
if os.path.isdir(path):
|
||||
shutil.rmtree(path)
|
||||
|
||||
|
||||
def generate(build_environment: BuildEnvironment, disable_extensions, configuration_path, bazel_app_arguments):
|
||||
project_path = os.path.join(build_environment.base_path, 'build-input/gen/project')
|
||||
app_target = 'Telegram'
|
||||
|
||||
'''
|
||||
TULSI_APP="build-input/gen/project/Tulsi.app"
|
||||
TULSI="$TULSI_APP/Contents/MacOS/Tulsi"
|
||||
|
||||
rm -rf "$GEN_DIRECTORY/${APP_TARGET}.tulsiproj"
|
||||
rm -rf "$TULSI_APP"
|
||||
'''
|
||||
|
||||
os.makedirs(project_path, exist_ok=True)
|
||||
remove_directory('{}/Tulsi.app'.format(project_path))
|
||||
remove_directory('{project}/{target}.tulsiproj'.format(project=project_path, target=app_target))
|
||||
|
||||
tulsi_path = os.path.join(project_path, 'Tulsi.app/Contents/MacOS/Tulsi')
|
||||
|
||||
if is_apple_silicon():
|
||||
tulsi_build_bazel_path = build_environment.bazel_x86_64_path
|
||||
if tulsi_build_bazel_path is None or not os.path.isfile(tulsi_build_bazel_path):
|
||||
print('Could not find a valid bazel x86_64 binary at {}'.format(tulsi_build_bazel_path))
|
||||
exit(1)
|
||||
else:
|
||||
tulsi_build_bazel_path = build_environment.bazel_path
|
||||
|
||||
current_dir = os.getcwd()
|
||||
os.chdir(os.path.join(build_environment.base_path, 'build-system/tulsi'))
|
||||
call_executable([
|
||||
tulsi_build_bazel_path,
|
||||
'build', '//:tulsi',
|
||||
'--xcode_version={}'.format(build_environment.xcode_version),
|
||||
'--use_top_level_targets_for_symlinks',
|
||||
'--verbose_failures'
|
||||
])
|
||||
os.chdir(current_dir)
|
||||
|
||||
bazel_wrapper_path = os.path.abspath('build-input/gen/project/bazel')
|
||||
|
||||
bazel_wrapper_arguments = []
|
||||
bazel_wrapper_arguments += ['--override_repository=build_configuration={}'.format(configuration_path)]
|
||||
if disable_extensions and False:
|
||||
bazel_wrapper_arguments += ['--//Telegram:disableExtensions']
|
||||
|
||||
with open(bazel_wrapper_path, 'wb') as bazel_wrapper:
|
||||
bazel_wrapper.write('''#!/bin/sh
|
||||
{bazel} "$@" {arguments}
|
||||
'''.format(
|
||||
bazel=build_environment.bazel_path,
|
||||
arguments=' '.join(bazel_wrapper_arguments)
|
||||
).encode('utf-8'))
|
||||
|
||||
call_executable(['chmod', '+x', bazel_wrapper_path])
|
||||
|
||||
call_executable([
|
||||
'unzip', '-oq',
|
||||
'build-system/tulsi/bazel-bin/tulsi.zip',
|
||||
'-d', project_path
|
||||
])
|
||||
|
||||
user_defaults_path = os.path.expanduser('~/Library/Preferences/com.google.Tulsi.plist')
|
||||
if os.path.isfile(user_defaults_path):
|
||||
os.unlink(user_defaults_path)
|
||||
|
||||
with open(user_defaults_path, 'wb') as user_defaults:
|
||||
user_defaults.write('''
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>defaultBazelURL</key>
|
||||
<string>{}</string>
|
||||
</dict>
|
||||
</plist>
|
||||
'''.format(bazel_wrapper_path).encode('utf-8'))
|
||||
|
||||
bazel_build_arguments = []
|
||||
bazel_build_arguments += ['--override_repository=build_configuration={}'.format(configuration_path)]
|
||||
if disable_extensions:
|
||||
bazel_build_arguments += ['--//Telegram:disableExtensions']
|
||||
|
||||
call_executable([
|
||||
tulsi_path,
|
||||
'--',
|
||||
'--verbose',
|
||||
'--create-tulsiproj', app_target,
|
||||
'--workspaceroot', './',
|
||||
'--bazel', bazel_wrapper_path,
|
||||
'--outputfolder', project_path,
|
||||
'--target', '{target}:{target}'.format(target=app_target),
|
||||
'--build-options', ' '.join(bazel_build_arguments)
|
||||
])
|
||||
|
||||
additional_arguments = []
|
||||
additional_arguments += ['--override_repository=build_configuration={}'.format(configuration_path)]
|
||||
additional_arguments += bazel_app_arguments
|
||||
if disable_extensions:
|
||||
additional_arguments += ['--//Telegram:disableExtensions']
|
||||
|
||||
additional_arguments_string = ' '.join(additional_arguments)
|
||||
|
||||
tulsi_config_path = 'build-input/gen/project/{target}.tulsiproj/Configs/{target}.tulsigen'.format(target=app_target)
|
||||
with open(tulsi_config_path, 'rb') as tulsi_config:
|
||||
tulsi_config_json = json.load(tulsi_config)
|
||||
for category in ['BazelBuildOptionsDebug', 'BazelBuildOptionsRelease']:
|
||||
tulsi_config_json['optionSet'][category]['p'] += ' {}'.format(additional_arguments_string)
|
||||
tulsi_config_json['sourceFilters'] = [
|
||||
'Telegram/...',
|
||||
'submodules/...',
|
||||
'third-party/...'
|
||||
]
|
||||
with open(tulsi_config_path, 'wb') as tulsi_config:
|
||||
tulsi_config.write(json.dumps(tulsi_config_json, indent=2).encode('utf-8'))
|
||||
|
||||
call_executable([
|
||||
tulsi_path,
|
||||
'--',
|
||||
'--verbose',
|
||||
'--genconfig', '{project}/{target}.tulsiproj:{target}'.format(project=project_path, target=app_target),
|
||||
'--bazel', bazel_wrapper_path,
|
||||
'--outputfolder', project_path,
|
||||
'--no-open-xcode'
|
||||
])
|
||||
|
||||
xcodeproj_path = '{project}/{target}.xcodeproj'.format(project=project_path, target=app_target)
|
||||
|
||||
bazel_build_settings_path = '{}/.tulsi/Scripts/bazel_build_settings.py'.format(xcodeproj_path)
|
||||
|
||||
with open(bazel_build_settings_path, 'rb') as bazel_build_settings:
|
||||
bazel_build_settings_contents = bazel_build_settings.read().decode('utf-8')
|
||||
bazel_build_settings_contents = bazel_build_settings_contents.replace(
|
||||
'BUILD_SETTINGS = BazelBuildSettings(',
|
||||
'import os\nBUILD_SETTINGS = BazelBuildSettings('
|
||||
)
|
||||
bazel_build_settings_contents = bazel_build_settings_contents.replace(
|
||||
'\'--cpu=ios_arm64\'',
|
||||
'\'--cpu=ios_arm64\'.replace(\'ios_arm64\', \'ios_sim_arm64\' if os.environ.get(\'EFFECTIVE_PLATFORM_NAME\') '
|
||||
'== \'-iphonesimulator\' else \'ios_arm64\')'
|
||||
)
|
||||
with open(bazel_build_settings_path, 'wb') as bazel_build_settings:
|
||||
bazel_build_settings.write(bazel_build_settings_contents.encode('utf-8'))
|
||||
|
||||
call_executable(['open', xcodeproj_path])
|
@ -1,4 +1,11 @@
|
||||
|
||||
exports_files(glob([
|
||||
"*.mobileprovision",
|
||||
exports_files([
|
||||
"Intents.mobileprovision",
|
||||
"NotificationContent.mobileprovision",
|
||||
"NotificationService.mobileprovision",
|
||||
"Share.mobileprovision",
|
||||
"Telegram.mobileprovision",
|
||||
"WatchApp.mobileprovision",
|
||||
"WatchExtension.mobileprovision",
|
||||
"Widget.mobileprovision",
|
||||
])
|
||||
|
@ -10,4 +10,3 @@ telegram_is_appstore_build = "true"
|
||||
telegram_appstore_id = "0"
|
||||
telegram_app_specific_url_scheme = "tg"
|
||||
telegram_aps_environment = "production"
|
||||
telegram_disable_extensions = False
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit b965114f31a464185318c71ef3d0c1538d0c52de
|
||||
Subproject commit ee28952fc91b493b5e1d11e4ccf12d7df4454504
|
Loading…
x
Reference in New Issue
Block a user