فهرست منبع

Generate CMake load dependencies for gem json dependencies (#15937)

* Added `o3de_add_variant_dependencies_for_gem_dependencies` cmake function

The `o3de_add_variant_dependencies_for_gem_dependencies` function will
add CMake TARGET dependencies for a specified Gem and a set of Gem variants.
For each Gem variant specified a check for a TARGET of `${gem_name}.${variant}` will occur on the gem.
If such a TARGET exists, then each of the specified Gem's dependent gems
listed in its gem.json `"dependencies"` field will have the
corresponding `${dependency}.${variant}` TARGET added as a dependency.

For example in the MultiplayerSample project, there is a
[MPSGameLift](https://github.com/o3de/o3de-multiplayersample/blob/development/MPSGameLift/gem.json) gem that has a dependency on the [AWSGameLift](https://github.com/o3de/o3de-multiplayersample/blob/development/MPSGameLift/gem.json#L23) gem.

If the desire for the MPSGameLift gem when active to to have the AWSGameLift gem be
added as a load dependency automatically for the Gem Variants of
`Clients`, `Servers` and `Unified`, then the MPSGameLift gem can use the
`o3de_add_variant_dependencies_for_gem_dependencies` function to add
the following dependencies
```
MPSGameLift.Clients -> AWSGameLift.Clients
MPSGameLift.Servers -> AWSGameLift.Servers
MPSGameLift.Unified -> AWSGameLift.Unified
```

This would cause the `cmake_dependencies.multiplayersample.<launcher>.setreg` files to add both MPSGameLift shared libraries and AWSGameLift shared libraries to the list of gems to load.

Signed-off-by: lumberyard-employee-dm <[email protected]>

* Removed circular dependency between the AtomBridge and
EditorModeFeedback gems

Signed-off-by: lumberyard-employee-dm <[email protected]>

* Updating the "CommonFeaturesAtom" gem to have alias targets of the form
"CommonFeaturesAtom.${variant}"

Signed-off-by: lumberyard-employee-dm <[email protected]>

* Replaced Gem module from o3de CMake targets BUILD_DEPENDENCIES

BUILD_DEPENDENCIES have been replaced with either the Gems's .API target
or .Static target.
CMake MODULE targets can't actually be added as dependencies of other
targets. The `ly_add_target` function actually detects if a dependent
target is a MODULE then extracts  the MODULE target link_library,
compile_definitions, compile_options and include_directories from the
CMake target properties and adds them to the target being added

Signed-off-by: lumberyard-employee-dm <[email protected]>

* Updated the Project and Gem Templates with `o3de_add_variants_dependencies_to_gem_dependencies`

This means that new Gems created from these templates will run as
dependencies to each Gem of it's Gem variant target such as
${gem_name}.Clients, ${gem_name}.Tools the corresponding Gem variant
target for any dependent gem listed in the gem.json "dependencies"
field.

Signed-off-by: lumberyard-employee-dm <[email protected]>

* Updated the NvCloth to use the `o3de_add_variants_for_gem_dependencies`
as the initial case for validating its functionality

Also updated the NvCloth CMakeLists.txt to use the `${gem_name}`
variable when referencing the gem in CMake to simplify renaming the gem
in the future.

Signed-off-by: lumberyard-employee-dm <[email protected]>

* Added missing registration of the GraphicsGem template

Signed-off-by: lumberyard-employee-dm <[email protected]>

---------

Signed-off-by: lumberyard-employee-dm <[email protected]>
lumberyard-employee-dm 2 سال پیش
والد
کامیت
66bf149a75
32فایلهای تغییر یافته به همراه393 افزوده شده و 155 حذف شده
  1. 1 3
      Code/Editor/CMakeLists.txt
  2. 0 1
      Gems/Atom/Tools/PassCanvas/Code/CMakeLists.txt
  3. 0 1
      Gems/AtomLyIntegration/AtomBridge/Code/CMakeLists.txt
  4. 5 0
      Gems/AtomLyIntegration/AtomViewportDisplayInfo/Code/CMakeLists.txt
  5. 13 1
      Gems/AtomLyIntegration/CommonFeatures/CMakeLists.txt
  6. 26 4
      Gems/AtomLyIntegration/CommonFeatures/Code/CMakeLists.txt
  7. 3 1
      Gems/AtomLyIntegration/EditorModeFeedback/Code/CMakeLists.txt
  8. 1 2
      Gems/AtomLyIntegration/EditorModeFeedback/gem.json
  9. 2 2
      Gems/DiffuseProbeGrid/Code/CMakeLists.txt
  10. 2 4
      Gems/GradientSignal/Code/CMakeLists.txt
  11. 10 13
      Gems/LyShine/Code/CMakeLists.txt
  12. 11 1
      Gems/NvCloth/CMakeLists.txt
  13. 29 26
      Gems/NvCloth/Code/CMakeLists.txt
  14. 3 5
      Gems/PhysX/Code/CMakeLists.txt
  15. 2 2
      Gems/SurfaceData/Code/CMakeLists.txt
  16. 7 7
      Gems/Terrain/Code/CMakeLists.txt
  17. 2 4
      Gems/Vegetation/Code/CMakeLists.txt
  18. 5 1
      Templates/AssetGem/Template/CMakeLists.txt
  19. 8 0
      Templates/CppToolGem/Template/Code/CMakeLists.txt
  20. 7 0
      Templates/DefaultGem/Template/Code/CMakeLists.txt
  21. 4 0
      Templates/DefaultProject/Template/Gem/CMakeLists.txt
  22. 10 2
      Templates/GraphicsGem/Template/Code/CMakeLists.txt
  23. 4 0
      Templates/MinimalProject/Template/Gem/CMakeLists.txt
  24. 8 0
      Templates/PrebuiltGem/Template/Code/CMakeLists.txt
  25. 4 0
      Templates/PythonToolGem/Template/Code/CMakeLists.txt
  26. 8 0
      Templates/UnifiedMultiplayerGem/Template/Code/CMakeLists.txt
  27. 80 8
      cmake/Gems.cmake
  28. 1 1
      cmake/O3DEJson.cmake
  29. 23 0
      cmake/Platform/Common/Install_common.cmake
  30. 16 7
      cmake/Projects.cmake
  31. 95 59
      cmake/SettingsRegistry.cmake
  32. 3 0
      engine.json

+ 1 - 3
Code/Editor/CMakeLists.txt

@@ -114,14 +114,12 @@ ly_add_target(
             Gem::Atom_Feature_Common.Static
             Gem::Atom_Feature_Common.Static
             Gem::AtomToolsFramework.Static
             Gem::AtomToolsFramework.Static
             Gem::AtomViewportDisplayInfo
             Gem::AtomViewportDisplayInfo
-            Gem::EditorModeFeedback.Editor
+            Gem::EditorModeFeedback.Editor.Static
             ${additional_dependencies}
             ${additional_dependencies}
         PUBLIC
         PUBLIC
             3rdParty::Qt::Network
             3rdParty::Qt::Network
             Legacy::EditorCore
             Legacy::EditorCore
     RUNTIME_DEPENDENCIES
     RUNTIME_DEPENDENCIES
-        Gem::AtomViewportDisplayInfo
-        Gem::EditorModeFeedback.Editor
         Legacy::EditorCommon
         Legacy::EditorCommon
 )
 )
 ly_add_source_properties(
 ly_add_source_properties(

+ 0 - 1
Gems/Atom/Tools/PassCanvas/Code/CMakeLists.txt

@@ -38,7 +38,6 @@ ly_add_target(
     BUILD_DEPENDENCIES
     BUILD_DEPENDENCIES
         PRIVATE
         PRIVATE
             Gem::AtomLyIntegration_CommonFeatures.Static
             Gem::AtomLyIntegration_CommonFeatures.Static
-            Gem::AtomToolsFramework.Editor
             Gem::AtomToolsFramework.Static
             Gem::AtomToolsFramework.Static
     RUNTIME_DEPENDENCIES
     RUNTIME_DEPENDENCIES
         Gem::AtomToolsFramework.Editor
         Gem::AtomToolsFramework.Editor

+ 0 - 1
Gems/AtomLyIntegration/AtomBridge/Code/CMakeLists.txt

@@ -121,7 +121,6 @@ if(PAL_TRAIT_BUILD_HOST_TOOLS)
             Gem::MaterialEditor.Builders
             Gem::MaterialEditor.Builders
             Gem::PassCanvas.Builders
             Gem::PassCanvas.Builders
             Gem::ShaderManagementConsole.Builders
             Gem::ShaderManagementConsole.Builders
-            Gem::EditorModeFeedback.Editor
     )
     )
 
 
 
 

+ 5 - 0
Gems/AtomLyIntegration/AtomViewportDisplayInfo/Code/CMakeLists.txt

@@ -25,6 +25,11 @@ ly_add_target(
             Gem::Atom_RPI.Public
             Gem::Atom_RPI.Public
 )
 )
 
 
+ly_create_alias(NAME AtomViewportDisplayInfo.Clients NAMESPACE Gem TARGETS Gem::AtomViewportDisplayInfo)
+ly_create_alias(NAME AtomViewportDisplayInfo.Tools NAMESPACE Gem TARGETS Gem::AtomViewportDisplayInfo)
+ly_create_alias(NAME AtomViewportDisplayInfo.Servers NAMESPACE Gem TARGETS Gem::AtomViewportDisplayInfo)
+ly_create_alias(NAME AtomViewportDisplayInfo.Unified NAMESPACE Gem TARGETS Gem::AtomViewportDisplayInfo)
+
 ################################################################################
 ################################################################################
 # Tests
 # Tests
 ################################################################################
 ################################################################################

+ 13 - 1
Gems/AtomLyIntegration/CommonFeatures/CMakeLists.txt

@@ -6,8 +6,20 @@
 #
 #
 #
 #
 
 
-set(gem_path ${CMAKE_CURRENT_LIST_DIR})
+o3de_find_ancestor_gem_root(gem_path gem_name "${CMAKE_CURRENT_SOURCE_DIR}")
+if (NOT gem_name)
+    set(gem_name "CommonFeaturesAtom")
+endif()
+
+# Fallback to using the current source CMakeLists.txt directory as the gem root path
+if (NOT gem_path)
+    set(gem_path ${CMAKE_CURRENT_SOURCE_DIR})
+endif()
+
 set(gem_json ${gem_path}/gem.json)
 set(gem_json ${gem_path}/gem.json)
+
 o3de_restricted_path(${gem_json} gem_restricted_path gem_parent_relative_path)
 o3de_restricted_path(${gem_json} gem_restricted_path gem_parent_relative_path)
 
 
+o3de_pal_dir(pal_dir ${CMAKE_CURRENT_SOURCE_DIR}/Platform/${PAL_PLATFORM_NAME} "${gem_restricted_path}" "${gem_path}" "${gem_parent_relative_path}")
+
 add_subdirectory(Code)
 add_subdirectory(Code)

+ 26 - 4
Gems/AtomLyIntegration/CommonFeatures/Code/CMakeLists.txt

@@ -61,7 +61,6 @@ ly_add_target(
             Gem::AtomLyIntegration_CommonFeatures.Static
             Gem::AtomLyIntegration_CommonFeatures.Static
     RUNTIME_DEPENDENCIES
     RUNTIME_DEPENDENCIES
         Gem::Atom_RPI.Private
         Gem::Atom_RPI.Private
-        Gem::Atom_Feature_Common
 )
 )
 
 
 # The AtomLyIntegration_CommonFeatures module is used for Clients and Servers
 # The AtomLyIntegration_CommonFeatures module is used for Clients and Servers
@@ -81,6 +80,21 @@ ly_create_alias(NAME AtomLyIntegration_CommonFeatures.Unified NAMESPACE Gem
         Gem::GradientSignal.Unified
         Gem::GradientSignal.Unified
 )
 )
 
 
