Added detection of gems which are not directly under an external subdirectory root (#1841)

* Added proper detection of the list of Gems in the Project Templates
enabled_gems.cmake file

Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com>

* Added a CMake alias target for the Atom Gem and the AtomLyIntegration

Both of those targets just aliases the Atom_AtomBridge gem
Therefore they turn on Atom

Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com>

* Replacing the Atom_AtomBridge gem in the project template with the Atom gem

The Atom gem is just an alias to the Atom_AtomBridge gem

Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com>

* Updated the manifest.py gem gathering logic to recurse through the external subdirecotories locating gem.json files to discover all gems in a subdirectory

Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com>
main
lumberyard-employee-dm 5 years ago committed by GitHub
parent d4e4ebc2a7
commit d73a98aa2f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -1,6 +1,6 @@
/* /*
* Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
* *
* SPDX-License-Identifier: Apache-2.0 OR MIT * SPDX-License-Identifier: Apache-2.0 OR MIT
* *
*/ */
@ -23,6 +23,8 @@
#include <AzCore/std/string/conversions.h> #include <AzCore/std/string/conversions.h>
#include <AzCore/StringFunc/StringFunc.h> #include <AzCore/StringFunc/StringFunc.h>
#include <QDir>
namespace Platform namespace Platform
{ {
bool InsertPythonLibraryPath( bool InsertPythonLibraryPath(
@ -42,7 +44,7 @@ namespace Platform
return false; return false;
} }
// Implemented in each different platform's PAL implentation files, as it differs per platform. // Implemented in each different platform's PAL implementation files, as it differs per platform.
AZStd::string GetPythonHomePath(const char* pythonPackage, const char* engineRoot); AZStd::string GetPythonHomePath(const char* pythonPackage, const char* engineRoot);
} // namespace Platform } // namespace Platform
@ -843,11 +845,19 @@ namespace O3DE::ProjectManager
templateInfo.m_canonicalTags.push_back(Py_To_String(tag)); templateInfo.m_canonicalTags.push_back(Py_To_String(tag));
} }
} }
if (data.contains("included_gems"))
QString templateProjectPath = QDir(templateInfo.m_path).filePath("Template");
auto enabledGemNames = GetEnabledGemNames(templateProjectPath);
if (enabledGemNames)
{ {
for (auto gem : data["included_gems"]) for (auto gem : enabledGemNames.GetValue())
{ {
templateInfo.m_includedGems.push_back(Py_To_String(gem)); // Exclude the template ${Name} placeholder for the list of included gems
// That Gem gets created with the project
if (!gem.contains("${Name}"))
{
templateInfo.m_includedGems.push_back(Py_To_String(gem.c_str()));
}
} }
} }
} }

@ -14,3 +14,11 @@ add_subdirectory(RPI)
add_subdirectory(Tools) add_subdirectory(Tools)
add_subdirectory(Utils) add_subdirectory(Utils)
# The "Atom" Gem will alias the real Atom_AtomBridge target variants
# allows the enabling and disabling the "Atom" Gem to build the pre-requisite dependencies
ly_create_alias(NAME Atom.Clients NAMESPACE Gem TARGETS Gem::Atom_AtomBridge.Clients)
ly_create_alias(NAME Atom.Servers NAMESPACE Gem TARGETS Gem::Atom_AtomBridge.Servers)
if(PAL_TRAIT_BUILD_HOST_TOOLS)
ly_create_alias(NAME Atom.Builders NAMESPACE Gem TARGETS Gem::Atom_AtomBridge.Builders)
ly_create_alias(NAME Atom.Tools NAMESPACE Gem TARGETS Gem::Atom_AtomBridge.Tools)
endif()

