Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add the initial skeleton of Matter Controller Java CLI App #23048

Merged
merged 3 commits into from
Oct 13, 2022
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
176 changes: 175 additions & 1 deletion build/chip/java/rules.gni
Original file line number Diff line number Diff line change
@@ -114,7 +114,7 @@ template("java_library") {
_data_deps = invoker.data_deps
}

# Generates a .java file containing all sources to be compiled
# Generates a .sources file containing all sources to be compiled
_java_sources_file = "$target_gen_dir/$target_name.sources"
if (defined(invoker.java_sources_file)) {
_java_sources_file = invoker.java_sources_file
@@ -176,6 +176,162 @@ template("java_library") {
}
}

# Declare a Java executable target
#
# Manifext.txt: contains the given class as the entrypoint about the files packaged in a Java executable target.
#
# sources: List of .java files included in this binary. Mutually exclusive with jar_path.
#
# jar_path: A path to an existing JAR. Mutually exclusive with sources.
#
# output_name: File name for the output binary under root_build_dir/bin.
#
# javac_flags: additional flags to pass to the javac compiler
#
template("java_binary") {
# Figure out the output name
_jar_name = target_name
if (defined(invoker.output_name)) {
_jar_name = invoker.output_name
} else {
_jar_name += ".jar"
}

_deps = []
if (defined(invoker.deps)) {
_deps = invoker.deps
}

# What files will be compiled
_java_files = []
if (defined(invoker.sources)) {
_java_files = invoker.sources
}

_is_prebuilt = defined(invoker.jar_path)

_jar_output = ""
_target_dir_name = get_label_info(":$target_name", "dir")
if (_is_prebuilt) {
assert(_java_files == [])
_jar_output = "$root_out_dir/bin/$_target_dir_name/" +
get_path_info(invoker.jar_path, "name") + ".jar"
} else {
_jar_output = "$root_out_dir/bin/$_target_dir_name/$_jar_name"
}

# Generate a list containing the expected build_config filepath of every dependency.
_deps_configs = []
foreach(_dep, _deps) {
_dep_gen_dir = get_label_info(_dep, "target_gen_dir")
_dep_name = get_label_info(_dep, "name")
_dep_config = "$_dep_gen_dir/$_dep_name.json"
_deps_configs += [ _dep_config ]
}
_rebased_deps_configs = rebase_path(_deps_configs, root_build_dir)

# Create the name for this target's build_config.
_library_target_name = target_name
_build_config = "$target_gen_dir/$_library_target_name.json"
_rebased_build_config = rebase_path(_build_config, root_build_dir)

# Write the build_config file for this target.
_config_target_name = target_name + "_config"
action(_config_target_name) {
script = write_build_config

deps = _deps

outputs = [ _build_config ]
args = [
"--jar-path",
rebase_path(_jar_output, root_build_dir),
"--build-config",
_rebased_build_config,
"--deps-configs=$_rebased_deps_configs",
]
}

# Building from sources - perform Java compilation and JAR creation.
if (!_is_prebuilt) {
# Additional flags
_javac_flags = [
"-Werror",
"-Xlint:all",
]
if (defined(invoker.javac_flags)) {
_javac_flags += invoker.javac_flags
}

# Data deps
_data_deps = []
if (defined(invoker.data_deps)) {
_data_deps = invoker.data_deps
}

# Generates a .sources file containing all sources to be compiled
_java_sources_file = "$target_gen_dir/$target_name.sources"
if (defined(invoker.java_sources_file)) {
_java_sources_file = invoker.java_sources_file
}
write_file(_java_sources_file, rebase_path(_java_files, root_build_dir))

# Compiles the given files into a directory and generates a 'class list'
_javac_target_name = target_name + "__javac"
_class_dir = rebase_path(target_out_dir, root_build_dir) + "/classes"
_class_list_file = "$target_gen_dir/$target_name.classlist"
action(_javac_target_name) {
sources = _java_files
deps = [ ":$_config_target_name" ]

outputs = [ _class_list_file ]

script = javac_runner

args = [
"--classdir",
_class_dir,
"--outfile",
rebase_path(_class_list_file, root_build_dir),
"--build-config",
_rebased_build_config,
"--",
"-d",
_class_dir,
"@" + rebase_path(_java_sources_file, root_build_dir),
] + _javac_flags
}

# Bundles all files within the 'class directory' into a jar file
action(target_name) {
deps = [ ":$_javac_target_name" ] + _deps

data_deps = _data_deps

outputs = [ _jar_output ]

script = jar_runner

args = [
"cfm",
rebase_path(_jar_output, root_build_dir),
"Manifest.txt",
"-C",
_class_dir,
".",
]
}
} else {
# Using pre-specified JAR instead of building from sources - simply copy the JAR to the output directory.
_original_jar_path = invoker.jar_path
copy(target_name) {
sources = [ _original_jar_path ]
outputs = [ _jar_output ]
deps = [ ":$_config_target_name" ] + _deps
}
}
}

