From c74f25f4cb0a3c2da5e688db606c0610678cd68b Mon Sep 17 00:00:00 2001 From: Dan Field Date: Tue, 13 Jul 2021 10:23:08 -0700 Subject: [PATCH] Reland build rules for scenario app (#27360) * Revert "Revert "Build rules for scenario_app (#27302)" (#27358)" This reverts commit 99f87912ef440cf5301a27fe8079e80df639f3a2. * Ignore *.*framework in copy_trees --- BUILD.gn | 4 + build/dart/rules.gni | 165 +++++++++++++++++- testing/scenario_app/BUILD.gn | 49 ++++++ testing/scenario_app/android/BUILD.gn | 50 ++++++ testing/scenario_app/android/app/build.gradle | 10 +- testing/scenario_app/android/build.gradle | 5 +- testing/scenario_app/android/run_gradle.py | 26 +++ testing/scenario_app/assemble_apk.sh | 13 +- .../build_and_run_android_tests.sh | 3 - .../scenario_app/build_and_run_ios_tests.sh | 2 - testing/scenario_app/compile_android_aot.sh | 80 --------- testing/scenario_app/compile_android_jit.sh | 93 ---------- testing/scenario_app/compile_ios_aot.sh | 103 ----------- testing/scenario_app/compile_ios_jit.sh | 109 ------------ testing/scenario_app/ios/BUILD.gn | 66 +++++++ .../Scenarios.xcodeproj/project.pbxproj | 2 +- testing/scenario_app/ios/app_stub.c | 2 + testing/scenario_app/run_android_tests.sh | 7 +- testing/scenario_app/run_ios_tests.sh | 2 +- testing/scenario_app/runtime_mode.gni | 9 + 20 files changed, 391 insertions(+), 409 deletions(-) create mode 100644 testing/scenario_app/BUILD.gn create mode 100644 testing/scenario_app/android/BUILD.gn create mode 100644 testing/scenario_app/android/run_gradle.py delete mode 100755 testing/scenario_app/compile_android_aot.sh delete mode 100755 testing/scenario_app/compile_android_jit.sh delete mode 100755 testing/scenario_app/compile_ios_aot.sh delete mode 100755 testing/scenario_app/compile_ios_jit.sh create mode 100644 testing/scenario_app/ios/BUILD.gn create mode 100644 testing/scenario_app/ios/app_stub.c create mode 100644 testing/scenario_app/runtime_mode.gni diff --git a/BUILD.gn b/BUILD.gn index 5be7ccf2fa..23f14443b1 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -116,6 +116,10 @@ group("flutter") { ] } + if (is_ios || is_android) { + public_deps += [ "//flutter/testing/scenario_app" ] + } + # Compile all unittests targets if enabled. if (enable_unittests) { public_deps += [ diff --git a/build/dart/rules.gni b/build/dart/rules.gni index dcafa6caf4..3ffe4d4aaa 100644 --- a/build/dart/rules.gni +++ b/build/dart/rules.gni @@ -2,10 +2,171 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -# This file has rules for making Dart packages and Dart-based Mojo applications. -# The entrypoint is the dart_pkg rule. +# This file has rules for making Dart packages and snapshots. +import("//build/compiled_action.gni") import("//build/module_args/dart.gni") +import("//flutter/common/config.gni") +import("//third_party/dart/build/dart/dart_action.gni") + +# Creates a dart kernel (dill) file suitable for use with gen_snapshot, as well +# as the app-jit, aot-elf, or aot-assembly snapshot for Android or iOS. +# +# Invoker must supply dart_main and package_config. Invoker may optionally +# supply aot as a boolean and product as a boolean. +template("dart_snapshot") { + assert(!is_fuchsia) + assert(defined(invoker.main_dart), "main_dart is a required parameter.") + assert(defined(invoker.package_config), + "package_config is a required parameter.") + + kernel_target = "_${target_name}_kernel" + snapshot_target = "_${target_name}_snapshot" + is_aot = + flutter_runtime_mode == "profile" || flutter_runtime_mode == "release" + + kernel_output = "$target_gen_dir/kernel_blob.bin" + + prebuilt_dart_action(kernel_target) { + script = "//flutter/flutter_frontend_server/bin/starter.dart" + + main_dart = rebase_path(invoker.main_dart) + package_config = rebase_path(invoker.package_config) + flutter_patched_sdk = rebase_path("$root_out_dir/flutter_patched_sdk") + + deps = [ "//flutter/lib/snapshot:strong_platform" ] + + inputs = [ + main_dart, + package_config, + ] + + outputs = [ kernel_output ] + + depfile = "$kernel_output.d" + abs_depfile = rebase_path(depfile) + rebased_output = rebase_path(kernel_output, root_build_dir) + vm_args = [ + "--depfile=$abs_depfile", + "--depfile_output_filename=$rebased_output", + "--disable-dart-dev", + ] + + args = [ + "--packages=" + rebase_path(package_config), + "--target=flutter", + "--sdk-root=" + flutter_patched_sdk, + "--output-dill=" + rebase_path(kernel_output), + ] + + if (is_aot) { + args += [ + "--aot", + "--tfa", + ] + } else { + # --no-link-platform is only valid when --aot isn't specified + args += [ "--no-link-platform" ] + } + + if (defined(invoker.product) && invoker.product) { + # Setting this flag in a non-product release build for AOT (a "profile" + # build) causes the vm service isolate code to be tree-shaken from an app. + # See the pragma on the entrypoint here: + # + # https://github.com/dart-lang/sdk/blob/master/sdk/lib/_internal/vm/bin/vmservice_io.dart#L240 + # + # Also, this define excludes debugging and profiling code from Flutter. + args += [ "-Ddart.vm.product=true" ] + } else { + if (!is_debug) { + # The following define excludes debugging code from Flutter. + args += [ "-Ddart.vm.profile=true" ] + } + } + + args += [ rebase_path(main_dart) ] + } + + compiled_action(snapshot_target) { + if (target_cpu == "x86" && host_os == "linux") { + # By default Dart will create a 32-bit gen_snapshot host binary if the target + # platform is 32-bit. Override this to create a 64-bit gen_snapshot for x86 + # targets because some host platforms may not support 32-bit binaries. + tool = "//third_party/dart/runtime/bin:gen_snapshot_host_targeting_host" + toolchain = "//build/toolchain/$host_os:clang_x64" + } else { + tool = "//third_party/dart/runtime/bin:gen_snapshot" + } + + inputs = [ kernel_output ] + deps = [ ":$kernel_target" ] + outputs = [] + + args = [ "--lazy_async_stacks" ] + + if (is_debug && flutter_runtime_mode != "profile" && + flutter_runtime_mode != "release" && + flutter_runtime_mode != "jit_release") { + args += [ "--enable_asserts" ] + } + + if (is_aot) { + args += [ "--deterministic" ] + if (is_ios) { + snapshot_assembly = "$target_gen_dir/ios/snapshot_assembly.S" + outputs += [ snapshot_assembly ] + args += [ + "--snapshot_kind=app-aot-assembly", + "--assembly=" + rebase_path(snapshot_assembly), + ] + } else if (is_android) { + libapp = "$target_gen_dir/android/libs/$android_app_abi/libapp.so" + outputs += [ libapp ] + args += [ + "--snapshot_kind=app-aot-elf", + "--elf=" + rebase_path(libapp), + ] + } else { + assert(false) + } + } else { + deps += [ "//flutter/lib/snapshot:generate_snapshot_bin" ] + vm_snapshot_data = + "$root_gen_dir/flutter/lib/snapshot/vm_isolate_snapshot.bin" + snapshot_data = "$root_gen_dir/flutter/lib/snapshot/isolate_snapshot.bin" + isolate_snapshot_data = "$target_gen_dir/isolate_snapshot_data" + isolate_snapshot_instructions = "$target_gen_dir/isolate_snapshot_instr" + + inputs += [ + vm_snapshot_data, + snapshot_data, + ] + + outputs += [ + isolate_snapshot_data, + isolate_snapshot_instructions, + ] + args += [ + "--snapshot_kind=app-jit", + "--load_vm_snapshot_data=" + rebase_path(vm_snapshot_data), + "--load_isolate_snapshot_data=" + rebase_path(snapshot_data), + "--isolate_snapshot_data=" + rebase_path(isolate_snapshot_data), + "--isolate_snapshot_instructions=" + + rebase_path(isolate_snapshot_instructions), + ] + } + + args += [ rebase_path(kernel_output) ] + } + + group(target_name) { + public_deps = [ + ":$kernel_target", + ":$snapshot_target", + ] + } +} template("dart_pkg_helper") { assert(defined(invoker.package_name)) diff --git a/testing/scenario_app/BUILD.gn b/testing/scenario_app/BUILD.gn new file mode 100644 index 0000000000..10b9bcf819 --- /dev/null +++ b/testing/scenario_app/BUILD.gn @@ -0,0 +1,49 @@ +# 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. + +import("//flutter/build/dart/rules.gni") +import("//flutter/testing/scenario_app/runtime_mode.gni") + +dart_snapshot("scenario_app_snapshot") { + main_dart = "lib/main.dart" + package_config = ".dart_tool/package_config.json" +} + +if (!is_aot) { + if (is_android) { + _flutter_assets_dir = "$root_out_dir/scenario_app/app/assets/flutter_assets" + } else if (is_ios) { + _flutter_assets_dir = + "$root_out_dir/scenario_app/Scenarios/App.framework/flutter_assets" + } else { + assert(false) + } + + copy("copy_jit_assets") { + visibility = [ ":*" ] + sources = [ + "$target_gen_dir/isolate_snapshot_data", + "$target_gen_dir/isolate_snapshot_instr", + "$target_gen_dir/kernel_blob.bin", + ] + outputs = [ "$_flutter_assets_dir/{{source_file_part}}" ] + deps = [ ":scenario_app_snapshot" ] + } +} + +group("scenario_app") { + deps = [ ":scenario_app_snapshot" ] + + if (!is_aot) { + deps += [ ":copy_jit_assets" ] + } + + if (is_android) { + deps += [ "android" ] + } + + if (is_ios) { + deps += [ "ios" ] + } +} diff --git a/testing/scenario_app/android/BUILD.gn b/testing/scenario_app/android/BUILD.gn new file mode 100644 index 0000000000..0cf5ae1fee --- /dev/null +++ b/testing/scenario_app/android/BUILD.gn @@ -0,0 +1,50 @@ +# 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. + +import("//flutter/testing/scenario_app/runtime_mode.gni") + +action("android") { + script = "run_gradle.py" + + inputs = [ "$root_out_dir/flutter.jar" ] + sources = [ + "app/build.gradle", + "app/src/androidTest/java/dev/flutter/TestRunner.java", + "app/src/androidTest/java/dev/flutter/scenarios/EngineLaunchE2ETest.java", + "app/src/androidTest/java/dev/flutter/scenarios/ExampleInstrumentedTest.java", + "app/src/androidTest/java/dev/flutter/scenariosui/MemoryLeakTests.java", + "app/src/androidTest/java/dev/flutter/scenariosui/PlatformTextureUiTests.java", + "app/src/androidTest/java/dev/flutter/scenariosui/PlatformViewUiTests.java", + "app/src/androidTest/java/dev/flutter/scenariosui/ScreenshotUtil.java", + "app/src/androidTest/java/dev/flutter/scenariosui/SpawnEngineTests.java", + "app/src/main/AndroidManifest.xml", + "app/src/main/java/dev/flutter/scenarios/SpawnedEngineActivity.java", + "app/src/main/java/dev/flutter/scenarios/StrictModeFlutterActivity.java", + "app/src/main/java/dev/flutter/scenarios/TestActivity.java", + "app/src/main/java/dev/flutter/scenarios/TestableFlutterActivity.java", + "app/src/main/java/dev/flutter/scenarios/TextPlatformView.java", + "app/src/main/java/dev/flutter/scenarios/TextPlatformViewActivity.java", + "app/src/main/java/dev/flutter/scenarios/TextPlatformViewFactory.java", + "app/src/main/java/io/flutter/plugins/GeneratedPluginRegistrant.java", + "build.gradle", + ] + outputs = [ "$root_out_dir/scenario_app/app/outputs/apk/debug/app-debug.apk" ] + + args = [ + "assembleDebug", + "--no-daemon", + "-Pflutter_jar=" + rebase_path("$root_out_dir/flutter.jar"), + "-Pout_dir=" + rebase_path("$root_out_dir/scenario_app"), + ] + + if (is_aot) { + args += [ "-Plibapp=" + rebase_path("$target_gen_dir/libs") ] + inputs += [ "$target_gen_dir/libs/$android_app_abi/libapp.so" ] + } + + deps = [ + "//flutter/shell/platform/android:android_jar", + "//flutter/testing/scenario_app:scenario_app_snapshot", + ] +} diff --git a/testing/scenario_app/android/app/build.gradle b/testing/scenario_app/android/app/build.gradle index 16288dd35f..316370fc4a 100644 --- a/testing/scenario_app/android/app/build.gradle +++ b/testing/scenario_app/android/app/build.gradle @@ -30,14 +30,18 @@ android { proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } - sourceSets { - main.assets.srcDirs += "${project.buildDir}/assets" + sourceSets.main { + assets.srcDirs += "${project.buildDir}/assets" + if (project.hasProperty('libapp')) { + jni.srcDirs = [] + jniLibs.srcDirs = [project.property('libapp')] + } } } dependencies { + implementation files(project.property('flutter_jar')) compile 'com.facebook.testing.screenshot:layout-hierarchy-common:0.12.0' - implementation fileTree(dir: 'libs', include: ['*.jar']) implementation 'androidx.appcompat:appcompat:1.1.0' implementation 'androidx.constraintlayout:constraintlayout:1.1.3' implementation 'com.google.android.material:material:1.0.0' diff --git a/testing/scenario_app/android/build.gradle b/testing/scenario_app/android/build.gradle index 205e758b64..9e1b24001d 100644 --- a/testing/scenario_app/android/build.gradle +++ b/testing/scenario_app/android/build.gradle @@ -21,7 +21,10 @@ allprojects { } } -rootProject.buildDir = '../build' +rootProject.buildDir = project.hasProperty('out_dir') + ? project.property('out_dir') + : '../build' + subprojects { project.buildDir = "${rootProject.buildDir}/${project.name}" } diff --git a/testing/scenario_app/android/run_gradle.py b/testing/scenario_app/android/run_gradle.py new file mode 100644 index 0000000000..b32ce5b1a5 --- /dev/null +++ b/testing/scenario_app/android/run_gradle.py @@ -0,0 +1,26 @@ +#!/usr/bin/env python +# 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. + +""" +Invokes gradlew for building the scenario_app from GN/Ninja. +""" + +import os +import sys +import subprocess + +def main(): + BAT = '.bat' if sys.platform.startswith(('cygwin', 'win')) else '' + android_dir = os.path.abspath(os.path.dirname(__file__)) + gradle_bin = os.path.join('.', 'gradlew%s' % BAT) + result = subprocess.check_output( + args=[gradle_bin] + sys.argv[1:], + cwd=android_dir, + ) + return 0 + + +if __name__ == '__main__': + sys.exit(main()) diff --git a/testing/scenario_app/assemble_apk.sh b/testing/scenario_app/assemble_apk.sh index 8ef5963284..bd54c7fb92 100755 --- a/testing/scenario_app/assemble_apk.sh +++ b/testing/scenario_app/assemble_apk.sh @@ -27,16 +27,9 @@ SCRIPT_DIR=$(follow_links "$(dirname -- "${BASH_SOURCE[0]}")") SRC_DIR="$(cd "$SCRIPT_DIR/../../.."; pwd -P)" export ANDROID_HOME="$SRC_DIR/third_party/android_tools/sdk" -"$SRC_DIR/flutter/tools/gn" --unopt -ninja -C "$SRC_DIR/out/host_debug_unopt" sky_engine -j 400 - -"$SCRIPT_DIR/compile_android_aot.sh" "$1" "$2" - -( - cd "$SCRIPT_DIR/android" - ./gradlew assembleDebug --no-daemon -) +# TODO(dnfield): Delete this whole file. +DEVICE_OUT_DIR=${2%"clang_x64"} # LUCI expects to find the APK here mkdir -p "$SCRIPT_DIR/android/app/build/outputs/apk/debug" -cp "$SCRIPT_DIR/build/app/outputs/apk/debug/app-debug.apk" "$SCRIPT_DIR/android/app/build/outputs/apk/debug" +cp "$DEVICE_OUT_DIR/scenario_app/app/outputs/apk/debug/app-debug.apk" "$SCRIPT_DIR/android/app/build/outputs/apk/debug" diff --git a/testing/scenario_app/build_and_run_android_tests.sh b/testing/scenario_app/build_and_run_android_tests.sh index 3f10102be1..73c2a9362d 100755 --- a/testing/scenario_app/build_and_run_android_tests.sh +++ b/testing/scenario_app/build_and_run_android_tests.sh @@ -39,11 +39,8 @@ fi if [[ ! -d "$SRC_DIR/out/$FLUTTER_ENGINE" ]]; then "$GN" --android --unoptimized --android-cpu x64 --runtime-mode debug - "$GN" --unoptimized --runtime-mode debug fi autoninja -C "$SRC_DIR/out/$FLUTTER_ENGINE" -autoninja -C "$SRC_DIR/out/host_debug_unopt" -"$SCRIPT_DIR/compile_android_jit.sh" "$SRC_DIR/out/host_debug_unopt" "$SRC_DIR/out/$FLUTTER_ENGINE/clang_x64" "$SCRIPT_DIR/run_android_tests.sh" "$FLUTTER_ENGINE" diff --git a/testing/scenario_app/build_and_run_ios_tests.sh b/testing/scenario_app/build_and_run_ios_tests.sh index 4f9b92c5f9..ef5a25d800 100755 --- a/testing/scenario_app/build_and_run_ios_tests.sh +++ b/testing/scenario_app/build_and_run_ios_tests.sh @@ -42,7 +42,5 @@ if [ ! -d "$SRC_DIR/out/$FLUTTER_ENGINE" ]; then fi autoninja -C "$SRC_DIR/out/$FLUTTER_ENGINE" -autoninja -C "$SRC_DIR/out/host_debug_unopt" -"$SCRIPT_DIR/compile_ios_jit.sh" "$SRC_DIR/out/host_debug_unopt" "$SRC_DIR/out/$FLUTTER_ENGINE/clang_x64" "$SCRIPT_DIR/run_ios_tests.sh" "$FLUTTER_ENGINE" diff --git a/testing/scenario_app/compile_android_aot.sh b/testing/scenario_app/compile_android_aot.sh deleted file mode 100755 index f1e52d3602..0000000000 --- a/testing/scenario_app/compile_android_aot.sh +++ /dev/null @@ -1,80 +0,0 @@ -#!/bin/bash -# 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. - -#TODO(dnfield): Get rid of this script and instead use proper build rules - -set -e - -# Needed because if it is set, cd may print the path it changed to. -unset CDPATH - -# On Mac OS, readlink -f doesn't work, so follow_links traverses the path one -# link at a time, and then cds into the link destination and find out where it -# ends up. -# -# The function is enclosed in a subshell to avoid changing the working directory -# of the caller. -function follow_links() ( - cd -P "$(dirname -- "$1")" - file="$PWD/$(basename -- "$1")" - while [[ -h "$file" ]]; do - cd -P "$(dirname -- "$file")" - file="$(readlink -- "$file")" - cd -P "$(dirname -- "$file")" - file="$PWD/$(basename -- "$file")" - done - echo "$file" -) - -SCRIPT_DIR=$(follow_links "$(dirname -- "${BASH_SOURCE[0]}")") - -HOST_TOOLS="$1" -DEVICE_TOOLS="$2" - -if [[ ! -d "$HOST_TOOLS" ]]; then - echo "Directory $HOST_TOOLS not found." - echo "First argument must specify the host out directory containing dart (e.g. out/host_debug_unopt)." - exit 1 -fi - -if [[ ! -d "$DEVICE_TOOLS" ]]; then - echo "Directory $DEVICE_TOOLS not found." - echo "Second argument must specify the device out directory containing gen_snapshot (e.g. out/android_debug_unopt_x64/clang_x64)." - exit 1 -fi - -echo "Using dart from $HOST_TOOLS, gen_snapshot from $DEVICE_TOOLS." - -OUTDIR="$SCRIPT_DIR/build/android" - -echo "Creating $OUTDIR..." - -mkdir -p "$OUTDIR" - -echo "Compiling kernel..." - -# --disable-dart-dev: No need for observatory/DDS. -# --no-print-incremental-dependencies: Avoid printing out a lot of verbosity that doesn't help this test. -"$HOST_TOOLS/dart" \ - --disable-dart-dev \ - "$HOST_TOOLS/gen/frontend_server.dart.snapshot" \ - --sdk-root "$HOST_TOOLS/flutter_patched_sdk" \ - --target=flutter \ - --no-print-incremental-dependencies \ - --aot \ - --tfa \ - --output-dill "$OUTDIR/app.dill" \ - "$SCRIPT_DIR/lib/main.dart" - -echo "Compiling ELF Shared Library..." - -"$DEVICE_TOOLS/gen_snapshot" --deterministic --snapshot_kind=app-aot-elf --elf="$OUTDIR/libapp.so" --strip "$OUTDIR/app.dill" - -mkdir -p "$SCRIPT_DIR/android/app/src/main/jniLibs/arm64-v8a" -mkdir -p "$SCRIPT_DIR/android/app/libs" -cp "$OUTDIR/libapp.so" "$SCRIPT_DIR/android/app/src/main/jniLibs/arm64-v8a/" -cp "$DEVICE_TOOLS/../flutter.jar" "$SCRIPT_DIR/android/app/libs/" - -echo "Created $OUTDIR/libapp.so." diff --git a/testing/scenario_app/compile_android_jit.sh b/testing/scenario_app/compile_android_jit.sh deleted file mode 100755 index 360f6997db..0000000000 --- a/testing/scenario_app/compile_android_jit.sh +++ /dev/null @@ -1,93 +0,0 @@ -#!/bin/bash -# 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. - -set -e - -# Needed because if it is set, cd may print the path it changed to. -unset CDPATH - -# On Mac OS, readlink -f doesn't work, so follow_links traverses the path one -# link at a time, and then cds into the link destination and find out where it -# ends up. -# -# The function is enclosed in a subshell to avoid changing the working directory -# of the caller. -function follow_links() ( - cd -P "$(dirname -- "$1")" - file="$PWD/$(basename -- "$1")" - while [[ -h "$file" ]]; do - cd -P "$(dirname -- "$file")" - file="$(readlink -- "$file")" - cd -P "$(dirname -- "$file")" - file="$PWD/$(basename -- "$file")" - done - echo "$file" -) - -SCRIPT_DIR=$(follow_links "$(dirname -- "${BASH_SOURCE[0]}")") - -HOST_TOOLS="$1" -DEVICE_TOOLS="$2" - -if [[ ! -d "$HOST_TOOLS" ]]; then - echo "Directory $HOST_TOOLS not found." - echo "First argument must specify the host out directory containing dart (e.g. host_debug_unopt)." - exit 1 -fi - -if [[ ! -d "$DEVICE_TOOLS" ]]; then - echo "Directory $DEVICE_TOOLS not found." - echo "Second argument must specify the device out directory containing gen_snapshot (e.g. android_debug_unopt_x64)." - exit 1 -fi - -echo "Using dart from $HOST_TOOLS, gen_snapshot from $DEVICE_TOOLS." - -OUTDIR="$SCRIPT_DIR/build/app" -FLUTTER_ASSETS_DIR="$OUTDIR/assets/flutter_assets" -LIBS_DIR="$SCRIPT_DIR/android/app/libs" -GEN_SNAPSHOT="$DEVICE_TOOLS/gen_snapshot" - -if [[ ! -f "$GEN_SNAPSHOT" ]]; then - GEN_SNAPSHOT="$DEVICE_TOOLS/gen_snapshot_host_targeting_host" -fi - -if [[ ! -f "$GEN_SNAPSHOT" ]]; then - echo "Could not find gen_snapshot in $DEVICE_TOOLS." - exit 1 -fi - -echo "Creating directories..." - -mkdir -p "$OUTDIR" -mkdir -p "$FLUTTER_ASSETS_DIR" -mkdir -p "$LIBS_DIR" - -echo "Compiling kernel..." - -"$HOST_TOOLS/dart" \ - "$HOST_TOOLS/gen/frontend_server.dart.snapshot" \ - --sdk-root "$HOST_TOOLS/flutter_patched_sdk" \ - --target=flutter \ - --no-link-platform \ - --output-dill "$FLUTTER_ASSETS_DIR/kernel_blob.bin" \ - "$SCRIPT_DIR/lib/main.dart" - -echo "Compiling JIT Snapshot..." - -"$GEN_SNAPSHOT" --deterministic \ - --enable-asserts \ - --lazy_async_stacks \ - --isolate_snapshot_instructions="$OUTDIR/isolate_snapshot_instr" \ - --snapshot_kind=app-jit \ - --load_vm_snapshot_data="$DEVICE_TOOLS/../gen/flutter/lib/snapshot/vm_isolate_snapshot.bin" \ - --load_isolate_snapshot_data="$DEVICE_TOOLS/../gen/flutter/lib/snapshot/isolate_snapshot.bin" \ - --isolate_snapshot_data="$FLUTTER_ASSETS_DIR/isolate_snapshot_data" \ - --isolate_snapshot_instructions="$FLUTTER_ASSETS_DIR/isolate_snapshot_instr" \ - "$FLUTTER_ASSETS_DIR/kernel_blob.bin" - -cp "$DEVICE_TOOLS/../flutter.jar" "$LIBS_DIR" - -echo "Created $OUTDIR." diff --git a/testing/scenario_app/compile_ios_aot.sh b/testing/scenario_app/compile_ios_aot.sh deleted file mode 100755 index 5d565eef40..0000000000 --- a/testing/scenario_app/compile_ios_aot.sh +++ /dev/null @@ -1,103 +0,0 @@ -#!/bin/bash -# 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. - -#TODO(dnfield): Get rid of this script and instead use proper build rules - -set -e - -# Needed because if it is set, cd may print the path it changed to. -unset CDPATH - -# On Mac OS, readlink -f doesn't work, so follow_links traverses the path one -# link at a time, and then cds into the link destination and find out where it -# ends up. -# -# The function is enclosed in a subshell to avoid changing the working directory -# of the caller. -function follow_links() ( - cd -P "$(dirname -- "$1")" - file="$PWD/$(basename -- "$1")" - while [[ -h "$file" ]]; do - cd -P "$(dirname -- "$file")" - file="$(readlink -- "$file")" - cd -P "$(dirname -- "$file")" - file="$PWD/$(basename -- "$file")" - done - echo "$file" -) - -SCRIPT_DIR=$(follow_links "$(dirname -- "${BASH_SOURCE[0]}")") - -HOST_TOOLS="$1" -DEVICE_TOOLS="$2" - -if [[ ! -d "$HOST_TOOLS" ]]; then - echo "Directory $HOST_TOOLS not found." - echo "First argument must specify the host out directory containing dart (e.g. host_debug_unopt)." - exit 1 -fi - -if [[ ! -d "$DEVICE_TOOLS" ]]; then - echo "Directory $DEVICE_TOOLS not found." - ehco "Second argument must specify the device out directory containing gen_snapshot (e.g. ios_debug_unopt)." - exit 1 -fi - -echo "Using dart from $HOST_TOOLS, gen_snapshot from $DEVICE_TOOLS." - -OUTDIR="$SCRIPT_DIR/build/ios" - -echo "Creating $OUTDIR..." - -mkdir -p "$OUTDIR" -mkdir -p "$OUTDIR/App.framework" - -echo "Compiling kernel..." - -"$HOST_TOOLS/dart" \ - "$HOST_TOOLS/gen/frontend_server.dart.snapshot" \ - --sdk-root "$HOST_TOOLS/flutter_patched_sdk" \ - --aot --tfa --target=flutter \ - --output-dill "$OUTDIR/app.dill" \ - "$SCRIPT_DIR/lib/main.dart" - -echo "Compiling AOT Assembly..." - -"$DEVICE_TOOLS/gen_snapshot" --deterministic --snapshot_kind=app-aot-assembly --assembly="$OUTDIR/snapshot_assembly.S" "$OUTDIR/app.dill" - -SYSROOT="$(xcrun --sdk iphoneos --show-sdk-path)" -echo "Using $SYSROOT as sysroot." -echo "Compiling Assembly..." - -cc -arch arm64 \ - -fembed-bitcode \ - -isysroot "$SYSROOT" \ - -miphoneos-version-min=8.0 \ - -c "$OUTDIR/snapshot_assembly.S" \ - -o "$OUTDIR/snapshot_assembly.o" - -echo "Linking App using $SYSROOT..." - -clang -arch arm64 \ - -fembed-bitcode \ - -isysroot "$SYSROOT" \ - -miphoneos-version-min=8.0 \ - -dynamiclib -Xlinker -rpath -Xlinker @executable_path/Frameworks \ - -Xlinker -rpath -Xlinker @loader_path/Frameworks \ - -install_name @rpath/App.framework/App \ - -o "$OUTDIR/App.framework/App" \ - "$OUTDIR/snapshot_assembly.o" - -strip "$OUTDIR/App.framework/App" - -cp "$SCRIPT_DIR/ios/AppFrameworkInfo.plist" "$OUTDIR/App.framework/Info.plist" - -echo "Created $OUTDIR/App.framework/App." - -rm -rf "$SCRIPT_DIR/ios/Scenarios/App.framework" -rm -rf "$SCRIPT_DIR/ios/Scenarios/Flutter.xcframework" -cp -R "$OUTDIR/App.framework" "$SCRIPT_DIR/ios/Scenarios" -cp -R "$DEVICE_TOOLS/../Flutter.xcframework" "$SCRIPT_DIR/ios/Scenarios" - diff --git a/testing/scenario_app/compile_ios_jit.sh b/testing/scenario_app/compile_ios_jit.sh deleted file mode 100755 index f43174e714..0000000000 --- a/testing/scenario_app/compile_ios_jit.sh +++ /dev/null @@ -1,109 +0,0 @@ -#!/bin/bash -# 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. - -#TODO(dnfield): Get rid of this script and instead use proper build rules - -set -e - -# Needed because if it is set, cd may print the path it changed to. -unset CDPATH - -# On Mac OS, readlink -f doesn't work, so follow_links traverses the path one -# link at a time, and then cds into the link destination and find out where it -# ends up. -# -# The function is enclosed in a subshell to avoid changing the working directory -# of the caller. -function follow_links() ( - cd -P "$(dirname -- "$1")" - file="$PWD/$(basename -- "$1")" - while [[ -h "$file" ]]; do - cd -P "$(dirname -- "$file")" - file="$(readlink -- "$file")" - cd -P "$(dirname -- "$file")" - file="$PWD/$(basename -- "$file")" - done - echo "$file" -) - -SCRIPT_DIR=$(follow_links "$(dirname -- "${BASH_SOURCE[0]}")") - -HOST_TOOLS="$1" -DEVICE_TOOLS="$2" - -if [[ ! -d "$HOST_TOOLS" ]]; then - echo "Directory $HOST_TOOLS not found." - echo "First argument must specify the host out directory containing dart (e.g. host_debug_unopt)." - exit 1 -fi - -if [[ ! -d "$DEVICE_TOOLS" ]]; then - echo "Directory $DEVICE_TOOLS not found." - ehco "Second argument must specify the device out directory containing gen_snapshot (e.g. ios_debug_unopt)." - exit 1 -fi - -echo "Using dart from $HOST_TOOLS, gen_snapshot from $DEVICE_TOOLS." - -OUTDIR="$SCRIPT_DIR/build/ios" - -echo "Creating $OUTDIR..." - -mkdir -p "$OUTDIR" -mkdir -p "$OUTDIR/App.framework/flutter_assets" - -echo "Compiling to kernel..." - -"$HOST_TOOLS/dart" \ - "$HOST_TOOLS/gen/frontend_server.dart.snapshot" \ - --sdk-root "$HOST_TOOLS/flutter_patched_sdk" \ - --target=flutter \ - --no-link-platform \ - --output-dill "$OUTDIR/App.framework/flutter_assets/kernel_blob.bin" \ - "${BASH_SOURCE%/*}/lib/main.dart" - -echo "Compiling JIT Snapshot..." - -"$DEVICE_TOOLS/gen_snapshot" --deterministic \ - --enable-asserts \ - --lazy_async_stacks \ - --isolate_snapshot_instructions="$OUTDIR/isolate_snapshot_instr" \ - --snapshot_kind=app-jit \ - --load_vm_snapshot_data="$DEVICE_TOOLS/../gen/flutter/lib/snapshot/vm_isolate_snapshot.bin" \ - --load_isolate_snapshot_data="$DEVICE_TOOLS/../gen/flutter/lib/snapshot/isolate_snapshot.bin" \ - --isolate_snapshot_data="$OUTDIR/App.framework/flutter_assets/isolate_snapshot_data" \ - --isolate_snapshot_instructions="$OUTDIR/App.framework/flutter_assets/isolate_snapshot_instr" \ - "$OUTDIR/App.framework/flutter_assets/kernel_blob.bin" - -cp "$DEVICE_TOOLS/../gen/flutter/lib/snapshot/vm_isolate_snapshot.bin" "$OUTDIR/App.framework/flutter_assets/vm_snapshot_data" - -LLVM_BIN_PATH="${SCRIPT_DIR}/../../../buildtools/mac-x64/clang/bin" -SYSROOT=$(xcrun --sdk iphonesimulator --show-sdk-path) -echo "Using $SYSROOT as sysroot." - -echo "Creating stub App using $SYSROOT..." - -# Use buildroot clang so we can override the linker to use in our LUCI recipe. -# See: https://github.com/flutter/flutter/issues/65901 -echo "static const int Moo = 88;" | "$LLVM_BIN_PATH/clang" -x c \ - -arch x86_64 \ - -fembed-bitcode-marker \ - -isysroot "$SYSROOT" \ - -miphoneos-version-min=8.0 \ - -dynamiclib \ - -Xlinker -rpath -Xlinker '@executable_path/Frameworks' \ - -Xlinker -rpath -Xlinker '@loader_path/Frameworks' \ - -install_name '@rpath/App.framework/App' \ - -o "$OUTDIR/App.framework/App" - - -strip "$OUTDIR/App.framework/App" - -cp "$SCRIPT_DIR/ios/AppFrameworkInfo.plist" "$OUTDIR/App.framework/Info.plist" -echo "Created $OUTDIR/App.framework/App." - -rm -rf "$SCRIPT_DIR/ios/Scenarios/App.framework" -rm -rf "$SCRIPT_DIR/ios/Scenarios/Flutter.xcframework" -cp -R "$OUTDIR/App.framework" "$SCRIPT_DIR/ios/Scenarios" -cp -R "$DEVICE_TOOLS/../Flutter.xcframework" "$SCRIPT_DIR/ios/Scenarios" diff --git a/testing/scenario_app/ios/BUILD.gn b/testing/scenario_app/ios/BUILD.gn new file mode 100644 index 0000000000..5209d480d4 --- /dev/null +++ b/testing/scenario_app/ios/BUILD.gn @@ -0,0 +1,66 @@ +# 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. + +import("//flutter/testing/scenario_app/runtime_mode.gni") +import("//third_party/dart/build/dart/copy_tree.gni") + +_app_framework_dir = "$root_out_dir/scenario_app/Scenarios/App.framework" + +shared_library("app_framework_dylib") { + visibility = [ ":*" ] + + output_name = "app" + + if (is_aot) { + sources = [ "$target_gen_dir/snapshot_assembly.S" ] + } else { + sources = [ "app_stub.c" ] + } + + ldflags = [ "-Wl,-install_name,@rpath/App.framework/App" ] + + deps = [ "//flutter/testing/scenario_app:scenario_app_snapshot" ] +} + +copy("copy_dylib") { + visibility = [ ":*" ] + + sources = [ "$root_out_dir/libapp.dylib" ] + outputs = [ "$_app_framework_dir/App" ] + deps = [ ":app_framework_dylib" ] +} + +copy("copy_info_plist") { + visibility = [ ":*" ] + sources = [ "AppFrameworkInfo.plist" ] + outputs = [ "$_app_framework_dir/Info.plist" ] +} + +copy_trees("scenario_ios") { + sources = [ + { + target = "copy_ios_xcodeproj" + visibility = [ ":*" ] + source = "." + dest = "$root_out_dir/scenario_app" + + # Ignore any stale App.framework or Flutter.xcframework files from + # historical builds. + # This can eventually be set to "{}" when all CI builder caches have been + # flushed that might still have these stale gitignored files from previous + # build scripts. + ignore_patterns = "*.*framework" + }, + ] +} + +group("ios") { + deps = [ + ":app_framework_dylib", + ":copy_dylib", + ":copy_info_plist", + ":copy_ios_xcodeproj", + "//flutter/shell/platform/darwin/ios:flutter_framework", + ] +} diff --git a/testing/scenario_app/ios/Scenarios/Scenarios.xcodeproj/project.pbxproj b/testing/scenario_app/ios/Scenarios/Scenarios.xcodeproj/project.pbxproj index 53ff9ba8e5..733c37ab32 100644 --- a/testing/scenario_app/ios/Scenarios/Scenarios.xcodeproj/project.pbxproj +++ b/testing/scenario_app/ios/Scenarios/Scenarios.xcodeproj/project.pbxproj @@ -135,7 +135,7 @@ 244EA6CF230DBE8900B2D26E /* golden_platform_view_D21AP.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = golden_platform_view_D21AP.png; sourceTree = ""; }; 246A6610252E693A00EAB0F3 /* RenderingSelectionTest.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RenderingSelectionTest.m; sourceTree = ""; }; 246B4E4122E3B5F700073EBF /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = App.framework; sourceTree = ""; }; - 246B4E4522E3B61000073EBF /* Flutter.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; path = Flutter.xcframework; sourceTree = ""; }; + 246B4E4522E3B61000073EBF /* Flutter.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; path = ../../Flutter.xcframework; sourceTree = ""; }; 248D76C722E388370012F0C1 /* Scenarios.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Scenarios.app; sourceTree = BUILT_PRODUCTS_DIR; }; 248D76CA22E388370012F0C1 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 248D76CB22E388370012F0C1 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; diff --git a/testing/scenario_app/ios/app_stub.c b/testing/scenario_app/ios/app_stub.c new file mode 100644 index 0000000000..5048cb03f7 --- /dev/null +++ b/testing/scenario_app/ios/app_stub.c @@ -0,0 +1,2 @@ +// This is a stub file used to create App.framework for JIT mode. +__attribute__((unused)) static const int Moo = 88; diff --git a/testing/scenario_app/run_android_tests.sh b/testing/scenario_app/run_android_tests.sh index efca54d75e..ca0896e545 100755 --- a/testing/scenario_app/run_android_tests.sh +++ b/testing/scenario_app/run_android_tests.sh @@ -29,7 +29,12 @@ function follow_links() ( ) SCRIPT_DIR=$(follow_links "$(dirname -- "${BASH_SOURCE[0]}")") +SRC_DIR="$(cd "$SCRIPT_DIR/../../.."; pwd -P)" +OUT_DIR="$SRC_DIR/out/$1" cd "$SCRIPT_DIR/android" GRADLE_USER_HOME="$PWD/android/gradle-home/.cache" -set -o pipefail && ./gradlew app:verifyDebugAndroidTestScreenshotTest --gradle-user-home "$GRADLE_USER_HOME" +set -o pipefail && ./gradlew app:verifyDebugAndroidTestScreenshotTest \ + --gradle-user-home "$GRADLE_USER_HOME" \ + -Pflutter_jar=$OUT_DIR/flutter.jar + -Pout_dir=$OUT_DIR/scenario_app_screenshot_test diff --git a/testing/scenario_app/run_ios_tests.sh b/testing/scenario_app/run_ios_tests.sh index 3a98e19c16..900ecca04f 100755 --- a/testing/scenario_app/run_ios_tests.sh +++ b/testing/scenario_app/run_ios_tests.sh @@ -37,7 +37,7 @@ fi # Can also be set via Simulator app Device > Rotate Device Automatically defaults write com.apple.iphonesimulator RotateWindowWhenSignaledByGuest -int 1 -cd ios/Scenarios +cd $SRC_DIR/out/$FLUTTER_ENGINE/scenario_app/Scenarios set -o pipefail && xcodebuild -sdk iphonesimulator \ -scheme Scenarios \ -destination 'platform=iOS Simulator,OS=13.0,name=iPhone 8' \ diff --git a/testing/scenario_app/runtime_mode.gni b/testing/scenario_app/runtime_mode.gni new file mode 100644 index 0000000000..620ac3dff0 --- /dev/null +++ b/testing/scenario_app/runtime_mode.gni @@ -0,0 +1,9 @@ +# 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. + +import("//flutter/common/config.gni") + +assert(is_android || is_ios) + +is_aot = flutter_runtime_mode == "profile" || flutter_runtime_mode == "release" -- GitLab