+# Add aliases that references the real name of the gem "CommonFeaturesAtom"
+# that reference the names Gem variants of "AtomLyIntegration_CommonFeatures"
+ly_create_alias(NAME ${gem_name}.Clients NAMESPACE Gem
+    TARGETS
+        Gem::AtomLyIntegration_CommonFeatures.Clients
+)
+ly_create_alias(NAME ${gem_name}.Servers NAMESPACE Gem
+    TARGETS
+        Gem::AtomLyIntegration_CommonFeatures.Servers
+)
+ly_create_alias(NAME ${gem_name}.Unified NAMESPACE Gem
+    TARGETS
+        Gem::AtomLyIntegration_CommonFeatures.Unified
+)
+
 if(PAL_TRAIT_BUILD_HOST_TOOLS)
 if(PAL_TRAIT_BUILD_HOST_TOOLS)
     ly_add_target(
     ly_add_target(
         NAME AtomLyIntegration_CommonFeatures.Editor.Static STATIC
         NAME AtomLyIntegration_CommonFeatures.Editor.Static STATIC
@@ -135,9 +149,6 @@ if(PAL_TRAIT_BUILD_HOST_TOOLS)
             PRIVATE
             PRIVATE
                 Gem::AtomLyIntegration_CommonFeatures.Editor.Static
                 Gem::AtomLyIntegration_CommonFeatures.Editor.Static
         RUNTIME_DEPENDENCIES
         RUNTIME_DEPENDENCIES
-            Gem::Atom_RPI.Editor
-            Gem::Atom_Feature_Common.Editor
-            Gem::AtomToolsFramework.Editor
             Legacy::EditorCommon
             Legacy::EditorCommon
     )
     )
 
 
@@ -155,6 +166,17 @@ if(PAL_TRAIT_BUILD_HOST_TOOLS)
             Gem::GradientSignal.Tools
             Gem::GradientSignal.Tools
     )
     )
 
 
+    # Add aliases that references the real name of the gem "CommonFeaturesAtom"
+    # Tools and Builders variants
+    ly_create_alias(NAME ${gem_name}.Builders NAMESPACE Gem
+        TARGETS
+            Gem::AtomLyIntegration_CommonFeatures.Builders
+    )
+    ly_create_alias(NAME ${gem_name}.Tools NAMESPACE Gem
+        TARGETS
+            Gem::AtomLyIntegration_CommonFeatures.Tools
+    )
+
     ################################################################################
     ################################################################################
     # Tests
     # Tests
     ################################################################################
     ################################################################################

+ 3 - 1
Gems/AtomLyIntegration/EditorModeFeedback/Code/CMakeLists.txt

@@ -23,7 +23,6 @@ if(PAL_TRAIT_BUILD_HOST_TOOLS)
                 Gem::Atom_RPI.Public
                 Gem::Atom_RPI.Public
                 Gem::Atom_Feature_Common.Static
                 Gem::Atom_Feature_Common.Static
                 Gem::AtomLyIntegration_CommonFeatures.Static
                 Gem::AtomLyIntegration_CommonFeatures.Static
-            PRIVATE
     )
     )
 
 
     ly_add_target(
     ly_add_target(
@@ -41,4 +40,7 @@ if(PAL_TRAIT_BUILD_HOST_TOOLS)
             PRIVATE
             PRIVATE
                 Gem::EditorModeFeedback.Editor.Static
                 Gem::EditorModeFeedback.Editor.Static
     )
     )
+
+    ly_create_alias(NAME EditorModeFeedback.Tools NAMESPACE Gem TARGETS Gem::EditorModeFeedback.Editor)
+    ly_create_alias(NAME EditorModeFeedback.Builders NAMESPACE Gem TARGETS Gem::EditorModeFeedback.Editor)
 endif()
 endif()

+ 1 - 2
Gems/AtomLyIntegration/EditorModeFeedback/gem.json

@@ -15,10 +15,9 @@
     "requirements": "",
     "requirements": "",
     "documentation_url": "",
     "documentation_url": "",
     "dependencies": [
     "dependencies": [
-        "Atom",
         "Atom_Feature_Common",
         "Atom_Feature_Common",
         "Atom_RPI",
         "Atom_RPI",
         "Atom_RHI",
         "Atom_RHI",
-        "Atom_Bootstrap"
+        "CommonFeaturesAtom"
     ]
     ]
 }
 }

+ 2 - 2
Gems/DiffuseProbeGrid/Code/CMakeLists.txt

@@ -45,7 +45,7 @@ ly_add_target(
     BUILD_DEPENDENCIES
     BUILD_DEPENDENCIES
         PRIVATE
         PRIVATE
             Gem::DiffuseProbeGrid.Static
             Gem::DiffuseProbeGrid.Static
-            Gem::LmbrCentral
+            Gem::LmbrCentral.API
     RUNTIME_DEPENDENCIES
     RUNTIME_DEPENDENCIES
         Gem::LmbrCentral
         Gem::LmbrCentral
 )
 )
@@ -81,4 +81,4 @@ if(PAL_TRAIT_BUILD_HOST_TOOLS)
 
 
     ly_create_alias(NAME DiffuseProbeGrid.Builders NAMESPACE Gem TARGETS Gem::DiffuseProbeGrid.Editor)
     ly_create_alias(NAME DiffuseProbeGrid.Builders NAMESPACE Gem TARGETS Gem::DiffuseProbeGrid.Editor)
     ly_create_alias(NAME DiffuseProbeGrid.Tools    NAMESPACE Gem TARGETS Gem::DiffuseProbeGrid.Editor)
     ly_create_alias(NAME DiffuseProbeGrid.Tools    NAMESPACE Gem TARGETS Gem::DiffuseProbeGrid.Editor)
-endif()
+endif()

+ 2 - 4
Gems/GradientSignal/Code/CMakeLists.txt

@@ -40,7 +40,7 @@ ly_add_target(
             Include
             Include
     BUILD_DEPENDENCIES
     BUILD_DEPENDENCIES
         PRIVATE
         PRIVATE
-            Gem::LmbrCentral
+            Gem::LmbrCentral.API
         PUBLIC
         PUBLIC
             AZ::AzCore
             AZ::AzCore
             Gem::GradientSignal.Static
             Gem::GradientSignal.Static
@@ -85,8 +85,7 @@ if(PAL_TRAIT_BUILD_HOST_TOOLS)
                 AZ::AssetBuilderSDK
                 AZ::AssetBuilderSDK
                 Gem::GradientSignal.Static
                 Gem::GradientSignal.Static
                 Gem::SurfaceData
                 Gem::SurfaceData
-        RUNTIME_DEPENDENCIES
-            Gem::LmbrCentral.Editor
+                Gem::LmbrCentral.Editor.Static
     )
     )
 
 
     ly_add_target(
     ly_add_target(
@@ -102,7 +101,6 @@ if(PAL_TRAIT_BUILD_HOST_TOOLS)
         BUILD_DEPENDENCIES
         BUILD_DEPENDENCIES
             PRIVATE
             PRIVATE
                 Gem::GradientSignal.Editor.Static
                 Gem::GradientSignal.Editor.Static
-                Gem::LmbrCentral.Editor
         RUNTIME_DEPENDENCIES
         RUNTIME_DEPENDENCIES
             Gem::LmbrCentral.Editor
             Gem::LmbrCentral.Editor
     )
     )

+ 10 - 13
Gems/LyShine/Code/CMakeLists.txt

@@ -47,7 +47,7 @@ ly_add_target(
         PRIVATE
         PRIVATE
             Gem::LyShine.Static
             Gem::LyShine.Static
             Legacy::CryCommon
             Legacy::CryCommon
-            Gem::LmbrCentral
+            Gem::LmbrCentral.API
         PUBLIC
         PUBLIC
             Gem::Atom_RHI.Reflect
             Gem::Atom_RHI.Reflect
             Gem::Atom_RPI.Public
             Gem::Atom_RPI.Public
@@ -91,18 +91,15 @@ if (PAL_TRAIT_BUILD_HOST_TOOLS)
                 Legacy::EditorCore
                 Legacy::EditorCore
                 Gem::LyShine.Static
                 Gem::LyShine.Static
                 Legacy::CryCommon
                 Legacy::CryCommon
-                Gem::LmbrCentral.Editor
-                Gem::TextureAtlas.Editor
+                Gem::LmbrCentral.Editor.Static
+                Gem::TextureAtlas.Static
                 Gem::AtomToolsFramework.Static
                 Gem::AtomToolsFramework.Static
-                Gem::AtomToolsFramework.Editor
                 ${additional_dependencies}
                 ${additional_dependencies}
             PUBLIC
             PUBLIC
                 Gem::Atom_RPI.Public
                 Gem::Atom_RPI.Public
                 Gem::Atom_Utils.Static
                 Gem::Atom_Utils.Static
                 Gem::AtomLyIntegration_CommonFeatures.Static
                 Gem::AtomLyIntegration_CommonFeatures.Static
                 Gem::Atom_Bootstrap.Headers
                 Gem::Atom_Bootstrap.Headers
-        RUNTIME_DEPENDENCIES
-            Gem::TextureAtlas.Editor
     )
     )
 
 
     ly_add_target(
     ly_add_target(
@@ -124,8 +121,8 @@ if (PAL_TRAIT_BUILD_HOST_TOOLS)
                 Legacy::CryCommon
                 Legacy::CryCommon
                 AZ::AzToolsFramework
                 AZ::AzToolsFramework
                 Gem::LyShine.Tools.Static
                 Gem::LyShine.Tools.Static
-                Gem::LmbrCentral.Editor
-                Gem::TextureAtlas.Editor
+                Gem::LmbrCentral.Editor.Static
+                Gem::TextureAtlas.Static
         RUNTIME_DEPENDENCIES
         RUNTIME_DEPENDENCIES
             Gem::LmbrCentral.Editor
             Gem::LmbrCentral.Editor
             Gem::TextureAtlas.Editor
             Gem::TextureAtlas.Editor
@@ -184,8 +181,8 @@ if (PAL_TRAIT_BUILD_HOST_TOOLS)
                 Legacy::CryCommon
                 Legacy::CryCommon
                 AZ::AssetBuilderSDK
                 AZ::AssetBuilderSDK
                 Gem::LyShine.Builders.Static
                 Gem::LyShine.Builders.Static
-                Gem::LmbrCentral.Editor
-                Gem::TextureAtlas.Editor
+                Gem::LmbrCentral.Editor.Static
+                Gem::TextureAtlas.Static
         RUNTIME_DEPENDENCIES
         RUNTIME_DEPENDENCIES
             Gem::UiBasics.Builders
             Gem::UiBasics.Builders
     )
     )
@@ -214,7 +211,7 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED)
                 AZ::AzTest
                 AZ::AzTest
                 Gem::LyShine.Static
                 Gem::LyShine.Static
                 Legacy::CryCommon
                 Legacy::CryCommon
-                Gem::LmbrCentral
+                Gem::LmbrCentral.API
         RUNTIME_DEPENDENCIES
         RUNTIME_DEPENDENCIES
             Gem::LmbrCentral
             Gem::LmbrCentral
             Gem::TextureAtlas
             Gem::TextureAtlas
@@ -251,8 +248,8 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED)
                     AZ::AzToolsFrameworkTestCommon
                     AZ::AzToolsFrameworkTestCommon
                     Gem::LyShine.Tools.Static
                     Gem::LyShine.Tools.Static
                     Gem::LyShine.Builders.Static
                     Gem::LyShine.Builders.Static
-                    Gem::LmbrCentral.Editor
-                    Gem::TextureAtlas
+                    Gem::LmbrCentral.Editor.Static
+                    Gem::TextureAtlas.Static
             RUNTIME_DEPENDENCIES
             RUNTIME_DEPENDENCIES
                 Gem::LmbrCentral.Editor
                 Gem::LmbrCentral.Editor
                 Gem::TextureAtlas.Editor
                 Gem::TextureAtlas.Editor

+ 11 - 1
Gems/NvCloth/CMakeLists.txt

@@ -6,8 +6,18 @@
 #
 #
 #
 #
 
 
