Skip to content

Commit 45f623b

Browse files
authored
[Tizen] Create TPK flashbundle with Tizen GN SDK (project-chip#18298)
1 parent aaad739 commit 45f623b

File tree

6 files changed

+216
-49
lines changed

6 files changed

+216
-49
lines changed

build_overrides/tizen.gni

+4-1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@
1313
# limitations under the License.
1414

1515
declare_args() {
16-
# Root directory for tizen.
16+
# Root directory for Tizen.
1717
tizen_root = "//config/tizen/chip-gn/platform"
18+
19+
# Root directory for Tizen SDK build support.
20+
tizen_sdk_build_root = "//third_party/tizen"
1821
}

examples/build_overrides/tizen.gni

+4-1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@
1313
# limitations under the License.
1414

1515
declare_args() {
16-
# Root directory for tizen.
16+
# Root directory for Tizen.
1717
tizen_root = "//third_party/connectedhomeip/config/tizen/chip-gn/platform"
18+
19+
# Root directory for Tizen SDK build support.
20+
tizen_sdk_build_root = "//third_party/connectedhomeip/third_party/tizen"
1821
}

examples/lighting-app/tizen/BUILD.gn

+12
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,11 @@
1313
# limitations under the License.
1414

1515
import("//build_overrides/chip.gni")
16+
import("//build_overrides/tizen.gni")
1617

1718
import("${chip_root}/build/chip/tools.gni")
1819
import("${chip_root}/src/app/common_flags.gni")
20+
import("${tizen_sdk_build_root}/tizen_sdk.gni")
1921

2022
assert(chip_build_tools)
2123

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

46+
tizen_sdk_package("chip-lighting-app:tpk") {
47+
deps = [ ":chip-lighting-app" ]
48+
manifest = rebase_path("tizen-manifest.xml")
49+
sign_security_profile = "CHIP"
50+
}
51+
4452
group("tizen") {
4553
deps = [ ":chip-lighting-app" ]
4654
}
4755

56+
group("tizen:tpk") {
57+
deps = [ ":chip-lighting-app:tpk" ]
58+
}
59+
4860
group("default") {
4961
deps = [ ":tizen" ]
5062
}

scripts/build/builders/tizen.py

+5-47
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15+
import logging
1516
import os
16-
import shutil
1717
from enum import Enum, auto
1818
from xml.etree import ElementTree as ET
1919

@@ -41,9 +41,6 @@ def PackageName(self):
4141
def PackageVersion(self):
4242
return self.manifest.get('version')
4343

44-
def PackageExecName(self):
45-
return self.manifest.find('{*}service-application').get('exec')
46-
4744
def parse_manifest(self, manifest: str):
4845
self.manifest = ET.parse(manifest).getroot()
4946

@@ -112,48 +109,9 @@ def GnBuildArgs(self):
112109
]
113110

