Skip to content

Commit

Permalink
[Tizen] Create TPK flashbundle with Tizen GN SDK (#18298)
Browse files Browse the repository at this point in the history
  • Loading branch information
arkq authored May 19, 2022
1 parent aaad739 commit 45f623b
Show file tree
Hide file tree
Showing 6 changed files with 216 additions and 49 deletions.
5 changes: 4 additions & 1 deletion build_overrides/tizen.gni
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
# limitations under the License.

declare_args() {
# Root directory for tizen.
# Root directory for Tizen.
tizen_root = "//config/tizen/chip-gn/platform"

# Root directory for Tizen SDK build support.
tizen_sdk_build_root = "//third_party/tizen"
}
5 changes: 4 additions & 1 deletion examples/build_overrides/tizen.gni
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
# limitations under the License.

declare_args() {
# Root directory for tizen.
# Root directory for Tizen.
tizen_root = "//third_party/connectedhomeip/config/tizen/chip-gn/platform"

# Root directory for Tizen SDK build support.
tizen_sdk_build_root = "//third_party/connectedhomeip/third_party/tizen"
}
12 changes: 12 additions & 0 deletions examples/lighting-app/tizen/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,11 @@
# limitations under the License.

import("//build_overrides/chip.gni")
import("//build_overrides/tizen.gni")

import("${chip_root}/build/chip/tools.gni")
import("${chip_root}/src/app/common_flags.gni")
import("${tizen_sdk_build_root}/tizen_sdk.gni")

assert(chip_build_tools)

Expand All @@ -41,10 +43,20 @@ executable("chip-lighting-app") {
output_dir = root_out_dir
}

tizen_sdk_package("chip-lighting-app:tpk") {
deps = [ ":chip-lighting-app" ]
manifest = rebase_path("tizen-manifest.xml")
sign_security_profile = "CHIP"
}

group("tizen") {
deps = [ ":chip-lighting-app" ]
}

group("tizen:tpk") {
deps = [ ":chip-lighting-app:tpk" ]
}

group("default") {
deps = [ ":tizen" ]
}
52 changes: 5 additions & 47 deletions scripts/build/builders/tizen.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.

import logging
import os
import shutil
from enum import Enum, auto
from xml.etree import ElementTree as ET

Expand Down Expand Up @@ -41,9 +41,6 @@ def PackageName(self):
def PackageVersion(self):
return self.manifest.get('version')

def PackageExecName(self):
return self.manifest.find('{*}service-application').get('exec')

def parse_manifest(self, manifest: str):
self.manifest = ET.parse(manifest).getroot()

Expand Down Expand Up @@ -112,48 +109,9 @@ def GnBuildArgs(self):
]

def _generate_flashbundle(self):

self.tizen_tpk_dir = os.path.join(self.output_dir, "tpk")
self.tizen_out_dir = os.path.join(self.tizen_tpk_dir, "out")

# Create dirrectory where the TPK package file will be created
os.makedirs(self.tizen_out_dir, exist_ok=True)

# Create a dummy project definition file, so the Tizen Studio CLI
# will recognize given directory as a Tizen project.
prj_def_file = os.path.join(self.tizen_tpk_dir, "project_def.prop")
with open(prj_def_file, "w") as f:
f.writelines(l + "\n" for l in [
"# Generated by the build script. DO NOT EDIT!",
"APPNAME = %s" % self.app.AppName(),
"type = app",
])

# Create a dummy project file, so the Tizen Studio CLI will not
# complain about invalid XPath (this file is not used anyway...)
prj_file = os.path.join(self.tizen_tpk_dir, ".project")
with open(prj_file, "w") as f:
f.writelines(l + "\n" for l in [
"<!-- Generated by the build script. DO NOT EDIT! -->",
"<projectDescription></projectDescription>",
])

# Copy Tizen manifest file into the dummy Tizen project.
shutil.copy(
os.path.join(self.root, "tizen-manifest.xml"),
self.tizen_tpk_dir)

# Create link with the application executable in the TPK package
# directory. This linked file will be used by the Tizen Studio CLI
# when creating TPK package.
exec = os.path.join(self.tizen_out_dir, self.app.PackageExecName())
if not os.path.exists(exec):
os.symlink(os.path.join(self.output_dir, self.app.AppName()),
exec)

self._Execute([self.tizen_sdk_cli, 'package', '--type', 'tpk',
'--sign', 'CHIP', '--', self.tizen_out_dir],
title='Generating TPK file for ' + self.identifier)
logging.info('Packaging %s', self.output_dir)
cmd = ['ninja', '-C', self.output_dir, self.app.AppName() + ':tpk']
self._Execute(cmd, title='Packaging ' + self.identifier)