@ -14,3 +14,12 @@ add_subdirectory(TechnicalArt)
add_subdirectory(AtomBridge) add_subdirectory(AtomBridge)
add_subdirectory(AtomViewportDisplayInfo) add_subdirectory(AtomViewportDisplayInfo)
add_subdirectory(AtomViewportDisplayIcons) add_subdirectory(AtomViewportDisplayIcons)
# The "AtomLyIntegration" Gem will also alias the real Atom_AtomBridge target variants
# The Atom Gem does the same at the moment.
ly_create_alias(NAME AtomLyIntegration.Clients NAMESPACE Gem TARGETS Gem::Atom_AtomBridge.Clients)
ly_create_alias(NAME AtomLyIntegration.Servers NAMESPACE Gem TARGETS Gem::Atom_AtomBridge.Servers)
if(PAL_TRAIT_BUILD_HOST_TOOLS)
ly_create_alias(NAME AtomLyIntegration.Builders NAMESPACE Gem TARGETS Gem::Atom_AtomBridge.Builders)
ly_create_alias(NAME AtomLyIntegration.Tools NAMESPACE Gem TARGETS Gem::Atom_AtomBridge.Tools)
endif()

@ -7,7 +7,7 @@
set(ENABLED_GEMS set(ENABLED_GEMS
${Name} ${Name}
Atom_AtomBridge Atom
AudioSystem AudioSystem
AWSCore AWSCore
CameraFramework CameraFramework

@ -6,7 +6,6 @@
"license": "What license DefaultProject uses goes here: i.e. https://opensource.org/licenses/MIT", "license": "What license DefaultProject uses goes here: i.e. https://opensource.org/licenses/MIT",
"display_name": "Standard", "display_name": "Standard",
"summary": "This template has everything you need to build a full online 3D game or application.", "summary": "This template has everything you need to build a full online 3D game or application.",
"included_gems": ["Atom","Camera","EMotionFX","UI","Maestro","Input","ImGui"],
"canonical_tags": [], "canonical_tags": [],
"user_tags": [ "user_tags": [
"DefaultProject" "DefaultProject"

@ -7,7 +7,7 @@
set(ENABLED_GEMS set(ENABLED_GEMS
${Name} ${Name}
Atom_AtomBridge Atom
CameraFramework CameraFramework
ImGui ImGui
) )

@ -31,25 +31,29 @@ function(ly_create_alias)
"Make sure the target wasn't copy and pasted here or elsewhere.") "Make sure the target wasn't copy and pasted here or elsewhere.")
endif() endif()
# easy version - if its juts one target, we can directly get the target, and make both aliases, # easy version - if its just one target and it exist at the time of this call,
# we can directly get the target, and make both aliases,
# the namespaced and non namespaced one, point at it. # the namespaced and non namespaced one, point at it.
list(LENGTH ly_create_alias_TARGETS number_of_targets) list(LENGTH ly_create_alias_TARGETS number_of_targets)
if (number_of_targets EQUAL 1) if (number_of_targets EQUAL 1)
ly_de_alias_target(${ly_create_alias_TARGETS} de_aliased_target_name) if(TARGET ${ly_create_alias_TARGETS})
add_library(${ly_create_alias_NAMESPACE}::${ly_create_alias_NAME} ALIAS ${de_aliased_target_name}) ly_de_alias_target(${ly_create_alias_TARGETS} de_aliased_target_name)
if (NOT TARGET ${ly_create_alias_NAME}) add_library(${ly_create_alias_NAMESPACE}::${ly_create_alias_NAME} ALIAS ${de_aliased_target_name})
add_library(${ly_create_alias_NAME} ALIAS ${de_aliased_target_name}) if (NOT TARGET ${ly_create_alias_NAME})
add_library(${ly_create_alias_NAME} ALIAS ${de_aliased_target_name})
endif()
# Store off the arguments needed used ly_create_alias into a DIRECTORY property
# This will be used to re-create the calls in the generated CMakeLists.txt in the INSTALL step
string(REPLACE ";" " " create_alias_args "${ly_create_alias_NAME},${ly_create_alias_NAMESPACE},${ly_create_alias_TARGETS}")
set_property(DIRECTORY APPEND PROPERTY LY_CREATE_ALIAS_ARGUMENTS "${ly_create_alias_NAME},${ly_create_alias_NAMESPACE},${ly_create_alias_TARGETS}")
return()
endif() endif()
# Store off the arguments needed used ly_create_alias into a DIRECTORY property
# This will be used to re-create the calls in the generated CMakeLists.txt in the INSTALL step
string(REPLACE ";" " " create_alias_args "${ly_create_alias_NAME},${ly_create_alias_NAMESPACE},${ly_create_alias_TARGETS}")
set_property(DIRECTORY APPEND PROPERTY LY_CREATE_ALIAS_ARGUMENTS "${ly_create_alias_NAME},${ly_create_alias_NAMESPACE},${ly_create_alias_TARGETS}")
return()
endif() endif()
# more complex version - one alias to multiple targets. To actually achieve this # more complex version - one alias to multiple targets or the alias is being made to a TARGET that doesn't exist yet.
# we have to create an interface library with those dependencies, then we have to create an alias to that target. # To actually achieve this we have to create an interface library with those dependencies,
# by convention we create one without a namespace then alias the namespaced one. # then we have to create an alias to that target.
# By convention we create one without a namespace then alias the namespaced one.
if(TARGET ${ly_create_alias_NAME}) if(TARGET ${ly_create_alias_NAME})
message(FATAL_ERROR "Internal alias target already exists, cannot create an alias for it: ${ly_create_alias_NAME}\n" message(FATAL_ERROR "Internal alias target already exists, cannot create an alias for it: ${ly_create_alias_NAME}\n"

@ -212,6 +212,28 @@ def save_o3de_manifest(json_data: dict, manifest_path: pathlib.Path = None) -> b
return False return False
def get_gems_from_subdirectories(external_subdirs: list) -> list:
'''
Helper Method for scanning a set of external subdirectories for gem.json files
'''
def is_gem_subdirectory(subdir_files):
for name in files:
if name == 'gem.json':
return True
return False
gem_directories = []
# Locate all subfolders with gem.json files within them
if external_subdirs:
for subdirectory in external_subdirs:
for root, dirs, files in os.walk(pathlib.Path(subdirectory).resolve()):
if is_gem_subdirectory(files):
gem_directories.append(pathlib.PurePath(root).as_posix())
return gem_directories
# Data query methods # Data query methods
def get_this_engine() -> dict: def get_this_engine() -> dict:
json_data = load_o3de_manifest() json_data = load_o3de_manifest()
@ -230,11 +252,7 @@ def get_projects() -> list:
def get_gems() -> list: def get_gems() -> list:
def is_gem_subdirectory(subdir): return get_gems_from_subdirectories(get_external_subdirectories())
return (pathlib.Path(subdir) / 'gem.json').exists()
external_subdirs = get_external_subdirectories()
return list(filter(is_gem_subdirectory, external_subdirs)) if external_subdirs else []
def get_external_subdirectories() -> list: def get_external_subdirectories() -> list:
@ -265,11 +283,7 @@ def get_engine_projects() -> list:
def get_engine_gems() -> list: def get_engine_gems() -> list:
def is_gem_subdirectory(subdir): return get_gems_from_subdirectories(get_engine_external_subdirectories())
return (pathlib.Path(subdir) / 'gem.json').exists()
external_subdirs = get_engine_external_subdirectories()
return list(filter(is_gem_subdirectory, external_subdirs)) if external_subdirs else []
def get_engine_external_subdirectories() -> list: def get_engine_external_subdirectories() -> list:
@ -295,11 +309,7 @@ def get_engine_restricted() -> list:
# project.json queries # project.json queries
def get_project_gems(project_path: pathlib.Path) -> list: def get_project_gems(project_path: pathlib.Path) -> list:
def is_gem_subdirectory(subdir): return get_gems_from_subdirectories(get_project_external_subdirectories(project_path))
return (pathlib.Path(subdir) / 'gem.json').exists()
external_subdirs = get_project_external_subdirectories(project_path)
return list(filter(is_gem_subdirectory, external_subdirs)) if external_subdirs else []
def get_project_external_subdirectories(project_path: pathlib.Path) -> list: def get_project_external_subdirectories(project_path: pathlib.Path) -> list:

Loading…
Cancel
Save