-set(gem_path ${CMAKE_CURRENT_LIST_DIR})
+o3de_find_ancestor_gem_root(gem_path gem_name "${CMAKE_CURRENT_SOURCE_DIR}")
+if (NOT gem_name)
+    set(gem_name "NvCloth")
+endif()
+
+# Fallback to using the current source CMakeLists.txt directory as the gem root path
+if (NOT gem_path)
+    set(gem_path ${CMAKE_CURRENT_SOURCE_DIR})
+endif()
+
 set(gem_json ${gem_path}/gem.json)
 set(gem_json ${gem_path}/gem.json)
+
 o3de_restricted_path(${gem_json} gem_restricted_path gem_parent_relative_path)
 o3de_restricted_path(${gem_json} gem_restricted_path gem_parent_relative_path)
 
 
 add_subdirectory(Code)
 add_subdirectory(Code)

+ 29 - 26
Gems/NvCloth/Code/CMakeLists.txt

@@ -16,7 +16,7 @@ if(PAL_TRAIT_NVCLOTH_USE_STUB)
 endif()
 endif()
 
 
 ly_add_target(
 ly_add_target(
-    NAME NvCloth.Static STATIC
+    NAME ${gem_name}.Static STATIC
     NAMESPACE Gem
     NAMESPACE Gem
     FILES_CMAKE
     FILES_CMAKE
         nvcloth_files.cmake
         nvcloth_files.cmake
@@ -34,9 +34,9 @@ ly_add_target(
 )
 )
 
 
 ly_add_target(
 ly_add_target(
-    NAME NvCloth ${PAL_TRAIT_MONOLITHIC_DRIVEN_MODULE_TYPE}
+    NAME ${gem_name} ${PAL_TRAIT_MONOLITHIC_DRIVEN_MODULE_TYPE}
     NAMESPACE Gem
     NAMESPACE Gem
-    OUTPUT_NAME NvCloth.Gem
+    OUTPUT_NAME ${gem_name}.Gem
     FILES_CMAKE
     FILES_CMAKE
         nvcloth_shared_files.cmake
         nvcloth_shared_files.cmake
     INCLUDE_DIRECTORIES
     INCLUDE_DIRECTORIES
@@ -48,19 +48,21 @@ ly_add_target(
         PUBLIC
         PUBLIC
             AZ::AzCore
             AZ::AzCore
         PRIVATE
         PRIVATE
-            Gem::NvCloth.Static
-    RUNTIME_DEPENDENCIES
-        Gem::AtomLyIntegration_CommonFeatures
+            Gem::${gem_name}.Static
 )
 )
 
 
 # use the NvCloth module in clients and servers:
 # use the NvCloth module in clients and servers:
-ly_create_alias(NAME NvCloth.Clients NAMESPACE Gem TARGETS Gem::NvCloth)
-ly_create_alias(NAME NvCloth.Servers NAMESPACE Gem TARGETS Gem::NvCloth)
-ly_create_alias(NAME NvCloth.Unified NAMESPACE Gem TARGETS Gem::NvCloth)
+ly_create_alias(NAME ${gem_name}.Clients NAMESPACE Gem TARGETS Gem::${gem_name})
+ly_create_alias(NAME ${gem_name}.Servers NAMESPACE Gem TARGETS Gem::${gem_name})
+ly_create_alias(NAME ${gem_name}.Unified NAMESPACE Gem TARGETS Gem::${gem_name})
+
+# Add each "dependencies" entry from the NvCloth gem.json as a dependency to the
+# NvCloth Clients, Servers and Unified targets
+o3de_add_variant_dependencies_for_gem_dependencies(GEM_NAME ${gem_name} VARIANTS Clients Servers Unified)
 
 
 if(PAL_TRAIT_BUILD_HOST_TOOLS)
 if(PAL_TRAIT_BUILD_HOST_TOOLS)
     ly_add_target(
     ly_add_target(
-        NAME NvCloth.Editor.Static STATIC
+        NAME ${gem_name}.Editor.Static STATIC
         NAMESPACE Gem
         NAMESPACE Gem
         AUTOMOC
         AUTOMOC
         FILES_CMAKE
         FILES_CMAKE
@@ -75,15 +77,15 @@ if(PAL_TRAIT_BUILD_HOST_TOOLS)
                 NVCLOTH_EDITOR
                 NVCLOTH_EDITOR
         BUILD_DEPENDENCIES
         BUILD_DEPENDENCIES
             PUBLIC
             PUBLIC
-                Gem::NvCloth.Static
+                Gem::${gem_name}.Static
                 AZ::AzToolsFramework
                 AZ::AzToolsFramework
                 AZ::SceneCore
                 AZ::SceneCore
     )
     )
 
 
     ly_add_target(
     ly_add_target(
-        NAME NvCloth.Editor GEM_MODULE
+        NAME ${gem_name}.Editor GEM_MODULE
         NAMESPACE Gem
         NAMESPACE Gem
-        OUTPUT_NAME NvCloth.Editor.Gem
+        OUTPUT_NAME ${gem_name}.Editor.Gem
         FILES_CMAKE
         FILES_CMAKE
             nvcloth_editor_shared_files.cmake
             nvcloth_editor_shared_files.cmake
         INCLUDE_DIRECTORIES
         INCLUDE_DIRECTORIES
@@ -95,14 +97,15 @@ if(PAL_TRAIT_BUILD_HOST_TOOLS)
                 NVCLOTH_EDITOR
                 NVCLOTH_EDITOR
         BUILD_DEPENDENCIES
         BUILD_DEPENDENCIES
             PRIVATE
             PRIVATE
-                Gem::NvCloth.Editor.Static
-        RUNTIME_DEPENDENCIES
-            Gem::AtomLyIntegration_CommonFeatures.Editor
+                Gem::${gem_name}.Editor.Static
     )
     )
 
 
     # use the NvCloth.Editor module in dev tools:
     # use the NvCloth.Editor module in dev tools:
-    ly_create_alias(NAME NvCloth.Builders NAMESPACE Gem TARGETS Gem::NvCloth.Editor)
-    ly_create_alias(NAME NvCloth.Tools    NAMESPACE Gem TARGETS Gem::NvCloth.Editor)
+    ly_create_alias(NAME ${gem_name}.Builders NAMESPACE Gem TARGETS Gem::${gem_name}.Editor)
+    ly_create_alias(NAME ${gem_name}.Tools    NAMESPACE Gem TARGETS Gem::${gem_name}.Editor)
+
+    # Add each "dependencies" entry from the NvCloth gem.json as a dependency to the NvCloth Tools and Builders targets
+    o3de_add_variant_dependencies_for_gem_dependencies(GEM_NAME ${gem_name} VARIANTS Tools Builders)
 endif()
 endif()
 
 
 ################################################################################
 ################################################################################
@@ -110,9 +113,9 @@ endif()
 ################################################################################
 ################################################################################
 if(PAL_TRAIT_BUILD_TESTS_SUPPORTED)
 if(PAL_TRAIT_BUILD_TESTS_SUPPORTED)
     ly_add_target(
     ly_add_target(
-        NAME NvCloth.Tests ${PAL_TRAIT_TEST_TARGET_TYPE}
+        NAME ${gem_name}.Tests ${PAL_TRAIT_TEST_TARGET_TYPE}
         NAMESPACE Gem
         NAMESPACE Gem
-        OUTPUT_NAME NvCloth.Tests.Gem
+        OUTPUT_NAME ${gem_name}.Tests.Gem
         FILES_CMAKE
         FILES_CMAKE
             nvcloth_tests_files.cmake
             nvcloth_tests_files.cmake
         INCLUDE_DIRECTORIES
         INCLUDE_DIRECTORIES
@@ -124,22 +127,22 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED)
             PRIVATE
             PRIVATE
                 AZ::AzTestShared
                 AZ::AzTestShared
                 AZ::AzTest
                 AZ::AzTest
-                Gem::NvCloth.Static
+                Gem::${gem_name}.Static
                 Gem::EMotionFXStaticLib
                 Gem::EMotionFXStaticLib
                 Gem::EMotionFX.Tests.Static
                 Gem::EMotionFX.Tests.Static
         RUNTIME_DEPENDENCIES
         RUNTIME_DEPENDENCIES
             Gem::EMotionFX
             Gem::EMotionFX
     )
     )
     ly_add_googletest(
     ly_add_googletest(
-        NAME Gem::NvCloth.Tests
+        NAME Gem::${gem_name}.Tests
         LABELS REQUIRES_tiaf
         LABELS REQUIRES_tiaf
     )
     )
     
     
     if(PAL_TRAIT_BUILD_HOST_TOOLS)
     if(PAL_TRAIT_BUILD_HOST_TOOLS)
         ly_add_target(
         ly_add_target(
-            NAME NvCloth.Editor.Tests ${PAL_TRAIT_TEST_TARGET_TYPE}
+            NAME ${gem_name}.Editor.Tests ${PAL_TRAIT_TEST_TARGET_TYPE}
             NAMESPACE Gem
             NAMESPACE Gem
-            OUTPUT_NAME NvCloth.Editor.Tests.Gem
+            OUTPUT_NAME ${gem_name}.Editor.Tests.Gem
             FILES_CMAKE
             FILES_CMAKE
                 nvcloth_editor_tests_files.cmake
                 nvcloth_editor_tests_files.cmake
             INCLUDE_DIRECTORIES
             INCLUDE_DIRECTORIES
@@ -155,14 +158,14 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED)
                     AZ::AzTestShared
                     AZ::AzTestShared
                     AZ::AzTest
                     AZ::AzTest
                     AZ::AzToolsFrameworkTestCommon
                     AZ::AzToolsFrameworkTestCommon
-                    Gem::NvCloth.Editor.Static
+                    Gem::${gem_name}.Editor.Static
                     Gem::EMotionFX.Editor.Static
                     Gem::EMotionFX.Editor.Static
                     Gem::EMotionFX.Tests.Static
                     Gem::EMotionFX.Tests.Static
             RUNTIME_DEPENDENCIES
             RUNTIME_DEPENDENCIES
                 Gem::EMotionFX.Editor
                 Gem::EMotionFX.Editor
         )
         )
         ly_add_googletest(
         ly_add_googletest(
-            NAME Gem::NvCloth.Editor.Tests
+            NAME Gem::${gem_name}.Editor.Tests
             LABELS REQUIRES_tiaf
             LABELS REQUIRES_tiaf
         )
         )
     endif()
     endif()

+ 3 - 5
Gems/PhysX/Code/CMakeLists.txt

@@ -47,7 +47,7 @@ ly_add_target(
             AZ::AzFramework
             AZ::AzFramework
             Legacy::CryCommon
             Legacy::CryCommon
         PRIVATE
         PRIVATE
-            Gem::LmbrCentral
+            Gem::LmbrCentral.API
 )
 )
 
 
 ly_add_target(
 ly_add_target(
@@ -67,7 +67,7 @@ ly_add_target(
     BUILD_DEPENDENCIES
     BUILD_DEPENDENCIES
         PRIVATE
         PRIVATE
             Gem::PhysX.Static
             Gem::PhysX.Static
-            Gem::LmbrCentral
+            Gem::LmbrCentral.API
     RUNTIME_DEPENDENCIES
     RUNTIME_DEPENDENCIES
         Gem::LmbrCentral
         Gem::LmbrCentral
 )
 )
@@ -140,8 +140,6 @@ if(PAL_TRAIT_BUILD_HOST_TOOLS)
         BUILD_DEPENDENCIES
         BUILD_DEPENDENCIES
             PRIVATE
             PRIVATE
                 Gem::PhysX.Editor.Static
                 Gem::PhysX.Editor.Static
-        RUNTIME_DEPENDENCIES
-            Gem::LmbrCentral.Editor
     )
     )
 
 
     # use the PhysX.Editor module in dev tools:
     # use the PhysX.Editor module in dev tools:
@@ -231,4 +229,4 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED)
             LABELS REQUIRES_tiaf
             LABELS REQUIRES_tiaf
         )
         )
     endif()
     endif()
