From 856ba4f6bea366e17fde4c897cab2a6b85a2b358 Mon Sep 17 00:00:00 2001 From: Andrei Litvin Date: Mon, 9 Aug 2021 12:26:50 -0400 Subject: [PATCH 01/16] Starting to build android: native library seems to build --- scripts/build/build/factory.py | 14 ++++- scripts/build/build/targets.py | 6 ++ scripts/build/builders/android.py | 99 +++++++++++++++++++++++++++++++ 3 files changed, 116 insertions(+), 3 deletions(-) create mode 100644 scripts/build/builders/android.py diff --git a/scripts/build/build/factory.py b/scripts/build/build/factory.py index b3ad36ac62e8b0..ea310781ad6ecc 100644 --- a/scripts/build/build/factory.py +++ b/scripts/build/build/factory.py @@ -17,11 +17,13 @@ from typing import Set from builders.builder import Builder -from builders.host import HostBuilder, HostApp -from builders.qpg import QpgBuilder -from builders.esp32 import Esp32Builder, Esp32Board, Esp32App + +from builders.android import AndroidBoard, AndroidBuilder from builders.efr32 import Efr32Builder, Efr32App, Efr32Board +from builders.esp32 import Esp32Builder, Esp32Board, Esp32App +from builders.host import HostBuilder, HostApp from builders.nrf import NrfApp, NrfBoard, NrfConnectBuilder +from builders.qpg import QpgBuilder from .targets import Application, Board, Platform @@ -84,6 +86,7 @@ def Create(self, runner, __board_key: Board, __app_key: Application, Platform.QPG: Matcher(QpgBuilder), Platform.EFR32: Matcher(Efr32Builder), Platform.NRF: Matcher(NrfConnectBuilder), + Platform.ANDROID: Matcher(AndroidBuilder), } # Matrix of what can be compiled and what build options are required @@ -121,6 +124,11 @@ def Create(self, runner, __board_key: Board, __app_key: Application, _MATCHERS[Platform.NRF].AcceptApplication(Application.LIGHT, app=NrfApp.LIGHT) _MATCHERS[Platform.NRF].AcceptApplication(Application.SHELL, app=NrfApp.SHELL) +_MATCHERS[Platform.ANDROID].AcceptBoard(Board.ARM, board=AndroidBoard.ARM) +_MATCHERS[Platform.ANDROID].AcceptBoard(Board.ARM64, board=AndroidBoard.ARM64) +_MATCHERS[Platform.ANDROID].AcceptBoard(Board.X64, board=AndroidBoard.X64) +_MATCHERS[Platform.ANDROID].AcceptApplication(Application.CHIP_TOOL) + class BuilderFactory: """Creates application builders.""" diff --git a/scripts/build/build/targets.py b/scripts/build/build/targets.py index 3fc53ce54f01da..53ded8da374588 100644 --- a/scripts/build/build/targets.py +++ b/scripts/build/build/targets.py @@ -26,6 +26,7 @@ class Platform(IntEnum): ESP32 = auto() EFR32 = auto() NRF = auto() + ANDROID = auto() @property def ArgName(self): @@ -59,6 +60,11 @@ class Board(IntEnum): NRF52840 = auto() NRF5340 = auto() + # Android platform + ARM = auto() + ARM64 = auto() + X64 = auto() + @property def ArgName(self): return self.name.lower() diff --git a/scripts/build/builders/android.py b/scripts/build/builders/android.py new file mode 100644 index 00000000000000..717dedc9729d1a --- /dev/null +++ b/scripts/build/builders/android.py @@ -0,0 +1,99 @@ +# Copyright (c) 2021 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import logging +import os +import shlex + +from enum import Enum, auto + +from .builder import Builder + + +class AndroidBoard(Enum): + ARM = auto() + ARM64 = auto() + X64 = auto() + + def TargetCpuName(self): + if self == AndroidBoard.ARM: + return 'arm' + elif self == AndroidBoard.ARM64: + return 'arm64' + elif self == AndroidBoard.X64: + return 'x64' + else: + raise Exception('Unknown board type: %r' % self) + + +class AndroidBuilder(Builder): + + def __init__(self, + root, + runner, + output_prefix: str, + board: AndroidBoard): + super(AndroidBuilder, self).__init__(root, runner, output_prefix) + self.board = board + + def validate_build_environment(self): + for k in ['ANDROID_NDK_HOME', 'ANDROID_HOME']: + if k not in os.environ: + raise Exception('Environment %s missing, cannot build android libraries' % k) + + + + def generate(self): + if not os.path.exists(self.output_dir): + # NRF does a in-place update of SDK tools + if not self._runner.dry_run: + self.validate_build_environment() + + gn_args = {} + gn_args['target_os'] = 'android' + gn_args['target_cpu'] = self.board.TargetCpuName() + gn_args['android_ndk_root'] = os.environ['ANDROID_NDK_HOME'] + gn_args['android_sdk_root'] = os.environ['ANDROID_HOME'] + + args = '--args=%s' % (' '.join(['%s="%s"' % (key, shlex.quote(value)) for key,value in gn_args.items()])) + + self._Execute(['gn', 'gen', '--check', '--fail-on-unused-args', self.output_dir, args], title='Generating ' + self.identifier) + + + def build(self): + self._Execute(['ninja', '-C', self.output_dir], title='Building ' + self.identifier) + + def jni_output_libs(self): + """Get a dictionary of JNI-required files.""" + items = {} + + scan_root = os.path.join(self.output_dir, 'lib', 'jni') + + for root, dirs, files in os.walk(scan_root): + dir_name = root[len(scan_root) + 1:] + for file_name in files: + items[os.path.join(dir_name, file_name)] = os.path.join(root, file_name) + + return items + + + def outputs(self): + outputs ={ + 'CHIPController.jar': os.path.join(self.output_dir, 'lib', 'CHIPController.jar'), + 'SetupPayloadParser.jar': os.path.join(self.output_dir, 'lib', 'SetupPayloadParser.jar'), + } + + outputs.update(self.jni_output_libs()) + + return outputs From c2f7d8ec1ca329f1d8d8a3de9a39855ab11db33a Mon Sep 17 00:00:00 2001 From: Andrei Litvin Date: Mon, 9 Aug 2021 12:54:23 -0400 Subject: [PATCH 02/16] Validate that sdkmanager is executable, then ensure ndk licenses are accepted at build time --- scripts/build/builders/android.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/scripts/build/builders/android.py b/scripts/build/builders/android.py index 717dedc9729d1a..1ef2a56a822914 100644 --- a/scripts/build/builders/android.py +++ b/scripts/build/builders/android.py @@ -51,6 +51,11 @@ def validate_build_environment(self): for k in ['ANDROID_NDK_HOME', 'ANDROID_HOME']: if k not in os.environ: raise Exception('Environment %s missing, cannot build android libraries' % k) + + sdk_manager = os.path.join(os.environ['ANDROID_HOME'], 'tools', 'bin', 'sdkmanager') + + if not (os.path.isfile(sdk_manager) and os.access(sdk_manager, os.X_OK)): + raise Exception("'%s' is not executable by the current user" % sdk_manager) @@ -70,9 +75,12 @@ def generate(self): self._Execute(['gn', 'gen', '--check', '--fail-on-unused-args', self.output_dir, args], title='Generating ' + self.identifier) + self._Execute(['bash', '-c', 'yes | %s/tools/bin/sdkmanager --licenses >/dev/null' % os.environ['ANDROID_HOME']], + title='Accepting NDK licenses') + def build(self): - self._Execute(['ninja', '-C', self.output_dir], title='Building ' + self.identifier) + self._Execute(['ninja', '-C', self.output_dir], title='Building JNI ' + self.identifier) def jni_output_libs(self): """Get a dictionary of JNI-required files.""" From 07c420a2690441441e4325966b5bc8973dc63814 Mon Sep 17 00:00:00 2001 From: Andrei Litvin Date: Mon, 9 Aug 2021 14:03:59 -0400 Subject: [PATCH 03/16] Compiling the apk now works (no jni so copying yet though) --- scripts/build/builders/android.py | 20 ++++++++++-- src/android/CHIPTool/app/build.gradle | 10 ++++++ src/android/CHIPTool/gradlew | 47 ++++++++++++++------------- 3 files changed, 51 insertions(+), 26 deletions(-) diff --git a/scripts/build/builders/android.py b/scripts/build/builders/android.py index 1ef2a56a822914..b46ed875716f81 100644 --- a/scripts/build/builders/android.py +++ b/scripts/build/builders/android.py @@ -52,11 +52,16 @@ def validate_build_environment(self): if k not in os.environ: raise Exception('Environment %s missing, cannot build android libraries' % k) + # SDK manager must be runnable to 'accept licenses' sdk_manager = os.path.join(os.environ['ANDROID_HOME'], 'tools', 'bin', 'sdkmanager') - if not (os.path.isfile(sdk_manager) and os.access(sdk_manager, os.X_OK)): raise Exception("'%s' is not executable by the current user" % sdk_manager) - + + # In order to accept a license, the licenses folder is updated with the hash of the + # accepted license + licenses = os.path.join(os.environ['ANDROID_HOME'], 'licenses') + if not os.access(licenses, os.W_OK): + raise Exception("'%s' is writable by the current user (needed to accept licenses)" % licenses) def generate(self): @@ -82,12 +87,21 @@ def generate(self): def build(self): self._Execute(['ninja', '-C', self.output_dir], title='Building JNI ' + self.identifier) + # NOTE: the following IDE-specific build instructions are NOT used: + # - "rsync -a out/"android_$TARGET_CPU"/lib/*.jar src/android/CHIPTool/app/libs" + # => using the 'ninjaOutputDir' project property instead to take the jar files directly + # from the output + # - "rsync -a out/"android_$TARGET_CPU"/lib/jni/* src/android/CHIPTool/app/src/main/jniLib" + # => JNI libraries not used by the build taks (TODO: is this true? APK?) + + self._Execute(['src/android/CHIPTool/gradlew', '-p', 'src/android/CHIPTool', '-PchipSdkJarDir=%s' % os.path.join(self.output_dir, 'lib'), + '-PbuildDir=%s' % self.output_dir, 'build'], title='Building APP ' + self.identifier) + def jni_output_libs(self): """Get a dictionary of JNI-required files.""" items = {} scan_root = os.path.join(self.output_dir, 'lib', 'jni') - for root, dirs, files in os.walk(scan_root): dir_name = root[len(scan_root) + 1:] for file_name in files: diff --git a/src/android/CHIPTool/app/build.gradle b/src/android/CHIPTool/app/build.gradle index fcb89aed6bd9e8..0f7bb5080b4214 100644 --- a/src/android/CHIPTool/app/build.gradle +++ b/src/android/CHIPTool/app/build.gradle @@ -49,7 +49,17 @@ dependencies { implementation "androidx.room:room-runtime:$room_version" annotationProcessor "androidx.room:room-compiler:$room_version" + + + // local in-source-tree copy of the dependencies. Useful for IDE compilation implementation fileTree(dir: "libs", include: ["*.jar", "*.so"]) + + // build time dependencies + if (project.hasProperty("chipSdkJarDir")) { + println "Compiling using custom sdk jar file directory: ${chipSdkJarDir}" + implementation fileTree(dir: "${chipSdkJarDir}", include: ["*.jar", "*.so"]) + } + implementation 'androidx.appcompat:appcompat:1.1.0' implementation 'androidx.preference:preference:1.1.1' implementation "com.google.android.gms:play-services-vision:20.1.0" diff --git a/src/android/CHIPTool/gradlew b/src/android/CHIPTool/gradlew index 482e1de1753755..460d15e28a024c 100755 --- a/src/android/CHIPTool/gradlew +++ b/src/android/CHIPTool/gradlew @@ -20,7 +20,8 @@ while [ -h "$PRG" ]; do fi done SAVED="$PWD" -cd "$(dirname \""$PRG"\")/" >/dev/null +PRG_DIRNAME=$(dirname $PRG) +cd $PRG_DIRNAME APP_HOME="$(pwd -P)" cd "$SAVED" >/dev/null @@ -50,18 +51,18 @@ msys=false darwin=false nonstop=false case "$(uname)" in - CYGWIN*) - cygwin=true - ;; - Darwin*) - darwin=true - ;; - MINGW*) - msys=true - ;; - NONSTOP*) - nonstop=true - ;; +CYGWIN*) + cygwin=true + ;; +Darwin*) + darwin=true + ;; +MINGW*) + msys=true + ;; +NONSTOP*) + nonstop=true + ;; esac CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar @@ -141,16 +142,16 @@ if "$cygwin"; then i=$((i + 1)) done case $i in - 0) set -- ;; - 1) set -- "$args0" ;; - 2) set -- "$args0" "$args1" ;; - 3) set -- "$args0" "$args1" "$args2" ;; - 4) set -- "$args0" "$args1" "$args2" "$args3" ;; - 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + 0) set -- ;; + 1) set -- "$args0" ;; + 2) set -- "$args0" "$args1" ;; + 3) set -- "$args0" "$args1" "$args2" ;; + 4) set -- "$args0" "$args1" "$args2" "$args3" ;; + 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; esac fi From 1eba6a7a523fc7a06371e67744acbd15e945c967 Mon Sep 17 00:00:00 2001 From: Andrei Litvin Date: Mon, 9 Aug 2021 14:04:35 -0400 Subject: [PATCH 04/16] Restyle fixes --- src/android/CHIPTool/gradlew | 48 ++++++++++++++++++------------------ 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/src/android/CHIPTool/gradlew b/src/android/CHIPTool/gradlew index 460d15e28a024c..b34b20eff161fa 100755 --- a/src/android/CHIPTool/gradlew +++ b/src/android/CHIPTool/gradlew @@ -20,8 +20,8 @@ while [ -h "$PRG" ]; do fi done SAVED="$PWD" -PRG_DIRNAME=$(dirname $PRG) -cd $PRG_DIRNAME +PRG_DIRNAME=$(dirname "$PRG") +cd "$PRG_DIRNAME" APP_HOME="$(pwd -P)" cd "$SAVED" >/dev/null @@ -51,18 +51,18 @@ msys=false darwin=false nonstop=false case "$(uname)" in -CYGWIN*) - cygwin=true - ;; -Darwin*) - darwin=true - ;; -MINGW*) - msys=true - ;; -NONSTOP*) - nonstop=true - ;; + CYGWIN*) + cygwin=true + ;; + Darwin*) + darwin=true + ;; + MINGW*) + msys=true + ;; + NONSTOP*) + nonstop=true + ;; esac CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar @@ -142,16 +142,16 @@ if "$cygwin"; then i=$((i + 1)) done case $i in - 0) set -- ;; - 1) set -- "$args0" ;; - 2) set -- "$args0" "$args1" ;; - 3) set -- "$args0" "$args1" "$args2" ;; - 4) set -- "$args0" "$args1" "$args2" "$args3" ;; - 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + 0) set -- ;; + 1) set -- "$args0" ;; + 2) set -- "$args0" "$args1" ;; + 3) set -- "$args0" "$args1" "$args2" ;; + 4) set -- "$args0" "$args1" "$args2" "$args3" ;; + 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; esac fi From b5ed6d3a7c0693d3d0aba2751524a06a935c94b3 Mon Sep 17 00:00:00 2001 From: Andrei Litvin Date: Mon, 9 Aug 2021 14:35:02 -0400 Subject: [PATCH 05/16] Apk build now includes .so files for jni --- scripts/build/builders/android.py | 12 ++++++++---- src/android/CHIPTool/.gitignore | 1 + 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/scripts/build/builders/android.py b/scripts/build/builders/android.py index b46ed875716f81..b047cf669a268a 100644 --- a/scripts/build/builders/android.py +++ b/scripts/build/builders/android.py @@ -91,11 +91,13 @@ def build(self): # - "rsync -a out/"android_$TARGET_CPU"/lib/*.jar src/android/CHIPTool/app/libs" # => using the 'ninjaOutputDir' project property instead to take the jar files directly # from the output - # - "rsync -a out/"android_$TARGET_CPU"/lib/jni/* src/android/CHIPTool/app/src/main/jniLib" - # => JNI libraries not used by the build taks (TODO: is this true? APK?) - self._Execute(['src/android/CHIPTool/gradlew', '-p', 'src/android/CHIPTool', '-PchipSdkJarDir=%s' % os.path.join(self.output_dir, 'lib'), - '-PbuildDir=%s' % self.output_dir, 'build'], title='Building APP ' + self.identifier) + # JNILibs will be copied as long as they reside in src/main/jniLibs/ABI: + # https://developer.android.com/studio/projects/gradle-external-native-builds#jniLibs + self._Execute(['bash', '-c', "rsync -a %s/lib/jni/* %s/src/android/CHIPTool/app/src/main/jniLibs/" % (self.output_dir, self.root)], title='Prepare Native libs ' + self.identifier) + + # App compilation + self._Execute(['src/android/CHIPTool/gradlew', '-p', 'src/android/CHIPTool', '-PchipSdkJarDir=%s' % os.path.join(self.output_dir, 'lib'), '-PbuildDir=%s' % self.output_dir, 'build'], title='Building APP ' + self.identifier) def jni_output_libs(self): """Get a dictionary of JNI-required files.""" @@ -114,6 +116,8 @@ def outputs(self): outputs ={ 'CHIPController.jar': os.path.join(self.output_dir, 'lib', 'CHIPController.jar'), 'SetupPayloadParser.jar': os.path.join(self.output_dir, 'lib', 'SetupPayloadParser.jar'), + 'ChipTool-debug.apk': os.path.join(self.output_dir, 'outputs', 'apk', 'debug', 'app-debug.apk'), + 'ChipTool-release-unsigned.apk': os.path.join(self.output_dir, 'outputs', 'apk', 'release', 'app-release-unsigned.apk'), } outputs.update(self.jni_output_libs()) diff --git a/src/android/CHIPTool/.gitignore b/src/android/CHIPTool/.gitignore index 850f598ea4734e..5ede938069bfd8 100644 --- a/src/android/CHIPTool/.gitignore +++ b/src/android/CHIPTool/.gitignore @@ -17,4 +17,5 @@ # Shared libs & JAR libs (those libs are copied into source tree for easy Android build). *.so +*.map *.jar From 7c5dfa4910a4b554f1492c3aada4b4420027d147 Mon Sep 17 00:00:00 2001 From: Andrei Litvin Date: Mon, 9 Aug 2021 14:35:57 -0400 Subject: [PATCH 06/16] PyFormat --- scripts/build/builders/android.py | 97 +++++++++++++++++++------------ 1 file changed, 61 insertions(+), 36 deletions(-) diff --git a/scripts/build/builders/android.py b/scripts/build/builders/android.py index b047cf669a268a..c18572093ba1c5 100644 --- a/scripts/build/builders/android.py +++ b/scripts/build/builders/android.py @@ -39,53 +39,63 @@ def TargetCpuName(self): class AndroidBuilder(Builder): - def __init__(self, - root, - runner, - output_prefix: str, - board: AndroidBoard): + def __init__(self, root, runner, output_prefix: str, board: AndroidBoard): super(AndroidBuilder, self).__init__(root, runner, output_prefix) self.board = board def validate_build_environment(self): for k in ['ANDROID_NDK_HOME', 'ANDROID_HOME']: if k not in os.environ: - raise Exception('Environment %s missing, cannot build android libraries' % k) + raise Exception( + 'Environment %s missing, cannot build android libraries' % k) # SDK manager must be runnable to 'accept licenses' - sdk_manager = os.path.join(os.environ['ANDROID_HOME'], 'tools', 'bin', 'sdkmanager') + sdk_manager = os.path.join(os.environ['ANDROID_HOME'], 'tools', 'bin', + 'sdkmanager') if not (os.path.isfile(sdk_manager) and os.access(sdk_manager, os.X_OK)): - raise Exception("'%s' is not executable by the current user" % sdk_manager) + raise Exception("'%s' is not executable by the current user" % + sdk_manager) # In order to accept a license, the licenses folder is updated with the hash of the # accepted license licenses = os.path.join(os.environ['ANDROID_HOME'], 'licenses') if not os.access(licenses, os.W_OK): - raise Exception("'%s' is writable by the current user (needed to accept licenses)" % licenses) - + raise Exception( + "'%s' is writable by the current user (needed to accept licenses)" % + licenses) def generate(self): if not os.path.exists(self.output_dir): - # NRF does a in-place update of SDK tools - if not self._runner.dry_run: - self.validate_build_environment() - - gn_args = {} - gn_args['target_os'] = 'android' - gn_args['target_cpu'] = self.board.TargetCpuName() - gn_args['android_ndk_root'] = os.environ['ANDROID_NDK_HOME'] - gn_args['android_sdk_root'] = os.environ['ANDROID_HOME'] - - args = '--args=%s' % (' '.join(['%s="%s"' % (key, shlex.quote(value)) for key,value in gn_args.items()])) - - self._Execute(['gn', 'gen', '--check', '--fail-on-unused-args', self.output_dir, args], title='Generating ' + self.identifier) - - self._Execute(['bash', '-c', 'yes | %s/tools/bin/sdkmanager --licenses >/dev/null' % os.environ['ANDROID_HOME']], - title='Accepting NDK licenses') - + # NRF does a in-place update of SDK tools + if not self._runner.dry_run: + self.validate_build_environment() + + gn_args = {} + gn_args['target_os'] = 'android' + gn_args['target_cpu'] = self.board.TargetCpuName() + gn_args['android_ndk_root'] = os.environ['ANDROID_NDK_HOME'] + gn_args['android_sdk_root'] = os.environ['ANDROID_HOME'] + + args = '--args=%s' % (' '.join([ + '%s="%s"' % (key, shlex.quote(value)) + for key, value in gn_args.items() + ])) + + self._Execute([ + 'gn', 'gen', '--check', '--fail-on-unused-args', self.output_dir, args + ], + title='Generating ' + self.identifier) + + self._Execute([ + 'bash', '-c', + 'yes | %s/tools/bin/sdkmanager --licenses >/dev/null' % + os.environ['ANDROID_HOME'] + ], + title='Accepting NDK licenses') def build(self): - self._Execute(['ninja', '-C', self.output_dir], title='Building JNI ' + self.identifier) + self._Execute(['ninja', '-C', self.output_dir], + title='Building JNI ' + self.identifier) # NOTE: the following IDE-specific build instructions are NOT used: # - "rsync -a out/"android_$TARGET_CPU"/lib/*.jar src/android/CHIPTool/app/libs" @@ -94,10 +104,20 @@ def build(self): # JNILibs will be copied as long as they reside in src/main/jniLibs/ABI: # https://developer.android.com/studio/projects/gradle-external-native-builds#jniLibs - self._Execute(['bash', '-c', "rsync -a %s/lib/jni/* %s/src/android/CHIPTool/app/src/main/jniLibs/" % (self.output_dir, self.root)], title='Prepare Native libs ' + self.identifier) + self._Execute([ + 'bash', '-c', + 'rsync -a %s/lib/jni/* %s/src/android/CHIPTool/app/src/main/jniLibs/' % + (self.output_dir, self.root) + ], + title='Prepare Native libs ' + self.identifier) # App compilation - self._Execute(['src/android/CHIPTool/gradlew', '-p', 'src/android/CHIPTool', '-PchipSdkJarDir=%s' % os.path.join(self.output_dir, 'lib'), '-PbuildDir=%s' % self.output_dir, 'build'], title='Building APP ' + self.identifier) + self._Execute([ + 'src/android/CHIPTool/gradlew', '-p', 'src/android/CHIPTool', + '-PchipSdkJarDir=%s' % os.path.join(self.output_dir, 'lib'), + '-PbuildDir=%s' % self.output_dir, 'build' + ], + title='Building APP ' + self.identifier) def jni_output_libs(self): """Get a dictionary of JNI-required files.""" @@ -111,13 +131,18 @@ def jni_output_libs(self): return items - def outputs(self): - outputs ={ - 'CHIPController.jar': os.path.join(self.output_dir, 'lib', 'CHIPController.jar'), - 'SetupPayloadParser.jar': os.path.join(self.output_dir, 'lib', 'SetupPayloadParser.jar'), - 'ChipTool-debug.apk': os.path.join(self.output_dir, 'outputs', 'apk', 'debug', 'app-debug.apk'), - 'ChipTool-release-unsigned.apk': os.path.join(self.output_dir, 'outputs', 'apk', 'release', 'app-release-unsigned.apk'), + outputs = { + 'CHIPController.jar': + os.path.join(self.output_dir, 'lib', 'CHIPController.jar'), + 'SetupPayloadParser.jar': + os.path.join(self.output_dir, 'lib', 'SetupPayloadParser.jar'), + 'ChipTool-debug.apk': + os.path.join(self.output_dir, 'outputs', 'apk', 'debug', + 'app-debug.apk'), + 'ChipTool-release-unsigned.apk': + os.path.join(self.output_dir, 'outputs', 'apk', 'release', + 'app-release-unsigned.apk'), } outputs.update(self.jni_output_libs()) From fdde1b0c9f4de0679e81445adffa584fa0f2ada9 Mon Sep 17 00:00:00 2001 From: Andrei Litvin Date: Mon, 9 Aug 2021 14:36:34 -0400 Subject: [PATCH 07/16] Another pyformat on factory/targets --- scripts/build/build/factory.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/scripts/build/build/factory.py b/scripts/build/build/factory.py index ea310781ad6ecc..113e349f40af8d 100644 --- a/scripts/build/build/factory.py +++ b/scripts/build/build/factory.py @@ -92,8 +92,10 @@ def Create(self, runner, __board_key: Board, __app_key: Application, # Matrix of what can be compiled and what build options are required # by such compilation _MATCHERS[Platform.HOST].AcceptBoard(Board.NATIVE) -_MATCHERS[Platform.HOST].AcceptApplication(Application.ALL_CLUSTERS, app=HostApp.ALL_CLUSTERS) -_MATCHERS[Platform.HOST].AcceptApplication(Application.CHIP_TOOL, app=HostApp.CHIP_TOOL) +_MATCHERS[Platform.HOST].AcceptApplication( + Application.ALL_CLUSTERS, app=HostApp.ALL_CLUSTERS) +_MATCHERS[Platform.HOST].AcceptApplication( + Application.CHIP_TOOL, app=HostApp.CHIP_TOOL) _MATCHERS[Platform.ESP32].AcceptBoard(Board.DEVKITC, board=Esp32Board.DevKitC) _MATCHERS[Platform.ESP32].AcceptBoard(Board.M5STACK, board=Esp32Board.M5Stack) @@ -117,7 +119,6 @@ def Create(self, runner, __board_key: Board, __app_key: Application, _MATCHERS[Platform.EFR32].AcceptApplication( Application.WINDOW_COVERING, app=Efr32App.WINDOW_COVERING) - _MATCHERS[Platform.NRF].AcceptBoard(Board.NRF5340, board=NrfBoard.NRF5340) _MATCHERS[Platform.NRF].AcceptBoard(Board.NRF52840, board=NrfBoard.NRF52840) _MATCHERS[Platform.NRF].AcceptApplication(Application.LOCK, app=NrfApp.LOCK) @@ -129,6 +130,7 @@ def Create(self, runner, __board_key: Board, __app_key: Application, _MATCHERS[Platform.ANDROID].AcceptBoard(Board.X64, board=AndroidBoard.X64) _MATCHERS[Platform.ANDROID].AcceptApplication(Application.CHIP_TOOL) + class BuilderFactory: """Creates application builders.""" @@ -148,7 +150,8 @@ def Create(self, platform: Platform, board: Board, app: Application): output_prefix=self.output_prefix) if builder: - builder.SetIdentifier(platform.name.lower(), board.name.lower(), app.name.lower()) + builder.SetIdentifier(platform.name.lower(), board.name.lower(), + app.name.lower()) return builder From 8fda0b419394a2c6db03d199da252571c4cefced Mon Sep 17 00:00:00 2001 From: Andrei Litvin Date: Mon, 9 Aug 2021 14:38:11 -0400 Subject: [PATCH 08/16] Move android to workflow_dispatch --- .github/workflows/android.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/android.yaml b/.github/workflows/android.yaml index 0df1750d17e937..17adcefe2e1fb2 100644 --- a/.github/workflows/android.yaml +++ b/.github/workflows/android.yaml @@ -15,8 +15,8 @@ name: Android on: - push: - pull_request: + workflow_dispatch: + # NOTE: not enabled in push/pull_request as this check is available in GCP concurrency: group: ${{ github.ref }}-${{ github.workflow }}-${{ (github.event_name == 'pull_request' && github.event.number) || (github.event_name == 'workflow_dispatch' && github.run_number) || github.sha }} From 077805f4634dee3557dfbdb27bdd8fea09dffd4a Mon Sep 17 00:00:00 2001 From: Andrei Litvin Date: Mon, 9 Aug 2021 15:01:06 -0400 Subject: [PATCH 09/16] Fix unit tests, pyformat android and test.py --- scripts/build/builders/android.py | 3 +- .../build/expected_all_platform_commands.txt | 47 +++++++++++++++++- scripts/build/test.py | 48 +++++++++++-------- 3 files changed, 76 insertions(+), 22 deletions(-) diff --git a/scripts/build/builders/android.py b/scripts/build/builders/android.py index c18572093ba1c5..c14cb6d4771419 100644 --- a/scripts/build/builders/android.py +++ b/scripts/build/builders/android.py @@ -113,7 +113,8 @@ def build(self): # App compilation self._Execute([ - 'src/android/CHIPTool/gradlew', '-p', 'src/android/CHIPTool', + '%s/src/android/CHIPTool/gradlew' % self.root, '-p', + '%s/src/android/CHIPTool' % self.root, '-PchipSdkJarDir=%s' % os.path.join(self.output_dir, 'lib'), '-PbuildDir=%s' % self.output_dir, 'build' ], diff --git a/scripts/build/expected_all_platform_commands.txt b/scripts/build/expected_all_platform_commands.txt index 5c53d4ebae2310..b7067c77c1e2c9 100644 --- a/scripts/build/expected_all_platform_commands.txt +++ b/scripts/build/expected_all_platform_commands.txt @@ -2,7 +2,7 @@ gn gen --check --fail-on-unused-args --root={root}/examples/all-clusters-app/linux {out}/{real_platform}-native-all_clusters # Generating {real_platform}-native-chip_tool -gn gen --check --fail-on-unused-args --root=/TEST/BUILD/ROOT/examples/chip-tool {out}/{real_platform}-native-chip_tool +gn gen --check --fail-on-unused-args --root={root}/examples/chip-tool {out}/{real_platform}-native-chip_tool # Generating qpg-qpg6100-lock gn gen --check --fail-on-unused-args --root={root}/examples/lock-app/qpg {out}/qpg-qpg6100-lock @@ -76,6 +76,24 @@ bash -c 'source "$ZEPHYR_BASE/zephyr-env.sh"; export GNUARMEMB_TOOLCHAIN_PATH="$PW_PIGWEED_CIPD_INSTALL_DIR"; west build --cmake-only -d {out}/nrf-nrf5340-shell -b nrf5340dk_nrf5340_cpuapp {root}/examples/shell/nrfconnect' +# Generating android-arm-chip_tool +gn gen --check --fail-on-unused-args {out}/android-arm-chip_tool '--args=target_os="android" target_cpu="arm" android_ndk_root="TEST_ANDROID_NDK_HOME" android_sdk_root="TEST_ANDROID_HOME"' + +# Accepting NDK licenses +bash -c 'yes | TEST_ANDROID_HOME/tools/bin/sdkmanager --licenses >/dev/null' + +# Generating android-arm64-chip_tool +gn gen --check --fail-on-unused-args {out}/android-arm64-chip_tool '--args=target_os="android" target_cpu="arm64" android_ndk_root="TEST_ANDROID_NDK_HOME" android_sdk_root="TEST_ANDROID_HOME"' + +# Accepting NDK licenses +bash -c 'yes | TEST_ANDROID_HOME/tools/bin/sdkmanager --licenses >/dev/null' + +# Generating android-x64-chip_tool +gn gen --check --fail-on-unused-args {out}/android-x64-chip_tool '--args=target_os="android" target_cpu="x64" android_ndk_root="TEST_ANDROID_NDK_HOME" android_sdk_root="TEST_ANDROID_HOME"' + +# Accepting NDK licenses +bash -c 'yes | TEST_ANDROID_HOME/tools/bin/sdkmanager --licenses >/dev/null' + # Building {real_platform}-native-all_clusters ninja -C {out}/{real_platform}-native-all_clusters @@ -130,4 +148,31 @@ ninja -C {out}/nrf-nrf5340-lock # Building nrf-nrf5340-shell ninja -C {out}/nrf-nrf5340-shell +# Building JNI android-arm-chip_tool +ninja -C {out}/android-arm-chip_tool + +# Prepare Native libs android-arm-chip_tool +bash -c 'rsync -a {out}/android-arm-chip_tool/lib/jni/* {root}/src/android/CHIPTool/app/src/main/jniLibs/' + +# Building APP android-arm-chip_tool +{root}/src/android/CHIPTool/gradlew -p {root}/src/android/CHIPTool -PchipSdkJarDir={out}/android-arm-chip_tool/lib -PbuildDir={out}/android-arm-chip_tool build + +# Building JNI android-arm64-chip_tool +ninja -C {out}/android-arm64-chip_tool + +# Prepare Native libs android-arm64-chip_tool +bash -c 'rsync -a {out}/android-arm64-chip_tool/lib/jni/* {root}/src/android/CHIPTool/app/src/main/jniLibs/' + +# Building APP android-arm64-chip_tool +{root}/src/android/CHIPTool/gradlew -p {root}/src/android/CHIPTool -PchipSdkJarDir={out}/android-arm64-chip_tool/lib -PbuildDir={out}/android-arm64-chip_tool build + +# Building JNI android-x64-chip_tool +ninja -C {out}/android-x64-chip_tool + +# Prepare Native libs android-x64-chip_tool +bash -c 'rsync -a {out}/android-x64-chip_tool/lib/jni/* {root}/src/android/CHIPTool/app/src/main/jniLibs/' + +# Building APP android-x64-chip_tool +{root}/src/android/CHIPTool/gradlew -p {root}/src/android/CHIPTool -PchipSdkJarDir={out}/android-x64-chip_tool/lib -PbuildDir={out}/android-x64-chip_tool build + diff --git a/scripts/build/test.py b/scripts/build/test.py index 600bef3f839976..0fbb31376fbbfd 100644 --- a/scripts/build/test.py +++ b/scripts/build/test.py @@ -29,34 +29,43 @@ SCRIPT_ROOT = os.path.dirname(__file__) + def build_expected_output(root: str, out: str) -> List[str]: - with open(os.path.join(SCRIPT_ROOT, 'expected_all_platform_commands.txt'), 'rt') as f: + with open( + os.path.join(SCRIPT_ROOT, 'expected_all_platform_commands.txt'), + 'rt') as f: for l in f.readlines(): - yield l.replace("{root}", root).replace("{out}", out).replace('{real_platform}', ConcretePlatformName()) - + yield l.replace('{root}', + root).replace('{out}', + out).replace('{real_platform}', + ConcretePlatformName()) def build_actual_output(root: str, out: str) -> List[str]: # Fake out that we have a project root - os.environ['PW_PROJECT_ROOT'] = root binary = os.path.join(SCRIPT_ROOT, 'build_examples.py') - retval = subprocess.run([ - binary, - '--platform', 'all', - '--log-level', 'FATAL', - '--dry-run', - '--repo', root, - '--out-prefix', out, - 'build' - ], stdout=subprocess.PIPE, check=True, encoding='UTF-8') - + retval = subprocess.run( + [ + binary, '--platform', 'all', '--log-level', 'FATAL', '--dry-run', + '--repo', root, '--out-prefix', out, 'build' + ], + stdout=subprocess.PIPE, + check=True, + encoding='UTF-8', + env={ + 'PW_PROJECT_ROOT': root, + 'ANDROID_NDK_HOME': 'TEST_ANDROID_NDK_HOME', + 'ANDROID_HOME': 'TEST_ANDROID_HOME', + }) return [l + '\n' for l in retval.stdout.split('\n')] def main(): - coloredlogs.install(level=logging.INFO, fmt='%(asctime)s %(name)s %(levelname)-7s %(message)s') + coloredlogs.install( + level=logging.INFO, + fmt='%(asctime)s %(name)s %(levelname)-7s %(message)s') ROOT = '/TEST/BUILD/ROOT' OUT = '/OUTPUT/DIR' @@ -67,12 +76,11 @@ def main(): diffs = [line for line in difflib.unified_diff(expected, actual)] if diffs: - logging.error("DIFFERENCE between expected and generated output") + logging.error('DIFFERENCE between expected and generated output') for l in diffs: - logging.warning(" " + l.strip()) + logging.warning(' ' + l.strip()) sys.exit(1) - -if __name__ == "__main__": - main() +if __name__ == '__main__': + main() From c08b1a3c538e398696c87905e2ac8eff36e2408f Mon Sep 17 00:00:00 2001 From: Andrei Litvin Date: Mon, 9 Aug 2021 15:03:17 -0400 Subject: [PATCH 10/16] Update error text for writable check on android home licenses --- scripts/build/builders/android.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/build/builders/android.py b/scripts/build/builders/android.py index c14cb6d4771419..1ab5368708ed5e 100644 --- a/scripts/build/builders/android.py +++ b/scripts/build/builders/android.py @@ -61,7 +61,7 @@ def validate_build_environment(self): licenses = os.path.join(os.environ['ANDROID_HOME'], 'licenses') if not os.access(licenses, os.W_OK): raise Exception( - "'%s' is writable by the current user (needed to accept licenses)" % + "'%s' is NOT writable by the current user (needed to accept licenses)" % licenses) def generate(self): From b196e5b9db866cbe7b2dee5b7cd25f25ed4e179d Mon Sep 17 00:00:00 2001 From: Andrei Litvin Date: Tue, 10 Aug 2021 09:17:53 -0400 Subject: [PATCH 11/16] Accept the possibility that the android licenses folder does not exist at all --- scripts/build/builders/android.py | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/scripts/build/builders/android.py b/scripts/build/builders/android.py index 1ab5368708ed5e..1c686dd8f98764 100644 --- a/scripts/build/builders/android.py +++ b/scripts/build/builders/android.py @@ -58,11 +58,19 @@ def validate_build_environment(self): # In order to accept a license, the licenses folder is updated with the hash of the # accepted license - licenses = os.path.join(os.environ['ANDROID_HOME'], 'licenses') - if not os.access(licenses, os.W_OK): + android_home = os.environ['ANDROID_HOME'] + licenses = os.path.join(android_home, 'licenses') + if not os.path.exists(licenses): + # Initial install may not have licenses at all + if not os.access(android_home, os.W_OK): + raise Exception( + "'%s' is NOT writable by the current user (needed to create licenses folder for accept)" + % android_home) + + elif not os.access(licenses, os.W_OK): raise Exception( - "'%s' is NOT writable by the current user (needed to accept licenses)" % - licenses) + "'%s' is NOT writable by the current user (needed to accept licenses)" + % licenses) def generate(self): if not os.path.exists(self.output_dir): From 979a2825fe0c3b60a61c9a34fee1fe3370ba733c Mon Sep 17 00:00:00 2001 From: Andrei Litvin Date: Wed, 11 Aug 2021 12:04:33 -0400 Subject: [PATCH 12/16] Update to _build and build_outputs method naming for android --- scripts/build/builders/android.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/build/builders/android.py b/scripts/build/builders/android.py index 1c686dd8f98764..718b06c16fdd47 100644 --- a/scripts/build/builders/android.py +++ b/scripts/build/builders/android.py @@ -101,7 +101,7 @@ def generate(self): ], title='Accepting NDK licenses') - def build(self): + def _build(self): self._Execute(['ninja', '-C', self.output_dir], title='Building JNI ' + self.identifier) @@ -140,7 +140,7 @@ def jni_output_libs(self): return items - def outputs(self): + def build_outputs(self): outputs = { 'CHIPController.jar': os.path.join(self.output_dir, 'lib', 'CHIPController.jar'), From 6437dcee64ba757952d6e3846d451fb831247793 Mon Sep 17 00:00:00 2001 From: Andrei Litvin Date: Wed, 11 Aug 2021 13:32:12 -0400 Subject: [PATCH 13/16] Do not use rsync and instead do explicit path updates for android native libraries --- scripts/build/builders/android.py | 42 +++++++++++-------- .../build/expected_all_platform_commands.txt | 18 ++++++-- 2 files changed, 39 insertions(+), 21 deletions(-) diff --git a/scripts/build/builders/android.py b/scripts/build/builders/android.py index 718b06c16fdd47..8e0f887f229235 100644 --- a/scripts/build/builders/android.py +++ b/scripts/build/builders/android.py @@ -36,6 +36,16 @@ def TargetCpuName(self): else: raise Exception('Unknown board type: %r' % self) + def AbiName(self): + if self == AndroidBoard.ARM: + return 'armeabi-v7a' + elif self == AndroidBoard.ARM64: + return 'arm64-v8a' + elif self == AndroidBoard.X64: + return 'x86_64' + else: + raise Exception('Unknown board type: %r' % self) + class AndroidBuilder(Builder): @@ -112,12 +122,14 @@ def _build(self): # JNILibs will be copied as long as they reside in src/main/jniLibs/ABI: # https://developer.android.com/studio/projects/gradle-external-native-builds#jniLibs - self._Execute([ - 'bash', '-c', - 'rsync -a %s/lib/jni/* %s/src/android/CHIPTool/app/src/main/jniLibs/' % - (self.output_dir, self.root) - ], - title='Prepare Native libs ' + self.identifier) + + # We do NOT use python builtins for copy, so that the 'execution commands' are available + # when using dry run. + jnilibs_dir = os.path.join(self.root, 'src/android/CHIPTool/app/src/main/jniLibs', self.board.AbiName()) + self._Execute(['mkdir', '-p', jnilibs_dir], title='Prepare Native libs ' + self.identifier) + + for libName in ['libSetupPayloadParser.so', 'libCHIPController.so']: + self._Execute(['cp', os.path.join(self.output_dir, 'lib', 'jni', self.board.AbiName(), libName), os.path.join(jnilibs_dir, libName)]) # App compilation self._Execute([ @@ -128,18 +140,6 @@ def _build(self): ], title='Building APP ' + self.identifier) - def jni_output_libs(self): - """Get a dictionary of JNI-required files.""" - items = {} - - scan_root = os.path.join(self.output_dir, 'lib', 'jni') - for root, dirs, files in os.walk(scan_root): - dir_name = root[len(scan_root) + 1:] - for file_name in files: - items[os.path.join(dir_name, file_name)] = os.path.join(root, file_name) - - return items - def build_outputs(self): outputs = { 'CHIPController.jar': @@ -152,6 +152,12 @@ def build_outputs(self): 'ChipTool-release-unsigned.apk': os.path.join(self.output_dir, 'outputs', 'apk', 'release', 'app-release-unsigned.apk'), + + 'jni/%s/libSetupPayloadParser.so' % self.board.AbiName(): + os.path.join(self.output_dir, 'lib', 'jni', self.board.AbiName(), 'libSetupPayloadParser.so'), + + 'jni/%s/libCHIPController.so' % self.board.AbiName(): + os.path.join(self.output_dir, 'lib', 'jni', self.board.AbiName(), 'libCHIPController.so'), } outputs.update(self.jni_output_libs()) diff --git a/scripts/build/expected_all_platform_commands.txt b/scripts/build/expected_all_platform_commands.txt index b7067c77c1e2c9..a7c3d6c3e643a2 100644 --- a/scripts/build/expected_all_platform_commands.txt +++ b/scripts/build/expected_all_platform_commands.txt @@ -152,7 +152,11 @@ ninja -C {out}/nrf-nrf5340-shell ninja -C {out}/android-arm-chip_tool # Prepare Native libs android-arm-chip_tool -bash -c 'rsync -a {out}/android-arm-chip_tool/lib/jni/* {root}/src/android/CHIPTool/app/src/main/jniLibs/' +mkdir -p {root}/src/android/CHIPTool/app/src/main/jniLibs/armeabi-v7a + +cp {out}/android-arm-chip_tool/lib/jni/armeabi-v7a/libSetupPayloadParser.so {root}/src/android/CHIPTool/app/src/main/jniLibs/armeabi-v7a/libSetupPayloadParser.so + +cp {out}/android-arm-chip_tool/lib/jni/armeabi-v7a/libCHIPController.so {root}/src/android/CHIPTool/app/src/main/jniLibs/armeabi-v7a/libCHIPController.so # Building APP android-arm-chip_tool {root}/src/android/CHIPTool/gradlew -p {root}/src/android/CHIPTool -PchipSdkJarDir={out}/android-arm-chip_tool/lib -PbuildDir={out}/android-arm-chip_tool build @@ -161,7 +165,11 @@ bash -c 'rsync -a {out}/android-arm-chip_tool/lib/jni/* {root}/src/android/CHIPT ninja -C {out}/android-arm64-chip_tool # Prepare Native libs android-arm64-chip_tool -bash -c 'rsync -a {out}/android-arm64-chip_tool/lib/jni/* {root}/src/android/CHIPTool/app/src/main/jniLibs/' +mkdir -p {root}/src/android/CHIPTool/app/src/main/jniLibs/arm64-v8a + +cp {out}/android-arm64-chip_tool/lib/jni/arm64-v8a/libSetupPayloadParser.so {root}/src/android/CHIPTool/app/src/main/jniLibs/arm64-v8a/libSetupPayloadParser.so + +cp {out}/android-arm64-chip_tool/lib/jni/arm64-v8a/libCHIPController.so {root}/src/android/CHIPTool/app/src/main/jniLibs/arm64-v8a/libCHIPController.so # Building APP android-arm64-chip_tool {root}/src/android/CHIPTool/gradlew -p {root}/src/android/CHIPTool -PchipSdkJarDir={out}/android-arm64-chip_tool/lib -PbuildDir={out}/android-arm64-chip_tool build @@ -170,7 +178,11 @@ bash -c 'rsync -a {out}/android-arm64-chip_tool/lib/jni/* {root}/src/android/CHI ninja -C {out}/android-x64-chip_tool # Prepare Native libs android-x64-chip_tool -bash -c 'rsync -a {out}/android-x64-chip_tool/lib/jni/* {root}/src/android/CHIPTool/app/src/main/jniLibs/' +mkdir -p {root}/src/android/CHIPTool/app/src/main/jniLibs/x86_64 + +cp {out}/android-x64-chip_tool/lib/jni/x86_64/libSetupPayloadParser.so {root}/src/android/CHIPTool/app/src/main/jniLibs/x86_64/libSetupPayloadParser.so + +cp {out}/android-x64-chip_tool/lib/jni/x86_64/libCHIPController.so {root}/src/android/CHIPTool/app/src/main/jniLibs/x86_64/libCHIPController.so # Building APP android-x64-chip_tool {root}/src/android/CHIPTool/gradlew -p {root}/src/android/CHIPTool -PchipSdkJarDir={out}/android-x64-chip_tool/lib -PbuildDir={out}/android-x64-chip_tool build From 6a73aabe4e5580af14b765b1c671a4e576652783 Mon Sep 17 00:00:00 2001 From: Andrei Litvin Date: Wed, 11 Aug 2021 13:36:54 -0400 Subject: [PATCH 14/16] Remove obsolete code for output calculation --- scripts/build/builders/android.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/scripts/build/builders/android.py b/scripts/build/builders/android.py index 8e0f887f229235..fb2b03db171744 100644 --- a/scripts/build/builders/android.py +++ b/scripts/build/builders/android.py @@ -160,6 +160,4 @@ def build_outputs(self): os.path.join(self.output_dir, 'lib', 'jni', self.board.AbiName(), 'libCHIPController.so'), } - outputs.update(self.jni_output_libs()) - return outputs From 45d472bda832f128ddbb48ad6dca02bee3f78b8a Mon Sep 17 00:00:00 2001 From: Andrei Litvin Date: Wed, 11 Aug 2021 15:06:25 -0400 Subject: [PATCH 15/16] Update GH Actions to use the updated examples build script --- .github/workflows/android.yaml | 54 ++++------------------------------ 1 file changed, 5 insertions(+), 49 deletions(-) diff --git a/.github/workflows/android.yaml b/.github/workflows/android.yaml index 17adcefe2e1fb2..5dab113e94b252 100644 --- a/.github/workflows/android.yaml +++ b/.github/workflows/android.yaml @@ -15,8 +15,8 @@ name: Android on: - workflow_dispatch: - # NOTE: not enabled in push/pull_request as this check is available in GCP + push: + pull_request: concurrency: group: ${{ github.ref }}-${{ github.workflow }}-${{ (github.event_name == 'pull_request' && github.event.number) || (github.event_name == 'workflow_dispatch' && github.run_number) || github.sha }} @@ -54,51 +54,7 @@ jobs: path: | .environment/gn_out/.ninja_log .environment/pigweed-venv/*.log - - name: Build arm libs - timeout-minutes: 2 + - name: Build android examples run: | - ./scripts/examples/android_app.sh - env: - BUILD_TYPE: android_arm - TARGET_CPU: arm - - name: Build arm App - timeout-minutes: 5 - run: | - yes | "$ANDROID_HOME"/tools/bin/sdkmanager --licenses - cd src/android/CHIPTool - ./gradlew build - env: - BUILD_TYPE: android_arm - TARGET_CPU: arm - - name: Build arm64 libs - timeout-minutes: 2 - run: | - ./scripts/examples/android_app.sh - env: - BUILD_TYPE: android_arm64 - TARGET_CPU: arm64 - - name: Build arm64 App - timeout-minutes: 5 - run: | - yes | "$ANDROID_HOME"/tools/bin/sdkmanager --licenses - cd src/android/CHIPTool - ./gradlew build - env: - BUILD_TYPE: android_arm64 - TARGET_CPU: arm64 - - name: Build x64 libs - timeout-minutes: 2 - run: | - ./scripts/examples/android_app.sh - env: - BUILD_TYPE: android_x64 - TARGET_CPU: x64 - - name: Build x64 App - timeout-minutes: 5 - run: | - yes | "$ANDROID_HOME"/tools/bin/sdkmanager --licenses - cd src/android/CHIPTool - ./gradlew build - env: - BUILD_TYPE: android_x64 - TARGET_CPU: x64 + ./scripts/run_in_build_env.sh \ + ./scripts/build/build_examples.py --platform android build From b1db41d7f4fc0e839b918a788ece66abe36037a9 Mon Sep 17 00:00:00 2001 From: Andrei Litvin Date: Wed, 11 Aug 2021 15:47:29 -0400 Subject: [PATCH 16/16] Fix android build examples command line - script to be executed must be a string apparently --- .github/workflows/android.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/android.yaml b/.github/workflows/android.yaml index 5dab113e94b252..042ef6c72291b2 100644 --- a/.github/workflows/android.yaml +++ b/.github/workflows/android.yaml @@ -57,4 +57,4 @@ jobs: - name: Build android examples run: | ./scripts/run_in_build_env.sh \ - ./scripts/build/build_examples.py --platform android build + "./scripts/build/build_examples.py --platform android build"