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",
|
load("@build_bazel_rules_apple//apple:ios.bzl",
|
||||||
"ios_application",
|
"ios_application",
|
||||||
"ios_extension",
|
"ios_extension",
|
||||||
@ -24,7 +28,6 @@ load(
|
|||||||
"telegram_bundle_id",
|
"telegram_bundle_id",
|
||||||
"telegram_aps_environment",
|
"telegram_aps_environment",
|
||||||
"telegram_team_id",
|
"telegram_team_id",
|
||||||
"telegram_disable_extensions",
|
|
||||||
)
|
)
|
||||||
|
|
||||||
config_setting(
|
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(
|
genrule(
|
||||||
name = "empty",
|
name = "empty",
|
||||||
outs = ["empty.swift"],
|
outs = ["empty.swift"],
|
||||||
@ -482,7 +498,7 @@ watchos_extension(
|
|||||||
":WatchExtensionNSExtensionInfoPlist",
|
":WatchExtensionNSExtensionInfoPlist",
|
||||||
],
|
],
|
||||||
minimum_os_version = "5.0",
|
minimum_os_version = "5.0",
|
||||||
provisioning_profile = "@build_configuration//data/provisioning-profiles:WatchExtension.mobileprovision",
|
provisioning_profile = "@build_configuration//provisioning:WatchExtension.mobileprovision",
|
||||||
resources = [
|
resources = [
|
||||||
":TelegramWatchExtensionResources",
|
":TelegramWatchExtensionResources",
|
||||||
],
|
],
|
||||||
@ -509,7 +525,7 @@ watchos_application(
|
|||||||
":WatchAppCompanionInfoPlist",
|
":WatchAppCompanionInfoPlist",
|
||||||
],
|
],
|
||||||
minimum_os_version = "5.0",
|
minimum_os_version = "5.0",
|
||||||
provisioning_profile = "@build_configuration//data/provisioning-profiles:WatchApp.mobileprovision",
|
provisioning_profile = "@build_configuration//provisioning:WatchApp.mobileprovision",
|
||||||
resources = [
|
resources = [
|
||||||
":TelegramWatchAppResources",
|
":TelegramWatchAppResources",
|
||||||
":TelegramWatchAppAssets",
|
":TelegramWatchAppAssets",
|
||||||
@ -1055,7 +1071,7 @@ ios_extension(
|
|||||||
":AppNameInfoPlist",
|
":AppNameInfoPlist",
|
||||||
],
|
],
|
||||||
minimum_os_version = "9.0",
|
minimum_os_version = "9.0",
|
||||||
provisioning_profile = "@build_configuration//data/provisioning-profiles:Share.mobileprovision",
|
provisioning_profile = "@build_configuration//provisioning:Share.mobileprovision",
|
||||||
deps = [":ShareExtensionLib"],
|
deps = [":ShareExtensionLib"],
|
||||||
frameworks = [
|
frameworks = [
|
||||||
":TelegramUIFramework"
|
":TelegramUIFramework"
|
||||||
@ -1123,7 +1139,7 @@ ios_extension(
|
|||||||
":AppNameInfoPlist",
|
":AppNameInfoPlist",
|
||||||
],
|
],
|
||||||
minimum_os_version = "10.0",
|
minimum_os_version = "10.0",
|
||||||
provisioning_profile = "@build_configuration//data/provisioning-profiles:NotificationContent.mobileprovision",
|
provisioning_profile = "@build_configuration//provisioning:NotificationContent.mobileprovision",
|
||||||
deps = [":NotificationContentExtensionLib"],
|
deps = [":NotificationContentExtensionLib"],
|
||||||
frameworks = [
|
frameworks = [
|
||||||
":TelegramUIFramework"
|
":TelegramUIFramework"
|
||||||
@ -1195,7 +1211,7 @@ ios_extension(
|
|||||||
],
|
],
|
||||||
minimum_os_version = "14.0",
|
minimum_os_version = "14.0",
|
||||||
provides_main = True,
|
provides_main = True,
|
||||||
provisioning_profile = "@build_configuration//data/provisioning-profiles:Widget.mobileprovision",
|
provisioning_profile = "@build_configuration//provisioning:Widget.mobileprovision",
|
||||||
deps = [":WidgetExtensionLib"],
|
deps = [":WidgetExtensionLib"],
|
||||||
frameworks = [
|
frameworks = [
|
||||||
":SwiftSignalKitFramework",
|
":SwiftSignalKitFramework",
|
||||||
@ -1283,7 +1299,7 @@ ios_extension(
|
|||||||
":AppNameInfoPlist",
|
":AppNameInfoPlist",
|
||||||
],
|
],
|
||||||
minimum_os_version = "10.0",
|
minimum_os_version = "10.0",
|
||||||
provisioning_profile = "@build_configuration//data/provisioning-profiles:Intents.mobileprovision",
|
provisioning_profile = "@build_configuration//provisioning:Intents.mobileprovision",
|
||||||
deps = [":IntentsExtensionLib"],
|
deps = [":IntentsExtensionLib"],
|
||||||
frameworks = [
|
frameworks = [
|
||||||
":SwiftSignalKitFramework",
|
":SwiftSignalKitFramework",
|
||||||
@ -1334,7 +1350,7 @@ ios_extension(
|
|||||||
":AppNameInfoPlist",
|
":AppNameInfoPlist",
|
||||||
],
|
],
|
||||||
minimum_os_version = "10.0",
|
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"],
|
deps = ["//Telegram/NotificationService:NotificationServiceExtensionLib"],
|
||||||
frameworks = [
|
frameworks = [
|
||||||
":MtProtoKitFramework",
|
":MtProtoKitFramework",
|
||||||
@ -1522,7 +1538,7 @@ ios_application(
|
|||||||
),
|
),
|
||||||
families = ["iphone", "ipad"],
|
families = ["iphone", "ipad"],
|
||||||
minimum_os_version = "9.0",
|
minimum_os_version = "9.0",
|
||||||
provisioning_profile = "@build_configuration//data/provisioning-profiles:Telegram.mobileprovision",
|
provisioning_profile = "@build_configuration//provisioning:Telegram.mobileprovision",
|
||||||
entitlements = ":TelegramEntitlements.entitlements",
|
entitlements = ":TelegramEntitlements.entitlements",
|
||||||
infoplists = [
|
infoplists = [
|
||||||
":TelegramInfoPlist",
|
":TelegramInfoPlist",
|
||||||
@ -1547,14 +1563,16 @@ ios_application(
|
|||||||
strings = [
|
strings = [
|
||||||
":AppStringResources",
|
":AppStringResources",
|
||||||
],
|
],
|
||||||
extensions = [
|
extensions = select({
|
||||||
] if telegram_disable_extensions else [
|
":disableExtensionsSetting": [],
|
||||||
|
"//conditions:default": [
|
||||||
":ShareExtension",
|
":ShareExtension",
|
||||||
":NotificationContentExtension",
|
":NotificationContentExtension",
|
||||||
":NotificationServiceExtension",
|
":NotificationServiceExtension",
|
||||||
":IntentsExtension",
|
":IntentsExtension",
|
||||||
":WidgetExtension",
|
":WidgetExtension",
|
||||||
],
|
],
|
||||||
|
}),
|
||||||
watch_application = ":TelegramWatchApp",
|
watch_application = ":TelegramWatchApp",
|
||||||
deps = [
|
deps = [
|
||||||
":Main",
|
":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([
|
exports_files([
|
||||||
"*.mobileprovision",
|
"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_appstore_id = "0"
|
||||||
telegram_app_specific_url_scheme = "tg"
|
telegram_app_specific_url_scheme = "tg"
|
||||||
telegram_aps_environment = "production"
|
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