-endif()
+endif()

+ 2 - 2
Gems/SurfaceData/Code/CMakeLists.txt

@@ -39,7 +39,7 @@ ly_add_target(
     BUILD_DEPENDENCIES
     BUILD_DEPENDENCIES
         PUBLIC
         PUBLIC
             Gem::SurfaceData.Static
             Gem::SurfaceData.Static
-            Gem::LmbrCentral
+            Gem::LmbrCentral.API
     RUNTIME_DEPENDENCIES
     RUNTIME_DEPENDENCIES
         Gem::LmbrCentral
         Gem::LmbrCentral
 )
 )
@@ -69,7 +69,7 @@ if (PAL_TRAIT_BUILD_HOST_TOOLS)
             PRIVATE
             PRIVATE
                 AZ::AzToolsFramework
                 AZ::AzToolsFramework
                 Gem::SurfaceData.Static
                 Gem::SurfaceData.Static
-                Gem::LmbrCentral.Editor
+                Gem::LmbrCentral.Editor.Static
         RUNTIME_DEPENDENCIES
         RUNTIME_DEPENDENCIES
             Gem::LmbrCentral.Editor
             Gem::LmbrCentral.Editor
     )
     )

+ 7 - 7
Gems/Terrain/Code/CMakeLists.txt

@@ -21,11 +21,11 @@ ly_add_target(
             AZ::AzFramework
             AZ::AzFramework
             Gem::Atom_RPI.Public
             Gem::Atom_RPI.Public
             Gem::Atom_Utils.Static
             Gem::Atom_Utils.Static
-            Gem::Atom_Feature_Common
+            Gem::Atom_Feature_Common.Static
             Gem::AtomLyIntegration_CommonFeatures.Static
             Gem::AtomLyIntegration_CommonFeatures.Static
-            Gem::GradientSignal
-            Gem::SurfaceData
-            Gem::LmbrCentral
+            Gem::GradientSignal.Static
+            Gem::SurfaceData.Static
+            Gem::LmbrCentral.API
 )
 )
 
 
 ly_add_target(
 ly_add_target(
@@ -41,7 +41,7 @@ ly_add_target(
     BUILD_DEPENDENCIES
     BUILD_DEPENDENCIES
         PRIVATE
         PRIVATE
             Gem::Terrain.Static
             Gem::Terrain.Static
-            Gem::LmbrCentral
+            Gem::LmbrCentral.API
     RUNTIME_DEPENDENCIES
     RUNTIME_DEPENDENCIES
         Gem::LmbrCentral
         Gem::LmbrCentral
 )
 )
@@ -74,8 +74,8 @@ if(PAL_TRAIT_BUILD_HOST_TOOLS)
                 Gem::GradientSignal.Editor.Static
                 Gem::GradientSignal.Editor.Static
             PUBLIC
             PUBLIC
                 AZ::AzToolsFramework
                 AZ::AzToolsFramework
-                Gem::GradientSignal
-                Gem::LmbrCentral
+                Gem::GradientSignal.Static
+                Gem::LmbrCentral.API
                 Gem::Terrain.Static
                 Gem::Terrain.Static
     )
     )
 
 

+ 2 - 4
Gems/Vegetation/Code/CMakeLists.txt

