def invoke_build(self): combined_arguments = [self.build_environment.bazel_path] combined_arguments += self.get_startup_bazel_arguments() combined_arguments += ['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 combined_arguments += self.get_define_arguments() combined_arguments += self.get_additional_build_arguments() 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') print(subprocess.list2cmdline(combined_arguments)) call_executable(combined_arguments)
def generate_project(arguments): bazel_command_line = BazelCommandLine( bazel_path=arguments.bazel, override_bazel_version=arguments.overrideBazelVersion, override_xcode_version=arguments.overrideXcodeVersion, bazel_user_root=arguments.bazelUserRoot) 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.cacheHost) resolve_configuration(bazel_command_line, arguments) bazel_command_line.set_build_number(arguments.buildNumber) disable_extensions = False if arguments.disableExtensions is not None: disable_extensions = arguments.disableExtensions if arguments.disableProvisioningProfiles is not None: disable_provisioning_profiles = arguments.disableProvisioningProfiles call_executable(['killall', 'Xcode'], check_result=False) generate(build_environment=bazel_command_line.build_environment, disable_extensions=disable_extensions, disable_provisioning_profiles=disable_provisioning_profiles, configuration_path=bazel_command_line.configuration_path, bazel_app_arguments=bazel_command_line. get_project_generation_arguments())
def invoke_clean(self): combined_arguments = [self.build_environment.bazel_path] combined_arguments += self.get_startup_bazel_arguments() combined_arguments += ['clean', '--expunge'] print('TelegramBuild: running {}'.format(combined_arguments)) call_executable(combined_arguments)
def locate_bazel(base_path): build_input_dir = '{}/build-input'.format(base_path) if not os.path.isdir(build_input_dir): os.mkdir(build_input_dir) versions = BuildEnvironmentVersions(base_path=os.getcwd()) if is_apple_silicon(): arch = 'darwin-arm64' else: arch = 'darwin-x86_64' bazel_name = 'bazel-{version}-{arch}'.format(version=versions.bazel_version, arch=arch) bazel_path = '{}/build-input/{}'.format(base_path, bazel_name) if not os.path.isfile(bazel_path): call_executable([ 'curl', '-L', 'https://github.com/bazelbuild/bazel/releases/download/{version}/{name}'.format( version=versions.bazel_version, name=bazel_name ), '--create-dirs', '--output', bazel_path ]) if not os.access(bazel_path, os.X_OK): st = os.stat(bazel_path) os.chmod(bazel_path, st.st_mode | stat.S_IEXEC) return bazel_path
def resolve_configuration(bazel_command_line: BazelCommandLine, arguments): if arguments.configurationGenerator is not None: configuration_generator_arguments = shlex.split(arguments.configurationGenerator) configuration_generator_executable = resolve_executable(configuration_generator_arguments[0]) if configuration_generator_executable is None: print('{} is not a valid executable'.format(configuration_generator_arguments[0])) exit(1) temp_configuration_path = tempfile.mkdtemp() resolved_configuration_generator_arguments = [configuration_generator_executable] resolved_configuration_generator_arguments += configuration_generator_arguments[1:] resolved_configuration_generator_arguments += [temp_configuration_path] call_executable(resolved_configuration_generator_arguments, use_clean_environment=False) 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(bazel, arguments): bazel_command_line = BazelCommandLine( bazel=bazel, override_bazel_version=arguments.overrideBazelVersion, override_xcode_version=arguments.overrideXcodeVersion, bazel_user_root=arguments.bazelUserRoot) 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.cacheHost) bazel_command_line.set_continue_on_error(arguments.continueOnError) resolve_configuration(bazel_command_line, arguments) bazel_command_line.set_build_number(arguments.buildNumber) disable_extensions = False disable_provisioning_profiles = False generate_dsym = False target_name = "Telegram" if arguments.disableExtensions is not None: disable_extensions = arguments.disableExtensions if arguments.disableProvisioningProfiles is not None: disable_provisioning_profiles = arguments.disableProvisioningProfiles if arguments.generateDsym is not None: generate_dsym = arguments.generateDsym if arguments.target is not None: target_name = arguments.target call_executable(['killall', 'Xcode'], check_result=False) generate(build_environment=bazel_command_line.build_environment, disable_extensions=disable_extensions, disable_provisioning_profiles=disable_provisioning_profiles, generate_dsym=generate_dsym, configuration_path=bazel_command_line.configuration_path, bazel_app_arguments=bazel_command_line. get_project_generation_arguments(), target_name=target_name)
def generate(build_environment: BuildEnvironment, disable_extensions, disable_provisioning_profiles, configuration_path, bazel_app_arguments): project_path = os.path.join(build_environment.base_path, 'build-input/gen/project') app_target = 'Telegram' 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') tulsi_build_bazel_path = build_environment.bazel_path current_dir = os.getcwd() os.chdir(os.path.join(build_environment.base_path, 'build-system/tulsi')) tulsi_build_command = [] tulsi_build_command += [tulsi_build_bazel_path] tulsi_build_command += ['build', '//:tulsi'] if is_apple_silicon(): tulsi_build_command += ['--macos_cpus=arm64'] tulsi_build_command += [ '--xcode_version={}'.format(build_environment.xcode_version) ] tulsi_build_command += ['--use_top_level_targets_for_symlinks'] tulsi_build_command += ['--verbose_failures'] call_executable(tulsi_build_command) 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) ] 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'] if disable_provisioning_profiles: bazel_build_arguments += ['--//Telegram:disableProvisioningProfiles'] 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])
def generate(build_environment: BuildEnvironment, disable_extensions, disable_provisioning_profiles, generate_dsym, configuration_path, bazel_app_arguments, target_name): project_path = os.path.join(build_environment.base_path, 'build-input/gen/project') if '/' in target_name: app_target_spec = target_name.split('/')[0] + '/' + target_name.split( '/')[1] + ':' + target_name.split('/')[1] app_target = target_name app_target_clean = app_target.replace('/', '_') else: app_target_spec = '{target}:{target}'.format(target=target_name) app_target = target_name app_target_clean = app_target.replace('/', '_') 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_clean)) tulsi_path = os.path.join(project_path, 'Tulsi.app/Contents/MacOS/Tulsi') tulsi_build_bazel_path = build_environment.bazel_path current_dir = os.getcwd() os.chdir(os.path.join(build_environment.base_path, 'build-system/tulsi')) tulsi_build_command = [] tulsi_build_command += [tulsi_build_bazel_path] tulsi_build_command += ['build', '//:tulsi'] if is_apple_silicon(): tulsi_build_command += ['--macos_cpus=arm64'] tulsi_build_command += [ '--xcode_version={}'.format(build_environment.xcode_version) ] tulsi_build_command += ['--use_top_level_targets_for_symlinks'] tulsi_build_command += ['--verbose_failures'] call_executable(tulsi_build_command) 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) ] 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 += [ '--//{}:disableExtensions'.format(app_target) ] if disable_provisioning_profiles: bazel_build_arguments += [ '--//{}:disableProvisioningProfiles'.format(app_target) ] if generate_dsym: bazel_build_arguments += ['--apple_generate_dsym'] bazel_build_arguments += ['--//{}:disableStripping'.format(app_target)] bazel_build_arguments += ['--strip=never'] call_executable([ tulsi_path, '--', '--verbose', '--create-tulsiproj', app_target_clean, '--workspaceroot', './', '--bazel', bazel_wrapper_path, '--outputfolder', project_path, '--target', '{target_spec}'.format(target_spec=app_target_spec), '--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 += ['--//{}:disableExtensions'.format(app_target)] additional_arguments_string = ' '.join(additional_arguments) tulsi_config_path = 'build-input/gen/project/{target}.tulsiproj/Configs/{target}.tulsigen'.format( target=app_target_clean) 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'] = [ '{}/...'.format(app_target), '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_clean), '--bazel', bazel_wrapper_path, '--outputfolder', project_path, '--no-open-xcode' ]) xcodeproj_path = '{project}/{target}.xcodeproj'.format( project=project_path, target=app_target_clean) call_executable(['open', xcodeproj_path])