114111
def _generate_flashbundle(self):
115-
116-
self.tizen_tpk_dir = os.path.join(self.output_dir, "tpk")
117-
self.tizen_out_dir = os.path.join(self.tizen_tpk_dir, "out")
118-
119-
# Create dirrectory where the TPK package file will be created
120-
os.makedirs(self.tizen_out_dir, exist_ok=True)
121-
122-
# Create a dummy project definition file, so the Tizen Studio CLI
123-
# will recognize given directory as a Tizen project.
124-
prj_def_file = os.path.join(self.tizen_tpk_dir, "project_def.prop")
125-
with open(prj_def_file, "w") as f:
126-
f.writelines(l + "\n" for l in [
127-
"# Generated by the build script. DO NOT EDIT!",
128-
"APPNAME = %s" % self.app.AppName(),
129-
"type = app",
130-
])
131-
132-
# Create a dummy project file, so the Tizen Studio CLI will not
133-
# complain about invalid XPath (this file is not used anyway...)
134-
prj_file = os.path.join(self.tizen_tpk_dir, ".project")
135-
with open(prj_file, "w") as f:
136-
f.writelines(l + "\n" for l in [
137-
"<!-- Generated by the build script. DO NOT EDIT! -->",
138-
"<projectDescription></projectDescription>",
139-
])
140-
141-
# Copy Tizen manifest file into the dummy Tizen project.
142-
shutil.copy(
143-
os.path.join(self.root, "tizen-manifest.xml"),
144-
self.tizen_tpk_dir)
145-
146-
# Create link with the application executable in the TPK package
147-
# directory. This linked file will be used by the Tizen Studio CLI
148-
# when creating TPK package.
149-
exec = os.path.join(self.tizen_out_dir, self.app.PackageExecName())
150-
if not os.path.exists(exec):
151-
os.symlink(os.path.join(self.output_dir, self.app.AppName()),
152-
exec)
153-
154-
self._Execute([self.tizen_sdk_cli, 'package', '--type', 'tpk',
155-
'--sign', 'CHIP', '--', self.tizen_out_dir],
156-
title='Generating TPK file for ' + self.identifier)
112+
logging.info('Packaging %s', self.output_dir)
113+
cmd = ['ninja', '-C', self.output_dir, self.app.AppName() + ':tpk']
114+
self._Execute(cmd, title='Packaging ' + self.identifier)
157115

