Browse Source

AGP accepts extras CMake arguments (#18586)

The Android Project Generator UI can now pass additional
CMake extra arguments for configuration. For example:
```
-DMYGEN_ENABLE=ON -DMY_ANDROID_VAR=OFF
```

Signed-off-by: galibzon <[email protected]>
galibzon 7 months ago
parent
commit
a16c67a735

+ 5 - 0
Code/Tools/Android/ProjectGenerator/config_data.py

@@ -31,6 +31,9 @@ class ConfigData:
         self.android_sdk_api_level = self.DEFAULT_API_LEVEL
         self.asset_mode = self.ASSET_MODE_LOOSE
         self.is_meta_quest_project = False
+        # When non-empty, looks like a series of space separated strings like
+        # "-DENABLE_MY_LIB=ON -DENABLE_ANOTHER_GEM=OFF"
+        self.extra_cmake_args = ""
 
 
     def as_dictionary(self) -> dict:
@@ -40,6 +43,7 @@ class ConfigData:
               "android_sdk_api_level" : self.android_sdk_api_level,
               "asset_mode":  self.asset_mode,
               "is_meta_quest_project": self.is_meta_quest_project,
+              "extra_cmake_args": self.extra_cmake_args,
               }
         return d
 
@@ -54,6 +58,7 @@ class ConfigData:
         self.android_sdk_api_level = d.get("android_sdk_api_level", self.DEFAULT_API_LEVEL)
         self.asset_mode = d.get("asset_mode", self.ASSET_MODE_LOOSE)
         self.is_meta_quest_project = d.get("is_meta_quest_project", False)
+        self.extra_cmake_args = d.get("extra_cmake_args", "")
 
 
     def save_to_json_file(self, filePath: str) -> bool:

+ 14 - 0
Code/Tools/Android/ProjectGenerator/main.py

@@ -48,6 +48,7 @@ class TkApp(tk.Tk):
         self._init_load_save_ui()
         self._init_keystore_settings_ui()
         self._init_sdk_settings_ui()
+        self._init_additional_build_settings_ui()
 
         # Add the project generation button.
         btn = tk.Button(self, text="Generate Project", command=self.on_generate_project_button)
@@ -135,6 +136,17 @@ class TkApp(tk.Tk):
         # Add the meta quest project checkbox
         self._android_quest_flag_var, _, row_number = self._add_checkbox(sdk_frame, "This is a Meta Quest project", cf.is_meta_quest_project)
 
+    
+    def _init_additional_build_settings_ui(self):
+        build_settings_frame = tk.LabelFrame(self, text="Additional Build Settings")
+        build_settings_frame.columnconfigure(0, weight=0)
+        build_settings_frame.columnconfigure(1, weight=1)
+        build_settings_frame.grid(padx=self._frame_pad_x, pady=self._frame_pad_y,sticky=tk.EW)
+
+        cf = self._config
+        self._extra_cmake_args_var = self._add_label_entry(build_settings_frame, "Extra CMake Arguments", cf.extra_cmake_args, entry_colspan=3, label_width=28)[0]
+
+
 
     def _add_label_entry(self, parent_frame: tk.Frame, lbl_name: str, default_value: str = "", entry_colspan=1, label_width=None, entry_read_only=False) -> tuple[tk.StringVar, tk.Entry, int]:
         """
@@ -244,6 +256,7 @@ class TkApp(tk.Tk):
         config.android_ndk_version = self._android_ndk_version_var.get()
         config.android_sdk_api_level = self._android_sdk_api_level_var.get()
         config.is_meta_quest_project = self._android_quest_flag_var.get()
+        config.extra_cmake_args = self._extra_cmake_args_var.get()
         config.keystore_settings = self.create_keystore_settings_from_widgets()
         return config
 
@@ -266,6 +279,7 @@ class TkApp(tk.Tk):
         self._android_ndk_version_var.set(config.android_ndk_version)
         self._android_sdk_api_level_var.set(config.android_sdk_api_level)
         self._android_quest_flag_var.set(config.is_meta_quest_project)
+        self._extra_cmake_args_var.set(config.extra_cmake_args)
         self.update_widgets_from_keystore_settings(config.keystore_settings)
 
 

+ 4 - 0
Code/Tools/Android/ProjectGenerator/project_generator.py

@@ -93,6 +93,10 @@ class ProjectGenerator(ThreadedLambda):
             ]
         if config.is_meta_quest_project:
             arg_list.extend(["--oculus-project"])
+        if config.extra_cmake_args:
+            # It is imperative to wrap the extra cmake arguments in double quotes "-DFOO=ON -DBAR=OFF"
+            # because the cmake arguments/variables are separated by spaces.
+            arg_list.extend(["--extra-cmake-args", f'"{config.extra_cmake_args}"'])
         self._generate_project_cmd = SubprocessRunner(
             arg_list,
             timeOutSeconds=60,

+ 6 - 1
scripts/o3de/o3de/android_support.py

@@ -1637,8 +1637,13 @@ class AndroidProjectGenerator(object):
                 cmake_argument_list.append(f'"-DLY_PROJECTS={template_project_path}"')
 
             if self._extra_cmake_configure_args:
+                # Extra cmake configure arguments are passed in as a single string separated by spaces and wrapped in quotes.
+                # We need to remove the quotes from the beginning and end of the string, and then split the string by spaces.
+                extra_cmake_args = self._extra_cmake_configure_args
+                if extra_cmake_args.startswith('"') and extra_cmake_args.endswith('"'):
+                    extra_cmake_args = extra_cmake_args[1:-1]
                 # Splits the arguments by white space but only if it's not in a quoted string (e.g. when specifiying a path with white spaces)
-                extra_cmake_configure_arg_list = [f'"{arg}"' for arg in re.split('''\s(?=(?:[^'"]|'[^']*'|"[^"]*")*$)''', self._extra_cmake_configure_args)]
+                extra_cmake_configure_arg_list = [f'"{arg}"' for arg in re.split('''\s(?=(?:[^'"]|'[^']*'|"[^"]*")*$)''', extra_cmake_args)]
                 cmake_argument_list.extend(extra_cmake_configure_arg_list)
 
             # Prepare the config-specific section to place the cmake argument list in the build.gradle for the app