template("android_library") {
java_library(target_name) {
forward_variables_from(invoker, "*")
@@ -194,6 +350,24 @@ template("android_library") {
}
}

template("android_binary") {
java_binary(target_name) {
forward_variables_from(invoker, "*")

if (!defined(javac_flags)) {
javac_flags = []
}

javac_flags += [
"-Xlint:-options",
"-source",
"8",
"-target",
"8",
]
}
}

template("java_prebuilt") {
java_library(target_name) {
forward_variables_from(invoker, "*")
20 changes: 20 additions & 0 deletions examples/java-matter-controller/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
*.iml
.gradle
/local.properties
/.idea/caches
/.idea/libraries
/.idea/modules.xml
/.idea/workspace.xml
/.idea/navEditor.xml
/.idea/assetWizardSettings.xml
.DS_Store
/build
/captures
.externalNativeBuild
.cxx
local.properties

# Shared libs & JAR libs (those libs are copied into source tree for easy Android build).
*.so
*.jar
*.map
25 changes: 25 additions & 0 deletions examples/java-matter-controller/.gn
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Copyright (c) 2020-2022 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("//build_overrides/build.gni")

# The location of the build configuration file.
buildconfig = "${build_root}/config/BUILDCONFIG.gn"

# CHIP uses angle bracket includes.
check_system_includes = true

default_args = {
import("//args.gni")
}
43 changes: 43 additions & 0 deletions examples/java-matter-controller/BUILD.gn
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Copyright (c) 2022 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("//build_overrides/build.gni")
import("//build_overrides/chip.gni")

import("${build_root}/config/android_abi.gni")
import("${chip_root}/build/chip/java/rules.gni")
import("${chip_root}/build/chip/tools.gni")

android_binary("java-matter-controller") {
output_name = "java-matter-controller"

deps = [
":android",
"${chip_root}/src/controller/java",
"${chip_root}/src/setup_payload/java",
"${chip_root}/third_party/android_deps:annotation",
]

sources = [ "java/src/com/matter/controller/Main.java" ]

javac_flags = [ "-Xlint:deprecation" ]
}

java_prebuilt("android") {
jar_path = "${android_sdk_root}/platforms/android-21/android.jar"
}

group("default") {
deps = [ ":java-matter-controller" ]
}
2 changes: 2 additions & 0 deletions examples/java-matter-controller/Manifest.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Main-Class: com.matter.controller.Main

67 changes: 67 additions & 0 deletions examples/java-matter-controller/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# Matter Controller Java App Example

This is a Matter Controller Java app that can be used to uses Matter to send
messages to a Matter server.

<hr>

- [Matter Controller Java App Example](#matter-controller-java-app-example)
- [Requirements for building](#requirements-for-building)
- [Gradle & JDK Version](#gradle--jdk-version)
- [Preparing for build](#preparing-for-build)
- [Building & Running the app](#building--running-the-app)

<hr>

<a name="requirements"></a>

## Requirements for building

You need Android SDK 21 & NDK downloaded to your machine. Set the
`$ANDROID_HOME` environment variable to where the SDK is downloaded and the
`$ANDROID_NDK_HOME` environment variable to point to where the NDK package is
downloaded.

<a name="jdk"></a>

### Gradle & JDK Version

We are using Gradle 7.1.1 for all android project which does not support Java 17
(https://docs.gradle.org/current/userguide/compatibility.html) while the default
JDK version on MacOS for Apple Silicon is 'openjdk 17.0.1' or above.

Using JDK bundled with Android Studio will help with that.

```shell
export JAVA_HOME=/Applications/Android\ Studio.app/Contents/jre/Contents/Home/
```

<hr>

<a name="preparing"></a>

## Preparing for build

Complete the following steps to prepare the Matter build:

1. Check out the Matter repository.

2. Run bootstrap (**only required first time**)

```shell
source scripts/bootstrap.sh
```

<a name="building-running"></a>

## Building & Running the app

This is the simplest option. In the command line, run the following command from
the top Matter directory:

```shell
./scripts/build/build_examples.py --target android-x86-java-matter-controller build
```

The Java executable file `java-matter-controller` will be generated at
`out/android-x86-java-matter-controller/bin/`
25 changes: 25 additions & 0 deletions examples/java-matter-controller/args.gni
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Copyright (c) 2020-2022 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("//build_overrides/chip.gni")

import("${chip_root}/config/standalone/args.gni")

chip_device_project_config_include = "<CHIPProjectAppConfig.h>"
chip_project_config_include = "<CHIPProjectAppConfig.h>"
chip_system_project_config_include = "<SystemProjectConfig.h>"

chip_project_config_include_dirs =
[ "${chip_root}/examples/java-matter-controller/include" ]
chip_project_config_include_dirs += [ "${chip_root}/config/standalone" ]
1 change: 1 addition & 0 deletions examples/java-matter-controller/build_overrides
Loading