158116
def build_outputs(self):
159117
return {
@@ -166,5 +124,5 @@ def build_outputs(self):
166124
def flashbundle(self):
167125
tpk = f'{self.app.PackageName()}-{self.app.PackageVersion()}.tpk'
168126
return {
169-
tpk: os.path.join(self.tizen_out_dir, tpk),
127+
tpk: os.path.join(self.output_dir, 'package', 'out', tpk),
170128
}
+73
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
#!/usr/bin/env python
2+
3+
# Copyright (c) 2022 Project CHIP Authors
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
17+
import argparse
18+
import json
19+
from xml.etree import ElementTree as ET
20+
21+
22+
class TizenManifest:
23+
24+
def __init__(self, manifest):
25+
self.manifest = ET.parse(manifest).getroot()
26+
27+
def _get_application(self, apptype):
28+
return self.manifest.find("{*}" + apptype)
29+
30+
def get_package_name(self):
31+
return self.manifest.get("package")
32+
33+
def get_package_version(self):
34+
return self.manifest.get("version")
35+
36+
def get_service_exec(self):
37+
app = self._get_application("service-application")
38+
return app.get("exec", "") if app else ""
39+
40+
def get_ui_exec(self):
41+
app = self._get_application("ui-application")
42+
return app.get("exec", "") if app else ""
43+
44+
def get_watch_exec(self):
45+
app = self._get_application("watch-application")
46+
return app.get("exec", "") if app else ""
47+
48+
def get_widget_exec(self):
49+
app = self._get_application("widget-application")
50+
return app.get("exec", "") if app else ""
51+
52+
53+
if __name__ == '__main__':
54+
55+
parser = argparse.ArgumentParser(
56+
description="Tool for extracting data from Tizen XML manifest file")
57+
parser.add_argument('MANIFEST', help="Tizen manifest XML file")
58+
59+
args = parser.parse_args()
60+
manifest = TizenManifest(args.MANIFEST)
61+
62+
print(json.dumps({
63+
'package': {
64+
'name': manifest.get_package_name(),
65+
'version': manifest.get_package_version(),
66+
},
67+
'apps': {
68+
'service': manifest.get_service_exec(),
69+
'ui': manifest.get_ui_exec(),
70+
'watch': manifest.get_watch_exec(),
71+
'widget': manifest.get_widget_exec(),
72+
}
73+
}))

third_party/tizen/tizen_sdk.gni

+118
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
# Copyright (c) 2020 Project CHIP Authors
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
import("//build_overrides/build.gni")
16+
import("//build_overrides/chip.gni")
17+
import("//build_overrides/tizen.gni")
18+
19+
import("${build_root}/config/tizen/config.gni")
20+
21+
tizen_manifest_parser = rebase_path("tizen_manifest_parser.py")
22+
23+
template("tizen_sdk") {
24+
forward_variables_from(invoker,
25+
[
26+
"project_build_dir",
27+
"project_app_name",
28+
])
29+
30+
if (!defined(project_app_name)) {
31+
project_app_name = "tizen-app"
32+
}
33+
34+
# Create a dummy project definition file, so the Tizen Studio CLI
35+
# will recognize our build directory as a Tizen project.
36+
write_file("${project_build_dir}/project_def.prop",
37+
[
38+
"# Generated by the GN script. DO NOT EDIT!",
39+
"APPNAME = " + project_app_name,
40+
"type = app",
41+
])
42+
43+
# Create a dummy project file, so the Tizen Studio CLI will not
44+
# complain about invalid XPath (this file is not used anyway...)
45+
write_file("${project_build_dir}/.project",
46+
[
47+
"<!-- Generated by the build script. DO NOT EDIT! -->",
48+
"<projectDescription></projectDescription>",
49+
])
50+
51+
action(target_name) {
52+
forward_variables_from(invoker,
53+
[
54+
"deps",
55+
"outputs",
56+
])
57+
script = "${build_root}/gn_run_binary.py"
58+
args = [ "${tizen_sdk_root}/tools/ide/bin/tizen" ] + invoker.args
59+
}
60+
}
61+
62+
template("tizen_sdk_package") {
63+
# Output directory where packaging will occur. We need a separate directory
64+
# for this, because Tizen Studio CLI scans "res" (resources), "shared" and
65+
# "lib" directories for items to pack. In our case it could include in the
66+
# TPK package libraries available in ${root_build_dir}/lib directory.
67+
tizen_package_dir = "${root_build_dir}/package"
68+
tizen_package_out_dir = "${tizen_package_dir}/out"
69+
70+
assert(defined(invoker.manifest),
71+
"It is required to specify Tizen `manifest` XML file.")
72+
assert(defined(invoker.sign_security_profile),
73+
"It is required to specify a `sign_security_profile` which " +
74+
"should be used for signing TPK package.")
75+
76+
# Extract data from Tizen XML manifest.
77+
manifest = exec_script(tizen_manifest_parser, [ invoker.manifest ], "json")
78+
manifest_package = manifest["package"]
79+
manifest_apps = manifest["apps"]
80+
81+
# Copy Tizen manifest from the source directory.
82+
copy("${target_name}:manifest") {
83+
sources = [ invoker.manifest ]
84+
outputs = [ "${tizen_package_dir}/{{source_file_part}}" ]
85+
deps = invoker.deps
86+
}
87+
88+
# List of dependencies for Tizen Studio CLI packager.
89+
dependencies = [ ":${target_name}:manifest" ]
90+
91+
# Copy executable(s) to temporary output directory. This action is required,
92+
# because Tizen Studio CLI expects particular directory layout - it is not
93+
# possible to specify input files manually.
94+
if (manifest_apps["service"] != "") {
95+
dependencies += [ ":${target_name}:app:service" ]
96+
copy("${target_name}:app:service") {
97+
sources = [ root_build_dir + "/" + manifest_apps["service"] ]
98+
outputs = [ "${tizen_package_out_dir}/{{source_file_part}}" ]
99+
deps = invoker.deps
100+
}
101+
}
102+
103+
tpk = manifest_package["name"] + "-" + manifest_package["version"] + ".tpk"
104+
tizen_sdk(target_name) {
105+
deps = invoker.deps + dependencies
106+
outputs = [ "${tizen_package_out_dir}/" + tpk ]
107+
project_build_dir = tizen_package_dir
108+
args = [
109+
"package",
110+
"--type",
111+
"tpk",
112+
"--sign",
113+
invoker.sign_security_profile,
114+
"--",
115+
tizen_package_out_dir,
116+
]
117+
}
118+
}

0 commit comments

Comments
 (0)