project_generator.py 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. #
  2. # Copyright (c) Contributors to the Open 3D Engine Project.
  3. # For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. #
  5. # SPDX-License-Identifier: Apache-2.0 OR MIT
  6. #
  7. import os
  8. from config_data import ConfigData
  9. from threaded_lambda import ThreadedLambda
  10. from subprocess_runner import SubprocessRunner
  11. class ProjectGenerator(ThreadedLambda):
  12. """
  13. This class knows how to create an Android project.
  14. It first runs the configuration commands supported by o3de.bat/o3de.sh,
  15. validates the configuration and generates the project.
  16. """
  17. def __init__(self, config: ConfigData):
  18. def _job_func():
  19. self._run_commands()
  20. super().__init__("Android Project Generator", _job_func)
  21. self._config = config
  22. o3de_cmd = config.get_o3de_cmd()
  23. self._sdk_root_configure_cmd = SubprocessRunner(
  24. [
  25. o3de_cmd,
  26. "android-configure",
  27. "--set-value",
  28. f"sdk.root={config.android_sdk_path}",
  29. "--project",
  30. config.project_path,
  31. ],
  32. timeOutSeconds=10,
  33. )
  34. self._api_level_configure_cmd = SubprocessRunner(
  35. [
  36. o3de_cmd,
  37. "android-configure",
  38. "--set-value",
  39. f"platform.sdk.api={config.android_sdk_api_level}",
  40. "--project",
  41. config.project_path,
  42. ],
  43. timeOutSeconds=10,
  44. )
  45. self._ndk_configure_cmd = SubprocessRunner(
  46. [
  47. o3de_cmd,
  48. "android-configure",
  49. "--set-value",
  50. f"ndk.version={config.android_ndk_version}",
  51. "--project",
  52. config.project_path,
  53. ],
  54. timeOutSeconds=10,
  55. )
  56. # agp is Android Gradle Plugin. FIXME: Make it a variable.
  57. self._agp_configure_cmd = SubprocessRunner(
  58. [
  59. o3de_cmd,
  60. "android-configure",
  61. "--set-value",
  62. "android.gradle.plugin=8.1.0",
  63. "--project",
  64. config.project_path,
  65. ],
  66. timeOutSeconds=10,
  67. )
  68. self._validate_configuration_cmd = SubprocessRunner(
  69. [
  70. o3de_cmd,
  71. "android-configure",
  72. "--validate",
  73. "--project",
  74. config.project_path,
  75. ],
  76. timeOutSeconds=60
  77. )
  78. arg_list = [
  79. o3de_cmd,
  80. "android-generate",
  81. "-p",
  82. config.get_project_name(),
  83. "-B",
  84. config.get_android_build_dir(),
  85. "--asset-mode",
  86. config.asset_mode,
  87. ]
  88. if config.is_meta_quest_project:
  89. arg_list.extend(["--oculus-project"])
  90. self._generate_project_cmd = SubprocessRunner(
  91. arg_list,
  92. timeOutSeconds=60,
  93. # The "android-generate" subcommand requires to be run from the project root directory,
  94. # otherwise it won't find the settings we previously defined with the multiple calls
  95. # to "android-configure" subcommand.
  96. cwd=config.project_path
  97. )
  98. def _run_commands(self):
  99. """
  100. This is a "protected" function. It is invoked when super().start() is called.
  101. """
  102. if self._is_cancelled:
  103. self._is_finished = True
  104. self._is_success = False
  105. return
  106. commands = [
  107. self._sdk_root_configure_cmd,
  108. self._api_level_configure_cmd,
  109. self._ndk_configure_cmd,
  110. self._agp_configure_cmd,
  111. self._validate_configuration_cmd,
  112. self._generate_project_cmd,
  113. ]
  114. for command in commands:
  115. if self._is_cancelled:
  116. self._is_finished = True
  117. self._is_success = False
  118. return
  119. if not command.run():
  120. self._record_command_error(command)
  121. return
  122. else:
  123. self._record_command_results(command)
  124. self._is_finished = True
  125. self._is_success = True
  126. self._report_msg += f"Next Steps:\nYou can compile, deploy and execute the android application with Android Studio by opening the project:\n{self._config.get_android_build_dir()}.\n"
  127. self._report_msg += "Alternatively, you can compile the project from the command line with the following commands:\n"
  128. self._report_msg += f"$ cd {self._config.get_android_build_dir()}\n$ .\\gradlew assembleProfile\nOr if interested in compiling for debugging:\n$ .\\gradlew assembleDebug\n"
  129. def _record_command_error(self, command: SubprocessRunner):
  130. self._is_finished = True
  131. self._is_success = False
  132. self._record_command_results(command)
  133. def _record_command_results(self, command: SubprocessRunner):
  134. self._report_msg += f"Command:\n{command.get_command_str()}\nCompleted with status code {command.get_error_code()}.\n"
  135. self._report_msg += command.get_stdall()
  136. # class ProjectGenerator END
  137. ######################################################