imx.py 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. # Copyright (c) 2021 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. import os
  15. import re
  16. import shlex
  17. from enum import Enum, auto
  18. from .gn import GnBuilder
  19. class IMXApp(Enum):
  20. CHIP_TOOL = auto()
  21. LIGHT = auto()
  22. THERMOSTAT = auto()
  23. ALL_CLUSTERS = auto()
  24. ALL_CLUSTERS_MINIMAL = auto()
  25. OTA_PROVIDER = auto()
  26. def ExamplePath(self):
  27. if self == IMXApp.CHIP_TOOL:
  28. return 'chip-tool'
  29. if self == IMXApp.LIGHT:
  30. return 'lighting-app/linux'
  31. if self == IMXApp.THERMOSTAT:
  32. return 'thermostat/linux'
  33. if self == IMXApp.ALL_CLUSTERS:
  34. return 'all-clusters-app/linux'
  35. if self == IMXApp.ALL_CLUSTERS_MINIMAL:
  36. return 'all-clusters-minimal-app/linux'
  37. if self == IMXApp.OTA_PROVIDER:
  38. return 'ota-provider-app/linux'
  39. def OutputNames(self):
  40. if self == IMXApp.CHIP_TOOL:
  41. yield 'chip-tool'
  42. yield 'chip-tool.map'
  43. if self == IMXApp.LIGHT:
  44. yield 'chip-lighting-app'
  45. yield 'chip-lighting-app.map'
  46. if self == IMXApp.THERMOSTAT:
  47. yield 'thermostat-app'
  48. yield 'thermostat-app.map'
  49. if self == IMXApp.ALL_CLUSTERS:
  50. yield 'chip-all-clusters-app'
  51. yield 'chip-all-clusters-app.map'
  52. if self == IMXApp.ALL_CLUSTERS_MINIMAL:
  53. yield 'chip-all-clusters-minimal-app'
  54. yield 'chip-all-clusters-minimal-app.map'
  55. if self == IMXApp.OTA_PROVIDER:
  56. yield 'chip-ota-provider-app'
  57. yield 'chip-ota-provider-app.map'
  58. class IMXBuilder(GnBuilder):
  59. def __init__(self,
  60. root,
  61. runner,
  62. app: IMXApp,
  63. release: bool = False):
  64. super(IMXBuilder, self).__init__(
  65. root=os.path.join(root, 'examples', app.ExamplePath()),
  66. runner=runner)
  67. self.release = release
  68. self.app = app
  69. def GnBuildArgs(self):
  70. try:
  71. entries = os.listdir(self.SysRootPath('IMX_SDK_ROOT'))
  72. except FileNotFoundError:
  73. if self.SysRootPath('IMX_SDK_ROOT') == 'IMX_SDK_ROOT':
  74. # CI test, use default value
  75. target_cpu = 'arm64'
  76. arm_arch = 'armv8-a'
  77. sdk_target_sysroot = os.path.join(self.SysRootPath('IMX_SDK_ROOT'), 'sysroots/cortexa53-crypto-poky-linux')
  78. cross_compile = 'aarch64-poky-linux'
  79. cc = 'aarch64-poky-linux-gcc'
  80. cxx = 'aarch64-poky-linux-g++'
  81. else:
  82. raise Exception('the value of env IMX_SDK_ROOT is not a valid path.')
  83. else:
  84. for entry in entries:
  85. if entry.startswith(r'environment-setup-'):
  86. env_setup_script = entry
  87. break
  88. try:
  89. env_setup_script
  90. except NameError:
  91. raise Exception('The SDK environment setup script is not found, make sure the env IMX_SDK_ROOT is correctly set.')
  92. else:
  93. with open(os.path.join(self.SysRootPath('IMX_SDK_ROOT'), env_setup_script), 'r') as env_setup_script_fd:
  94. lines = env_setup_script_fd.readlines()
  95. for line in lines:
  96. line = line.strip('\n')
  97. m = re.match(r'^\s*export\s+SDKTARGETSYSROOT=(.*)', line)
  98. if m:
  99. sdk_target_sysroot = shlex.split(m.group(1))[0]
  100. m = re.match(r'^\s*export\s+CC=(.*)', line)
  101. if m:
  102. cc = shlex.split(m.group(1))[0]
  103. m = re.match(r'^\s*export\s+CXX=(.*)', line)
  104. if m:
  105. cxx = shlex.split(m.group(1))[0]
  106. m = re.match(r'^\s*export\s+ARCH=(.*)', line)
  107. if m:
  108. target_cpu = shlex.split(m.group(1))[0]
  109. if target_cpu == 'arm64':
  110. arm_arch = 'armv8-a'
  111. elif target_cpu == 'arm':
  112. arm_arch = 'armv7ve'
  113. else:
  114. raise Exception('ARCH should be arm64 or arm in the SDK environment setup script.')
  115. m = re.match(r'^\s*export\s+CROSS_COMPILE=(.*)', line)
  116. if m:
  117. cross_compile = shlex.split(m.group(1))[0][:-1]
  118. try:
  119. sdk_target_sysroot
  120. except NameError:
  121. raise Exception('SDKTARGETSYSROOT is not found in the SDK environment setup script.')
  122. else:
  123. try:
  124. cc
  125. cxx
  126. except NameError:
  127. raise Exception('CC and/or CXX are not found in the SDK environment setup script.')
  128. else:
  129. cc = cc.replace('$SDKTARGETSYSROOT', sdk_target_sysroot)
  130. cxx = cxx.replace('$SDKTARGETSYSROOT', sdk_target_sysroot)
  131. try:
  132. target_cpu
  133. cross_compile
  134. except NameError:
  135. raise Exception('ARCH and/or CROSS_COMPILE are not found in the SDK environment setup script.')
  136. args = [
  137. 'treat_warnings_as_errors=false',
  138. 'target_os="linux"',
  139. 'target_cpu="%s"' % target_cpu,
  140. 'arm_arch="%s"' % arm_arch,
  141. 'import(\"//build_overrides/build.gni\")',
  142. 'custom_toolchain=\"${build_root}/toolchain/custom\"',
  143. 'sysroot="%s"' % sdk_target_sysroot,
  144. 'target_cflags=[ "-DCHIP_DEVICE_CONFIG_WIFI_STATION_IF_NAME=\\"mlan0\\"", "-DCHIP_DEVICE_CONFIG_LINUX_DHCPC_CMD=\\"udhcpc -b -i %s \\"" ]',
  145. 'target_cc="%s/sysroots/x86_64-pokysdk-linux/usr/bin/%s/%s"' % (self.SysRootPath('IMX_SDK_ROOT'), cross_compile,
  146. cc),
  147. 'target_cxx="%s/sysroots/x86_64-pokysdk-linux/usr/bin/%s/%s"' % (self.SysRootPath('IMX_SDK_ROOT'), cross_compile,
  148. cxx),
  149. 'target_ar="%s/sysroots/x86_64-pokysdk-linux/usr/bin/%s/%s-ar"' % (self.SysRootPath('IMX_SDK_ROOT'), cross_compile,
  150. cross_compile),
  151. ]
  152. if self.release:
  153. args.append('is_debug=false')
  154. else:
  155. args.append('optimize_debug=true')
  156. return args
  157. def SysRootPath(self, name):
  158. if name not in os.environ:
  159. raise Exception('Missing environment variable "%s"' % name)
  160. return os.environ[name]
  161. def build_outputs(self):
  162. outputs = {}
  163. for name in self.app.OutputNames():
  164. path = os.path.join(self.output_dir, name)
  165. if os.path.isdir(path):
  166. for root, dirs, files in os.walk(path):
  167. for file in files:
  168. outputs.update({
  169. file: os.path.join(root, file)
  170. })
  171. else:
  172. outputs.update({
  173. name: os.path.join(self.output_dir, name)
  174. })
  175. return outputs