diff --git a/Telegram/BUILD b/Telegram/BUILD index f7b29682b4..3d6ddc2f4b 100644 --- a/Telegram/BUILD +++ b/Telegram/BUILD @@ -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", diff --git a/build-system/Make/BuildEnvironment.py b/build-system/Make/BuildEnvironment.py new file mode 100644 index 0000000000..0769f580bb --- /dev/null +++ b/build-system/Make/BuildEnvironment.py @@ -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) diff --git a/build-system/Make/Make.py b/build-system/Make/Make.py new file mode 100644 index 0000000000..2e6878a95c --- /dev/null +++ b/build-system/Make/Make.py @@ -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 diff --git a/build-system/Make/ProjectGeneration.py b/build-system/Make/ProjectGeneration.py new file mode 100644 index 0000000000..dab2520e34 --- /dev/null +++ b/build-system/Make/ProjectGeneration.py @@ -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(''' + + + + + defaultBazelURL + {} + + +'''.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]) diff --git a/build-system/example-configuration/provisioning/BUILD b/build-system/example-configuration/provisioning/BUILD index 171ad85d32..9abb88a19d 100644 --- a/build-system/example-configuration/provisioning/BUILD +++ b/build-system/example-configuration/provisioning/BUILD @@ -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", ]) diff --git a/build-system/example-configuration/variables.bzl b/build-system/example-configuration/variables.bzl index 0d2d187fa2..84476eb7a2 100644 --- a/build-system/example-configuration/variables.bzl +++ b/build-system/example-configuration/variables.bzl @@ -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 diff --git a/build-system/tulsi b/build-system/tulsi index b965114f31..ee28952fc9 160000 --- a/build-system/tulsi +++ b/build-system/tulsi @@ -1 +1 @@ -Subproject commit b965114f31a464185318c71ef3d0c1538d0c52de +Subproject commit ee28952fc91b493b5e1d11e4ccf12d7df4454504