diff --git a/Gems/AWSCore/Code/CMakeLists.txt b/Gems/AWSCore/Code/CMakeLists.txt index 7559f4720b..d84f7814c3 100644 --- a/Gems/AWSCore/Code/CMakeLists.txt +++ b/Gems/AWSCore/Code/CMakeLists.txt @@ -111,6 +111,9 @@ if (PAL_TRAIT_BUILD_HOST_TOOLS) BUILD_DEPENDENCIES PRIVATE Gem::AWSCore.Editor.Static + RUNTIME_DEPENDENCIES + 3rdParty::pyside2 + ) ly_add_dependencies(AWSCore.Editor AWSCore.ResourceMappingTool) diff --git a/Gems/AWSCore/Code/Include/Private/Editor/UI/AWSCoreResourceMappingToolAction.h b/Gems/AWSCore/Code/Include/Private/Editor/UI/AWSCoreResourceMappingToolAction.h index 1a4c428e68..a065773743 100644 --- a/Gems/AWSCore/Code/Include/Private/Editor/UI/AWSCoreResourceMappingToolAction.h +++ b/Gems/AWSCore/Code/Include/Private/Editor/UI/AWSCoreResourceMappingToolAction.h @@ -13,6 +13,8 @@ #include #include +#include "AWSCoreEditor_Traits_Platform.h" + namespace AWSCore { class AWSCoreResourceMappingToolAction @@ -22,7 +24,7 @@ namespace AWSCore static constexpr const char AWSCoreResourceMappingToolActionName[] = "AWSCoreResourceMappingToolAction"; static constexpr const char ResourceMappingToolDirectoryPath[] = "Gems/AWSCore/Code/Tools/ResourceMappingTool"; static constexpr const char ResourceMappingToolLogDirectoryPath[] = "user/log/"; - static constexpr const char EngineWindowsPythonEntryScriptPath[] = "python/python.cmd"; + static constexpr const char EngineWindowsPythonEntryScriptPath[] = AWSCORE_EDITOR_PYTHON_COMMAND; AWSCoreResourceMappingToolAction(const QString& text, QObject* parent = nullptr); diff --git a/Gems/AWSCore/Code/Platform/Linux/AWSCoreEditor_Traits_Linux.h b/Gems/AWSCore/Code/Platform/Linux/AWSCoreEditor_Traits_Linux.h index fb82911dd4..726d4cc86f 100644 --- a/Gems/AWSCore/Code/Platform/Linux/AWSCoreEditor_Traits_Linux.h +++ b/Gems/AWSCore/Code/Platform/Linux/AWSCoreEditor_Traits_Linux.h @@ -7,4 +7,6 @@ */ #pragma once -#define AWSCORE_EDITOR_RESOURCE_MAPPING_TOOL_ENABLED 0 +#define AWSCORE_EDITOR_RESOURCE_MAPPING_TOOL_ENABLED 1 +#define AWSCORE_EDITOR_PYTHON_DEBUG_ARGUMENT "" +#define AWSCORE_EDITOR_PYTHON_COMMAND "python/python.sh" diff --git a/Gems/AWSCore/Code/Platform/Mac/AWSCoreEditor_Traits_Mac.h b/Gems/AWSCore/Code/Platform/Mac/AWSCoreEditor_Traits_Mac.h index fb82911dd4..d815c8273e 100644 --- a/Gems/AWSCore/Code/Platform/Mac/AWSCoreEditor_Traits_Mac.h +++ b/Gems/AWSCore/Code/Platform/Mac/AWSCoreEditor_Traits_Mac.h @@ -8,3 +8,5 @@ #pragma once #define AWSCORE_EDITOR_RESOURCE_MAPPING_TOOL_ENABLED 0 +#define AWSCORE_EDITOR_PYTHON_DEBUG_ARGUMENT "" +#define AWSCORE_EDITOR_PYTHON_COMMAND "python/python.sh" diff --git a/Gems/AWSCore/Code/Platform/Windows/AWSCoreEditor_Traits_Windows.h b/Gems/AWSCore/Code/Platform/Windows/AWSCoreEditor_Traits_Windows.h index e1522db32c..6eca30a8ac 100644 --- a/Gems/AWSCore/Code/Platform/Windows/AWSCoreEditor_Traits_Windows.h +++ b/Gems/AWSCore/Code/Platform/Windows/AWSCoreEditor_Traits_Windows.h @@ -8,3 +8,5 @@ #pragma once #define AWSCORE_EDITOR_RESOURCE_MAPPING_TOOL_ENABLED 1 +#define AWSCORE_EDITOR_PYTHON_DEBUG_ARGUMENT "debug " +#define AWSCORE_EDITOR_PYTHON_COMMAND "python/python.cmd" diff --git a/Gems/AWSCore/Code/Source/Editor/UI/AWSCoreResourceMappingToolAction.cpp b/Gems/AWSCore/Code/Source/Editor/UI/AWSCoreResourceMappingToolAction.cpp index 858d30fa40..49f800dbea 100644 --- a/Gems/AWSCore/Code/Source/Editor/UI/AWSCoreResourceMappingToolAction.cpp +++ b/Gems/AWSCore/Code/Source/Editor/UI/AWSCoreResourceMappingToolAction.cpp @@ -58,7 +58,7 @@ namespace AWSCore if (m_isDebug) { return AZStd::string::format( - "\"%s\" debug -B \"%s\" --binaries-path \"%s\" --debug --profile \"%s\" --config-path \"%s\" --log-path \"%s\"", + "\"%s\" " AWSCORE_EDITOR_PYTHON_DEBUG_ARGUMENT "-B \"%s\" --binaries-path \"%s\" --debug --profile \"%s\" --config-path \"%s\" --log-path \"%s\"", m_enginePythonEntryPath.c_str(), m_toolScriptPath.c_str(), m_toolQtBinDirectoryPath.c_str(), profileName.c_str(), m_toolConfigDirectoryPath.c_str(), m_toolLogDirectoryPath.c_str()); } diff --git a/Gems/AWSCore/Code/Tools/ResourceMappingTool/README.md b/Gems/AWSCore/Code/Tools/ResourceMappingTool/README.md index e09ecc281f..29479fa3e1 100644 --- a/Gems/AWSCore/Code/Tools/ResourceMappingTool/README.md +++ b/Gems/AWSCore/Code/Tools/ResourceMappingTool/README.md @@ -39,6 +39,16 @@ Follow cmake instructions to configure your project, for example: ``` $ python\python.cmd debug Gems\AWSCore\Code\Tools\ResourceMappingTool\resource_mapping_tool.py --binaries_path \bin\debug\AWSCoreEditorQtBin ``` + * Linux + * release mode + ``` + $ python/python.sh Gems/AWSCore/Code/Tools/ResourceMappingTool/resource_mapping_tool.py --binaries_path /bin/profile/AWSCoreEditorQtBin + ``` + * debug mode + ``` + $ python/python.sh Gems/AWSCore/Code/Tools/ResourceMappingTool/resource_mapping_tool.py --binaries_path /bin/debug/AWSCoreEditorQtBin + ``` + * Note - Editor is integrated with the same engine python environment to launch Resource Mapping Tool. If it is failed to launch the tool in Editor, please follow above steps to make sure expected scripts/binaries are present. diff --git a/Gems/AWSCore/Code/Tools/ResourceMappingTool/resource_mapping_tool.py b/Gems/AWSCore/Code/Tools/ResourceMappingTool/resource_mapping_tool.py index 2351fd001b..b254960f77 100755 --- a/Gems/AWSCore/Code/Tools/ResourceMappingTool/resource_mapping_tool.py +++ b/Gems/AWSCore/Code/Tools/ResourceMappingTool/resource_mapping_tool.py @@ -20,6 +20,7 @@ argument_parser.add_argument('--debug', action='store_true', help='Execute on de argument_parser.add_argument('--log-path', help='Path to resource mapping tool logging directory ' '(if not provided, logging file will be located at tool directory)') argument_parser.add_argument('--profile', default='default', help='Named AWS profile to use for querying AWS resources') + arguments: Namespace = argument_parser.parse_args() # logging setup diff --git a/Gems/AWSCore/Code/Tools/ResourceMappingTool/tests/unit/utils/test_environment_utils.py b/Gems/AWSCore/Code/Tools/ResourceMappingTool/tests/unit/utils/test_environment_utils.py index 756d6fdb10..3d36a56468 100644 --- a/Gems/AWSCore/Code/Tools/ResourceMappingTool/tests/unit/utils/test_environment_utils.py +++ b/Gems/AWSCore/Code/Tools/ResourceMappingTool/tests/unit/utils/test_environment_utils.py @@ -5,6 +5,7 @@ For complete copyright and license terms please see the LICENSE at the root of t SPDX-License-Identifier: Apache-2.0 OR MIT """ +import platform from typing import List from unittest import TestCase from unittest.mock import (ANY, call, MagicMock, patch) @@ -27,14 +28,24 @@ class TestEnvironmentUtils(TestCase): self.addCleanup(os_pathsep_patcher.stop) self._mock_os_pathsep: MagicMock = os_pathsep_patcher.start() - def test_setup_qt_environment_global_flag_is_set(self) -> None: + @patch('os.path.exists') + @patch('ctypes.CDLL') + def test_setup_qt_environment_global_flag_is_set(self, mock_os_path_exists, mock_ctype_cdll) -> None: + mock_os_path_exists.return_value = True environment_utils.setup_qt_environment("dummy") self._mock_os_environ.copy.assert_called_once() self._mock_os_pathsep.join.assert_called_once() assert environment_utils.is_qt_linked() is True + if platform.system() == 'Linux': + mock_os_path_exists.assert_called() - def test_cleanup_qt_environment_global_flag_is_set(self) -> None: + @patch('os.path.exists') + @patch('ctypes.CDLL') + def test_cleanup_qt_environment_global_flag_is_set(self, mock_os_path_exists, mock_ctype_cdll) -> None: + mock_os_path_exists.return_value = True environment_utils.setup_qt_environment("dummy") assert environment_utils.is_qt_linked() is True environment_utils.cleanup_qt_environment() assert environment_utils.is_qt_linked() is False + if platform.system() == 'Linux': + mock_os_path_exists.assert_called() diff --git a/Gems/AWSCore/Code/Tools/ResourceMappingTool/utils/environment_utils.py b/Gems/AWSCore/Code/Tools/ResourceMappingTool/utils/environment_utils.py index 8600fe31b5..b67f64e715 100644 --- a/Gems/AWSCore/Code/Tools/ResourceMappingTool/utils/environment_utils.py +++ b/Gems/AWSCore/Code/Tools/ResourceMappingTool/utils/environment_utils.py @@ -7,6 +7,7 @@ SPDX-License-Identifier: Apache-2.0 OR MIT import logging import os +import platform from typing import Dict from utils import file_utils @@ -38,6 +39,20 @@ def setup_qt_environment(bin_path: str) -> None: new_path = os.pathsep.join([binaries_path, path]) os.environ['PATH'] = new_path + # On Linux, we need to load pyside2 and related modules as well + if platform.system() == 'Linux': + import ctypes + + preload_shared_libs = [f'{bin_path}/libpyside2.abi3.so.5.14', + f'{bin_path}/libQt5Widgets.so.5'] + + for preload_shared_lib in preload_shared_libs: + if not os.path.exists(preload_shared_lib): + logger.error(f"Cannot find required shared library at {preload_shared_lib}") + return + else: + ctypes.CDLL(preload_shared_lib) + global qt_binaries_linked qt_binaries_linked = True