def build_outputs(self):
return {
Expand All @@ -166,5 +124,5 @@ def build_outputs(self):
def flashbundle(self):
tpk = f'{self.app.PackageName()}-{self.app.PackageVersion()}.tpk'
return {
tpk: os.path.join(self.tizen_out_dir, tpk),
tpk: os.path.join(self.output_dir, 'package', 'out', tpk),
}
73 changes: 73 additions & 0 deletions third_party/tizen/tizen_manifest_parser.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
#!/usr/bin/env python

# 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 argparse
import json
from xml.etree import ElementTree as ET


class TizenManifest:

def __init__(self, manifest):
self.manifest = ET.parse(manifest).getroot()

def _get_application(self, apptype):
return self.manifest.find("{*}" + apptype)

def get_package_name(self):
return self.manifest.get("package")

def get_package_version(self):
return self.manifest.get("version")

def get_service_exec(self):
app = self._get_application("service-application")
return app.get("exec", "") if app else ""

def get_ui_exec(self):
app = self._get_application("ui-application")
return app.get("exec", "") if app else ""

def get_watch_exec(self):
app = self._get_application("watch-application")
return app.get("exec", "") if app else ""

def get_widget_exec(self):
app = self._get_application("widget-application")
return app.get("exec", "") if app else ""


if __name__ == '__main__':

parser = argparse.ArgumentParser(
description="Tool for extracting data from Tizen XML manifest file")
parser.add_argument('MANIFEST', help="Tizen manifest XML file")

args = parser.parse_args()
manifest = TizenManifest(args.MANIFEST)

print(json.dumps({
'package': {
'name': manifest.get_package_name(),
'version': manifest.get_package_version(),
},
'apps': {
'service': manifest.get_service_exec(),
'ui': manifest.get_ui_exec(),
'watch': manifest.get_watch_exec(),
'widget': manifest.get_widget_exec(),
}
}))
118 changes: 118 additions & 0 deletions third_party/tizen/tizen_sdk.gni
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
# Copyright (c) 2020 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_overrides/tizen.gni")

import("${build_root}/config/tizen/config.gni")

tizen_manifest_parser = rebase_path("tizen_manifest_parser.py")

template("tizen_sdk") {
forward_variables_from(invoker,
[
"project_build_dir",
"project_app_name",
])

if (!defined(project_app_name)) {
project_app_name = "tizen-app"
}

# Create a dummy project definition file, so the Tizen Studio CLI
# will recognize our build directory as a Tizen project.
write_file("${project_build_dir}/project_def.prop",
[
"# Generated by the GN script. DO NOT EDIT!",
"APPNAME = " + project_app_name,
"type = app",
])

# Create a dummy project file, so the Tizen Studio CLI will not
# complain about invalid XPath (this file is not used anyway...)
write_file("${project_build_dir}/.project",
[
"<!-- Generated by the build script. DO NOT EDIT! -->",
"<projectDescription></projectDescription>",
])

action(target_name) {
forward_variables_from(invoker,
[
"deps",
"outputs",
])
script = "${build_root}/gn_run_binary.py"
args = [ "${tizen_sdk_root}/tools/ide/bin/tizen" ] + invoker.args
}
}

template("tizen_sdk_package") {
# Output directory where packaging will occur. We need a separate directory
# for this, because Tizen Studio CLI scans "res" (resources), "shared" and
# "lib" directories for items to pack. In our case it could include in the
# TPK package libraries available in ${root_build_dir}/lib directory.
tizen_package_dir = "${root_build_dir}/package"
tizen_package_out_dir = "${tizen_package_dir}/out"

assert(defined(invoker.manifest),
"It is required to specify Tizen `manifest` XML file.")
assert(defined(invoker.sign_security_profile),
"It is required to specify a `sign_security_profile` which " +
"should be used for signing TPK package.")

# Extract data from Tizen XML manifest.
manifest = exec_script(tizen_manifest_parser, [ invoker.manifest ], "json")
manifest_package = manifest["package"]
manifest_apps = manifest["apps"]

# Copy Tizen manifest from the source directory.
copy("${target_name}:manifest") {
sources = [ invoker.manifest ]
outputs = [ "${tizen_package_dir}/{{source_file_part}}" ]
deps = invoker.deps
}

# List of dependencies for Tizen Studio CLI packager.
dependencies = [ ":${target_name}:manifest" ]

# Copy executable(s) to temporary output directory. This action is required,
# because Tizen Studio CLI expects particular directory layout - it is not
# possible to specify input files manually.
if (manifest_apps["service"] != "") {
dependencies += [ ":${target_name}:app:service" ]
copy("${target_name}:app:service") {
sources = [ root_build_dir + "/" + manifest_apps["service"] ]
outputs = [ "${tizen_package_out_dir}/{{source_file_part}}" ]
deps = invoker.deps
}
}

tpk = manifest_package["name"] + "-" + manifest_package["version"] + ".tpk"
tizen_sdk(target_name) {
deps = invoker.deps + dependencies
outputs = [ "${tizen_package_out_dir}/" + tpk ]
project_build_dir = tizen_package_dir
args = [
"package",
"--type",
"tpk",
"--sign",
invoker.sign_security_profile,
"--",
tizen_package_out_dir,
]
}
}

0 comments on commit 45f623b

Please sign in to comment.