From bc3b18085b7efbc47f7c616fce99d430c22edf1a Mon Sep 17 00:00:00 2001 From: "auto-submit[bot]" <98614782+auto-submit[bot]@users.noreply.github.com> Date: Fri, 11 Oct 2024 17:51:47 +0000 Subject: [PATCH] Reverts "[Fuchsia] Use more high level fuchsia-gn-sdk templates (#55445)" (#55834) Reverts: flutter/engine#55445 Initiated by: zijiehe-google-com Reason for reverting: This change would break the build_fuchsia_artifacts.py without https://github.com/flutter/engine/pull/55832/files. I'd merge two into one. Original PR Author: zijiehe-google-com Reviewed By: {jrwang} This change reverts the following previous change: This change removes the in-house built pm-based build rules in favor of the high level fuchsia_component / fuchsia_package in the gn-sdk. The build_fuchsia_artifacts.py is still using pm, and it will be handled in a following change. Bug: http://b/353729557, http://b/368608542 [C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style --- shell/platform/fuchsia/dart_runner/BUILD.gn | 6 + tools/fuchsia/build_fuchsia_artifacts.py | 2 - tools/fuchsia/copy_path.py | 68 +++++ tools/fuchsia/fuchsia_archive.gni | 319 ++++++++++++++------ tools/fuchsia/gen_repo.py | 52 ++++ 5 files changed, 348 insertions(+), 99 deletions(-) create mode 100755 tools/fuchsia/copy_path.py create mode 100755 tools/fuchsia/gen_repo.py diff --git a/shell/platform/fuchsia/dart_runner/BUILD.gn b/shell/platform/fuchsia/dart_runner/BUILD.gn index 1a626e1f7af47..e36ce92743002 100644 --- a/shell/platform/fuchsia/dart_runner/BUILD.gn +++ b/shell/platform/fuchsia/dart_runner/BUILD.gn @@ -190,6 +190,12 @@ template("aot_runner_package") { "//flutter/shell/platform/fuchsia/runtime/dart/profiler_symbols:dart_aot_runner", "target_gen_dir") + "/dart_aot_runner.dartprofilersymbols") + inputs = [ + vmservice_snapshot, + observatory_archive_file, + dart_profiler_symbols, + ] + resources += [ { path = vmservice_snapshot diff --git a/tools/fuchsia/build_fuchsia_artifacts.py b/tools/fuchsia/build_fuchsia_artifacts.py index 3a30ad47bcd39..5258466145387 100755 --- a/tools/fuchsia/build_fuchsia_artifacts.py +++ b/tools/fuchsia/build_fuchsia_artifacts.py @@ -146,8 +146,6 @@ def CopyZirconFFILibIfExists(source, destination): FindFileAndCopyTo('libzircon_ffi.so', source_root, destination_base) -# TODO(zijiehe): http://crbug.com/368608542, avoid using pm or building far -# packages here, packages should be built by ninja. def CopyToBucketWithMode(source, destination, aot, product, runner_type, api_level): mode = 'aot' if aot else 'jit' product_suff = '_product' if product else '' diff --git a/tools/fuchsia/copy_path.py b/tools/fuchsia/copy_path.py new file mode 100755 index 0000000000000..7f46cb0918057 --- /dev/null +++ b/tools/fuchsia/copy_path.py @@ -0,0 +1,68 @@ +#!/usr/bin/env python3 +# +# Copyright 2013 The Flutter Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +""" Copies paths, creates if they do not exist. +""" + +import argparse +import errno +import json +import os +import platform +import shutil +import subprocess +import sys + + +def EnsureParentExists(path): + dir_name, _ = os.path.split(path) + if not os.path.exists(dir_name): + os.makedirs(dir_name) + + +def SameStat(s1, s2): + return s1.st_ino == s2.st_ino and s1.st_dev == s2.st_dev + + +def SameFile(f1, f2): + if not os.path.exists(f2): + return False + s1 = os.stat(f1) + s2 = os.stat(f2) + return SameStat(s1, s2) + + +def CopyPath(src, dst): + try: + EnsureParentExists(dst) + shutil.copytree(src, dst) + except OSError as exc: + if exc.errno == errno.ENOTDIR: + if not SameFile(src, dst): + shutil.copyfile(src, dst) + else: + raise + + +def main(): + parser = argparse.ArgumentParser() + + parser.add_argument('--file-list', dest='file_list', action='store', required=True) + + args = parser.parse_args() + + files = open(args.file_list, 'r') + files_to_copy = files.read().split() + num_files = len(files_to_copy) // 2 + + for i in range(num_files): + CopyPath(files_to_copy[i], files_to_copy[num_files + i]) + + return 0 + + +if __name__ == '__main__': + sys.exit(main()) diff --git a/tools/fuchsia/fuchsia_archive.gni b/tools/fuchsia/fuchsia_archive.gni index 911c30ac3da03..d18a4c9ec8043 100644 --- a/tools/fuchsia/fuchsia_archive.gni +++ b/tools/fuchsia/fuchsia_archive.gni @@ -5,135 +5,244 @@ import("//flutter/tools/fuchsia/fuchsia_debug_symbols.gni") import("//flutter/tools/fuchsia/fuchsia_libs.gni") import("//flutter/tools/fuchsia/gn-sdk/src/cmc.gni") -import("//flutter/tools/fuchsia/gn-sdk/src/component.gni") import("//flutter/tools/fuchsia/gn-sdk/src/gn_configs.gni") -import("//flutter/tools/fuchsia/gn-sdk/src/package.gni") -# Creates a Fuchsia archive (.far) file from the Fuchsia SDK and gn-sdk. -# -# An archive combines an ELF binary and a component manifest to create -# a packaged Fuchsia program that can be deployed to a Fuchsia device. +# Alias of cmc_compile in gn-sdk/src/cmc.gni +template("_compile_cml") { + assert(defined(invoker.manifest), "_compile_cml must define manifest") + + # Create an empty depfile, it's not used in flutter. + write_file("${target_gen_dir}/${target_name}/${target_name}.d", + [], + "list lines") + + cmc_compile(target_name) { + forward_variables_from(invoker, + [ + "deps", + "manifest", + "testonly", + ]) + output_file = invoker.output + } +} + +# TODO(zijiehe): May use fuchsia_package in gn-sdk if possible. - http://crbug.com/40935282 + +# Creates a Fuchsia archive (.far) file using PM from the Fuchsia SDK. # -# binary (optional): -# The ELF binary for the archive's program, or target_name if unspecified. +# binary (required): +# The ELF binary for the archive's program. # deps (optional): # The code dependencies for the archive. +# inputs (optional): +# When these files are changed, the package should be regenerated. # libraries (optional): # Paths to .so libraries that should be dynamically linked to the binary. -# manifest (optional): -# The component manifest cml file, or meta/binary.cml if unspecified. # resources (optional): # Files that should be placed into the `data/` directory of the archive. # testonly (optional): # Set this to true for archives that are only used for tests. -template("fuchsia_archive") { - if (defined(invoker.binary)) { - _binary = invoker.binary - } else { - _binary = target_name - } +template("_fuchsia_archive") { + assert(defined(invoker.binary), "package must define binary") - if (defined(invoker.manifest)) { - _manifest = invoker.manifest - } else { - _manifest = rebase_path("meta/${_binary}.cml") - } - - _component_target = target_name + "__component" - fuchsia_component(_component_target) { + pkg_testonly = defined(invoker.testonly) && invoker.testonly + pkg_target_name = target_name + pkg = { + package_version = "0" # placeholder forward_variables_from(invoker, [ + "binary", "deps", - "testonly", + "resources", + "libraries", ]) - manifest = _manifest + if (!defined(package_name)) { + package_name = pkg_target_name + } + if (!defined(deps)) { + deps = [] + } + if (!defined(resources)) { + resources = [] + } + if (!defined(libraries)) { + libraries = [] + } + } - resources = [ - { - path = "$root_out_dir/$_binary" - dest = "bin/app" - }, - ] - if (defined(invoker.resources)) { - foreach(resource, invoker.resources) { - resources += [ - { - path = resource.path - dest = "data/${resource.dest}" - }, - ] - } + far_base_dir = "$root_out_dir/${pkg_target_name}_far" + + copy_sources = [ "$root_out_dir/${invoker.binary}" ] + copy_outputs = [ "$far_base_dir/bin/app" ] + + foreach(res, pkg.resources) { + copy_sources += [ res.path ] + copy_outputs += [ "$far_base_dir/data/${res.dest}" ] + } + + foreach(lib, pkg.libraries) { + output_path = "" + + if (defined(lib.output_path)) { + output_path = lib.output_path } - _libs = common_libs - if (defined(invoker.libraries)) { - _libs += invoker.libraries + copy_sources += [ "${lib.path}/${lib.name}" ] + copy_outputs += [ "$far_base_dir/lib/${output_path}${lib.name}" ] + } + + pkg_dir_deps = pkg.deps + + write_file("${far_base_dir}/meta/package", + { + name = pkg.package_name + version = pkg.package_version + }, + "json") + + _dbg_symbols_target = "${target_name}_dbg_symbols" + fuchsia_debug_symbols(_dbg_symbols_target) { + deps = pkg.deps + testonly = pkg_testonly + binary = invoker.binary + } + + action("${target_name}_dir") { + script = "//flutter/tools/fuchsia/copy_path.py" + sources = copy_sources + response_file_contents = rebase_path(copy_sources + copy_outputs) + deps = pkg_dir_deps + args = [ "--file-list={{response_file_name}}" ] + outputs = copy_outputs + testonly = pkg_testonly + } + + manifest_json_file = "${root_out_dir}/${target_name}_package_manifest.json" + action(target_name) { + script = "//flutter/tools/fuchsia/gen_package.py" + deps = pkg_dir_deps + [ + ":${target_name}_dir", + ":${_dbg_symbols_target}", + ] + + sources = copy_outputs + + inputs = [] + if (defined(invoker.inputs)) { + inputs += invoker.inputs } - foreach(lib, _libs) { - output_path = "" - if (defined(lib.output_path)) { - output_path = lib.output_path - } - resources += [ - { - path = "${lib.path}/${lib.name}" - dest = "lib/${output_path}${lib.name}" - }, + + args = [ + "--pm-bin", + rebase_path("$fuchsia_tool_dir/pm"), + "--package-dir", + rebase_path(far_base_dir), + "--far-name", + target_name, + "--manifest-json-file", + rebase_path(manifest_json_file, root_build_dir), + ] + + assert(fuchsia_target_api_level != -1, + "Must set a target api level when creating an archive") + if (fuchsia_target_api_level != -1) { + args += [ + "--api-level", + "${fuchsia_target_api_level}", ] } + + outputs = [ + manifest_json_file, + "${far_base_dir}.manifest", + "$root_out_dir/${target_name}-0.far", + ] + testonly = pkg_testonly + } +} + +# Creates a Fuchsia archive. +# +# An archive combines an ELF binary and a component manifest to create +# a packaged Fuchsia program that can be deployed to a Fuchsia device. +# +# binary (optional): +# The ELF binary for the archive's program, or target_name if unspecified. +# deps (optional): +# The code dependencies for the archive. +# inputs (optional): +# When these files are changed, the package should be regenerated. +# libraries (optional): +# Paths to .so libraries that should be dynamically linked to the binary. +# resources (optional): +# Files that should be placed into the `data/` directory of the archive. +# testonly (optional): +# Set this to true for archives that are only used for tests. +template("fuchsia_archive") { + if (!defined(invoker.binary)) { + _binary = target_name + } else { + _binary = invoker.binary } + _deps = [] + if (defined(invoker.deps)) { + _deps += invoker.deps + } + + _cml_file = rebase_path("meta/${_binary}.cml") + _far_base_dir = "$root_out_dir/${target_name}_far" + _cml_file_name = get_path_info(_cml_file, "name") + _compile_cml_target = "${target_name}_${_cml_file_name}_compile_cml" - _package_target = target_name + "__package" - _package_name = target_name - fuchsia_package(_package_target) { + _compile_cml(_compile_cml_target) { forward_variables_from(invoker, [ "testonly" ]) - package_name = _package_name - deps = [ ":$_component_target" ] + + manifest = _cml_file + output = "$_far_base_dir/meta/${_cml_file_name}.cm" } + _deps += [ ":$_compile_cml_target" ] - # TODO(zijiehe): http://crbug.com/368608542, prefer using - # gn-sdk/build_id_dir.gni - _build_id_target = target_name + "__build_id" - fuchsia_debug_symbols(_build_id_target) { + _fuchsia_archive(target_name) { + deps = _deps + binary = _binary forward_variables_from(invoker, [ - "deps", + "inputs", + "libraries", + "resources", "testonly", ]) - binary = _binary - } - - # TODO(zijiehe): http://crbug.com/368608542, copying the far files is not very - # necessary, try to remove the -0.far copy. - copy(target_name) { - forward_variables_from(invoker, [ "testonly" ]) - package_output_dir = get_label_info(":$_package_target", "target_gen_dir") - sources = [ "$package_output_dir/$_package_name/${_package_name}.far" ] - outputs = [ "$root_out_dir/${_package_name}-0.far" ] - deps = [ - ":$_build_id_target", - ":$_package_target", - ] } } # Creates a Fuchsia archive (.far) file containing a generated test root -# component and test driver component. +# component and test driver component, using PM from the Fuchsia SDK. # -# binary: -# Forward to fuchsia_archive +# binary (optional): +# The binary for the test, or target_name if unspecified. # deps (required): # Dependencies for the test archive. # gen_cml_file (optional): # If is defined and true, an interpolate cml file will be generated. -# libraries: -# Forward to fuchsia_archive -# resources: -# Forward to fuchsia_archive +# libraries (optional): +# Paths to .so libraries that should be dynamically linked to the binary. +# resources (optional): +# Files that should be placed into the `data/` directory of the archive. template("fuchsia_test_archive") { assert(defined(invoker.deps), "package must define deps") - _deps = invoker.deps - if (defined(invoker.gen_cml_file) && invoker.gen_cml_file) { + if (!defined(invoker.binary)) { + _binary = target_name + } else { + _binary = invoker.binary + } + _deps = [] + if (defined(invoker.deps)) { + _deps += invoker.deps + } + + _generated_cml = defined(invoker.gen_cml_file) && invoker.gen_cml_file + if (_generated_cml) { _cml_file = "$root_out_dir/${target_name}.cml" _interpolate_cml_target = "${target_name}_interpolate_cml" action(_interpolate_cml_target) { @@ -150,20 +259,36 @@ template("fuchsia_test_archive") { ] outputs = [ _cml_file ] } - _deps += [ ":$_interpolate_cml_target" ] + } else { + _cml_file = rebase_path("meta/${_binary}.cml") } - fuchsia_archive(target_name) { - forward_variables_from(invoker, - [ - "binary", - "libraries", - "resources", - ]) + _far_base_dir = "$root_out_dir/${target_name}_far" + _cml_file_name = get_path_info(_cml_file, "name") + _compile_cml_target = "${target_name}_${_cml_file_name}_compile_cml" + + _compile_cml(_compile_cml_target) { + testonly = true + + manifest = _cml_file + output = "$_far_base_dir/meta/${_cml_file_name}.cm" + + if (_generated_cml) { + deps = [ ":$_interpolate_cml_target" ] + } + } + _deps += [ ":$_compile_cml_target" ] + + _fuchsia_archive(target_name) { testonly = true - if (defined(_cml_file)) { - manifest = _cml_file + binary = _binary + forward_variables_from(invoker, [ "resources" ]) + + libraries = common_libs + if (defined(invoker.libraries)) { + libraries += invoker.libraries } + deps = _deps } } diff --git a/tools/fuchsia/gen_repo.py b/tools/fuchsia/gen_repo.py new file mode 100755 index 0000000000000..b795254b8df06 --- /dev/null +++ b/tools/fuchsia/gen_repo.py @@ -0,0 +1,52 @@ +#!/usr/bin/env python3 +# +# Copyright 2013 The Flutter Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +""" Generate a Fuchsia repo capable of serving Fuchsia archives over the +network. +""" +import argparse +import collections +import json +import os +import subprocess +import sys + + +def main(): + parser = argparse.ArgumentParser() + + parser.add_argument('--pm-bin', dest='pm_bin', action='store', required=True) + parser.add_argument('--repo-dir', dest='repo_dir', action='store', required=True) + parser.add_argument('--archive', dest='archives', action='append', required=True) + + args = parser.parse_args() + + assert os.path.exists(args.pm_bin) + + if not os.path.exists(args.repo_dir): + pm_newrepo_command = [args.pm_bin, 'newrepo', '-repo', args.repo_dir] + subprocess.check_call(pm_newrepo_command) + + pm_publish_command = [ + args.pm_bin, + 'publish', + '-C', # Remove all previous registrations. + '-a', # Publish archives from an archive (mode). + '-repo', + args.repo_dir + ] + + for archive in args.archives: + pm_publish_command.append('-f') + pm_publish_command.append(archive) + + subprocess.check_call(pm_publish_command) + + return 0 + + +if __name__ == '__main__': + sys.exit(main())