@@ -22,13 +22,11 @@ ly_add_target(
             Include
             Include
     BUILD_DEPENDENCIES
     BUILD_DEPENDENCIES
         PRIVATE
         PRIVATE
-            Gem::LmbrCentral
-            Gem::SurfaceData
+            Gem::LmbrCentral.API
+            Gem::SurfaceData.Static
             Legacy::CryCommon
             Legacy::CryCommon
         PUBLIC
         PUBLIC
             Gem::AtomLyIntegration_CommonFeatures.Static
             Gem::AtomLyIntegration_CommonFeatures.Static
-    RUNTIME_DEPENDENCIES
-        Gem::GradientSignal
 )
 )
 
 
 ly_add_target(
 ly_add_target(

+ 5 - 1
Templates/AssetGem/Template/CMakeLists.txt

@@ -20,5 +20,9 @@ endif()
 # to see the gem as active
 # to see the gem as active
 if(PAL_TRAIT_BUILD_HOST_TOOLS)
 if(PAL_TRAIT_BUILD_HOST_TOOLS)
     ly_create_alias(NAME ${gem_name}.Builders NAMESPACE Gem)
     ly_create_alias(NAME ${gem_name}.Builders NAMESPACE Gem)
-    ly_create_alias(NAME ${gem_name}.Tool NAMESPACE Gem)
+    ly_create_alias(NAME ${gem_name}.Tools NAMESPACE Gem)
+
+    # Add in CMake dependencies for each gem dependency listed in this gem's gem.json file
+    # for the Tools and Builders gem variants
+    o3de_add_variant_dependencies_for_gem_dependencies(GEM_NAME ${gem_name} VARIANTS Tools Builders)
 endif()
 endif()

+ 8 - 0
Templates/CppToolGem/Template/Code/CMakeLists.txt

@@ -90,6 +90,10 @@ ly_create_alias(NAME ${gem_name}.Clients.API NAMESPACE Gem TARGETS Gem::${gem_na
 ly_create_alias(NAME ${gem_name}.Servers.API NAMESPACE Gem TARGETS Gem::${gem_name}.API)
 ly_create_alias(NAME ${gem_name}.Servers.API NAMESPACE Gem TARGETS Gem::${gem_name}.API)
 ly_create_alias(NAME ${gem_name}.Unified.API NAMESPACE Gem TARGETS Gem::${gem_name}.API)
 ly_create_alias(NAME ${gem_name}.Unified.API NAMESPACE Gem TARGETS Gem::${gem_name}.API)
 
 
+# Add in CMake dependencies for each gem dependency listed in this gem's gem.json file
+# for the Clients, Servers and Unified gem variants
+o3de_add_variant_dependencies_for_gem_dependencies(GEM_NAME ${gem_name} VARIANTS Clients Servers Unified)
+
 # If we are on a host platform, we want to add the host tools targets like the ${gem_name}.Editor MODULE target
 # If we are on a host platform, we want to add the host tools targets like the ${gem_name}.Editor MODULE target
 if(PAL_TRAIT_BUILD_HOST_TOOLS)
 if(PAL_TRAIT_BUILD_HOST_TOOLS)
     # The ${gem_name}.Editor.API target can be used by other gems that want to interact with the ${gem_name}.Editor module
     # The ${gem_name}.Editor.API target can be used by other gems that want to interact with the ${gem_name}.Editor module
@@ -157,6 +161,10 @@ if(PAL_TRAIT_BUILD_HOST_TOOLS)
     ly_create_alias(NAME ${gem_name}.Tools.API NAMESPACE Gem TARGETS Gem::${gem_name}.Editor.API)
     ly_create_alias(NAME ${gem_name}.Tools.API NAMESPACE Gem TARGETS Gem::${gem_name}.Editor.API)
     ly_create_alias(NAME ${gem_name}.Builders.API NAMESPACE Gem TARGETS Gem::${gem_name}.Editor.API)
     ly_create_alias(NAME ${gem_name}.Builders.API NAMESPACE Gem TARGETS Gem::${gem_name}.Editor.API)
 
 
+    # Add in CMake dependencies for each gem dependency listed in this gem's gem.json file
+    # for the Tools and Builders gem variants
+    o3de_add_variant_dependencies_for_gem_dependencies(GEM_NAME ${gem_name} VARIANTS Tools Builders)
+
 endif()
 endif()
 
 
 ################################################################################
 ################################################################################

+ 7 - 0
Templates/DefaultGem/Template/Code/CMakeLists.txt

@@ -90,6 +90,10 @@ ly_create_alias(NAME ${gem_name}.Clients.API NAMESPACE Gem TARGETS Gem::${gem_na
 ly_create_alias(NAME ${gem_name}.Servers.API NAMESPACE Gem TARGETS Gem::${gem_name}.API)
 ly_create_alias(NAME ${gem_name}.Servers.API NAMESPACE Gem TARGETS Gem::${gem_name}.API)
 ly_create_alias(NAME ${gem_name}.Unified.API NAMESPACE Gem TARGETS Gem::${gem_name}.API)
 ly_create_alias(NAME ${gem_name}.Unified.API NAMESPACE Gem TARGETS Gem::${gem_name}.API)
 
 
+# Add in CMake dependencies for each gem dependency listed in this gem's gem.json file
+# for the Clients, Servers, Unified gem variants
+o3de_add_variant_dependencies_for_gem_dependencies(GEM_NAME ${gem_name} VARIANTS Clients Servers Unified)
+
 # If we are on a host platform, we want to add the host tools targets like the ${gem_name}.Editor MODULE target
 # If we are on a host platform, we want to add the host tools targets like the ${gem_name}.Editor MODULE target
 if(PAL_TRAIT_BUILD_HOST_TOOLS)
 if(PAL_TRAIT_BUILD_HOST_TOOLS)
     # The ${gem_name}.Editor.API target can be used by other gems that want to interact with the ${gem_name}.Editor module
     # The ${gem_name}.Editor.API target can be used by other gems that want to interact with the ${gem_name}.Editor module
@@ -155,6 +159,9 @@ if(PAL_TRAIT_BUILD_HOST_TOOLS)
     ly_create_alias(NAME ${gem_name}.Tools.API NAMESPACE Gem TARGETS Gem::${gem_name}.Editor.API)
     ly_create_alias(NAME ${gem_name}.Tools.API NAMESPACE Gem TARGETS Gem::${gem_name}.Editor.API)
     ly_create_alias(NAME ${gem_name}.Builders.API NAMESPACE Gem TARGETS Gem::${gem_name}.Editor.API)
     ly_create_alias(NAME ${gem_name}.Builders.API NAMESPACE Gem TARGETS Gem::${gem_name}.Editor.API)
 
 
+    # Add in CMake dependencies for each gem dependency listed in this gem's gem.json file
+    # for the Tools and Builders gem variants
+    o3de_add_variant_dependencies_for_gem_dependencies(GEM_NAME ${gem_name} VARIANTS Tools Builders)
 endif()
 endif()
 
 
 ################################################################################
 ################################################################################

+ 4 - 0
Templates/DefaultProject/Template/Gem/CMakeLists.txt

@@ -84,6 +84,10 @@ ly_create_alias(NAME ${gem_name}.Clients  NAMESPACE Gem TARGETS Gem::${gem_name}
 ly_create_alias(NAME ${gem_name}.Servers  NAMESPACE Gem TARGETS Gem::${gem_name})
 ly_create_alias(NAME ${gem_name}.Servers  NAMESPACE Gem TARGETS Gem::${gem_name})
 ly_create_alias(NAME ${gem_name}.Unified  NAMESPACE Gem TARGETS Gem::${gem_name})
 ly_create_alias(NAME ${gem_name}.Unified  NAMESPACE Gem TARGETS Gem::${gem_name})
 
 
+# Add in CMake dependencies for each gem dependency listed in this gem's gem.json file
+# for the primary gem variants used in most o3de applications
+o3de_add_variant_dependencies_for_gem_dependencies(GEM_NAME ${gem_name} VARIANTS Builders Tools Clients Servers Unified)
+
 ################################################################################
 ################################################################################
 # Gem dependencies
 # Gem dependencies
 ################################################################################
 ################################################################################

+ 10 - 2
Templates/GraphicsGem/Template/Code/CMakeLists.txt

@@ -98,6 +98,10 @@ ly_create_alias(NAME ${gem_name}.Clients.API NAMESPACE Gem TARGETS Gem::${gem_na
 ly_create_alias(NAME ${gem_name}.Servers.API NAMESPACE Gem TARGETS Gem::${gem_name}.API)
 ly_create_alias(NAME ${gem_name}.Servers.API NAMESPACE Gem TARGETS Gem::${gem_name}.API)
 ly_create_alias(NAME ${gem_name}.Unified.API NAMESPACE Gem TARGETS Gem::${gem_name}.API)
 ly_create_alias(NAME ${gem_name}.Unified.API NAMESPACE Gem TARGETS Gem::${gem_name}.API)
 
 
+# Add in CMake dependencies for each gem dependency listed in this gem's gem.json file
+# for the Clients, Servers and Unified gem variants
+o3de_add_variant_dependencies_for_gem_dependencies(GEM_NAME ${gem_name} VARIANTS Clients Servers Unified)
+
 # If we are on a host platform, we want to add the host tools targets like the ${gem_name}.Editor MODULE target
 # If we are on a host platform, we want to add the host tools targets like the ${gem_name}.Editor MODULE target
 if(PAL_TRAIT_BUILD_HOST_TOOLS)
 if(PAL_TRAIT_BUILD_HOST_TOOLS)
     # The ${gem_name}.Editor.API target can be used by other gems that want to interact with the ${gem_name}.Editor module
     # The ${gem_name}.Editor.API target can be used by other gems that want to interact with the ${gem_name}.Editor module
@@ -134,8 +138,8 @@ if(PAL_TRAIT_BUILD_HOST_TOOLS)
                 AZ::AzToolsFramework
                 AZ::AzToolsFramework
                 $<TARGET_OBJECTS:Gem::${gem_name}.Private.Object>
                 $<TARGET_OBJECTS:Gem::${gem_name}.Private.Object>
                 Gem::Atom_Utils.Static
                 Gem::Atom_Utils.Static
-                Gem::Atom_Feature_Common
-                Gem::AtomLyIntegration_CommonFeatures.Static                
+                Gem::Atom_Feature_Common.Static
+                Gem::AtomLyIntegration_CommonFeatures.Static
     )
     )
 
 
     ly_add_target(
     ly_add_target(
@@ -166,6 +170,10 @@ if(PAL_TRAIT_BUILD_HOST_TOOLS)
     ly_create_alias(NAME ${gem_name}.Tools.API NAMESPACE Gem TARGETS Gem::${gem_name}.Editor.API)
     ly_create_alias(NAME ${gem_name}.Tools.API NAMESPACE Gem TARGETS Gem::${gem_name}.Editor.API)
     ly_create_alias(NAME ${gem_name}.Builders.API NAMESPACE Gem TARGETS Gem::${gem_name}.Editor.API)
     ly_create_alias(NAME ${gem_name}.Builders.API NAMESPACE Gem TARGETS Gem::${gem_name}.Editor.API)
 
 
+    # Add in CMake dependencies for each gem dependency listed in this gem's gem.json file
+    # for the Tools and Builders gem variants
+    o3de_add_variant_dependencies_for_gem_dependencies(GEM_NAME ${gem_name} VARIANTS Tools Builders)
+
 endif()
 endif()
 
 
 ################################################################################
 ################################################################################

+ 4 - 0
Templates/MinimalProject/Template/Gem/CMakeLists.txt

@@ -84,6 +84,10 @@ ly_create_alias(NAME ${gem_name}.Clients  NAMESPACE Gem TARGETS Gem::${gem_name}
 ly_create_alias(NAME ${gem_name}.Servers  NAMESPACE Gem TARGETS Gem::${gem_name})
 ly_create_alias(NAME ${gem_name}.Servers  NAMESPACE Gem TARGETS Gem::${gem_name})
 ly_create_alias(NAME ${gem_name}.Unified  NAMESPACE Gem TARGETS Gem::${gem_name})
 ly_create_alias(NAME ${gem_name}.Unified  NAMESPACE Gem TARGETS Gem::${gem_name})
 
 
+# Add in CMake dependencies for each gem dependency listed in this gem's gem.json file
+# for the primary gem variants used in most o3de applications
+o3de_add_variant_dependencies_for_gem_dependencies(GEM_NAME ${gem_name} VARIANTS Builders Tools Clients Servers Unified)
+
 ################################################################################
 ################################################################################
 # Gem dependencies
 # Gem dependencies
 ################################################################################
 ################################################################################

+ 8 - 0
Templates/PrebuiltGem/Template/Code/CMakeLists.txt

@@ -70,6 +70,10 @@ ly_create_alias(NAME ${gem_name}.Clients.API NAMESPACE Gem TARGETS Gem::${gem_na
 ly_create_alias(NAME ${gem_name}.Servers.API NAMESPACE Gem TARGETS Gem::${gem_name}.API)
 ly_create_alias(NAME ${gem_name}.Servers.API NAMESPACE Gem TARGETS Gem::${gem_name}.API)
 ly_create_alias(NAME ${gem_name}.Unified.API NAMESPACE Gem TARGETS Gem::${gem_name}.API)
 ly_create_alias(NAME ${gem_name}.Unified.API NAMESPACE Gem TARGETS Gem::${gem_name}.API)
 
 
+# Add in CMake dependencies for each gem dependency listed in this gem's gem.json file
+# for the Client, Server and Unified gem variants
+o3de_add_variant_dependencies_for_gem_dependencies(GEM_NAME ${gem_name} VARIANTS Client Server Unified)
+
 # If we are on a host platform, we want to add the host tools targets like the ${gem_name}.Tools and ${gem_name}.Builders
 # If we are on a host platform, we want to add the host tools targets like the ${gem_name}.Tools and ${gem_name}.Builders
 if (PAL_TRAIT_BUILD_HOST_TOOLS)
 if (PAL_TRAIT_BUILD_HOST_TOOLS)
     # The ${gem_name}.Tools.API target can be used by other gems that want to interact with the ${gem_name}.Tools module
     # The ${gem_name}.Tools.API target can be used by other gems that want to interact with the ${gem_name}.Tools module
@@ -134,6 +138,10 @@ if (PAL_TRAIT_BUILD_HOST_TOOLS)
         RUNTIME_DEPENDENCIES
         RUNTIME_DEPENDENCIES
         TARGET_PROPERTIES
         TARGET_PROPERTIES
     )
     )
+
+    # Add in CMake dependencies for each gem dependency listed in this gem's gem.json file
+    # for the Tools and Builders gem variants
+    o3de_add_variant_dependencies_for_gem_dependencies(GEM_NAME ${gem_name} VARIANTS Tools Builders)
 endif()
 endif()
 
 
 ################################################################################
 ################################################################################

+ 4 - 0
Templates/PythonToolGem/Template/Code/CMakeLists.txt

@@ -92,6 +92,10 @@ if(PAL_TRAIT_BUILD_HOST_TOOLS)
     ly_create_alias(NAME ${gem_name}.Tools.API NAMESPACE Gem TARGETS Gem::${gem_name}.Editor.API)
     ly_create_alias(NAME ${gem_name}.Tools.API NAMESPACE Gem TARGETS Gem::${gem_name}.Editor.API)
     ly_create_alias(NAME ${gem_name}.Builders.API NAMESPACE Gem TARGETS Gem::${gem_name}.Editor.API)
     ly_create_alias(NAME ${gem_name}.Builders.API NAMESPACE Gem TARGETS Gem::${gem_name}.Editor.API)
 
 
+    # Add in CMake dependencies for each gem dependency listed in this gem's gem.json file
+    # for the Tools and Builders gem variants
+    o3de_add_variant_dependencies_for_gem_dependencies(GEM_NAME ${gem_name} VARIANTS Tools Builders)
+
 endif()
 endif()
 
 
 ################################################################################
 ################################################################################

+ 8 - 0
Templates/UnifiedMultiplayerGem/Template/Code/CMakeLists.txt

@@ -171,6 +171,10 @@ ly_create_alias(NAME ${gem_name}.Clients.API NAMESPACE Gem TARGETS Gem::${gem_na
 ly_create_alias(NAME ${gem_name}.Servers.API NAMESPACE Gem TARGETS Gem::${gem_name}.API)
 ly_create_alias(NAME ${gem_name}.Servers.API NAMESPACE Gem TARGETS Gem::${gem_name}.API)
 ly_create_alias(NAME ${gem_name}.Unified.API NAMESPACE Gem TARGETS Gem::${gem_name}.API)
 ly_create_alias(NAME ${gem_name}.Unified.API NAMESPACE Gem TARGETS Gem::${gem_name}.API)
 
 
+# Add in CMake dependencies for each gem dependency listed in this gem's gem.json file
+# for the Clients, Servers and Unified gem variants
+o3de_add_variant_dependencies_for_gem_dependencies(GEM_NAME ${gem_name} VARIANTS Clients Servers Unified)
+
 # If we are on a host platform, we want to add the host tools targets like the ${gem_name}.Editor MODULE target
 # If we are on a host platform, we want to add the host tools targets like the ${gem_name}.Editor MODULE target
 if(PAL_TRAIT_BUILD_HOST_TOOLS)
 if(PAL_TRAIT_BUILD_HOST_TOOLS)
     # The ${gem_name}.Editor.API target can be used by other gems that want to interact with the ${gem_name}.Editor module
     # The ${gem_name}.Editor.API target can be used by other gems that want to interact with the ${gem_name}.Editor module
@@ -236,6 +240,10 @@ if(PAL_TRAIT_BUILD_HOST_TOOLS)
     ly_create_alias(NAME ${gem_name}.Tools.API NAMESPACE Gem TARGETS Gem::${gem_name}.Editor.API)
     ly_create_alias(NAME ${gem_name}.Tools.API NAMESPACE Gem TARGETS Gem::${gem_name}.Editor.API)
     ly_create_alias(NAME ${gem_name}.Builders.API NAMESPACE Gem TARGETS Gem::${gem_name}.Editor.API)
     ly_create_alias(NAME ${gem_name}.Builders.API NAMESPACE Gem TARGETS Gem::${gem_name}.Editor.API)
 
 
+    # Add in CMake dependencies for each gem dependency listed in this gem's gem.json file
+    # for the Tools and Builders gem variants
+    o3de_add_variant_dependencies_for_gem_dependencies(GEM_NAME ${gem_name} VARIANTS Tools Builders)
+
 endif()
 endif()
 
 
 ################################################################################
 ################################################################################

+ 80 - 8
cmake/Gems.cmake

@@ -57,6 +57,75 @@ function(o3de_find_ancestor_gem_root output_gem_module_root output_gem_name sour
     endif()
     endif()
 endfunction()
 endfunction()
 
 
+# o3de_add_variant_dependencies_for_gem_dependencies
+#
+# For the specified gem, creates cmake TARGET dependencies using
+# the gem's "dependencies" field as a prefix for each gem variant supplied to this function
+# \arg:GEM_NAME(STRING) - Gem name whose "dependencies" will be queried from its gem.json
+# \arg:VARIANTS(LIST) - List of Gem variants which will be suffixed to the input gem name and
+#      its gem dependencies
+function(o3de_add_variant_dependencies_for_gem_dependencies)
+    set(options)
+    set(oneValueArgs GEM_NAME)
+    set(multiValueArgs VARIANTS)
+
+    cmake_parse_arguments(o3de_add_variant_dependencies_for_gem_dependencies "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
+    set(gem_name ${o3de_add_variant_dependencies_for_gem_dependencies_GEM_NAME})
+    set(gem_variants ${o3de_add_variant_dependencies_for_gem_dependencies_VARIANTS})
+    if(NOT gem_name OR NOT gem_variants)
+        return() # Nothing to do
+    endif()
+
+    # Get the gem path using the gem name as a key
+    get_property(gem_path GLOBAL PROPERTY "@GEMROOT:${gem_name}@")
+    if(NOT gem_path)
+        message(FATAL_ERROR "Unable to locate gem path for Gem \"${gem_name}\"."
+        " Is the gem registered in either the ~/.o3de/o3de_manifest.json, ${LY_ROOT_FOLDER}/engine.json,"
+        " any project.json or any gem.json which itself is registered?")
+    endif()
+
+     # Open gem.json and read "dependencies" array
+     unset(gem_dependencies)
+     o3de_read_json_array(gem_dependencies "${gem_path}/gem.json" "dependencies")
+
+    foreach(variant IN LISTS gem_variants)
+        set(gem_variant_target "${gem_name}.${variant}")
+        # Continue to the next variant if the gem didn't specify
+        # a CMake target for the current variant
+        if(NOT TARGET ${gem_variant_target})
+            continue()
+        endif()
+
+        # Append to the list of target dependencies for the current list
+        # CMake targets that actually exists
+        unset(target_dependencies_for_variant)
+        foreach(gem_dependency IN LISTS gem_dependencies)
+            set(gem_dependency_variant_target "${gem_dependency}.${variant}")
+            if(TARGET ${gem_dependency_variant_target})
+                list(APPEND target_dependencies_for_variant ${gem_dependency_variant_target})
+            endif()
+        endforeach()
+        # Validate that there is at least one dependency being added
+        if(target_dependencies_for_variant)
+            ly_add_dependencies(${gem_variant_target} ${target_dependencies_for_variant})
+            message(VERBOSE "Adding target dependencies for Gem \"${gem_name}\" by appending variant \"${variant}\""
+                " to gem names found in this gem's \"dependencies\" field\n"
+                "${gem_variant_target} -> ${gem_dependencies_for_variant}")
+        endif()
+    endforeach()
+
+    # Store of the arguments used to invoke this function in order to replicate the call
+    # in the SDK install layout
+    unset(add_variant_dependencies_for_gem_dependencies_args)
+    list(APPEND add_variant_dependencies_for_gem_dependencies_args
+        GEM_NAME ${gem_name}
+        VARIANTS ${gem_variants})
+    # Replace the list separator with space to have it be stored as a single property element
+    list(JOIN add_variant_dependencies_for_gem_dependencies_args " " add_variant_dependencies_for_gem_dependencies_args)
+    set_property(DIRECTORY APPEND PROPERTY O3DE_ADD_VARIANT_DEPENDENCIES_FOR_GEM_DEPENDENCIES_ARGUMENTS
+        "${add_variant_dependencies_for_gem_dependencies_args}")
+endfunction()
+
 # ly_create_alias
 # ly_create_alias
 # given an alias to create, and a list of one or more targets,
 # given an alias to create, and a list of one or more targets,
 # this creates an alias that depends on all of the given targets.
 # this creates an alias that depends on all of the given targets.
@@ -126,7 +195,7 @@ function(ly_create_alias)
     # This will be used to re-create the calls in the generated CMakeLists.txt in the INSTALL step
     # This will be used to re-create the calls in the generated CMakeLists.txt in the INSTALL step
     # Replace the CMake list separator with a space to replicate the space separated arguments
     # Replace the CMake list separator with a space to replicate the space separated arguments
     # A single create_alias_args variable encodes two values. The alias NAME used to check if the target exists
     # A single create_alias_args variable encodes two values. The alias NAME used to check if the target exists
-    # and the ly_create_alias arguments to replace this function call
+    # and the ly_create_alias arguments to replicate this function call
     unset(create_alias_args)
     unset(create_alias_args)
     list(APPEND create_alias_args "${ly_create_alias_NAME},"
     list(APPEND create_alias_args "${ly_create_alias_NAME},"
         NAME ${ly_create_alias_NAME}
         NAME ${ly_create_alias_NAME}
@@ -303,7 +372,8 @@ function(ly_add_gem_dependencies_to_project_variants)
             ly_add_target_dependencies(
             ly_add_target_dependencies(
                 ${PREFIX_CLAUSE}
                 ${PREFIX_CLAUSE}
                 TARGETS ${ly_add_gem_dependencies_TARGET}
                 TARGETS ${ly_add_gem_dependencies_TARGET}
-                DEPENDENT_TARGETS ${dealiased_gem_target})
+                DEPENDENT_TARGETS ${dealiased_gem_target}
+                GEM_VARIANT ${ly_add_gem_dependencies_VARIANT})
         else()
         else()
             message(VERBOSE "Gem \"${gem_name}\" does not expose a variant of ${ly_add_gem_dependencies_VARIANT}")
             message(VERBOSE "Gem \"${gem_name}\" does not expose a variant of ${ly_add_gem_dependencies_VARIANT}")
         endif()
         endif()
@@ -349,11 +419,13 @@ function(ly_enable_gems_delayed)
                     # cmake_dependencies.*.setreg file for the (project, target) tuple to be regenerated
                     # cmake_dependencies.*.setreg file for the (project, target) tuple to be regenerated
                     # This is needed if the ENABLED_GEMS list for a project goes from >0 to 0. In this case
                     # This is needed if the ENABLED_GEMS list for a project goes from >0 to 0. In this case
                     # the cmake_dependencies would have a stale list of gems to load unless it is regenerated
                     # the cmake_dependencies would have a stale list of gems to load unless it is regenerated
-                    get_property(delayed_load_target_set GLOBAL PROPERTY LY_DELAYED_LOAD_"${project},${target}" SET)
-                    if(NOT delayed_load_target_set)
-                        set_property(GLOBAL APPEND PROPERTY LY_DELAYED_LOAD_DEPENDENCIES "${project},${target}")
-                        set_property(GLOBAL APPEND PROPERTY LY_DELAYED_LOAD_"${project},${target}" "")
-                    endif()
+                    foreach(variant IN LISTS target_gem_variants)
+                        get_property(delayed_load_target_set GLOBAL PROPERTY LY_DELAYED_LOAD_"${project},${target},${variant}" SET)
+                        if(NOT delayed_load_target_set)
+                            set_property(GLOBAL APPEND PROPERTY LY_DELAYED_LOAD_DEPENDENCIES "${project},${target},${variant}")
+                            set_property(GLOBAL APPEND PROPERTY LY_DELAYED_LOAD_"${project},${target},${variant}" "")
+                        endif()
+                    endforeach()
                 endif()
                 endif()
                 # Continue to the next iteration loop regardless as there are no gem dependencies
                 # Continue to the next iteration loop regardless as there are no gem dependencies
                 continue()
                 continue()
@@ -361,7 +433,7 @@ function(ly_enable_gems_delayed)
 
 
             # Gather the Gem variants associated with this target and iterate over them to combine them with the enabled
             # Gather the Gem variants associated with this target and iterate over them to combine them with the enabled
             # gems for the each project
             # gems for the each project
-            foreach(variant ${target_gem_variants})
+            foreach(variant IN LISTS target_gem_variants)
                 ly_add_gem_dependencies_to_project_variants(
                 ly_add_gem_dependencies_to_project_variants(
                     PROJECT_NAME ${project}
                     PROJECT_NAME ${project}
                     TARGET ${target}
                     TARGET ${target}

+ 1 - 1
cmake/O3DEJson.cmake

@@ -25,7 +25,7 @@ endfunction()
 #! read_json_array
 #! read_json_array
 #  Reads the a json array field into a cmake list variable
 #  Reads the a json array field into a cmake list variable
 function(o3de_read_json_array read_output_array input_json_path array_key)
 function(o3de_read_json_array read_output_array input_json_path array_key)
-    ly_file_read(${input_json_path} manifest_json_data)
+    o3de_file_read_cache(${input_json_path} manifest_json_data)
     string(JSON array_count ERROR_VARIABLE manifest_json_error
     string(JSON array_count ERROR_VARIABLE manifest_json_error
         LENGTH ${manifest_json_data} ${array_key})
         LENGTH ${manifest_json_data} ${array_key})
     if(manifest_json_error)
     if(manifest_json_error)

+ 23 - 0
cmake/Platform/Common/Install_common.cmake

@@ -403,6 +403,7 @@ endif()
     #    that will declare the target and configure it
     #    that will declare the target and configure it
     ly_setup_subdirectory_create_alias("${absolute_target_source_dir}" CREATE_ALIASES_PLACEHOLDER)
     ly_setup_subdirectory_create_alias("${absolute_target_source_dir}" CREATE_ALIASES_PLACEHOLDER)
     ly_setup_subdirectory_set_gem_variant_to_load("${absolute_target_source_dir}" GEM_VARIANT_TO_LOAD_PLACEHOLDER)
     ly_setup_subdirectory_set_gem_variant_to_load("${absolute_target_source_dir}" GEM_VARIANT_TO_LOAD_PLACEHOLDER)
+    ly_setup_add_variant_dependencies_for_gem_dependencies("${absolute_target_source_dir}" O3DE_ADD_VARIANT_DEPS_FOR_GEM_DEPS)
     ly_setup_subdirectory_enable_gems("${absolute_target_source_dir}" ENABLE_GEMS_PLACEHOLDER)
     ly_setup_subdirectory_enable_gems("${absolute_target_source_dir}" ENABLE_GEMS_PLACEHOLDER)
     ly_setup_subdirectory_install_code("${absolute_target_source_dir}" O3DE_INSTALL_CODE_PLACEHOLDER)
     ly_setup_subdirectory_install_code("${absolute_target_source_dir}" O3DE_INSTALL_CODE_PLACEHOLDER)
 
 
@@ -414,6 +415,7 @@ endif()
         "\n"
         "\n"
         "${CREATE_ALIASES_PLACEHOLDER}"
         "${CREATE_ALIASES_PLACEHOLDER}"
         "${GEM_VARIANT_TO_LOAD_PLACEHOLDER}"
         "${GEM_VARIANT_TO_LOAD_PLACEHOLDER}"
+        "${O3DE_ADD_VARIANT_DEPS_FOR_GEM_DEPS}"
         "${ENABLE_GEMS_PLACEHOLDER}"
         "${ENABLE_GEMS_PLACEHOLDER}"
     )
     )
 
 
@@ -838,6 +840,27 @@ function(ly_setup_assets)
 
 
 endfunction()
 endfunction()
 
 
+#! ly_setup_add_variant_dependencies_for_gem_dependencies: Replicates the call to
+#!  the `o3de_add_variant_dependencies_for_gem_dependencies` function
+#! within the generated CMakeLists.txt in the same relative install layout directory
+function(ly_setup_add_variant_dependencies_for_gem_dependencies absolute_target_source_dir output_script)
+    # Replicate the create_alias() calls made in the SOURCE_DIR into the generated CMakeLists.txt
+    string(JOIN "\n" add_variant_dependencies_for_gem_dependencies_template
+        "o3de_add_variant_dependencies_for_gem_dependencies(@add_variant_dependencies_for_gem_dependencies_args@)"
+        "")
+
+    unset(${output_script} PARENT_SCOPE)
+    get_property(add_variant_dependencies_for_gem_dependencies_args_list
+        DIRECTORY ${absolute_target_source_dir}
+        PROPERTY O3DE_ADD_VARIANT_DEPENDENCIES_FOR_GEM_DEPENDENCIES_ARGUMENTS)
+
+    unset(add_variant_dependencies_for_gem_dependencies_calls)
+    foreach(add_variant_dependencies_for_gem_dependencies_args IN LISTS add_variant_dependencies_for_gem_dependencies_args_list)
+        string(CONFIGURE "${add_variant_dependencies_for_gem_dependencies_template}" add_variant_dependencies_for_gem_dependencies_command @ONLY)
+        string(APPEND add_variant_dependencies_for_gem_dependencies_calls ${add_variant_dependencies_for_gem_dependencies_command})
+    endforeach()
+    set(${output_script} ${add_variant_dependencies_for_gem_dependencies_calls} PARENT_SCOPE)
+endfunction()
 
 
 #! ly_setup_subdirectory_create_alias: Replicates the call to the `ly_create_alias` function
 #! ly_setup_subdirectory_create_alias: Replicates the call to the `ly_create_alias` function
 #! within the generated CMakeLists.txt in the same relative install layout directory
 #! within the generated CMakeLists.txt in the same relative install layout directory

+ 16 - 7
cmake/Projects.cmake

@@ -71,11 +71,13 @@ endfunction()
 # \arg:TARGETS names of the targets to associate the dependencies to
 # \arg:TARGETS names of the targets to associate the dependencies to
 # \arg:DEPENDENCIES_FILES file(s) that contains the load-time dependencies the TARGETS will be associated to
 # \arg:DEPENDENCIES_FILES file(s) that contains the load-time dependencies the TARGETS will be associated to
 # \arg:DEPENDENT_TARGETS additional list of targets should be added as load-time dependencies for the TARGETS list
 # \arg:DEPENDENT_TARGETS additional list of targets should be added as load-time dependencies for the TARGETS list
+# \arg:GEM_VARIANT variant associated with TARGETS dependencies are being added to
+#      Some variant values are "Clients", "Servers", "Tools", "Builders", "Unified"
 #
 #
 function(ly_add_target_dependencies)
 function(ly_add_target_dependencies)
 
 
     set(options)
     set(options)
-    set(oneValueArgs PREFIX)
+    set(oneValueArgs PREFIX GEM_VARIANT)
     set(multiValueArgs TARGETS DEPENDENCIES_FILES DEPENDENT_TARGETS)
     set(multiValueArgs TARGETS DEPENDENCIES_FILES DEPENDENT_TARGETS)
 
 
     cmake_parse_arguments(ly_add_gem_dependencies "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
     cmake_parse_arguments(ly_add_gem_dependencies "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
@@ -89,6 +91,8 @@ function(ly_add_target_dependencies)
         message(FATAL_ERROR "DEPENDENCIES_FILES parameter missing. It must be supplied unless the DEPENDENT_TARGETS parameter is set")
         message(FATAL_ERROR "DEPENDENCIES_FILES parameter missing. It must be supplied unless the DEPENDENT_TARGETS parameter is set")
     endif()
     endif()
 
 
+
+    set(gem_variant ${ly_add_gem_dependencies_GEM_VARIANT})
     unset(ALL_GEM_DEPENDENCIES)
     unset(ALL_GEM_DEPENDENCIES)
     foreach(dependency_file ${ly_add_gem_dependencies_DEPENDENCIES_FILES})
     foreach(dependency_file ${ly_add_gem_dependencies_DEPENDENCIES_FILES})
         #unset any GEM_DEPENDENCIES and include the dependencies file, that should populate GEM_DEPENDENCIES
         #unset any GEM_DEPENDENCIES and include the dependencies file, that should populate GEM_DEPENDENCIES
@@ -100,20 +104,25 @@ function(ly_add_target_dependencies)
     # Append the DEPENDENT_TARGETS to the list of ALL_GEM_DEPENDENCIES
     # Append the DEPENDENT_TARGETS to the list of ALL_GEM_DEPENDENCIES
     list(APPEND ALL_GEM_DEPENDENCIES ${ly_add_gem_dependencies_DEPENDENT_TARGETS})
     list(APPEND ALL_GEM_DEPENDENCIES ${ly_add_gem_dependencies_DEPENDENT_TARGETS})
 
 
-    # for each target, add the dependencies and generate setreg json with the list of gems to load
+    # for each target, add the dependencies and set a global property that maps
+    # the prefix, target name and gem variant to that list of dependencies to load
+    # This list is iterated in [SettingsRegistry.cmake](./SettingsRegistry.cmake)
+    # to generate json with the list of active gem modules to load
     foreach(target ${ly_add_gem_dependencies_TARGETS})
     foreach(target ${ly_add_gem_dependencies_TARGETS})
         ly_add_dependencies(${target} ${ALL_GEM_DEPENDENCIES})
         ly_add_dependencies(${target} ${ALL_GEM_DEPENDENCIES})
 
 
+        set(delayed_load_dependency_key "${ly_add_gem_dependencies_PREFIX},${target},${gem_variant}")
         # Add the target to the LY_DELAYED_LOAD_DEPENDENCIES if it isn't already on the list
         # Add the target to the LY_DELAYED_LOAD_DEPENDENCIES if it isn't already on the list
         get_property(load_dependencies_set GLOBAL PROPERTY LY_DELAYED_LOAD_DEPENDENCIES)
         get_property(load_dependencies_set GLOBAL PROPERTY LY_DELAYED_LOAD_DEPENDENCIES)
-        if(NOT "${ly_add_gem_dependencies_PREFIX},${target}" IN_LIST load_dependencies_set)
-            set_property(GLOBAL APPEND PROPERTY LY_DELAYED_LOAD_DEPENDENCIES "${ly_add_gem_dependencies_PREFIX},${target}")
+        if(NOT "${delayed_load_dependency_key}" IN_LIST load_dependencies_set)
+            set_property(GLOBAL APPEND PROPERTY LY_DELAYED_LOAD_DEPENDENCIES "${delayed_load_dependency_key}")
         endif()
         endif()
         foreach(gem_target ${ALL_GEM_DEPENDENCIES})
         foreach(gem_target ${ALL_GEM_DEPENDENCIES})
-            # Add the list of gem dependencies to the LY_TARGET_DELAYED_DEPENDENCIES_${ly_add_gem_dependencies_PREFIX};${target} property
-            get_property(target_load_dependencies GLOBAL PROPERTY LY_DELAYED_LOAD_"${ly_add_gem_dependencies_PREFIX},${target}")
+            # Add the list of gem dependencies to the
+            # LY_TARGET_DELAYED_DEPENDENCIES_${ly_add_gem_dependencies_PREFIX},${target},${variant} property
+            get_property(target_load_dependencies GLOBAL PROPERTY LY_DELAYED_LOAD_"${delayed_load_dependency_key}")
             if(NOT "${gem_target}" IN_LIST target_load_dependencies)
             if(NOT "${gem_target}" IN_LIST target_load_dependencies)
-                set_property(GLOBAL APPEND PROPERTY LY_DELAYED_LOAD_"${ly_add_gem_dependencies_PREFIX},${target}" ${gem_target})
+                set_property(GLOBAL APPEND PROPERTY LY_DELAYED_LOAD_"${delayed_load_dependency_key}" ${gem_target})
             endif()
             endif()
         endforeach()
         endforeach()
     endforeach()
     endforeach()

+ 95 - 59
cmake/SettingsRegistry.cmake

@@ -69,75 +69,106 @@ function(ly_detect_cycle_through_visitation item visited_items visited_items_var
     set(${visited_items_var} "${visited_items}" PARENT_SCOPE)
     set(${visited_items_var} "${visited_items}" PARENT_SCOPE)
 endfunction()
 endfunction()
 
 
-#!ly_get_gem_load_dependencies: Retrieves the list of "load" dependencies for a target
-# Visits through only MANUALLY_ADDED_DEPENDENCIES of targets with a GEM_MODULE property
+#!o3de_get_gem_load_dependencies: Retrieves the list of "load" dependencies for a target
+# Visits through MANUALLY_ADDED_DEPENDENCIES of targets with a GEM_MODULE property
 # to determine which gems a target needs to load
 # to determine which gems a target needs to load
-# ly_get_runtime_dependencies cannot be used as it will recurse through non-manually added dependencies
+#
+# NOTE: ly_get_runtime_dependencies cannot be used as it will recurse through non-manually added dependencies
 # to add manually added added which results in false load dependencies.
 # to add manually added added which results in false load dependencies.
-# \arg:ly_GEM_LOAD_DEPENDENCIES(name) - Output variable to be populated gem load dependencies
-# \arg:ly_TARGET(TARGET) - CMake target to examine for dependencies
-function(ly_get_gem_load_dependencies ly_GEM_LOAD_DEPENDENCIES ly_TARGET)
-    if(NOT TARGET ${ly_TARGET})
+# \arg:GEM_LOAD_DEPENDENCIES(name) - Output variable to be populated gem load dependencies
+# \arg:TARGET(TARGET) - CMake target to examine for dependencies
+# \arg:CYCLE_DETECTION_SET(variable name)[optional] - Used to track cycles in load dependencies
+function(o3de_get_gem_load_dependencies)
+    set(options)
+    set(oneValueArgs TARGET GEM_LOAD_DEPENDENCIES_VAR)
+    set(multiValueArgs CYCLE_DETECTION_SET)
+
+    cmake_parse_arguments(o3de_get_gem_load_dependencies "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
+    if(NOT TARGET ${o3de_get_gem_load_dependencies_TARGET})
         return() # Nothing to do
         return() # Nothing to do
     endif()
     endif()
-    # Internally we use a third parameter to pass the list of targets that we have traversed. This is
-    # used to detect runtime cycles
-    if(ARGC EQUAL 3)
-        set(ly_CYCLE_DETECTION_TARGETS ${ARGV2})
-    else()
-        set(ly_CYCLE_DETECTION_TARGETS "")
+
+    # Define the indent level variable to 0 in the first iteration
+    if(NOT DEFINED indent_level)
+        set(indent_level "0")
     endif()
     endif()
 
 
+    # Set indent string for current indent level
+    string(REPEAT " " "${indent_level}" indent)
+
+    set(target ${o3de_get_gem_load_dependencies_TARGET})
+    set(gem_load_dependencies_var ${o3de_get_gem_load_dependencies_GEM_LOAD_DEPENDENCIES_VAR})
+    set(cycle_detection_targets ${o3de_get_gem_load_dependencies_CYCLE_DETECTION_SET})
+
     # Optimize the search by caching gem load dependencies
     # Optimize the search by caching gem load dependencies
-    get_property(are_dependencies_cached GLOBAL PROPERTY LY_GEM_LOAD_DEPENDENCIES_${ly_TARGET} SET)
+    get_property(are_dependencies_cached GLOBAL PROPERTY "LY_GEM_LOAD_DEPENDENCIES,${target}" SET)
     if(are_dependencies_cached)
     if(are_dependencies_cached)
         # We already walked through this target
         # We already walked through this target
-        get_property(cached_dependencies GLOBAL PROPERTY LY_GEM_LOAD_DEPENDENCIES_${ly_TARGET})
-        set(${ly_GEM_LOAD_DEPENDENCIES} ${cached_dependencies} PARENT_SCOPE)
+        get_property(cached_dependencies GLOBAL PROPERTY "LY_GEM_LOAD_DEPENDENCIES,${target}")
+        set(${gem_load_dependencies_var} ${cached_dependencies} PARENT_SCOPE)
+        message(DEBUG "${indent}Found cache load dependencies for Gem Target \"${target}\": ${cached_dependencies}")
         return()
         return()
     endif()
     endif()
 
 
+    message(DEBUG "${indent}Visiting target \"${target}\" when looking for gem module load dependencies")
+
     # detect cycles
     # detect cycles
     unset(cycle_detected)
     unset(cycle_detected)
-    ly_detect_cycle_through_visitation(${ly_TARGET} "${ly_CYCLE_DETECTION_TARGETS}" ly_CYCLE_DETECTION_TARGETS cycle_detected)
+    ly_detect_cycle_through_visitation(${target} "${cycle_detection_targets}" cycle_detection_targets cycle_detected)
     if(cycle_detected)
     if(cycle_detected)
         message(FATAL_ERROR "Runtime dependency detected: ${cycle_detected}")
         message(FATAL_ERROR "Runtime dependency detected: ${cycle_detected}")
     endif()
     endif()
 
 
-    unset(all_gem_load_dependencies)
-
     # For load dependencies, we want to copy over the dependency and traverse them
     # For load dependencies, we want to copy over the dependency and traverse them
     # Only if the dependency has a GEM_MODULE property
     # Only if the dependency has a GEM_MODULE property
+    get_property(manually_added_dependencies TARGET ${target} PROPERTY MANUALLY_ADDED_DEPENDENCIES)
     unset(load_dependencies)
     unset(load_dependencies)
-    get_target_property(load_dependencies ${ly_TARGET} MANUALLY_ADDED_DEPENDENCIES)
-    if(load_dependencies)
-        foreach(load_dependency ${load_dependencies})
-            # Skip wrapping produced when targets are not created in the same directory
-            ly_de_alias_target(${load_dependency} dealias_load_dependency)
-            get_property(is_gem_target TARGET ${dealias_load_dependency} PROPERTY GEM_MODULE SET)
-            # If the dependency is a "gem module" then add it as a load dependencies
-            # and recurse into its manually added dependencies
-            if (is_gem_target)
-                unset(dependencies)
-                ly_get_gem_load_dependencies(dependencies ${dealias_load_dependency} "${ly_CYCLE_DETECTION_TARGETS}")
-                list(APPEND all_gem_load_dependencies ${dependencies})
-                list(APPEND all_gem_load_dependencies ${dealias_load_dependency})
-            endif()
-        endforeach()
+    if(manually_added_dependencies)
+        list(APPEND load_dependencies ${manually_added_dependencies})
+        message(VERBOSE "${indent}Gem Target \"${target}\" has direct manually added dependencies of: ${manually_added_dependencies}")
     endif()
     endif()
 
 
+    # unset all_gem_load_dependencies to prevent using variable values from the PARENT_SCOPE
+    unset(all_gem_load_dependencies)
+    # Remove duplicate load dependencies
+    list(REMOVE_DUPLICATES load_dependencies)
+    foreach(load_dependency IN LISTS load_dependencies)
+        # Skip wrapping produced when targets are not created in the same directory
+        ly_de_alias_target(${load_dependency} dealias_load_dependency)
+        get_property(is_gem_target TARGET ${dealias_load_dependency} PROPERTY GEM_MODULE SET)
+        # If the dependency is a "gem module" then add it as a load dependencies
+        # and recurse into its manually added dependencies
+        if (is_gem_target)
+            # shift identation level for recursive calls to ${CMAKE_CURRENT_FUNCTION}
+            set(current_indent_level "${indent_level}")
+            math(EXPR indent_level "${current_indent_level} + 2")
+            unset(dependencies)
+            o3de_get_gem_load_dependencies(
+                GEM_LOAD_DEPENDENCIES_VAR dependencies
+                TARGET ${dealias_load_dependency}
+                CYCLE_DETECTION_SET "${cycle_detection_set}"
+            )
+            # restore indentation level
+            set(indent_level "${current_indent_level}")
+
+            list(APPEND all_gem_load_dependencies ${dependencies})
+            list(APPEND all_gem_load_dependencies ${dealias_load_dependency})
+        endif()
+    endforeach()
+
     list(REMOVE_DUPLICATES all_gem_load_dependencies)
     list(REMOVE_DUPLICATES all_gem_load_dependencies)
-    set_property(GLOBAL PROPERTY LY_GEM_LOAD_DEPENDENCIES_${ly_TARGET} "${all_gem_load_dependencies}")
-    set(${ly_GEM_LOAD_DEPENDENCIES} ${all_gem_load_dependencies} PARENT_SCOPE)
-    message(VERBOSE "Gem Target \"${ly_TARGET}\" has load dependencies of: ${all_gem_load_dependencies}")
+    set_property(GLOBAL PROPERTY "LY_GEM_LOAD_DEPENDENCIES,${target}" "${all_gem_load_dependencies}")
+    set(${gem_load_dependencies_var} ${all_gem_load_dependencies} PARENT_SCOPE)
+    message(VERBOSE "${indent}Gem Target \"${target}\" has load dependencies of: ${all_gem_load_dependencies}")
 
 
 endfunction()
 endfunction()
 
 
-#!ly_get_gem_module_root: Uses the supplied gem_target to lookup the nearest gem.json file above the SOURCE_DIR
+#!o3de_get_gem_root_from_target: Uses the supplied gem_target to lookup the nearest
+# gem.json file at an ancestor of targets SOURCE_DIR property
 #
 #
 # \arg:gem_target(TARGET) - Target to look upwards from using its SOURCE_DIR property
 # \arg:gem_target(TARGET) - Target to look upwards from using its SOURCE_DIR property
-function(ly_get_gem_module_root output_gem_module_root output_gem_name gem_target)
-    unset(${output_gem_module_root} PARENT_SCOPE)
+function(o3de_get_gem_root_from_target output_gem_root output_gem_name gem_target)
+    unset(${output_gem_root} PARENT_SCOPE)
     get_property(gem_source_dir TARGET ${gem_target} PROPERTY SOURCE_DIR)
     get_property(gem_source_dir TARGET ${gem_target} PROPERTY SOURCE_DIR)
 
 
     # the o3de_find_ancestor_gem_root looks up the nearest gem root path
     # the o3de_find_ancestor_gem_root looks up the nearest gem root path
@@ -146,7 +177,7 @@ function(ly_get_gem_module_root output_gem_module_root output_gem_name gem_targe
 
 
     # Set the gem module root output directory to the location with the gem.json file within it or
     # Set the gem module root output directory to the location with the gem.json file within it or
     # the supplied gem_target SOURCE_DIR location if no gem.json file was found
     # the supplied gem_target SOURCE_DIR location if no gem.json file was found
-    set(${output_gem_module_root} ${gem_source_dir} PARENT_SCOPE)
+    set(${output_gem_root} ${gem_source_dir} PARENT_SCOPE)
 
 
     # Set the gem name output value to the name of the gem as in the gem.json file
     # Set the gem name output value to the name of the gem as in the gem.json file
     if(gem_name)
     if(gem_name)
@@ -166,7 +197,7 @@ function(ly_populate_gem_objects output_gem_setreg_objects all_gem_dependencies)
             message(FATAL_ERROR "Dependency ${gem_target} from ${target} does not exist")
             message(FATAL_ERROR "Dependency ${gem_target} from ${target} does not exist")
         endif()
         endif()
 
 
-        ly_get_gem_module_root(gem_module_root gem_name_value ${gem_target})
+        o3de_get_gem_root_from_target(gem_module_root gem_name_value ${gem_target})
         if (NOT gem_module_root)
         if (NOT gem_module_root)
             # If the target doesn't have a gem.json, skip it
             # If the target doesn't have a gem.json, skip it
             continue()
             continue()
@@ -215,26 +246,31 @@ function(ly_delayed_generate_settings_registry)
     endif()
     endif()
 
 
     get_property(ly_delayed_load_targets GLOBAL PROPERTY LY_DELAYED_LOAD_DEPENDENCIES)
     get_property(ly_delayed_load_targets GLOBAL PROPERTY LY_DELAYED_LOAD_DEPENDENCIES)
-    foreach(prefix_target ${ly_delayed_load_targets})
-        string(REPLACE "," ";" prefix_target_list "${prefix_target}")
-        list(LENGTH prefix_target_list prefix_target_length)
-        if(prefix_target_length EQUAL 0)
+    foreach(prefix_target_variant ${ly_delayed_load_targets})
+        string(REPLACE "," ";" prefix_target_variant_list "${prefix_target_variant}")
+        list(LENGTH prefix_target_variant_list prefix_target_variant_length)
+        if(prefix_target_variant_length EQUAL 0)
             continue()
             continue()
         endif()
         endif()
 
 
-        # Retrieve the target name from the back of the list
-        list(POP_BACK prefix_target_list target)
-        # Retrieves the prefix if available from the remaining element of the list
-        list(POP_BACK prefix_target_list prefix)
+        # Retrieves the prefix if available from the front of the list
+        list(POP_FRONT prefix_target_variant_list prefix)
+        # Retrieve the target name from the next element of the list
+        list(POP_FRONT prefix_target_variant_list target)
+        # Retreive the variant name from the last element of the list
+        list(POP_BACK prefix_target_variant_list variant)
 
 
         # Get the gem dependencies for the given project and target combination
         # Get the gem dependencies for the given project and target combination
-        get_property(gem_dependencies GLOBAL PROPERTY LY_DELAYED_LOAD_"${prefix_target}")
-        message(VERBOSE "${prefix_target} has direct gem load dependencies of ${gem_dependencies}")
-        list(REMOVE_DUPLICATES gem_dependencies) # Strip out any duplicate gem targets
+        get_property(target_load_dependencies GLOBAL PROPERTY LY_DELAYED_LOAD_"${prefix_target_variant}")
+        message(VERBOSE "prefix=${prefix},target=${target},variant=${variant} has direct load dependencies of ${target_load_dependencies}")
+        list(REMOVE_DUPLICATES target_load_dependencies) # Strip out any duplicate load dependency CMake targets
         unset(all_gem_dependencies)
         unset(all_gem_dependencies)
 
 
-        foreach(gem_target ${gem_dependencies})
-            ly_get_gem_load_dependencies(gem_load_gem_dependencies ${gem_target})
+        foreach(gem_target IN LISTS target_load_dependencies)
+            o3de_get_gem_load_dependencies(
+                GEM_LOAD_DEPENDENCIES_VAR gem_load_gem_dependencies
+                TARGET "${gem_target}"
+            )
             list(APPEND all_gem_dependencies ${gem_load_gem_dependencies} ${gem_target})
             list(APPEND all_gem_dependencies ${gem_load_gem_dependencies} ${gem_target})
         endforeach()
         endforeach()
         list(REMOVE_DUPLICATES all_gem_dependencies)
         list(REMOVE_DUPLICATES all_gem_dependencies)
@@ -250,7 +286,7 @@ function(ly_delayed_generate_settings_registry)
 
 
         # Fill out the gem_setreg_objects variable with the json fields for each gem
         # Fill out the gem_setreg_objects variable with the json fields for each gem
         unset(gem_setreg_objects)
         unset(gem_setreg_objects)
-        ly_populate_gem_objects(gem_json "${all_gem_dependencies}")
+        ly_populate_gem_objects(gem_load_dependencies_json "${all_gem_dependencies}")
 
 
         string(REPLACE "." "_" escaped_target ${target})
         string(REPLACE "." "_" escaped_target ${target})
         string(JOIN "." specialization_name ${prefix} ${escaped_target})
         string(JOIN "." specialization_name ${prefix} ${escaped_target})
@@ -270,11 +306,11 @@ function(ly_delayed_generate_settings_registry)
             set(target_dir $<TARGET_FILE_DIR:${target}>)
             set(target_dir $<TARGET_FILE_DIR:${target}>)
         endif()
         endif()
         set(dependencies_setreg ${target_dir}/Registry/cmake_dependencies.${specialization_name}.setreg)
         set(dependencies_setreg ${target_dir}/Registry/cmake_dependencies.${specialization_name}.setreg)
-        file(GENERATE OUTPUT ${dependencies_setreg} CONTENT "${gem_json}")
+        file(GENERATE OUTPUT ${dependencies_setreg} CONTENT "${gem_load_dependencies_json}")
         set_property(TARGET ${target} APPEND PROPERTY INTERFACE_LY_TARGET_FILES "${dependencies_setreg}\nRegistry")
         set_property(TARGET ${target} APPEND PROPERTY INTERFACE_LY_TARGET_FILES "${dependencies_setreg}\nRegistry")
 
 
-        # Clear out load dependencies for the project/target combination
-        set_property(GLOBAL PROPERTY LY_DELAYED_LOAD_"${prefix_target}")
+        # Clear out load dependencies for the prefix,target,variant combination
+        set_property(GLOBAL PROPERTY LY_DELAYED_LOAD_"${prefix_target_variant}")
     endforeach()
     endforeach()
 
 
     # Clear out the load targets from the global load dependencies list
     # Clear out the load targets from the global load dependencies list

+ 3 - 0
engine.json

@@ -105,8 +105,10 @@
     "gem_names": [
     "gem_names": [
         "Atom_Bootstrap",
         "Atom_Bootstrap",
         "AtomShader",
         "AtomShader",
+        "AtomViewportDisplayInfo",
         "Camera",
         "Camera",
         "CommonFeaturesAtom",
         "CommonFeaturesAtom",
+        "EditorModeFeedback",
         "Maestro",
         "Maestro",
         "PrefabBuilder",
         "PrefabBuilder",
         "SceneProcessing"
         "SceneProcessing"
@@ -121,6 +123,7 @@
         "Templates/DefaultGem",
         "Templates/DefaultGem",
         "Templates/DefaultProject",
         "Templates/DefaultProject",
         "Templates/GemRepo",
         "Templates/GemRepo",
+        "Templates/GraphicsGems",
         "Templates/MinimalProject",
         "Templates/MinimalProject",
         "Templates/PrebuiltGem",
         "Templates/PrebuiltGem",
         "Templates/PythonToolGem",
         "Templates/PythonToolGem",