Răsfoiți Sursa

[IMPACTFUL CHANGE] Shared AZ Framework

Update Framework Libraries (AzCore, AzFramework, AzToolsFramework) to shared libraries.

RFC: https://github.com/o3de/sig-core/blob/cacff6e84b5ef33a6cfa0f511ec9ad0fc9c35437/rfcs/rfc-core-2025-04-20-shared-az-framework-libraries.md 

Signed-off-by: Steve Pham <[email protected]>
Steve Pham 4 zile în urmă
părinte
comite
8dd450dac8
100 a modificat fișierele cu 838 adăugiri și 717 ștergeri
  1. 4 0
      AutomatedTesting/Gem/PythonTests/editor_test_testing/TestSuite_Main.py
  2. 1 1
      Code/Editor/AzAssetBrowser/AzAssetBrowserWindow.cpp
  3. 2 2
      Code/Editor/EditorPreferencesPageAWS.cpp
  4. 4 0
      Code/Editor/Platform/Windows/editor_lib_windows.cmake
  5. 10 10
      Code/Editor/Util/Variable.h
  6. 2 0
      Code/Framework/AzCore/AzCore/Asset/AssetCommon.cpp
  7. 18 24
      Code/Framework/AzCore/AzCore/Asset/AssetCommon.h
  8. 1 1
      Code/Framework/AzCore/AzCore/Asset/AssetContainer.h
  9. 1 1
      Code/Framework/AzCore/AzCore/Asset/AssetDataStream.h
  10. 2 2
      Code/Framework/AzCore/AzCore/Asset/AssetJsonSerializer.h
  11. 2 0
      Code/Framework/AzCore/AzCore/Asset/AssetManager.cpp
  12. 8 8
      Code/Framework/AzCore/AzCore/Asset/AssetManager.h
  13. 12 0
      Code/Framework/AzCore/AzCore/Asset/AssetManagerBus.cpp
  14. 4 8
      Code/Framework/AzCore/AzCore/Asset/AssetManagerBus.h
  15. 2 6
      Code/Framework/AzCore/AzCore/Asset/AssetManagerComponent.h
  16. 1 1
      Code/Framework/AzCore/AzCore/Asset/AssetManager_private.h
  17. 3 3
      Code/Framework/AzCore/AzCore/Asset/AssetSerializer.h
  18. 12 0
      Code/Framework/AzCore/AzCore/Asset/AssetTypeInfoBus.cpp
  19. 1 1
      Code/Framework/AzCore/AzCore/Asset/AssetTypeInfoBus.h
  20. 2 0
      Code/Framework/AzCore/AzCore/Component/Component.cpp
  21. 5 4
      Code/Framework/AzCore/AzCore/Component/Component.h
  22. 6 3
      Code/Framework/AzCore/AzCore/Component/ComponentApplication.cpp
  23. 4 4
      Code/Framework/AzCore/AzCore/Component/ComponentApplication.h
  24. 11 0
      Code/Framework/AzCore/AzCore/Component/ComponentApplicationBus.cpp
  25. 4 4
      Code/Framework/AzCore/AzCore/Component/ComponentApplicationBus.h
  26. 4 4
      Code/Framework/AzCore/AzCore/Component/ComponentApplicationLifecycle.h
  27. 2 6
      Code/Framework/AzCore/AzCore/Component/ComponentBus.h
  28. 1 1
      Code/Framework/AzCore/AzCore/Component/ComponentExport.h
  29. 1 1
      Code/Framework/AzCore/AzCore/Component/Entity.h
  30. 11 0
      Code/Framework/AzCore/AzCore/Component/EntityBus.cpp
  31. 5 10
      Code/Framework/AzCore/AzCore/Component/EntityBus.h
  32. 1 1
      Code/Framework/AzCore/AzCore/Component/EntityId.h
  33. 1 1
      Code/Framework/AzCore/AzCore/Component/EntityIdSerializer.h
  34. 2 2
      Code/Framework/AzCore/AzCore/Component/EntitySerializer.h
  35. 12 12
      Code/Framework/AzCore/AzCore/Component/EntityUtils.h
  36. 1 1
      Code/Framework/AzCore/AzCore/Component/NamedEntityId.h
  37. 2 0
      Code/Framework/AzCore/AzCore/Component/NonUniformScaleBus.cpp
  38. 3 3
      Code/Framework/AzCore/AzCore/Component/NonUniformScaleBus.h
  39. 12 0
      Code/Framework/AzCore/AzCore/Component/TickBus.cpp
  40. 4 9
      Code/Framework/AzCore/AzCore/Component/TickBus.h
  41. 13 0
      Code/Framework/AzCore/AzCore/Component/TransformBus.cpp
  42. 3 3
      Code/Framework/AzCore/AzCore/Component/TransformBus.h
  43. 1 1
      Code/Framework/AzCore/AzCore/Compression/Compression.h
  44. 1 1
      Code/Framework/AzCore/AzCore/Compression/zstd_compression.h
  45. 1 1
      Code/Framework/AzCore/AzCore/Console/Console.h
  46. 2 2
      Code/Framework/AzCore/AzCore/Console/ConsoleFunctor.h
  47. 23 0
      Code/Framework/AzCore/AzCore/Console/IConsole.h
  48. 1 1
      Code/Framework/AzCore/AzCore/Console/LoggerSystemComponent.h
  49. 8 8
      Code/Framework/AzCore/AzCore/DOM/Backends/JSON/JsonSerializationUtils.h
  50. 1 1
      Code/Framework/AzCore/AzCore/DOM/DomBackend.h
  51. 2 1
      Code/Framework/AzCore/AzCore/DOM/DomComparison.h
  52. 5 5
      Code/Framework/AzCore/AzCore/DOM/DomPatch.h
  53. 4 4
      Code/Framework/AzCore/AzCore/DOM/DomPath.h
  54. 17 17
      Code/Framework/AzCore/AzCore/DOM/DomUtils.h
  55. 4 4
      Code/Framework/AzCore/AzCore/DOM/DomValue.h
  56. 5 3
      Code/Framework/AzCore/AzCore/DOM/DomValueWriter.h
  57. 2 2
      Code/Framework/AzCore/AzCore/DOM/DomVisitor.h
  58. 9 9
      Code/Framework/AzCore/AzCore/Date/DateFormat.h
  59. 23 5
      Code/Framework/AzCore/AzCore/Debug/Budget.h
  60. 1 1
      Code/Framework/AzCore/AzCore/Debug/BudgetTracker.h
  61. 0 1
      Code/Framework/AzCore/AzCore/Debug/ITrace.cpp
  62. 2 2
      Code/Framework/AzCore/AzCore/Debug/PerformanceCollector.h
  63. 11 11
      Code/Framework/AzCore/AzCore/Debug/Profiler.cpp
  64. 2 2
      Code/Framework/AzCore/AzCore/Debug/Profiler.h
  65. 1 1
      Code/Framework/AzCore/AzCore/Debug/ProfilerBus.h
  66. 1 1
      Code/Framework/AzCore/AzCore/Debug/ProfilerReflection.h
  67. 4 4
      Code/Framework/AzCore/AzCore/Debug/StackTracer.h
  68. 1 1
      Code/Framework/AzCore/AzCore/Debug/Timer.h
  69. 1 1
      Code/Framework/AzCore/AzCore/Debug/Trace.cpp
  70. 3 4
      Code/Framework/AzCore/AzCore/Debug/Trace.h
  71. 10 0
      Code/Framework/AzCore/AzCore/Debug/TraceMessageBus.cpp
  72. 1 1
      Code/Framework/AzCore/AzCore/Debug/TraceMessageBus.h
  73. 3 1
      Code/Framework/AzCore/AzCore/Debug/TraceReflection.h
  74. 88 360
      Code/Framework/AzCore/AzCore/EBus/EBus.h
  75. 2 1
      Code/Framework/AzCore/AzCore/EBus/EBusEnvironment.cpp
  76. 3 5
      Code/Framework/AzCore/AzCore/EBus/Environment.h
  77. 1 1
      Code/Framework/AzCore/AzCore/EBus/EventSchedulerSystemComponent.h
  78. 299 32
      Code/Framework/AzCore/AzCore/EBus/Internal/Handlers.h
  79. 1 1
      Code/Framework/AzCore/AzCore/EBus/ScheduledEvent.h
  80. 1 1
      Code/Framework/AzCore/AzCore/EBus/ScheduledEventHandle.h
  81. 6 4
      Code/Framework/AzCore/AzCore/IO/AnsiTerminalUtils.h
  82. 2 0
      Code/Framework/AzCore/AzCore/IO/CompressionBus.cpp
  83. 5 3
      Code/Framework/AzCore/AzCore/IO/CompressionBus.h
  84. 3 3
      Code/Framework/AzCore/AzCore/IO/Compressor.h
  85. 1 1
      Code/Framework/AzCore/AzCore/IO/CompressorStream.h
  86. 2 2
      Code/Framework/AzCore/AzCore/IO/CompressorZLib.h
  87. 2 2
      Code/Framework/AzCore/AzCore/IO/CompressorZStd.h
  88. 7 7
      Code/Framework/AzCore/AzCore/IO/FileIO.h
  89. 1 1
      Code/Framework/AzCore/AzCore/IO/FileReader.h
  90. 4 4
      Code/Framework/AzCore/AzCore/IO/GenericStreams.h
  91. 1 1
      Code/Framework/AzCore/AzCore/IO/IOUtils.cpp
  92. 3 1
      Code/Framework/AzCore/AzCore/IO/IOUtils.h
  93. 9 9
      Code/Framework/AzCore/AzCore/IO/IStreamerTypes.h
  94. 4 4
      Code/Framework/AzCore/AzCore/IO/OpenMode.h
  95. 21 21
      Code/Framework/AzCore/AzCore/IO/Path/Path.cpp
  96. 9 9
      Code/Framework/AzCore/AzCore/IO/Path/Path.h
  97. 7 7
      Code/Framework/AzCore/AzCore/IO/Path/Path.inl
  98. 1 1
      Code/Framework/AzCore/AzCore/IO/Path/PathReflect.cpp
  99. 3 1
      Code/Framework/AzCore/AzCore/IO/Path/PathReflect.h
  100. 2 2
      Code/Framework/AzCore/AzCore/IO/Streamer/BlockCache.h

+ 4 - 0
AutomatedTesting/Gem/PythonTests/editor_test_testing/TestSuite_Main.py

@@ -194,6 +194,7 @@ class TestEditorTest:
         # 1 Fail, 1 Passes +1(batch runner)
         result.assert_outcomes(passed=2, failed=1)
 
+    @pytest.mark.skipif(sys.platform == "linux", reason="Skipping crash tests on Linux due to inconsistency between AR and local tests, but keeping for reference.")
     def test_batched_1_pass_1_fail_1_crash(self, request, workspace, launcher_platform, pytester):
         result = self._run_shared_test(pytester, workspace,
             """
@@ -229,6 +230,7 @@ class TestEditorTest:
         # 2 Passes +1(parallel runner)
         result.assert_outcomes(passed=3)
 
+    @pytest.mark.skipif(sys.platform == "linux", reason="Skipping crash tests on Linux due to inconsistency between AR and local tests, but keeping for reference.")
     def test_parallel_1_pass_1_fail_1_crash(self, request, workspace, launcher_platform, pytester):
         result = self._run_shared_test(pytester, workspace,
             """
@@ -262,6 +264,7 @@ class TestEditorTest:
         # 2 Passes +1(batched+parallel runner)
         result.assert_outcomes(passed=3)
 
+    @pytest.mark.skipif(sys.platform == "linux", reason="Skipping crash tests on Linux due to inconsistency between AR and local tests, but keeping for reference.")
     def test_parallel_batched_1_pass_1_fail_1_crash(self, request, workspace, launcher_platform, pytester):
         result = self._run_shared_test(pytester, workspace,
             """
@@ -278,6 +281,7 @@ class TestEditorTest:
         # 2 Fail, 1 Passes + 1(batched+parallel runner)
         result.assert_outcomes(passed=2, failed=2)
 
+    @pytest.mark.skipif(sys.platform == "linux", reason="Skipping crash tests on Linux due to inconsistency between AR and local tests, but keeping for reference.")
     def test_selection_2_deselected_1_selected(self, request, workspace, launcher_platform, pytester):
         result = self._run_shared_test(pytester, workspace,
             """

+ 1 - 1
Code/Editor/AzAssetBrowser/AzAssetBrowserWindow.cpp

@@ -39,7 +39,7 @@ AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING
 #include <AzAssetBrowser/ui_AzAssetBrowserWindow.h>
 AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING
 
-AZ_CVAR_EXTERNED(bool, ed_useNewAssetBrowserListView);
+AZ_CVAR_API_EXTERNED(AZTF_API, bool, ed_useNewAssetBrowserListView);
 
 AZ_CVAR(bool, ed_useWIPAssetBrowserDesign, true, nullptr, AZ::ConsoleFunctorFlags::Null, "Use the in-progress new Asset Browser design");
 

+ 2 - 2
Code/Editor/EditorPreferencesPageAWS.cpp

@@ -83,7 +83,7 @@ void CEditorPreferencesPage_AWS::SaveSettingsRegistryFile()
 
             // Resolve path to editor_aws_preferences.setreg
             AZStd::string editorPreferencesFilePath =
-                AZStd::string::format("@user@/%s/%s", AZ::SettingsRegistryInterface::RegistryFolder, EditorAWSPreferencesFileName);
+                AZStd::string::format("@user@/%s/%s", AZ::SettingsRegistryConstants::RegistryFolder, EditorAWSPreferencesFileName);
             AZStd::array<char, AZ::IO::MaxPathLength> resolvedPath{};
             fileIO->ResolvePath(editorPreferencesFilePath.c_str(), resolvedPath.data(), resolvedPath.size());
 
@@ -125,7 +125,7 @@ void CEditorPreferencesPage_AWS::InitializeSettings()
 
     // Resolve path to editor_aws_preferences.setreg
     AZStd::string editorAWSPreferencesFilePath =
-        AZStd::string::format("@user@/%s/%s", AZ::SettingsRegistryInterface::RegistryFolder, EditorAWSPreferencesFileName);
+        AZStd::string::format("@user@/%s/%s", AZ::SettingsRegistryConstants::RegistryFolder, EditorAWSPreferencesFileName);
     AZStd::array<char, AZ::IO::MaxPathLength> resolvedPathAWSPreference{};
     if (!fileIO->ResolvePath(editorAWSPreferencesFilePath.c_str(), resolvedPathAWSPreference.data(), resolvedPathAWSPreference.size()))
     {

+ 4 - 0
Code/Editor/Platform/Windows/editor_lib_windows.cmake

@@ -5,3 +5,7 @@
 # SPDX-License-Identifier: Apache-2.0 OR MIT
 #
 #
+set(LY_BUILD_DEPENDENCIES
+    PRIVATE
+        version.lib
+)

+ 10 - 10
Code/Editor/Util/Variable.h

@@ -1014,35 +1014,35 @@ namespace var_type
         {
             AZ::Locale::ScopedSerializationLocale scopedLocale; // String should be interpreted in the "C" Locale.
             char buf[128] = { 0 };
-            azsprintf(buf, "%f,%f", value.x, value.y);
+            azsnprintf(buf, sizeof(buf), "%f,%f", value.x, value.y);
             to.assign(buf);
         }
         void operator()(const Vec3& value, AZStd::string& to) const
         {
             AZ::Locale::ScopedSerializationLocale scopedLocale; // String should be interpreted in the "C" Locale.
             char buf[192] = { 0 };
-            azsprintf(buf, "%f,%f,%f", value.x, value.y, value.z);
+            azsnprintf(buf, sizeof(buf), "%f,%f,%f", value.x, value.y, value.z);
             to.assign(buf);
         }
         void operator()(const Vec4& value, AZStd::string& to) const
         {
             AZ::Locale::ScopedSerializationLocale scopedLocale; // String should be interpreted in the "C" Locale.
             char buf[256] = { 0 };
-            azsprintf(buf, "%f,%f,%f,%f", value.x, value.y, value.z, value.w);
+            azsnprintf(buf, sizeof(buf), "%f,%f,%f,%f", value.x, value.y, value.z, value.w);
             to.assign(buf);
         }
         void operator()(const Ang3& value, AZStd::string& to) const
         {
             AZ::Locale::ScopedSerializationLocale scopedLocale; // String should be interpreted in the "C" Locale.
             char buf[192] = { 0 };
-            azsprintf(buf, "%f,%f,%f", value.x, value.y, value.z);
+            azsnprintf(buf, sizeof(buf), "%f,%f,%f", value.x, value.y, value.z);
             to.assign(buf);
         }
         void operator()(const Quat& value, AZStd::string& to) const
         {
             AZ::Locale::ScopedSerializationLocale scopedLocale; // String should be interpreted in the "C" Locale.
             char buf[256] = { 0 };
-            azsprintf(buf, "%f,%f,%f,%f", value.w, value.v.x, value.v.y, value.v.z);
+            azsnprintf(buf, sizeof(buf), "%f,%f,%f,%f", value.w, value.v.x, value.v.y, value.v.z);
             to.assign(buf);
         }
 
@@ -1050,35 +1050,35 @@ namespace var_type
         {
             AZ::Locale::ScopedSerializationLocale scopedLocale; // String should be interpreted in the "C" Locale.
             char buf[256] = { 0 };
-            azsprintf(buf, "%f,%f,%f,%f", from.GetR(), from.GetG(), from.GetB(), from.GetA());
+            azsnprintf(buf, sizeof(buf), "%f,%f,%f,%f", from.GetR(), from.GetG(), from.GetB(), from.GetA());
             to.assign(buf);
         }
         void operator()(const AZ::Vector2& from, AZStd::string& to) const
         {
             AZ::Locale::ScopedSerializationLocale scopedLocale; // String should be interpreted in the "C" Locale.
             char buf[128] = { 0 };
-            azsprintf(buf, "%f,%f", from.GetX(), from.GetY());
+            azsnprintf(buf, sizeof(buf), "%f,%f", from.GetX(), from.GetY());
             to.assign(buf);
         }
         void operator()(const AZ::Vector3& from, AZStd::string& to) const
         {
             AZ::Locale::ScopedSerializationLocale scopedLocale; // String should be interpreted in the "C" Locale.
             char buf[192] = { 0 };
-            azsprintf(buf, "%f,%f,%f", from.GetX(), from.GetY(), from.GetZ());
+            azsnprintf(buf, sizeof(buf), "%f,%f,%f", from.GetX(), from.GetY(), from.GetZ());
             to.assign(buf);
         }
         void operator()(const AZ::Vector4& from, AZStd::string& to) const
         {
             AZ::Locale::ScopedSerializationLocale scopedLocale; // String should be interpreted in the "C" Locale.
             char buf[256] = { 0 };
-            azsprintf(buf, "%f,%f,%f,%f", from.GetX(), from.GetY(), from.GetZ(), from.GetZ());
+            azsnprintf(buf, sizeof(buf), "%f,%f,%f,%f", from.GetX(), from.GetY(), from.GetZ(), from.GetZ());
             to.assign(buf);
         }
         void operator()(const AZ::Quaternion& from, AZStd::string& to) const
         {
             AZ::Locale::ScopedSerializationLocale scopedLocale; // String should be interpreted in the "C" Locale.
             char buf[256] = { 0 };
-            azsprintf(buf, "%f,%f,%f,%f", from.GetX(), from.GetY(), from.GetZ(), from.GetZ());
+            azsnprintf(buf, sizeof(buf), "%f,%f,%f,%f", from.GetX(), from.GetY(), from.GetZ(), from.GetZ());
             to.assign(buf);
         }
 

+ 2 - 0
Code/Framework/AzCore/AzCore/Asset/AssetCommon.cpp

@@ -14,6 +14,8 @@
 #include <AzCore/std/parallel/lock.h>
 #include <AzCore/std/string/conversions.h>
 
+AZ_INSTANTIATE_EBUS_MULTI_ADDRESS(AZCORE_API, AZ::Data::AssetEvents);
+
 namespace AZ::Data
 {
     AssetFilterInfo::AssetFilterInfo(const AssetId& id, const AssetType& assetType, AssetLoadBehavior loadBehavior)

+ 18 - 24
Code/Framework/AzCore/AzCore/Asset/AssetCommon.h

@@ -42,17 +42,12 @@ namespace AZ
 
         typedef Uuid AssetType;
 
-        namespace AssetInternal
-        {
-            bool IsValidAssetType(const AssetType& type, AZ::SerializeContext* serializeContext = nullptr);
-        }
-
         /**
          * Asset ID types
          */
         typedef AssetData*  AssetPtr;
 
-        struct AssetId
+        struct AZCORE_API AssetId
         {
             AZ_TYPE_INFO(AssetId, "{652ED536-3402-439B-AEBE-4A5DBC554085}");
 
@@ -109,7 +104,7 @@ namespace AZ
         /**
          * Base class for all asset types.
          */
-        class AssetData
+        class AZCORE_API AssetData
         {
             template<class T>
             friend class Asset;
@@ -227,7 +222,7 @@ namespace AZ
             (Default, QueueLoad)
         );
 
-        struct AssetFilterInfo
+        struct AZCORE_API AssetFilterInfo
         {
             AssetId m_assetId;
             AssetType m_assetType;
@@ -249,7 +244,7 @@ namespace AZ
             LoadAll = 1
         };
 
-        struct AssetLoadParameters
+        struct AZCORE_API AssetLoadParameters
         {
             AssetLoadParameters() : m_assetLoadFilterCB() {}
 
@@ -509,15 +504,14 @@ namespace AZ
 
         namespace AssetInternal
         {
-            Asset<AssetData> FindOrCreateAsset(const AssetId& id, const AssetType& type, AssetLoadBehavior assetReferenceLoadBehavior);
-            Asset<AssetData> GetAsset(const AssetId& id, const AssetType& type, AssetLoadBehavior assetReferenceLoadBehavior,
-                const AZ::Data::AssetLoadParameters& assetLoadFilterCB = AssetLoadParameters{});
-            AssetData::AssetStatus BlockUntilLoadComplete(const Asset<AssetData>& asset);
-            void UpdateAssetInfo(AssetId& id, AZStd::string& assetHint);
-            bool ReloadAsset(AssetData* assetData, AssetLoadBehavior assetReferenceLoadBehavior);
-            bool SaveAsset(AssetData* assetData, AssetLoadBehavior assetReferenceLoadBehavior);
-            Asset<AssetData> GetAssetData(const AssetId& id, AssetLoadBehavior assetReferenceLoadBehavior);
-            AssetId ResolveAssetId(const AssetId& id);
+            AZCORE_API Asset<AssetData> FindOrCreateAsset(const AssetId& id, const AssetType& type, AssetLoadBehavior assetReferenceLoadBehavior);
+            AZCORE_API Asset<AssetData> GetAsset(const AssetId& id, const AssetType& type, AssetLoadBehavior assetReferenceLoadBehavior, const AZ::Data::AssetLoadParameters& assetLoadFilterCB = AssetLoadParameters{});
+            AZCORE_API AssetData::AssetStatus BlockUntilLoadComplete(const Asset<AssetData>& asset);
+            AZCORE_API void UpdateAssetInfo(AssetId& id, AZStd::string& assetHint);
+            AZCORE_API bool ReloadAsset(AssetData* assetData, AssetLoadBehavior assetReferenceLoadBehavior);
+            AZCORE_API bool SaveAsset(AssetData* assetData, AssetLoadBehavior assetReferenceLoadBehavior);
+            AZCORE_API Asset<AssetData> GetAssetData(const AssetId& id, AssetLoadBehavior assetReferenceLoadBehavior);
+            AZCORE_API AssetId ResolveAssetId(const AssetId& id);
         }
 
         /**
@@ -631,7 +625,7 @@ namespace AZ
         /*
          * AssetBusCallbacks is a utility class that maps AssetBus events to user callbacks
          */
-        class AssetBusCallbacks
+        class AZCORE_API AssetBusCallbacks
             : public AssetBus::Handler
         {
         public:
@@ -1224,7 +1218,7 @@ namespace AZ
         //=========================================================================
 
         /// Indiscriminately skips all asset references.
-        bool AssetFilterNoAssetLoading(const AssetFilterInfo& filterInfo);
+        AZCORE_API bool AssetFilterNoAssetLoading(const AssetFilterInfo& filterInfo);
 
         // Shared ProductDependency concepts between AP and LY
         namespace ProductDependencyInfo
@@ -1240,8 +1234,8 @@ namespace AZ
                 Unused
             };
             using ProductDependencyFlags = AZStd::bitset<64>;
-            AZ::Data::AssetLoadBehavior LoadBehaviorFromFlags(const ProductDependencyFlags& dependencyFlags);
-            AZ::Data::ProductDependencyInfo::ProductDependencyFlags CreateFlags(AZ::Data::AssetLoadBehavior autoLoadBehavior);
+            AZCORE_API AZ::Data::AssetLoadBehavior LoadBehaviorFromFlags(const ProductDependencyFlags& dependencyFlags);
+            AZCORE_API AZ::Data::ProductDependencyInfo::ProductDependencyFlags CreateFlags(AZ::Data::AssetLoadBehavior autoLoadBehavior);
         } // namespace ProductDependencyInfo
     }  // namespace Data
 
@@ -1254,7 +1248,7 @@ namespace AZStd
 {
     // hash specialization
     template <>
-    struct hash<AZ::Data::AssetId>
+    struct AZCORE_API hash<AZ::Data::AssetId>
     {
         typedef AZ::Uuid    argument_type;
         typedef size_t      result_type;
@@ -1266,4 +1260,4 @@ namespace AZStd
     };
 }
 
-DECLARE_EBUS_EXTERN_DLL_MULTI_ADDRESS(Data::AssetEvents);
+AZ_DECLARE_EBUS_MULTI_ADDRESS(AZCORE_API, AZ::Data::AssetEvents);

+ 1 - 1
Code/Framework/AzCore/AzCore/Asset/AssetContainer.h

@@ -28,7 +28,7 @@ namespace AZ
         // no guaranteed order.  However, the OnAssetContainerReady signals will not emit until all PreLoad and QueueLoad assets
         // are ready.  NoLoad dependencies are not loaded by default but can be loaded along with their dependencies using the
         // same rules as above by using the LoadAll dependency rule.
-        class AssetContainer :
+        class AZCORE_API AssetContainer :
             AZ::Data::AssetLoadBus::MultiHandler
         {
         public:

+ 1 - 1
Code/Framework/AzCore/AzCore/Asset/AssetDataStream.h

@@ -25,7 +25,7 @@ namespace AZ::Data
         struct AssetDataStreamPrivate;
     }
 
-    class AssetDataStream : public AZ::IO::GenericStream
+    class AZCORE_API AssetDataStream : public AZ::IO::GenericStream
     {
     public:
         using VectorDataSource = AZStd::vector<AZ::u8, AZStd::allocator>;

+ 2 - 2
Code/Framework/AzCore/AzCore/Asset/AssetJsonSerializer.h

@@ -17,7 +17,7 @@ namespace AZ
     namespace Data
     {
         //! JSON serializer for Asset<T>.
-        class AssetJsonSerializer
+        class AZCORE_API AssetJsonSerializer
             : public BaseJsonSerializer
         {
         public:
@@ -35,7 +35,7 @@ namespace AZ
             JsonSerializationResult::Result LoadAsset(void* outputValue, const rapidjson::Value& inputValue, JsonDeserializerContext& context);
         };
 
-        class SerializedAssetTracker final
+        class AZCORE_API SerializedAssetTracker final
         {
         public:
             AZ_RTTI(SerializedAssetTracker, "{1E067091-8C0A-44B1-A455-6E97663F6963}");

+ 2 - 0
Code/Framework/AzCore/AzCore/Asset/AssetManager.cpp

@@ -39,6 +39,8 @@
 #define ASSET_DEBUG_OUTPUT(OUTPUT)
 #endif
 
+AZ_INSTANTIATE_EBUS_MULTI_ADDRESS(AZCORE_API, AZ::Data::AssetLoadEvents);
+
 namespace AZ::Data
 {
     AZ_CVAR(bool, cl_assetLoadWarningEnable, false, nullptr, AZ::ConsoleFunctorFlags::Null,

+ 8 - 8
Code/Framework/AzCore/AzCore/Asset/AssetManager.h

@@ -56,7 +56,7 @@ namespace AZ
         class AssetDatabaseJob;
         class WaitForAsset;
 
-        struct IDebugAssetEvent
+        struct AZCORE_API IDebugAssetEvent
         {
             AZ_RTTI(IDebugAssetEvent, "{1FEF8289-C730-426D-B3B9-4BBA66339D66}");
 
@@ -67,7 +67,7 @@ namespace AZ
             virtual void ReleaseAsset(AZ::Data::AssetId id) = 0;
         };
 
-        struct AssetContainerKey
+        struct AZCORE_API AssetContainerKey
         {
             AssetId m_assetId;
             AssetLoadParameters m_loadParameters;
@@ -78,7 +78,7 @@ namespace AZ
             }
         };
 
-        class AssetStreamInfo
+        class AZCORE_API AssetStreamInfo
         {
         public:
             AssetStreamInfo()
@@ -98,7 +98,7 @@ namespace AZ
             u64             m_dataOffset;
         };
 
-        struct AssetDependencyEntry
+        struct AZCORE_API AssetDependencyEntry
         {
             AssetId     m_assetId;
             AssetType   m_assetType;
@@ -108,7 +108,7 @@ namespace AZ
         /*
          * This is the base class for Async AssetDatabase jobs
          */
-        class AssetDatabaseJob
+        class AZCORE_API AssetDatabaseJob
             : public AZStd::intrusive_list_node<AssetDatabaseJob>
         {
             friend class AssetManager;
@@ -133,7 +133,7 @@ namespace AZ
          * If an asset is ready at the time you connect to AssetBus or GetAsset() is called,
          * your handler will be notified immediately, otherwise all events are dispatched asynchronously.
          */
-        class AssetManager
+        class AZCORE_API AssetManager
             : private AssetManagerBus::Handler
         {
             friend class AssetData;
@@ -145,7 +145,7 @@ namespace AZ
             friend class WaitForAsset;
 
         public:
-            struct Descriptor
+            struct AZCORE_API Descriptor
             {
                 Descriptor() = default;
             };
@@ -514,7 +514,7 @@ namespace AZ
          }
 
          */
-        class AssetHandler
+        class AZCORE_API  AssetHandler
         {
             friend class AssetManager;
             friend class AssetData;

+ 12 - 0
Code/Framework/AzCore/AzCore/Asset/AssetManagerBus.cpp

@@ -0,0 +1,12 @@
+/*
+ * 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
+ *
+ */
+#include <AzCore/Asset/AssetManagerBus.h>
+
+AZ_INSTANTIATE_EBUS_SINGLE_ADDRESS(AZCORE_API, Data::AssetManagerNotifications);
+AZ_INSTANTIATE_EBUS_SINGLE_ADDRESS(AZCORE_API, Data::AssetCatalogRequests);
+AZ_INSTANTIATE_EBUS_SINGLE_ADDRESS(AZCORE_API, Data::AssetManagerEvents);

+ 4 - 8
Code/Framework/AzCore/AzCore/Asset/AssetManagerBus.h

@@ -5,8 +5,7 @@
  * SPDX-License-Identifier: Apache-2.0 OR MIT
  *
  */
-#ifndef AZCORE_ASSET_DATABASE_BUS_H
-#define AZCORE_ASSET_DATABASE_BUS_H
+#pragma once
 
 #include <AzCore/EBus/EBus.h>
 #include <AzCore/Asset/AssetCommon.h>
@@ -298,9 +297,6 @@ namespace AZ
     }   // namespace Data
 }   // namespace AZ
 
-DECLARE_EBUS_EXTERN_DLL_SINGLE_ADDRESS(Data::AssetManagerNotifications);
-DECLARE_EBUS_EXTERN_DLL_SINGLE_ADDRESS(Data::AssetCatalogRequests);
-DECLARE_EBUS_EXTERN_DLL_SINGLE_ADDRESS(Data::AssetManagerEvents);
-
-#endif  // AZCORE_ASSET_DATABASE_BUS_H
-#pragma once
+AZ_DECLARE_EBUS_SINGLE_ADDRESS(AZCORE_API, AZ::Data::AssetManagerNotifications);
+AZ_DECLARE_EBUS_SINGLE_ADDRESS(AZCORE_API, AZ::Data::AssetCatalogRequests);
+AZ_DECLARE_EBUS_SINGLE_ADDRESS(AZCORE_API, AZ::Data::AssetManagerEvents);

+ 2 - 6
Code/Framework/AzCore/AzCore/Asset/AssetManagerComponent.h

@@ -5,8 +5,7 @@
  * SPDX-License-Identifier: Apache-2.0 OR MIT
  *
  */
-#ifndef AZCORE_ASSETDATABASE_COMPONENT_H
-#define AZCORE_ASSETDATABASE_COMPONENT_H
+#pragma once
 
 #include <AzCore/Component/Component.h>
 #include <AzCore/Component/TickBus.h>
@@ -17,7 +16,7 @@ namespace AZ
     /**
      *
      */
-    class AssetManagerComponent
+    class AZCORE_API AssetManagerComponent
         : public Component
         , public SystemTickBus::Handler
     {
@@ -48,6 +47,3 @@ namespace AZ
         static void Reflect(ReflectContext* reflection);
     };
 }
-
-#endif // AZCORE_ASSETDATABASE_COMPONENT_H
-#pragma once

+ 1 - 1
Code/Framework/AzCore/AzCore/Asset/AssetManager_private.h

@@ -47,5 +47,5 @@ namespace AZ
     }  // namespace Data
 }   // namespace AZ
 
-
+AZ_DECLARE_EBUS_MULTI_ADDRESS(AZCORE_API, AZ::Data::AssetLoadEvents);
 

+ 3 - 3
Code/Framework/AzCore/AzCore/Asset/AssetSerializer.h

@@ -26,12 +26,12 @@ namespace AZ {
     /*
      * Returns the serialization UUID for Asset class
      */
-    const Uuid& GetAssetClassId();
+    AZCORE_API const Uuid& GetAssetClassId();
 
     /// Generic IDataSerializer specialization for Asset<T>
     /// This is used internally by the object stream because assets need
     /// special handling during serialization
-    class AssetSerializer
+    class AZCORE_API AssetSerializer
         : public SerializeContext::IDataSerializer
     {
     public:
@@ -197,7 +197,7 @@ namespace AZ {
 
         static ClassInfoType* GetGenericInfo()
         {
-            return GetCurrentSerializeContextModule().CreateGenericClassInfo<ThisType>();
+            return GetGlobalSerializeContextModule().CreateGenericClassInfo<ThisType>();
         }
 
         static AZ::TypeId GetClassTypeId()

+ 12 - 0
Code/Framework/AzCore/AzCore/Asset/AssetTypeInfoBus.cpp

@@ -0,0 +1,12 @@
+/*
+ * 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
+ *
+ */
+
+#include <AzCore/Asset/AssetTypeInfoBus.h>
+
+AZ_INSTANTIATE_EBUS_MULTI_ADDRESS(AZCORE_API, AZ::AssetTypeInfo);
+

+ 1 - 1
Code/Framework/AzCore/AzCore/Asset/AssetTypeInfoBus.h

@@ -72,4 +72,4 @@ namespace AZ
     using AssetTypeInfoBus = AZ::EBus<AssetTypeInfo>;
 } // namespace AZ
 
-DECLARE_EBUS_EXTERN_DLL_MULTI_ADDRESS(AssetTypeInfo);
+AZ_DECLARE_EBUS_MULTI_ADDRESS(AZCORE_API, AZ::AssetTypeInfo);

+ 2 - 0
Code/Framework/AzCore/AzCore/Component/Component.cpp

@@ -14,6 +14,8 @@
 #include <AzCore/Math/Sfmt.h>
 #include <AzCore/Math/Crc.h>
 
+AZ_INSTANTIATE_EBUS_MULTI_ADDRESS_WITH_TRAITS(AZCORE_API, AZ::ComponentDescriptor, AZ::ComponentDescriptorBusTraits);
+
 namespace AZ
 {
     // Add definition for type info and runtime type information to component

+ 5 - 4
Code/Framework/AzCore/AzCore/Component/Component.h

@@ -42,7 +42,7 @@ namespace AZ
     /**
      * Base class for all components.
      */
-    class Component
+    class AZCORE_API Component
     {
         friend class Entity;
     public:
@@ -50,7 +50,7 @@ namespace AZ
         /**
          * Forward declare run-time type information to the component.
          */
-        AZ_TYPE_INFO_WITH_NAME_DECL(Component);
+        AZ_TYPE_INFO_WITH_NAME_DECL_API(AZCORE_API, Component);
         AZ_RTTI_NO_TYPE_INFO_DECL();
         AZ_CLASS_ALLOCATOR_DECL
 
@@ -258,6 +258,7 @@ namespace AZ
         Entity*     m_entity;       ///< Reference to the entity that owns the component. The value is null if the component is not attached to an entity.
         ComponentId m_id;           ///< A component ID that is unique for an entity. This component ID is not unique across all entities.
     };
+    AZ_TYPE_INFO_WITH_NAME_DECL_EXT_API(AZCORE_API, Component);
 
     /**
      * Includes the core component code required to make a component work.
@@ -524,7 +525,7 @@ namespace AZ
      * If you implement a component descriptor, inherit from ComponentDescriptorHelper
      * to implement additional functionality.
      */
-    class ComponentDescriptor
+    class AZCORE_API ComponentDescriptor
     {
     public:
         AZ_CLASS_ALLOCATOR(ComponentDescriptor, ComponentAllocator);
@@ -826,4 +827,4 @@ namespace AZ
     };
 }
 
-DECLARE_EBUS_EXTERN_DLL_SINGLE_ADDRESS_WITH_TRAITS(ComponentDescriptor, ComponentDescriptorBusTraits);
+AZ_DECLARE_EBUS_MULTI_ADDRESS_WITH_TRAITS(AZCORE_API, AZ::ComponentDescriptor, AZ::ComponentDescriptorBusTraits);

+ 6 - 3
Code/Framework/AzCore/AzCore/Component/ComponentApplication.cpp

@@ -677,12 +677,11 @@ namespace AZ
             {
                 // Default to looking for startup config file at "<exe-directory>/startup.cfg" if the O3DE_STARTUP_CFG_FILE env is not set
                 startupCfgPath =
-                    AZ::IO::FixedMaxPath(AZ::Utils::GetExecutableDirectory()) / SettingsRegistryInterface::RegistryFolder / "startup.cfg";
+                    AZ::IO::FixedMaxPath(AZ::Utils::GetExecutableDirectory()) / SettingsRegistryConstants::RegistryFolder / "startup.cfg";
                 if (!AZ::IO::SystemFile::Exists(startupCfgPath.c_str()))
                 {
                     // If a <exe-directory>/startup.cfg doesn't exist, try to locate the startup config file at "~/.o3de/Registry/startup.cfg"
-                    startupCfgPath =
-                        AZ::IO::FixedMaxPath(AZ::Utils::GetO3deManifestDirectory()) / SettingsRegistryInterface::RegistryFolder / "startup.cfg";
+                    startupCfgPath = AZ::IO::FixedMaxPath(AZ::Utils::GetO3deManifestDirectory()) / SettingsRegistryConstants::RegistryFolder / "startup.cfg";
                 }
             }
 
@@ -1031,6 +1030,10 @@ namespace AZ
         // budgets initialized cross boundary are freed properly
         m_budgetTracker.Reset();
 #endif
+        // Cleanup the SerializeContext ClassInfos before we unload the modules since some ClassInfos will have
+        // symbols that were registered from the modules and will cause issues if the modules are unloaded before
+        // we clean them up
+        AZ::GetGlobalSerializeContextModule().Cleanup();
 
         // Uninit and unload any dynamic modules.
         m_moduleManager->UnloadModules();

+ 4 - 4
Code/Framework/AzCore/AzCore/Component/ComponentApplication.h

@@ -50,7 +50,7 @@ namespace AZ::Metrics
 
 namespace AZ
 {
-    class ReflectionEnvironment
+    class AZCORE_API ReflectionEnvironment
     {
     public:
 
@@ -74,7 +74,7 @@ namespace AZ
     //! Settings used to customize the constructor calls for the ComponentApplications
     //! This differs from the ComponentApplication::StartupParameters and ComponentApplication::Descriptor structs
     //! These settings are only used at construction time of the ComponentApplication and not in ComponentApplication::Create()
-    struct ComponentApplicationSettings
+    struct AZCORE_API ComponentApplicationSettings
     {
         //! JSON string that will be merged to the Settings Registry right after construction
         AZStd::string_view m_setregBootstrapJson;
@@ -91,7 +91,7 @@ namespace AZ
      * data that will allocate memory on construction. This is because the memory managers
      * are NOT yet ready. They will be initialized during the Create call.
      */
-    class ComponentApplication
+    class AZCORE_API ComponentApplication
         : public ComponentApplicationBus::Handler
         , public TickRequestBus::Handler
     {
@@ -109,7 +109,7 @@ namespace AZ
          * \note It's important this structure not contain members that allocate from the system allocator.
          *       Use the OSAllocator only.
          */
-        struct Descriptor
+        struct AZCORE_API Descriptor
         {
             AZ_TYPE_INFO(ComponentApplication::Descriptor, "{70277A3E-2AF5-4309-9BBF-6161AFBDE792}");
             AZ_CLASS_ALLOCATOR(ComponentApplication::Descriptor, SystemAllocator);

+ 11 - 0
Code/Framework/AzCore/AzCore/Component/ComponentApplicationBus.cpp

@@ -0,0 +1,11 @@
+/*
+ * 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
+ *
+ */
+
+#include <AzCore/Component/ComponentApplicationBus.h>
+
+AZ_INSTANTIATE_EBUS_SINGLE_ADDRESS_WITH_TRAITS(AZCORE_API, ComponentApplicationRequests, ComponentApplicationRequestsEBusTraits);

+ 4 - 4
Code/Framework/AzCore/AzCore/Component/ComponentApplicationBus.h

@@ -6,7 +6,7 @@
  *
  */
 
-#pragma once
+ #pragma once
 
 #include <AzCore/EBus/EBus.h>
 #include <AzCore/EBus/Event.h>
@@ -37,7 +37,7 @@ namespace AZ
         class ComponentFactoryInterface;
     }
 
-    struct ApplicationTypeQuery
+    struct AZCORE_API ApplicationTypeQuery
     {
         //! Signals if the application is the Editor.
         bool IsEditor() const;
@@ -89,7 +89,7 @@ namespace AZ
     using EntityDeactivatedEvent = AZ::Event<AZ::Entity*>;
 
     //! Interface that components can use to make requests of the main application.
-    class ComponentApplicationRequests
+    class AZCORE_API ComponentApplicationRequests
     {
     public:
         AZ_RTTI(ComponentApplicationRequests, "{E8BE41B7-615F-4FE8-B611-8A9E441290A8}");
@@ -234,4 +234,4 @@ namespace AZ
     using ComponentApplicationBus = AZ::EBus<ComponentApplicationRequests, ComponentApplicationRequestsEBusTraits>;
 }
 
-DECLARE_EBUS_EXTERN_DLL_SINGLE_ADDRESS_WITH_TRAITS(ComponentApplicationRequests, ComponentApplicationRequestsEBusTraits);
+AZ_DECLARE_EBUS_SINGLE_ADDRESS_WITH_TRAITS(AZCORE_API, AZ::ComponentApplicationRequests, AZ::ComponentApplicationRequestsEBusTraits);

+ 4 - 4
Code/Framework/AzCore/AzCore/Component/ComponentApplicationLifecycle.h

@@ -27,7 +27,7 @@ namespace AZ::ComponentApplicationLifecycle
     //! @param settingsRegistry registry where @eventName will be searched
     //! @param eventName name of key that validated that exists as an element in the ApplicationLifecycleEventRegistrationKey array
     //! @return true if the @eventName was found in the ApplicationLifecycleEventRegistrationKey array
-    bool ValidateEvent(AZ::SettingsRegistryInterface& settingsRegistry, AZStd::string_view eventName);
+    AZCORE_API bool ValidateEvent(AZ::SettingsRegistryInterface& settingsRegistry, AZStd::string_view eventName);
 
     //! Wrapper around setting a value underneath the ApplicationLifecycleEventRegistrationKey
     //! It validates if the @eventName is is part of the ApplicationLifecycleEventRegistrationKey array 
@@ -38,13 +38,13 @@ namespace AZ::ComponentApplicationLifecycle
     //! @param eventName name of key underneath the ApplicationLifecycleEventRegistrationKey to signal
     //! @param eventValue JSON Object that will be merged into the SettingsRegistry at <ApplicationLifecycleEventRootKey>/<eventName>
     //! @return true if the eventValue was successfully merged at the <ApplicationLifecycleEventRootKey>/<eventName>
-    bool SignalEvent(AZ::SettingsRegistryInterface& settingsRegistry, AZStd::string_view eventName, AZStd::string_view eventValue);
+    AZCORE_API bool SignalEvent(AZ::SettingsRegistryInterface& settingsRegistry, AZStd::string_view eventName, AZStd::string_view eventValue);
 
     //! Register that the event @eventName is stored in the array at ApplicationLifecycleEventRegistrationKey
     //! @param settingsRegistry registry where @eventName will be searched
     //! @param eventName name of key that will be stored in the ApplicationLifecycleEventRegistrationKey array
     //! @return true if the event passed validation or the eventName was stored in the ApplicationLifecycleEventRegistrationKey array
-    bool RegisterEvent(AZ::SettingsRegistryInterface& settingsRegistry, AZStd::string_view eventName);
+    AZCORE_API bool RegisterEvent(AZ::SettingsRegistryInterface& settingsRegistry, AZStd::string_view eventName);
 
     //! Wrapper around registering the NotifyEventHandler with the SettingsRegistry for the specified event
     //! It validates if the @eventName is is part of the ApplicationLifecycleEventRegistrationKey array and if
@@ -57,6 +57,6 @@ namespace AZ::ComponentApplicationLifecycle
     //! @param autoRegisterEvent automatically register this event if it hasn't been registered yet. This is useful
     //!         when registering a handler before the settings registry has been loaded.
     //! @return true if the handler was registered with the SettingsRegistry NotifyEvent
-    bool RegisterHandler(AZ::SettingsRegistryInterface& settingsRegistry, AZ::SettingsRegistryInterface::NotifyEventHandler& handler,
+    AZCORE_API bool RegisterHandler(AZ::SettingsRegistryInterface& settingsRegistry, AZ::SettingsRegistryInterface::NotifyEventHandler& handler,
         AZ::SettingsRegistryInterface::NotifyCallback callback, AZStd::string_view eventName, bool autoRegisterEvent = false);
 }

+ 2 - 6
Code/Framework/AzCore/AzCore/Component/ComponentBus.h

@@ -11,9 +11,7 @@
  * class for their buses. Buses enable components to communicate with each other and 
  * with external systems.
  */
-
-#ifndef AZCORE_COMPONENT_BUS_H
-#define AZCORE_COMPONENT_BUS_H
+#pragma once
 
 #include <AzCore/Memory/SystemAllocator.h>
 #include <AzCore/RTTI/RTTI.h>
@@ -96,7 +94,7 @@ namespace AZ
      * A pair of entity and component IDs that are used to access an address 
      * of an AZ::EntityComponentBus.
      */
-    class EntityComponentIdPair 
+    class AZCORE_API EntityComponentIdPair 
     {
     public:
 
@@ -237,5 +235,3 @@ namespace AZStd
         }
     };
 }
-#endif // AZCORE_COMPONENT_BUS_H
-#pragma once

+ 1 - 1
Code/Framework/AzCore/AzCore/Component/ComponentExport.h

@@ -21,7 +21,7 @@ namespace AZ
     /**
      * Descriptor used when converting editor components to runtime components (slice processing, play-in-editor, etc).
      */
-    struct ExportedComponent
+    struct AZCORE_API ExportedComponent
     {
         AZ_TYPE_INFO(ExportedComponent, "{F8A00B8B-6981-4508-B939-731563849B97}");
 

+ 1 - 1
Code/Framework/AzCore/AzCore/Component/Entity.h

@@ -29,7 +29,7 @@ namespace AZ
     //! An addressable container for a group of components. 
     //! An entity creates, initializes, activates, and deactivates its components.  
     //! An entity has an ID and, optionally, a name.  
-    class Entity
+    class AZCORE_API Entity
     {
         friend class JsonEntitySerializer;
 

+ 11 - 0
Code/Framework/AzCore/AzCore/Component/EntityBus.cpp

@@ -0,0 +1,11 @@
+/*
+ * 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
+ *
+ */
+
+ #include <AzCore/Component/EntityBus.h>
+
+AZ_INSTANTIATE_EBUS_MULTI_ADDRESS(AZCORE_API, AZ::EntityEvents);

+ 5 - 10
Code/Framework/AzCore/AzCore/Component/EntityBus.h

@@ -11,10 +11,8 @@
  * Buses enable entities and components to communicate with each other and with external 
  * systems.
  */
-
-#ifndef AZCORE_ENTITY_BUS_H
-#define AZCORE_ENTITY_BUS_H
-
+#pragma once
+ 
 #include <AzCore/std/string/string.h>
 #include <AzCore/Component/ComponentBus.h>
 #include <AzCore/Component/ComponentApplicationBus.h>
@@ -184,10 +182,7 @@ namespace AZ
      * The EBus for notification events dispatched by a specific entity.
      * The events are defined in the AZ::EntityEvents class.
      */
-    typedef AZ::EBus<EntityEvents>  EntityBus;
-}
-
-#endif // AZCORE_ENTITY_BUS_H
-#pragma once
+    using EntityBus = AZ::EBus<EntityEvents>;
+} // namespace AZ
 
-DECLARE_EBUS_EXTERN_DLL_SINGLE_ADDRESS(EntityEvents);
+AZ_DECLARE_EBUS_MULTI_ADDRESS(AZCORE_API, AZ::EntityEvents);

+ 1 - 1
Code/Framework/AzCore/AzCore/Component/EntityId.h

@@ -29,7 +29,7 @@ namespace AZ
      * attached to an entity is tagged with the entity's ID, and component buses 
      * are typically addressed by entity ID.
      */
-    class EntityId
+    class AZCORE_API EntityId
     {
         friend class JsonEntityIdSerializer;
         friend class Entity;

+ 1 - 1
Code/Framework/AzCore/AzCore/Component/EntityIdSerializer.h

@@ -15,7 +15,7 @@ namespace AZ
 {
     class EntityId;
 
-    class JsonEntityIdSerializer
+    class AZCORE_API JsonEntityIdSerializer
         : public BaseJsonSerializer
     {
     public:

+ 2 - 2
Code/Framework/AzCore/AzCore/Component/EntitySerializer.h

@@ -14,7 +14,7 @@
 
 namespace AZ
 {
-    class JsonEntitySerializer
+    class AZCORE_API JsonEntitySerializer
         : public BaseJsonSerializer
     {
     public:
@@ -32,7 +32,7 @@ namespace AZ
     //! When this class is added to the metadata of a Json deserializer setting,
     //! custom component serializers can add themselves to the list so users
     //! can be informed of component deprecation upon load completion
-    class DeprecatedComponentMetadata
+    class AZCORE_API DeprecatedComponentMetadata
     {
     public:
         AZ_TYPE_INFO(DeprecatedComponentMetadata, "{3D5F5EAE-BDA9-43AA-958E-E87158BAFB9F}");

+ 12 - 12
Code/Framework/AzCore/AzCore/Component/EntityUtils.h

@@ -18,7 +18,7 @@ namespace AZ
     namespace EntityUtils
     {
         /// Return default application serialization context.
-        SerializeContext* GetApplicationSerializeContext();
+        AZCORE_API SerializeContext* GetApplicationSerializeContext();
 
         /**
          * Serializable container for entities, useful for data patching and serializer enumeration.
@@ -35,7 +35,7 @@ namespace AZ
         /**
          * Reflect entity utils data types.
          */
-        void Reflect(ReflectContext* context);
+        AZCORE_API void Reflect(ReflectContext* context);
 
         /**
         * Given key, return the EntityId to map to
@@ -67,7 +67,7 @@ namespace AZ
         * \param classUuid - the object instance's type Id.
         * \param visitor - the visitor callback to be invoked for Entity::m_id (isEntityId==true) or reflected EntityId field, aka reference (isEntityId==false).
         */
-        void EnumerateEntityIds(const void* classPtr, const Uuid& classUuid, const EntityIdVisitor& visitor, SerializeContext* context = nullptr);
+        AZCORE_API void EnumerateEntityIds(const void* classPtr, const Uuid& classUuid, const EntityIdVisitor& visitor, SerializeContext* context = nullptr);
 
         template<class T>
         void EnumerateEntityIds(const T* classPtr, const EntityIdVisitor& visitor, SerializeContext* context = nullptr)
@@ -145,8 +145,8 @@ namespace AZ
 
 
         /// Return the first component that is either of the specified type or derive from the specified type
-        Component* FindFirstDerivedComponent(const Entity* entity, const Uuid& typeId);
-        Component* FindFirstDerivedComponent(EntityId entityId, const Uuid& typeId);
+        AZCORE_API Component* FindFirstDerivedComponent(const Entity* entity, const Uuid& typeId);
+        AZCORE_API Component* FindFirstDerivedComponent(EntityId entityId, const Uuid& typeId);
 
         /// Return the first component that is either of the specified type or derive from the specified type
         template<class ComponentType>
@@ -164,8 +164,8 @@ namespace AZ
         }
 
         /// Return a vector of all components that are either of the specified type or derive from the specified type
-        Entity::ComponentArrayType FindDerivedComponents(const Entity* entity, const Uuid& typeId);
-        Entity::ComponentArrayType FindDerivedComponents(EntityId entityId, const Uuid& typeId);
+        AZCORE_API Entity::ComponentArrayType FindDerivedComponents(const Entity* entity, const Uuid& typeId);
+        AZCORE_API Entity::ComponentArrayType FindDerivedComponents(EntityId entityId, const Uuid& typeId);
 
         /// Return a vector of all components that are either of the specified type or derive from the specified type
         template<class ComponentType>
@@ -192,15 +192,15 @@ namespace AZ
         }
 
         using EnumerateBaseRecursiveVisitor = AZStd::function< bool(const SerializeContext::ClassData*, const Uuid&)>;
-        bool EnumerateBaseRecursive(SerializeContext* context, const EnumerateBaseRecursiveVisitor& baseClassVisitor, const TypeId& typeToExamine);
+        AZCORE_API bool EnumerateBaseRecursive(SerializeContext* context, const EnumerateBaseRecursiveVisitor& baseClassVisitor, const TypeId& typeToExamine);
 
         //! Performs a recursive search of all classes declared in the serialize hierarchy of typeToExamine
         //! and returns true it has been marked as deprecated, false otherwise.
-        bool CheckIfClassIsDeprecated(SerializeContext* context, const TypeId& typeToExamine);
+        AZCORE_API bool CheckIfClassIsDeprecated(SerializeContext* context, const TypeId& typeToExamine);
 
         //! performs a recursive search of all classes declared in the serialize hierarchy of typeToExamine
         //! and returns true if it finds typeToFind, false otherwise.
-        bool CheckDeclaresSerializeBaseClass(SerializeContext* context, const TypeId& typeToFind, const TypeId& typeToExamine);
+        AZCORE_API bool CheckDeclaresSerializeBaseClass(SerializeContext* context, const TypeId& typeToFind, const TypeId& typeToExamine);
 
         //! Checks if the provided service array has any duplicates of the iterator, after that iterator.
         //! If a duplicate is found, a warning is given and the duplicate is removed from the providedServiceArray.
@@ -209,7 +209,7 @@ namespace AZ
         //! \param providedServiceArray The container of services to scan for duplicates.
         //! \param entity An optional associated entity, used in error reporting.
         //! \return True if a duplicate service was found, false if not.
-        bool RemoveDuplicateServicesOfAndAfterIterator(
+        AZCORE_API bool RemoveDuplicateServicesOfAndAfterIterator(
             const ComponentDescriptor::DependencyArrayType::iterator& iterator,
             ComponentDescriptor::DependencyArrayType& providedServiceArray,
             const Entity* entity);
@@ -217,7 +217,7 @@ namespace AZ
         //! Converts a vector of components to a map of pairs of component alias and component.
         //! \param components Component vector to be converted.
         //! \param[out] componentMapOut Component map that stores a component alias as key and a component as value.
-        void ConvertComponentVectorToMap(
+        AZCORE_API void ConvertComponentVectorToMap(
             AZStd::span<AZ::Component* const> components, AZStd::unordered_map<AZStd::string, AZ::Component*>& componentMapOut);
 
     } // namespace EntityUtils

+ 1 - 1
Code/Framework/AzCore/AzCore/Component/NamedEntityId.h

@@ -17,7 +17,7 @@ namespace AZ
 {
     class ReflectContext;
 
-    class NamedEntityId
+    class AZCORE_API NamedEntityId
         : public EntityId
     {
     public: 

+ 2 - 0
Code/Framework/AzCore/AzCore/Component/NonUniformScaleBus.cpp

@@ -10,6 +10,8 @@
 #include <AzCore/RTTI/BehaviorContext.h>
 #include <AzCore/Math/Vector3.h>
 
+AZ_INSTANTIATE_EBUS_MULTI_ADDRESS(AZCORE_API, AZ::NonUniformScaleRequests);
+
 namespace AZ
 {
     void NonUniformScaleRequests::Reflect(ReflectContext* context)

+ 3 - 3
Code/Framework/AzCore/AzCore/Component/NonUniformScaleBus.h

@@ -18,7 +18,7 @@ namespace AZ
     using NonUniformScaleChangedEvent = AZ::Event<const AZ::Vector3&>;
 
     //! Requests for working with non-uniform scale.
-    class NonUniformScaleRequests
+    class AZCORE_API NonUniformScaleRequests
         : public AZ::ComponentBus
     {
     public:
@@ -35,7 +35,7 @@ namespace AZ
         virtual void RegisterScaleChangedEvent(NonUniformScaleChangedEvent::Handler& handler) = 0;
     };
 
-    using NonUniformScaleRequestBus = AZ::EBus<NonUniformScaleRequests>;
+    using NonUniformScaleRequestBus = AZCORE_API AZ::EBus<NonUniformScaleRequests>;
 } // namespace AZ
 
-DECLARE_EBUS_EXTERN_DLL_SINGLE_ADDRESS(NonUniformScaleRequests);
+AZ_DECLARE_EBUS_MULTI_ADDRESS(AZCORE_API, AZ::NonUniformScaleRequests);

+ 12 - 0
Code/Framework/AzCore/AzCore/Component/TickBus.cpp

@@ -0,0 +1,12 @@
+/*
+ * 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
+ *
+ */
+#include <AzCore/Component/TickBus.h>
+
+AZ_INSTANTIATE_EBUS_SINGLE_ADDRESS(AZCORE_API, AZ::TickEvents);
+AZ_INSTANTIATE_EBUS_SINGLE_ADDRESS(AZCORE_API, AZ::SystemTickEvents);
+AZ_INSTANTIATE_EBUS_SINGLE_ADDRESS(AZCORE_API, AZ::TickRequests);

+ 4 - 9
Code/Framework/AzCore/AzCore/Component/TickBus.h

@@ -11,9 +11,7 @@
  * and receive tick-related requests.
  * A tick is a unit of time generated by the application. 
  */
-
-#ifndef AZCORE_COMPONENT_TICK_BUS_H
-#define AZCORE_COMPONENT_TICK_BUS_H
+#pragma once
 
 #include <AzCore/Component/ComponentBus.h>
 #include <AzCore/std/chrono/chrono.h>
@@ -228,9 +226,6 @@ namespace AZ
     using SystemTickBus = AZ::EBus<SystemTickEvents>;
 }
 
-DECLARE_EBUS_EXTERN_DLL_SINGLE_ADDRESS(TickEvents);
-DECLARE_EBUS_EXTERN_DLL_SINGLE_ADDRESS(SystemTickEvents);
-DECLARE_EBUS_EXTERN_DLL_SINGLE_ADDRESS(TickRequests);
-
-#endif // AZCORE_COMPONENT_TICK_BUS_H
-#pragma once
+AZ_DECLARE_EBUS_SINGLE_ADDRESS(AZCORE_API, AZ::TickEvents);
+AZ_DECLARE_EBUS_SINGLE_ADDRESS(AZCORE_API, AZ::SystemTickEvents);
+AZ_DECLARE_EBUS_SINGLE_ADDRESS(AZCORE_API, AZ::TickRequests);

+ 13 - 0
Code/Framework/AzCore/AzCore/Component/TransformBus.cpp

@@ -0,0 +1,13 @@
+/*
+ * 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
+ *
+ */
+
+#include <AzCore/Component/TransformBus.h>
+
+AZ_INSTANTIATE_EBUS_SINGLE_ADDRESS(AZCORE_API, AZ::TransformInterface);
+AZ_INSTANTIATE_EBUS_MULTI_ADDRESS(AZCORE_API, AZ::TransformNotification);
+AZ_INSTANTIATE_EBUS_MULTI_ADDRESS(AZCORE_API, AZ::TransformHierarchyInformation);

+ 3 - 3
Code/Framework/AzCore/AzCore/Component/TransformBus.h

@@ -488,6 +488,6 @@ namespace AZ
     /// @endcond
 }
 
-DECLARE_EBUS_EXTERN_DLL_SINGLE_ADDRESS(TransformInterface);
-DECLARE_EBUS_EXTERN_DLL_SINGLE_ADDRESS(TransformNotification);
-DECLARE_EBUS_EXTERN_DLL_MULTI_ADDRESS(TransformHierarchyInformation);
+AZ_DECLARE_EBUS_SINGLE_ADDRESS(AZCORE_API, AZ::TransformInterface);
+AZ_DECLARE_EBUS_MULTI_ADDRESS(AZCORE_API, AZ::TransformNotification);
+AZ_DECLARE_EBUS_MULTI_ADDRESS(AZCORE_API, AZ::TransformHierarchyInformation);

+ 1 - 1
Code/Framework/AzCore/AzCore/Compression/Compression.h

@@ -21,7 +21,7 @@ namespace AZ
      * the speed and memory usage can be an issue. If you want detailed control over the compressed stream, include
      * "AzCore/compression/zlib/zlib.h" and do it yourself!
      */
-    class ZLib
+    class AZCORE_API ZLib
     {
     public:
         ZLib(IAllocator* workMemAllocator = 0);

+ 1 - 1
Code/Framework/AzCore/AzCore/Compression/zstd_compression.h

@@ -18,7 +18,7 @@ namespace AZ
 {
     class IAllocator;
 
-    class ZStd
+    class AZCORE_API ZStd
     {
     public:
         ZStd(IAllocator* workMemAllocator = 0);

+ 1 - 1
Code/Framework/AzCore/AzCore/Console/Console.h

@@ -18,7 +18,7 @@ namespace AZ
 {
     //! @class Console
     //! A simple console class for providing text based variable and process interaction.
-    class Console final
+    class AZCORE_API Console final
         : public IConsole
     {
     public:

+ 2 - 2
Code/Framework/AzCore/AzCore/Console/ConsoleFunctor.h

@@ -27,11 +27,11 @@ namespace AZ
         TypeNotConvertible,
         ConsoleVarNotFound,
     };
-    const char* GetEnumString(GetValueResult value);
+    AZCORE_API const char* GetEnumString(GetValueResult value);
 
     //! @class ConsoleFunctorBase
     //! Base class for console functors.
-    class ConsoleFunctorBase
+    class AZCORE_API ConsoleFunctorBase
     {
     public:
 

+ 23 - 0
Code/Framework/AzCore/AzCore/Console/IConsole.h

@@ -221,6 +221,22 @@ static constexpr AZ::ThreadSafety ConsoleThreadSafety<_TYPE, std::enable_if_t<st
     using CVarDataWrapperType##_NAME = AZ::ConsoleDataWrapper<_TYPE, ConsoleThreadSafety<_TYPE>>; \
     inline CVarDataWrapperType##_NAME _NAME(_INIT, _CALLBACK, #_NAME, _DESC, _FLAGS)
 
+//! Shared Library exported cvar macro.
+//! This is used in conjunction with the AZ_CVAR_API_EXTERNED
+//! @param _API  the conditional export macro for the shared library that owns the cvar
+//! @param _TYPE the data type of the cvar
+//! @param _TYPE the data type of the cvar
+//! @param _NAME the name of the cvar
+//! @param _INIT the initial value to assign to the cvar
+//! @param _CALLBACK this is an optional callback function to get invoked when a cvar changes value
+//!        You have no guarantees as to what thread will invoke the callback
+//!        It is the responsibility of the implementor of the callback to ensure thread safety
+//! @param _FLAGS a set of AzFramework::ConsoleFunctorFlags used to mutate behaviour
+//! @param _DESC a description of the cvar
+#define AZ_CVAR_API(_API, _TYPE, _NAME, _INIT, _CALLBACK, _FLAGS, _DESC)                                                                             \
+    using CVarDataWrapperType##_NAME = AZ::ConsoleDataWrapper<_TYPE, ConsoleThreadSafety<_TYPE>>;                                          \
+    _API CVarDataWrapperType##_NAME _NAME(_INIT, _CALLBACK, #_NAME, _DESC, _FLAGS)
+
 //! Block-scoped cvar macro.
 //! This declaration should only be used within a block-scope or function body
 //! @param _TYPE the data type of the cvar
@@ -242,6 +258,13 @@ static constexpr AZ::ThreadSafety ConsoleThreadSafety<_TYPE, std::enable_if_t<st
     using CVarDataWrapperType##_NAME = AZ::ConsoleDataWrapper<_TYPE, ConsoleThreadSafety<_TYPE>>; \
     extern CVarDataWrapperType##_NAME _NAME;
 
+//! Cvar macro that dll externs a console variable.
+//! @param _TYPE the data type of the cvar to extern
+//! @param _NAME the name of the cvar to extern
+#define AZ_CVAR_API_EXTERNED(_API, _TYPE, _NAME) \
+    using CVarDataWrapperType##_NAME = AZ::ConsoleDataWrapper<_TYPE, ConsoleThreadSafety<_TYPE>>;  \
+    _API extern CVarDataWrapperType##_NAME _NAME;
+
 //! Implements a console functor for a class member function.
 //! @param _CLASS the class that the function gets invoked on
 //! @param _FUNCTION the method to invoke

+ 1 - 1
Code/Framework/AzCore/AzCore/Console/LoggerSystemComponent.h

@@ -17,7 +17,7 @@
 namespace AZ
 {
     //! Implementation of the ILogger system interface.
-    class LoggerSystemComponent
+    class AZCORE_API LoggerSystemComponent
         : public AZ::Component
         , public ILoggerRequestBus::Handler
     {

+ 8 - 8
Code/Framework/AzCore/AzCore/DOM/Backends/JSON/JsonSerializationUtils.h

@@ -42,10 +42,11 @@ namespace AZ::Dom::Json
     AZ_DEFINE_ENUM_BITWISE_OPERATORS(ParseFlags);
 
     //! Visitor that feeds into a rapidjson::Value
-    class RapidJsonValueWriter final : public Visitor
+    class AZCORE_API RapidJsonValueWriter final : public Visitor
     {
     public:
         RapidJsonValueWriter(rapidjson::Value& outputValue, rapidjson::Value::AllocatorType& allocator);
+        AZ_DISABLE_COPY_MOVE(RapidJsonValueWriter);
 
         VisitorFlags GetVisitorFlags() const override;
         Result Null() override;
@@ -69,7 +70,6 @@ namespace AZ::Dom::Json
         struct ValueInfo
         {
             ValueInfo(bool isObject, rapidjson::Value& container);
-
             rapidjson::Value m_key;
             rapidjson::Value m_value;
             rapidjson::Value& m_container;
@@ -83,7 +83,7 @@ namespace AZ::Dom::Json
     };
 
     //! Handler for a rapidjson::Reader that translates reads into an AZ::Dom::Visitor
-    struct RapidJsonReadHandler
+    struct AZCORE_API RapidJsonReadHandler
     {
     public:
         RapidJsonReadHandler(Visitor* visitor, Lifetime stringLifetime);
@@ -115,7 +115,7 @@ namespace AZ::Dom::Json
     //! rapidjson stream wrapper for AZStd::string suitable for in-situ parsing
     //! Faster than rapidjson::MemoryStream for reading from AZStd::string / AZStd::string_view (because it requires a null terminator)
     //! \note This needs to be inlined for performance reasons.
-    struct NullDelimitedStringStream
+    struct AZCORE_API NullDelimitedStringStream
     {
         using Ch = char; //<! Denotes the string character storage type for rapidjson
 
@@ -182,7 +182,7 @@ namespace AZ::Dom::Json
     //! \param stream The stream the visitor will write to.
     //! \param format The format to write in.
     //! \return A Visitor that will write to stream when visited.
-    AZStd::unique_ptr<Visitor> CreateJsonStreamWriter(
+    AZCORE_API AZStd::unique_ptr<Visitor> CreateJsonStreamWriter(
         AZ::IO::GenericStream& stream, OutputFormatting format = OutputFormatting::PrettyPrintedJson);
     //! Reads serialized JSON from a string and applies it to a visitor.
     //! \param buffer The UTF-8 serialized JSON to read.
@@ -207,13 +207,13 @@ namespace AZ::Dom::Json
     //! Takes a visitor specified by a callback and produces a rapidjson::Document.
     //! \param writeCallback A callback specifying a visitor to accept to build the resulting document.
     //! \return An outcome with either the rapidjson::Document or an error message.
-    AZ::Outcome<rapidjson::Document, AZStd::string> WriteToRapidJsonDocument(Backend::WriteCallback writeCallback);
+    AZCORE_API AZ::Outcome<rapidjson::Document, AZStd::string> WriteToRapidJsonDocument(Backend::WriteCallback writeCallback);
     //! Takes a visitor specified by a callback and reads them into a rapidjson::Value.
     //! \param value The value to read into, its contents will be overridden.
     //! \param allocator The allocator to use when performing rapidjson allocations (generally provded by the rapidjson::Document).
     //! \param writeCallback A callback specifying a visitor to accept to build the resulting document.
     //! \return An outcome with either the rapidjson::Document or an error message.
-    Visitor::Result WriteToRapidJsonValue(
+    AZCORE_API Visitor::Result WriteToRapidJsonValue(
         rapidjson::Value& value, rapidjson::Value::AllocatorType& allocator, Backend::WriteCallback writeCallback);
     //! Accepts a visitor with the contents of a rapidjson::Value.
     //! \param value The rapidjson::Value to apply to visitor.
@@ -221,7 +221,7 @@ namespace AZ::Dom::Json
     //! \param lifetime The lifetime to specify for visiting strings. If the rapidjson::Value might be destroyed or changed
     //! before the visitor is finished using these values, Lifetime::Temporary should be specified.
     //! \return The aggregate result specifying whether the visitor operations were successful.
-    Visitor::Result VisitRapidJsonValue(const rapidjson::Value& value, Visitor& visitor, Lifetime lifetime);
+    AZCORE_API Visitor::Result VisitRapidJsonValue(const rapidjson::Value& value, Visitor& visitor, Lifetime lifetime);
 
     template<ParseFlags parseFlags>
     Visitor::Result VisitSerializedJson(AZStd::string_view buffer, Lifetime lifetime, Visitor& visitor)

+ 1 - 1
Code/Framework/AzCore/AzCore/DOM/DomBackend.h

@@ -18,7 +18,7 @@
 namespace AZ::Dom
 {
     //! Backends are registered centrally and used to transition DOM formats to and from a textual format.
-    class Backend
+    class AZCORE_API Backend
     {
     public:
         virtual ~Backend() = default;

+ 2 - 1
Code/Framework/AzCore/AzCore/DOM/DomComparison.h

@@ -10,6 +10,7 @@
 
 #include <AzCore/DOM/DomPatch.h>
 
+
 namespace AZ::Dom
 {
     //! A set of patches for applying a change and doing the inverse operation.
@@ -42,6 +43,6 @@ namespace AZ::Dom
     //! Generates a set of patches such that m_forwardPatches.Apply(beforeState) shall produce a document equivalent to afterState, and
     //! a subsequent m_inversePatches.Apply(beforeState) shall produce the original document. This patch generation strategy does a
     //! hierarchical comparison and is not guaranteed to create the minimal set of patches required to transform between the two states.
-    PatchUndoRedoInfo GenerateHierarchicalDeltaPatch(
+    AZCORE_API PatchUndoRedoInfo GenerateHierarchicalDeltaPatch(
         const Value& beforeState, const Value& afterState, const DeltaPatchGenerationParameters& params = {});
 } // namespace AZ::Dom

+ 5 - 5
Code/Framework/AzCore/AzCore/DOM/DomPatch.h

@@ -15,11 +15,11 @@
 namespace AZ::Dom
 {
     using PatchOutcome = AZ::Outcome<void, AZStd::string>;
-    void CombinePatchOutcomes(PatchOutcome& lhs, PatchOutcome&& rhs);
+    AZCORE_API void CombinePatchOutcomes(PatchOutcome& lhs, PatchOutcome&& rhs);
 
     //! A patch operation that represents an atomic operation for mutating or validating a Value.
     //! PatchOperations can be created with helper methods in Patch. /see Patch
-    class PatchOperation final
+    class AZCORE_API PatchOperation final
     {
     public:
         //! The operation to perform.
@@ -135,14 +135,14 @@ namespace AZ::Dom
     namespace PatchApplicationStrategy
     {
         //! The default patching strategy. Applies all operations in a patch, but halts if any one operation fails.
-        void HaltOnFailure(PatchApplicationState& state);
+        AZCORE_API void HaltOnFailure(PatchApplicationState& state);
         //! Patching strategy that attemps to apply all operations in a patch, but ignores operation failures and continues.
-        void IgnoreFailureAndContinue(PatchApplicationState& state);
+        AZCORE_API void IgnoreFailureAndContinue(PatchApplicationState& state);
     } // namespace PatchApplicationStrategy
 
     //! A set of operations that can be applied to a Value to produce a new Value.
     //! \see PatchOperation
-    class Patch final
+    class AZCORE_API Patch final
     {
     public:
         using StrategyFunctor = AZStd::function<void(PatchApplicationState&)>;

+ 4 - 4
Code/Framework/AzCore/AzCore/DOM/DomPath.h

@@ -20,7 +20,7 @@ namespace AZ::Dom
     //! - Key, a name for indexing within Objects and Nodes
     //! - EndOfArray, a special-case indicator for representing the end of an array
     //!   used by the patching system to represent push / pop back operations.
-    class PathEntry final
+    class AZCORE_API PathEntry final
     {
     public:
         static constexpr size_t EndOfArrayIndex = size_t(-1);
@@ -65,7 +65,7 @@ namespace AZ::Dom
 namespace AZ::Dom
 {
     //! Represents a path, represented as a series of PathEntry values, to a position in a Value.
-    class Path final
+    class AZCORE_API Path final
     {
     public:
         AZ_TYPE_INFO(AZ::Dom::Path, "{C0081C45-F15D-4F46-9680-19535D33C312}")
@@ -170,13 +170,13 @@ namespace AZ::Dom
 namespace AZStd
 {
     template<>
-    struct hash<AZ::Dom::PathEntry>
+    struct AZCORE_API hash<AZ::Dom::PathEntry>
     {
         size_t operator()(const AZ::Dom::PathEntry& entry) const;
     };
 
     template<>
-    struct hash<AZ::Dom::Path>
+    struct AZCORE_API hash<AZ::Dom::Path>
     {
         size_t operator()(const AZ::Dom::Path& path) const
         {

+ 17 - 17
Code/Framework/AzCore/AzCore/DOM/DomUtils.h

@@ -14,13 +14,13 @@
 
 namespace AZ::Dom::Utils
 {
-    Visitor::Result ReadFromString(Backend& backend, AZStd::string_view string, AZ::Dom::Lifetime lifetime, Visitor& visitor);
-    Visitor::Result ReadFromStringInPlace(Backend& backend, AZStd::string& string, Visitor& visitor);
+    AZCORE_API Visitor::Result ReadFromString(Backend& backend, AZStd::string_view string, AZ::Dom::Lifetime lifetime, Visitor& visitor);
+    AZCORE_API Visitor::Result ReadFromStringInPlace(Backend& backend, AZStd::string& string, Visitor& visitor);
 
-    AZ::Outcome<Value, AZStd::string> SerializedStringToValue(Backend& backend, AZStd::string_view string, AZ::Dom::Lifetime lifetime);
-    AZ::Outcome<void, AZStd::string> ValueToSerializedString(Backend& backend, Dom::Value value, AZStd::string& buffer);
+    AZCORE_API AZ::Outcome<Value, AZStd::string> SerializedStringToValue(Backend& backend, AZStd::string_view string, AZ::Dom::Lifetime lifetime);
+    AZCORE_API AZ::Outcome<void, AZStd::string> ValueToSerializedString(Backend& backend, Dom::Value value, AZStd::string& buffer);
 
-    AZ::Outcome<Value, AZStd::string> WriteToValue(const Backend::WriteCallback& writeCallback);
+    AZCORE_API AZ::Outcome<Value, AZStd::string> WriteToValue(const Backend::WriteCallback& writeCallback);
 
     struct ComparisonParameters
     {
@@ -30,9 +30,9 @@ namespace AZ::Dom::Utils
         bool m_treatOpaqueValuesOfSameTypeAsEqual = false;
     };
 
-    bool DeepCompareIsEqual(const Value& lhs, const Value& rhs, const ComparisonParameters& parameters = {});
-    Value TypeIdToDomValue(const AZ::TypeId& typeId);
-    AZ::TypeId DomValueToTypeId(const AZ::Dom::Value& value, const AZ::TypeId* baseClassId = nullptr);
+    AZCORE_API bool DeepCompareIsEqual(const Value& lhs, const Value& rhs, const ComparisonParameters& parameters = {});
+    AZCORE_API Value TypeIdToDomValue(const AZ::TypeId& typeId);
+    AZCORE_API AZ::TypeId DomValueToTypeId(const AZ::Dom::Value& value, const AZ::TypeId* baseClassId = nullptr);
     //! Runs a dry-run JSON Serializer over the Dom::Value to check if it can be converted to the type associated
     //! with the AZ TypeId
     //! @param typeId TypeInfo ID associated with C++ type to determine if the Dom Value can be deserialized into
@@ -40,12 +40,12 @@ namespace AZ::Dom::Utils
     //! @param settings Json Deserializer Settings which is used to query the serialize context to use for loading the raw object
     //!        data from the Dom Value
     //! @return true if the Dom Value can be deserialized into the type associated with the TypeInfo ID
-    bool CanLoadViaJsonSerialization(
+    AZCORE_API bool CanLoadViaJsonSerialization(
         const AZ::TypeId& typeId, const Value& root, JsonDeserializerSettings settings = {});
 
-    JsonSerializationResult::ResultCode LoadViaJsonSerialization(
+    AZCORE_API JsonSerializationResult::ResultCode LoadViaJsonSerialization(
         void* object, const AZ::TypeId& typeId, const Value& root, const JsonDeserializerSettings& settings = {});
-    JsonSerializationResult::ResultCode StoreViaJsonSerialization(
+    AZCORE_API JsonSerializationResult::ResultCode StoreViaJsonSerialization(
         const void* object,
         const void* defaultObject,
         const AZ::TypeId& typeId,
@@ -73,7 +73,7 @@ namespace AZ::Dom::Utils
         return StoreViaJsonSerialization(&object, &defaultObject, azrtti_typeid<T>(), output, settings);
     }
 
-    Value DeepCopy(const Value& value, bool copyStrings = true);
+    AZCORE_API Value DeepCopy(const Value& value, bool copyStrings = true);
 
     template <typename T>
     using is_dom_value = AZStd::bool_constant<AZStd::is_same_v<AZStd::remove_cvref_t<T>, Dom::Value>>;
@@ -110,8 +110,8 @@ namespace AZ::Dom::Utils
     extern const AZ::Name PointerValueFieldName;
     extern const AZ::Name PointerTypeFieldName;
 
-    Dom::Value MarshalTypedPointerToValue(const void* value, const AZ::TypeId& typeId);
-    void* TryMarshalValueToPointer(const AZ::Dom::Value& value, const AZ::TypeId& expectedType = AZ::TypeId::CreateNull());
+    AZCORE_API Dom::Value MarshalTypedPointerToValue(const void* value, const AZ::TypeId& typeId);
+    AZCORE_API void* TryMarshalValueToPointer(const AZ::Dom::Value& value, const AZ::TypeId& expectedType = AZ::TypeId::CreateNull());
 
     struct MarshalTypeTraits
     {
@@ -122,7 +122,7 @@ namespace AZ::Dom::Utils
         size_t m_typeSize{};
     };
 
-    Dom::Value MarshalOpaqueValue(const void* valueAddress, const MarshalTypeTraits& typeTraits,
+    AZCORE_API Dom::Value MarshalOpaqueValue(const void* valueAddress, const MarshalTypeTraits& typeTraits,
         AZStd::any::action_handler_for_t actionHandler);
 
     template <typename T>
@@ -155,7 +155,7 @@ namespace AZ::Dom::Utils
         }
     }
 
-    Dom::Value ValueFromType(const void* valueAddress, const MarshalTypeTraits& typeTraits,
+    AZCORE_API Dom::Value ValueFromType(const void* valueAddress, const MarshalTypeTraits& typeTraits,
         AZStd::any::action_handler_for_t actionHandler);
 
     template<typename T>
@@ -198,7 +198,7 @@ namespace AZ::Dom::Utils
         }
     }
 
-    AZ::TypeId GetValueTypeId(const Dom::Value& value);
+    AZCORE_API AZ::TypeId GetValueTypeId(const Dom::Value& value);
 
     template<typename T>
     bool CanConvertValueToType(const Dom::Value& value)

+ 4 - 4
Code/Framework/AzCore/AzCore/DOM/DomValue.h

@@ -50,7 +50,7 @@ namespace AZ::Dom
     class Value;
 
     //! Internal storage for a Value array: an ordered list of Values.
-    class Array
+    class AZCORE_API Array
     {
     public:
         using ContainerType = AZStd::vector<Value, ValueAllocator_for_std_t>;
@@ -71,7 +71,7 @@ namespace AZ::Dom
     using ConstArrayPtr = AZStd::shared_ptr<const Array>;
 
     //! Internal storage for a Value object: an ordered list of Name / Value pairs.
-    class Object
+    class AZCORE_API Object
     {
     public:
         using EntryType = AZStd::pair<KeyType, Value>;
@@ -95,7 +95,7 @@ namespace AZ::Dom
     //! Storage for a Value node: a named Value with both properties and children.
     //! Properties are stored as an ordered list of Name / Value pairs.
     //! Children are stored as an oredered list of Values.
-    class Node
+    class AZCORE_API Node
     {
     public:
         Node() = default;
@@ -145,7 +145,7 @@ namespace AZ::Dom
     //! value itself (objects, arrays, and nodes) are copied by new Values only when their contents change, so care should be taken in
     //! performance critical code to avoid mutation operations such as operator[] to avoid copies. It is recommended that an immutable Value
     //! be explicitly be stored as a `const Value` to avoid accidental detach and copy operations.
-    class Value final
+    class AZCORE_API Value final
     {
     public:
         AZ_TYPE_INFO(Value, "{3E20677F-3B8E-4F89-B665-ED41D74F4799}");

+ 5 - 3
Code/Framework/AzCore/AzCore/DOM/DomValueWriter.h

@@ -15,11 +15,13 @@ namespace AZ::Dom
 {
     //! Visitor that writes to a Value.
     //! Supports all Visitor operations.
-    class ValueWriter : public Visitor
+    class AZCORE_API  ValueWriter : public Visitor
     {
     public:
         ValueWriter(Value& outputValue);
 
+        AZ_DISABLE_COPY_MOVE(ValueWriter);
+
         VisitorFlags GetVisitorFlags() const override;
         Result Null() override;
         Result Bool(bool value) override;
@@ -45,7 +47,7 @@ namespace AZ::Dom
         Value& CurrentValue();
         Visitor::Result EndContainer(Type containerType, AZ::u64 attributeCount, AZ::u64 elementCount);
 
-        struct ValueInfo
+        struct AZCORE_API ValueInfo
         {
             ValueInfo(Value& container);
 
@@ -54,7 +56,7 @@ namespace AZ::Dom
             Value& m_container;
         };
 
-        struct ValueBuffer
+        struct AZCORE_API ValueBuffer
         {
             Array::ContainerType m_elements;
             Object::ContainerType m_attributes;

+ 2 - 2
Code/Framework/AzCore/AzCore/DOM/DomVisitor.h

@@ -54,7 +54,7 @@ namespace AZ::Dom
     // VisitorError class
     //
     //! Details of the reason for failure within a VisitorInterface operation.
-    class VisitorError final
+    class AZCORE_API VisitorError final
     {
     public:
         explicit VisitorError(VisitorErrorCode code);
@@ -129,7 +129,7 @@ namespace AZ::Dom
     //!   Opaque values are rejected by the default VisitorInterface implementation.
     //!
     //!   Care should be ensured that DOMs representing opaque types are only visited by consumers that understand them.
-    class Visitor
+    class AZCORE_API Visitor
     {
     public:
         virtual ~Visitor() = default;

+ 9 - 9
Code/Framework/AzCore/AzCore/Date/DateFormat.h

@@ -466,48 +466,48 @@ namespace AZ::Date
     //! returns ISO 8601 extended format date + time based on the current time
     //! The timestamp will be in the format of "YYYY-MM-DD[T]HH:MM:SS[Z]"
     //! Ex. "2025-04-21T13:17:55"
-    bool GetIso8601ExtendedFormatNow(Iso8601TimestampString& utcTimestamp);
+    AZCORE_API bool GetIso8601ExtendedFormatNow(Iso8601TimestampString& utcTimestamp);
 
     //! returns ISO 8601 extended format date + time based on the current time with fractional milliseconds included
     //! The timestamp will be in the format of "YYYY-MM-DD[T]HH:MM:SS.fff[Z]"
     //! Ex. "2025-04-21T13:17:55.537Z"
-    bool GetIso8601ExtendedFormatNowWithMilliseconds(Iso8601TimestampString& utcTimestamp);
+    AZCORE_API bool GetIso8601ExtendedFormatNowWithMilliseconds(Iso8601TimestampString& utcTimestamp);
 
     //! returns ISO 8601 extended format date + timebased on the current time with fractional microseconds included
     //! The timestamp will be in the format of "YYYY-MM-DD[T]HH:MM:SS.ffffff[Z]"
     //! Ex. "2025-04-21T13:17:55.537982Z"
-    bool GetIso8601ExtendedFormatNowWithMicroseconds(Iso8601TimestampString& utcTimestamp);
+    AZCORE_API bool GetIso8601ExtendedFormatNowWithMicroseconds(Iso8601TimestampString& utcTimestamp);
 
     //! returns ISO 8601 basic format date + timebased on the current time
     //! The timestamp will be in the format of "YYYYMMDD[T]HHMMSS[Z]"
     //! Ex. "20250421T131755537982Z"
-    bool GetIso8601BasicFormatNow(Iso8601TimestampString& utcTimestamp);
+    AZCORE_API bool GetIso8601BasicFormatNow(Iso8601TimestampString& utcTimestamp);
 
     //! returns ISO 8601 extended format date + timebased on the current time with fractional milliseconds included
     //! The timestamp will be in the format of "YYYY-MM-DD[T]HH:MM:SS.fff[Z]"
     //! Ex. 20250421T131755.537Z
-    bool GetIso8601BasicFormatNowWithMilliseconds(Iso8601TimestampString& utcTimestamp);
+    AZCORE_API bool GetIso8601BasicFormatNowWithMilliseconds(Iso8601TimestampString& utcTimestamp);
 
     //! returns ISO 8601 extended format date + timebased on the current time with fractional microseconds included
     //! The timestamp will be in the format of "YYYYMMDD[T]HHMMSS.ffffff[Z]"
     //! Ex. "20250421T131755.537982Z"
-    bool GetIso8601BasicFormatNowWithMicroseconds(Iso8601TimestampString& utcTimestamp);
+    AZCORE_API bool GetIso8601BasicFormatNowWithMicroseconds(Iso8601TimestampString& utcTimestamp);
 
     //! returns a non-standard ISO 8601 style timestampe which is safe to use as a filename on Windows and Posix platforms
     //! It combines the extended format for the date portion with the basic format for the time portion
     //! The timestamp will be in the format of "YYYY-MM-DD[T]HHMMSS[Z]"
     //! Ex. "2025-04-21T131755Z"
-    bool GetFilenameCompatibleFormatNow(Iso8601TimestampString& utcTimestamp);
+    AZCORE_API bool GetFilenameCompatibleFormatNow(Iso8601TimestampString& utcTimestamp);
 
     //! returns a non-standard ISO 8601 style timestampe which is safe to use as a filename on Windows and Posix platforms
     //! It combines the extended format for the date portion with the basic format for the time portion
     //! The timestamp includes fractional milliseconds and it will be in the format of "YYYY-MM-DD[T]HHMMSS.fff[Z]"
     //! Ex. "2025-04-21T131755.537Z"
-    bool GetFilenameCompatibleFormatNowWithMilliseconds(Iso8601TimestampString& utcTimestamp);
+    AZCORE_API bool GetFilenameCompatibleFormatNowWithMilliseconds(Iso8601TimestampString& utcTimestamp);
 
     //! returns a non-standard ISO 8601 style timestampe which is safe to use as a filename on Windows and Posix platforms
     //! It combines the extended format for the date portion with the basic format for the time portion
     //! The timestamp includes fractional microseconds and it will be in the format of "YYYY-MM-DD[T]HHMMSS.ffffff[Z]"
     //! Ex. "2025-04-21T131755.537982Z"
-    bool GetFilenameCompatibleFormatNowWithMicroseconds(Iso8601TimestampString& utcTimestamp);
+    AZCORE_API bool GetFilenameCompatibleFormatNowWithMicroseconds(Iso8601TimestampString& utcTimestamp);
 }

+ 23 - 5
Code/Framework/AzCore/AzCore/Debug/Budget.h

@@ -13,7 +13,7 @@
 namespace AZ::Debug
 {
     // A budget collates per-frame resource utilization and memory for a particular category
-    class Budget final
+    class AZCORE_API Budget final
     {
     public:
         explicit Budget(const char* name);
@@ -58,10 +58,11 @@ namespace AZ::Debug
 #else
 // Usage example:
 // In a single C++ source file:
-// AZ_DEFINE_BUDGET(AzCore);
+// AZ_DEFINE_BUDGET(AzCore);   
+// 
+// In addition, depending on if the source file is part of a static or shared library, the budget needs to be declared appropriately and must
+// be done before the AZ_DEFINE_BUDGET declaration (see below)
 //
-// Anywhere the budget is used, the budget must be declared (either in a header or in the source file itself)
-// AZ_DECLARE_BUDGET(AzCore);
 #define AZ_DEFINE_BUDGET(name)                                                          \
     ::AZ::Debug::Budget* AZ_BUDGET_GETTER(name)()                                       \
     {                                                                                   \
@@ -75,13 +76,20 @@ namespace AZ::Debug
     }
 #endif
 
+// Anywhere the budget is used, the budget must be declared (either in a header or in the source file itself)
+// AZ_DECLARE_BUDGET(AzCore);
+
 // If using a budget defined in a different C++ source file, add AZ_DECLARE_BUDGET(yourBudget); somewhere in your source file at namespace
-// scope Alternatively, AZ_DECLARE_BUDGET can be used in a header to declare the budget for use across any users of the header
+// scope Alternatively, AZ_DECLARE_BUDGET can be used in a header to declare the budget for use across any users of the header. If the budget
+// is declared in a shared library and is meant to be visible outside of that library, use the AZ_DECLARE_BUDGET_SHARED instead.
 #define AZ_DECLARE_BUDGET(name) ::AZ::Debug::Budget* AZ_BUDGET_GETTER(name)()
 
+#define AZ_DECLARE_BUDGET_SHARED(name) AZ_DLL_EXPORT ::AZ::Debug::Budget* AZ_BUDGET_GETTER(name)()
+
 // Declare budgets that are core engine budgets, or may be shared/needed across multiple external gems
 // You should NOT need to declare user-space or budgets with isolated usage here. Prefer declaring them local to the module(s) that use
 // the budget and defining them within a single module to avoid needing to recompile the entire engine.
+#if defined(AZ_MONOLITHIC_BUILD)
 AZ_DECLARE_BUDGET(Animation);
 AZ_DECLARE_BUDGET(Audio);
 AZ_DECLARE_BUDGET(AzCore);
@@ -90,3 +98,13 @@ AZ_DECLARE_BUDGET(Entity);
 AZ_DECLARE_BUDGET(Game);
 AZ_DECLARE_BUDGET(System);
 AZ_DECLARE_BUDGET(Physics);
+#else
+AZ_DECLARE_BUDGET_SHARED(Animation);
+AZ_DECLARE_BUDGET_SHARED(Audio);
+AZ_DECLARE_BUDGET_SHARED(AzCore);
+AZ_DECLARE_BUDGET_SHARED(Editor);
+AZ_DECLARE_BUDGET_SHARED(Entity);
+AZ_DECLARE_BUDGET_SHARED(Game);
+AZ_DECLARE_BUDGET_SHARED(System);
+AZ_DECLARE_BUDGET_SHARED(Physics);
+#endif

+ 1 - 1
Code/Framework/AzCore/AzCore/Debug/BudgetTracker.h

@@ -16,7 +16,7 @@ namespace AZ::Debug
 {
     class Budget;
 
-    class BudgetTracker
+    class AZCORE_API BudgetTracker
     {
     public:
         AZ_TYPE_INFO(BudgetTracker, "{E14A746D-BFFE-4C02-90FB-4699B79864A5}");

+ 0 - 1
Code/Framework/AzCore/AzCore/Debug/ITrace.cpp

@@ -6,7 +6,6 @@
  *
  */
 
-#include <AzCore/O3DEKernelConfiguration.h>
 #include <AzCore/Debug/Trace.h>
 
 namespace AZ::Debug

+ 2 - 2
Code/Framework/AzCore/AzCore/Debug/PerformanceCollector.h

@@ -19,7 +19,7 @@ namespace AZ::Debug
     //! The metrics can be recorded as raw events (DataLogType::LogAllSamples)
     //! or aggregated as statistical summaries (DataLogType::LogStatistics).
     //! Performance is captured in batches of frames.
-    class PerformanceCollector final
+    class AZCORE_API PerformanceCollector final
     {
     public:
         PerformanceCollector() = delete;
@@ -144,7 +144,7 @@ namespace AZ::Debug
 
     //! A Convenience class used to measure time performance of scopes of code
     //! with constructor/destructor.
-    class ScopeDuration
+    class AZCORE_API ScopeDuration
     {
     public:
         ScopeDuration() = delete;

+ 11 - 11
Code/Framework/AzCore/AzCore/Debug/Profiler.cpp

@@ -138,17 +138,17 @@ namespace AZ::Debug
     }
 
     // Explicitly instantiate ReportCounter<T>-function for all possible integral types
-    template void Profiler::ReportCounter(const Budget* budget, const wchar_t* counterName, const bool& value);
-    template void Profiler::ReportCounter(const Budget* budget, const wchar_t* counterName, const float& value);
-    template void Profiler::ReportCounter(const Budget* budget, const wchar_t* counterName, const double& value);
-    template void Profiler::ReportCounter(const Budget* budget, const wchar_t* counterName, const AZ::s8& value);
-    template void Profiler::ReportCounter(const Budget* budget, const wchar_t* counterName, const AZ::s16& value);
-    template void Profiler::ReportCounter(const Budget* budget, const wchar_t* counterName, const AZ::s32& value);
-    template void Profiler::ReportCounter(const Budget* budget, const wchar_t* counterName, const AZ::s64& value);
-    template void Profiler::ReportCounter(const Budget* budget, const wchar_t* counterName, const AZ::u8& value);
-    template void Profiler::ReportCounter(const Budget* budget, const wchar_t* counterName, const AZ::u16& value);
-    template void Profiler::ReportCounter(const Budget* budget, const wchar_t* counterName, const AZ::u32& value);
-    template void Profiler::ReportCounter(const Budget* budget, const wchar_t* counterName, const AZ::u64& value);
+    template AZCORE_API_EXPORT void Profiler::ReportCounter(const Budget* budget, const wchar_t* counterName, const bool& value);
+    template AZCORE_API_EXPORT void Profiler::ReportCounter(const Budget* budget, const wchar_t* counterName, const float& value);
+    template AZCORE_API_EXPORT void Profiler::ReportCounter(const Budget* budget, const wchar_t* counterName, const double& value);
+    template AZCORE_API_EXPORT void Profiler::ReportCounter(const Budget* budget, const wchar_t* counterName, const AZ::s8& value);
+    template AZCORE_API_EXPORT void Profiler::ReportCounter(const Budget* budget, const wchar_t* counterName, const AZ::s16& value);
+    template AZCORE_API_EXPORT void Profiler::ReportCounter(const Budget* budget, const wchar_t* counterName, const AZ::s32& value);
+    template AZCORE_API_EXPORT void Profiler::ReportCounter(const Budget* budget, const wchar_t* counterName, const AZ::s64& value);
+    template AZCORE_API_EXPORT void Profiler::ReportCounter(const Budget* budget, const wchar_t* counterName, const AZ::u8& value);
+    template AZCORE_API_EXPORT void Profiler::ReportCounter(const Budget* budget, const wchar_t* counterName, const AZ::u16& value);
+    template AZCORE_API_EXPORT void Profiler::ReportCounter(const Budget* budget, const wchar_t* counterName, const AZ::u32& value);
+    template AZCORE_API_EXPORT void Profiler::ReportCounter(const Budget* budget, const wchar_t* counterName, const AZ::u64& value);
 
     void Profiler::ReportProfileEvent([[maybe_unused]] const Budget* budget, [[maybe_unused]] const char* eventName)
     {

+ 2 - 2
Code/Framework/AzCore/AzCore/Debug/Profiler.h

@@ -66,7 +66,7 @@ namespace AZStd
 namespace AZ::Debug
 {
     // interface for externally defined profiler systems
-    class Profiler
+    class AZCORE_API Profiler
     {
     public:
         AZ_RTTI(Profiler, "{3E5D6329-72D1-41BA-9158-68A349D1A4D5}");
@@ -82,7 +82,7 @@ namespace AZ::Debug
         static void ReportProfileEvent(const Budget* budget, const char* eventName);
     };
 
-    class ProfileScope
+    class AZCORE_API ProfileScope
     {
     public:
         static void BeginRegion(Budget* budget, const char* eventName, ...);

+ 1 - 1
Code/Framework/AzCore/AzCore/Debug/ProfilerBus.h

@@ -68,6 +68,6 @@ namespace AZ
 
         //! helper function for getting the profiler capture location from the settings registry that
         //! includes fallback handing in the event the registry value can't be determined
-        AZ::IO::FixedMaxPathString GetProfilerCaptureLocation();
+        AZCORE_API AZ::IO::FixedMaxPathString GetProfilerCaptureLocation();
     } // namespace Debug
 } // namespace AZ

+ 1 - 1
Code/Framework/AzCore/AzCore/Debug/ProfilerReflection.h

@@ -14,6 +14,6 @@ namespace AZ
     namespace Debug
     {
         //! Reflects the profiler bus script bindings
-        void ProfilerReflect(AZ::ReflectContext* context);
+        AZCORE_API void ProfilerReflect(AZ::ReflectContext* context);
     } // namespace Debug
 } // namespace AZ

+ 4 - 4
Code/Framework/AzCore/AzCore/Debug/StackTracer.h

@@ -15,7 +15,7 @@ namespace AZ
 {
     namespace Debug
     {
-        struct StackFrame
+        struct AZCORE_API StackFrame
         {
             StackFrame()
                 : m_programCounter(0)  {}
@@ -27,7 +27,7 @@ namespace AZ
         /**
          *
          */
-        class StackRecorder
+        class AZCORE_API StackRecorder
         {
         public:
             /**
@@ -40,13 +40,13 @@ namespace AZ
             static unsigned int Record(StackFrame* frames, unsigned int maxNumOfFrames, unsigned int suppressCount = 0, void* nativeThread = 0);
         };
 
-        class StackConverter
+        class AZCORE_API StackConverter
         {
         public:
             static unsigned int FromNative(StackFrame* frames, unsigned int maxNumOfFrames, void* nativeContext);
         };
 
-        class SymbolStorage
+        class AZCORE_API SymbolStorage
         {
         public:
             struct ModuleDataInfoHeader

+ 1 - 1
Code/Framework/AzCore/AzCore/Debug/Timer.h

@@ -18,7 +18,7 @@ namespace AZ
         /**
          * \todo use AZStd::chrono
          */
-        class Timer
+        class AZCORE_API Timer
         {
         public:
             /// Stores the current time in the timer.

+ 1 - 1
Code/Framework/AzCore/AzCore/Debug/Trace.cpp

@@ -87,7 +87,7 @@ namespace AZ::Debug
         Debug::ITrace::Instance().SetAlwaysPrintCallstack(enable);
     }
 
-    AZ_CVAR_SCOPED(int, bg_traceLogLevel, static_cast<int>(LogLevel::Info), &TraceLevelChanged, ConsoleFunctorFlags::Null, "Enable trace message logging in release mode.  0=disabled, 1=errors, 2=warnings, 3=info, 4=debug, 5=trace.");
+    AZ_CVAR_API(AZCORE_API, int, bg_traceLogLevel, static_cast<int>(LogLevel::Info), &TraceLevelChanged, ConsoleFunctorFlags::Null, "Enable trace message logging in release mode.  0=disabled, 1=errors, 2=warnings, 3=info, 4=debug, 5=trace.");
     AZ_CVAR_SCOPED(bool, bg_alwaysShowCallstack, false, &AlwaysShowCallstackChanged, ConsoleFunctorFlags::Null, "Force stack trace output without allowing ebus interception.");
 
     // Allow redirection of trace raw output writes to stdout, stderr or to /dev/null

+ 3 - 4
Code/Framework/AzCore/AzCore/Debug/Trace.h

@@ -9,7 +9,6 @@
 
 #include <AzCore/PlatformDef.h>
 #include <AzCore/base.h>
-#include <AzCore/O3DEKernelConfiguration.h>
 #include <cstdarg>
 
 namespace AZStd
@@ -30,7 +29,7 @@ namespace AZ
         inline constexpr const char* NoWindow = "";
         namespace Platform
         {
-            void OutputToDebugger(AZStd::basic_string_view<char, AZStd::char_traits<char>> window, AZStd::basic_string_view<char, AZStd::char_traits<char>> message);
+            AZCORE_API void OutputToDebugger(AZStd::basic_string_view<char, AZStd::char_traits<char>> window, AZStd::basic_string_view<char, AZStd::char_traits<char>> message);
         }
 
         enum class LogLevel { Disabled = 0, Errors = 1, Warnings = 2, Info = 3, Debug = 4, Trace = 5 };
@@ -43,7 +42,7 @@ namespace AZ
             None
         };
 
-        class O3DEKERNEL_API ITrace
+        class AZCORE_API ITrace
         {
         public:
             ITrace();
@@ -148,7 +147,7 @@ namespace AZ
             bool m_printCallstack = false;
         };
 
-        class Trace
+        class AZCORE_API Trace
             : public ITrace
         {
         public:

+ 10 - 0
Code/Framework/AzCore/AzCore/Debug/TraceMessageBus.cpp

@@ -0,0 +1,10 @@
+/*
+ * 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
+ *
+ */
+#include <AzCore/Debug/TraceMessageBus.h>
+
+AZ_INSTANTIATE_EBUS_SINGLE_ADDRESS(AZCORE_API, AZ::Debug::TraceMessageEvents)

+ 1 - 1
Code/Framework/AzCore/AzCore/Debug/TraceMessageBus.h

@@ -61,4 +61,4 @@ namespace AZ
     } // namespace Debug
 } // namespace AZ
 
-DECLARE_EBUS_EXTERN_DLL_SINGLE_ADDRESS(Debug::TraceMessageEvents);
+AZ_DECLARE_EBUS_SINGLE_ADDRESS(AZCORE_API, AZ::Debug::TraceMessageEvents);

+ 3 - 1
Code/Framework/AzCore/AzCore/Debug/TraceReflection.h

@@ -7,6 +7,8 @@
  */
 #pragma once
 
+#include <AzCore/base.h>
+
 namespace AZ
 {
     class ReflectContext;
@@ -16,6 +18,6 @@ namespace AZ
         /**
          * Reflect trace events(errors, warnings, asserts, etc)
          */
-        void TraceReflect(AZ::ReflectContext* context);
+        AZCORE_API void TraceReflect(AZ::ReflectContext* context);
     }
 }

+ 88 - 360
Code/Framework/AzCore/AzCore/EBus/EBus.h

@@ -1386,344 +1386,6 @@ AZ_POP_DISABLE_WARNING
 
     namespace Internal
     {
-        //////////////////////////////////////////////////////////////////////////
-        // NonIdHandler
-
-        template<typename Interface, typename Traits, typename ContainerType>
-        NonIdHandler<Interface, Traits, ContainerType>::NonIdHandler()
-            : m_node(nullptr)
-        {
-        }
-
-        template <typename Interface, typename Traits, typename ContainerType>
-        NonIdHandler<Interface, Traits, ContainerType>::NonIdHandler(const NonIdHandler& rhs)
-            : m_node(nullptr)
-        {
-            *this = rhs;
-        }
-
-        template <typename Interface, typename Traits, typename ContainerType>
-        NonIdHandler<Interface, Traits, ContainerType>& NonIdHandler<Interface, Traits, ContainerType>::operator=(const NonIdHandler& rhs)
-        {
-            BusDisconnect();
-            if (rhs.BusIsConnected())
-            {
-                BusConnect();
-            }
-            return *this;
-        }
-
-        template <typename Interface, typename Traits, typename ContainerType>
-        NonIdHandler<Interface, Traits, ContainerType>::NonIdHandler(NonIdHandler&& rhs)
-            : m_node(nullptr)
-        {
-            *this = AZStd::move(rhs);
-        }
-
-        template <typename Interface, typename Traits, typename ContainerType>
-        NonIdHandler<Interface, Traits, ContainerType>& NonIdHandler<Interface, Traits, ContainerType>::operator=(NonIdHandler&& rhs)
-        {
-            BusDisconnect();
-            if (rhs.BusIsConnected())
-            {
-                rhs.BusDisconnect();
-                BusConnect();
-            }
-            return *this;
-        }
-
-        template <typename Interface, typename Traits, typename ContainerType>
-        NonIdHandler<Interface, Traits, ContainerType>::~NonIdHandler()
-        {
-            AZ_PUSH_DISABLE_WARNING(4127, "-Wunknown-warning-option") // conditional expression is constant (for Traits::LocklessDispatch in asserts)
-            AZ_Assert((!AZStd::is_polymorphic<typename BusType::InterfaceType>::value || AZStd::is_same<typename BusType::MutexType, AZ::NullMutex>::value || !BusIsConnected()), "EBus handlers must be disconnected prior to destruction on multi-threaded buses with virtual functions");
-            AZ_POP_DISABLE_WARNING
-
-            if (BusIsConnected())
-            {
-                BusDisconnect();
-            }
-            EBUS_ASSERT(!BusIsConnected(), "Internal error: Bus was not properly disconnected!");
-        }
-
-        template <typename Interface, typename Traits, typename ContainerType>
-        void NonIdHandler<Interface, Traits, ContainerType>::BusConnect()
-        {
-            typename BusType::Context& context = BusType::GetOrCreateContext();
-            typename BusType::Context::ConnectLockGuard contextLock(context.m_contextMutex);
-            if (!BusIsConnected())
-            {
-                typename Traits::BusIdType id;
-                m_node = this;
-                BusType::ConnectInternal(context, m_node, contextLock, id);
-            }
-        }
-
-        template <typename Interface, typename Traits, typename ContainerType>
-        void NonIdHandler<Interface, Traits, ContainerType>::BusDisconnect()
-        {
-            if (typename BusType::Context* context = BusType::GetContext())
-            {
-                typename BusType::Context::ConnectLockGuard contextLock(context->m_contextMutex);
-                if (BusIsConnected())
-                {
-                    BusType::DisconnectInternal(*context, m_node);
-                }
-            }
-        }
-
-        template <typename Interface, typename Traits, typename ContainerType>
-        bool NonIdHandler<Interface, Traits, ContainerType>::BusIsConnected() const
-        {
-            return static_cast<Interface*>(m_node) != nullptr;
-        }
-
-        // End of NonIdHandler
-        //////////////////////////////////////////////////////////////////////////
-
-        //////////////////////////////////////////////////////////////////////////
-        // IdHandler
-
-        template <typename Interface, typename Traits, typename ContainerType>
-        IdHandler<Interface, Traits, ContainerType>::IdHandler()
-            : m_node(nullptr)
-        {
-        }
-
-        template <typename Interface, typename Traits, typename ContainerType>
-        IdHandler<Interface, Traits, ContainerType>::IdHandler(const IdHandler& rhs)
-            : m_node(nullptr)
-        {
-            *this = rhs;
-        }
-
-        template <typename Interface, typename Traits, typename ContainerType>
-        IdHandler<Interface, Traits, ContainerType>& IdHandler<Interface, Traits, ContainerType>::operator=(const IdHandler& rhs)
-        {
-            BusDisconnect();
-            if (rhs.BusIsConnected())
-            {
-                BusConnect(rhs.m_node.GetBusId());
-            }
-            return *this;
-        }
-
-        template <typename Interface, typename Traits, typename ContainerType>
-        IdHandler<Interface, Traits, ContainerType>::IdHandler(IdHandler&& rhs)
-            : m_node(nullptr)
-        {
-            *this = AZStd::move(rhs);
-        }
-
-        template <typename Interface, typename Traits, typename ContainerType>
-        IdHandler<Interface, Traits, ContainerType>& IdHandler<Interface, Traits, ContainerType>::operator=(IdHandler&& rhs)
-        {
-            BusDisconnect();
-            if (rhs.BusIsConnected())
-            {
-                IdType id = rhs.m_node.GetBusId();
-                rhs.BusDisconnect(id);
-                BusConnect(id);
-            }
-            return *this;
-        }
-
-        template <typename Interface, typename Traits, typename ContainerType>
-        IdHandler<Interface, Traits, ContainerType>::~IdHandler()
-        {
-            AZ_PUSH_DISABLE_WARNING(4127, "-Wunknown-warning-option") // conditional expression is constant (for Traits::LocklessDispatch in asserts)
-            AZ_Assert((!AZStd::is_polymorphic<typename BusType::InterfaceType>::value || AZStd::is_same_v<typename BusType::MutexType, AZ::NullMutex> || !BusIsConnected()), "EBus handlers must be disconnected prior to destruction on multi-threaded buses with virtual functions");
-            AZ_POP_DISABLE_WARNING
-
-            if (BusIsConnected())
-            {
-                BusDisconnect();
-            }
-            EBUS_ASSERT(!BusIsConnected(), "Internal error: Bus was not properly disconnected!");
-        }
-
-        template <typename Interface, typename Traits, typename ContainerType>
-        void IdHandler<Interface, Traits, ContainerType>::BusConnect(const IdType& id)
-        {
-            typename BusType::Context& context = BusType::GetOrCreateContext();
-            typename BusType::Context::ConnectLockGuard contextLock(context.m_contextMutex);
-            if (BusIsConnected())
-            {
-                // Connecting on the BusId that is already connected is a no-op
-                if (m_node.GetBusId() == id)
-                {
-                    return;
-                }
-                AZ_Assert(false, "Connecting to a different id on this bus without disconnecting first! Please ensure you call BusDisconnect before calling BusConnect again, or if multiple connections are desired you must use a MultiHandler instead.");
-                BusType::DisconnectInternal(context, m_node);
-            }
-
-            m_node = this;
-            BusType::ConnectInternal(context, m_node, contextLock, id);
-        }
-
-        template <typename Interface, typename Traits, typename ContainerType>
-        void IdHandler<Interface, Traits, ContainerType>::BusDisconnect(const IdType& id)
-        {
-            if (typename BusType::Context* context = BusType::GetContext())
-            {
-                typename BusType::Context::ConnectLockGuard contextLock(context->m_contextMutex);
-                if (BusIsConnectedId(id))
-                {
-                    BusType::DisconnectInternal(*context, m_node);
-                }
-            }
-        }
-
-        template <typename Interface, typename Traits, typename ContainerType>
-        void IdHandler<Interface, Traits, ContainerType>::BusDisconnect()
-        {
-            if (typename BusType::Context* context = BusType::GetContext())
-            {
-                typename BusType::Context::ConnectLockGuard contextLock(context->m_contextMutex);
-                if (BusIsConnected())
-                {
-                    BusType::DisconnectInternal(*context, m_node);
-                }
-            }
-        }
-
-        template <typename Interface, typename Traits, typename ContainerType>
-        bool IdHandler<Interface, Traits, ContainerType>::BusIsConnectedId(const IdType& id) const
-        {
-            return BusIsConnected() && m_node.GetBusId() == id;
-        }
-
-        template <typename Interface, typename Traits, typename ContainerType>
-        bool IdHandler<Interface, Traits, ContainerType>::BusIsConnected() const
-        {
-            return m_node.m_holder != nullptr;
-        }
-
-        // End of IdHandler
-        //////////////////////////////////////////////////////////////////////////
-
-        //////////////////////////////////////////////////////////////////////////
-        // MultiHandler
-
-        template <typename Interface, typename Traits, typename ContainerType>
-        MultiHandler<Interface, Traits, ContainerType>::MultiHandler() = default;
-
-        template <typename Interface, typename Traits, typename ContainerType>
-        MultiHandler<Interface, Traits, ContainerType>::MultiHandler(const MultiHandler& rhs)
-        {
-            *this = rhs;
-        }
-
-        template <typename Interface, typename Traits, typename ContainerType>
-        MultiHandler<Interface, Traits, ContainerType>& MultiHandler<Interface, Traits, ContainerType>::operator=(const MultiHandler& rhs)
-        {
-            BusDisconnect();
-            for (const auto& nodePair : rhs.m_handlerNodes)
-            {
-                BusConnect(nodePair.first);
-            }
-            return *this;
-        }
-
-        template <typename Interface, typename Traits, typename ContainerType>
-        MultiHandler<Interface, Traits, ContainerType>::MultiHandler(MultiHandler&& rhs)
-        {
-            *this = AZStd::move(rhs);
-        }
-
-        template <typename Interface, typename Traits, typename ContainerType>
-        MultiHandler<Interface, Traits, ContainerType>& MultiHandler<Interface, Traits, ContainerType>::operator=(MultiHandler&& rhs)
-        {
-            BusDisconnect();
-            for (const auto& nodePair : rhs.m_handlerNodes)
-            {
-                BusConnect(nodePair.first);
-            }
-            rhs.BusDisconnect();
-            return *this;
-        }
-
-        template <typename Interface, typename Traits, typename ContainerType>
-        MultiHandler<Interface, Traits, ContainerType>::~MultiHandler()
-        {
-            AZ_PUSH_DISABLE_WARNING(4127, "-Wunknown-warning-option") // conditional expression is constant (for Traits::LocklessDispatch in asserts)
-            AZ_Assert((!AZStd::is_polymorphic<typename BusType::InterfaceType>::value || AZStd::is_same<typename BusType::MutexType, AZ::NullMutex>::value || !BusIsConnected()), "EBus handlers must be disconnected prior to destruction on multi-threaded buses with virtual functions");
-            AZ_POP_DISABLE_WARNING
-
-            if (BusIsConnected())
-            {
-                BusDisconnect();
-            }
-            EBUS_ASSERT(!BusIsConnected(), "Internal error: Bus was not properly disconnected!");
-        }
-
-        template <typename Interface, typename Traits, typename ContainerType>
-        void MultiHandler<Interface, Traits, ContainerType>::BusConnect(const IdType& id)
-        {
-            typename BusType::Context& context = BusType::GetOrCreateContext();
-            typename BusType::Context::ConnectLockGuard contextLock(context.m_contextMutex);
-            if (m_handlerNodes.find(id) == m_handlerNodes.end())
-            {
-                void* handlerNodeAddr = m_handlerNodes.get_allocator().allocate(sizeof(HandlerNode), AZStd::alignment_of<HandlerNode>::value);
-                auto handlerNode = new(handlerNodeAddr) HandlerNode(this);
-                m_handlerNodes.emplace(id, AZStd::move(handlerNode));
-                BusType::ConnectInternal(context, *handlerNode, contextLock, id);
-            }
-        }
-
-        template <typename Interface, typename Traits, typename ContainerType>
-        void MultiHandler<Interface, Traits, ContainerType>::BusDisconnect(const IdType& id)
-        {
-            if (typename BusType::Context* context = BusType::GetContext())
-            {
-                typename BusType::Context::ConnectLockGuard contextLock(context->m_contextMutex);
-                auto nodeIt = m_handlerNodes.find(id);
-                if (nodeIt != m_handlerNodes.end())
-                {
-                    HandlerNode* handlerNode = nodeIt->second;
-                    BusType::DisconnectInternal(*context, *handlerNode);
-                    m_handlerNodes.erase(nodeIt);
-                    handlerNode->~HandlerNode();
-                    m_handlerNodes.get_allocator().deallocate(handlerNode, sizeof(HandlerNode), alignof(HandlerNode));
-                }
-            }
-        }
-
-        template <typename Interface, typename Traits, typename ContainerType>
-        void MultiHandler<Interface, Traits, ContainerType>::BusDisconnect()
-        {
-            decltype(m_handlerNodes) handlerNodesToDisconnect;
-            if (typename BusType::Context* context = BusType::GetContext())
-            {
-                typename BusType::Context::ConnectLockGuard contextLock(context->m_contextMutex);
-                handlerNodesToDisconnect = AZStd::move(m_handlerNodes);
-
-                for (const auto& nodePair : handlerNodesToDisconnect)
-                {
-                    BusType::DisconnectInternal(*context, *nodePair.second);
-
-                    nodePair.second->~HandlerNode();
-                    handlerNodesToDisconnect.get_allocator().deallocate(nodePair.second, sizeof(HandlerNode), AZStd::alignment_of<HandlerNode>::value);
-                }
-            }
-        }
-
-        template <typename Interface, typename Traits, typename ContainerType>
-        bool MultiHandler<Interface, Traits, ContainerType>::BusIsConnectedId(const IdType& id) const
-        {
-            return m_handlerNodes.end() != m_handlerNodes.find(id);
-        }
-
-        template <typename Interface, typename Traits, typename ContainerType>
-        bool MultiHandler<Interface, Traits, ContainerType>::BusIsConnected() const
-        {
-            return !m_handlerNodes.empty();
-        }
-
-        // End of MultiHandler
-        //////////////////////////////////////////////////////////////////////////
-
         template <class EBus, class TargetEBus, class BusIdType>
         struct EBusRouterQueueEventForwarder
         {
@@ -2247,20 +1909,84 @@ namespace AZ \
    template class EBus<a, a>; \
 }
 
+#if defined(AZ_MONOLITHIC_BUILD)
+
+//! Declares an EBus class template, which uses EBusAddressPolicy::Single and is instantiated in a shared library, as extern using only the
+//! interface argument for both the EBus Interface and BusTraits template parameters
+#define AZ_DECLARE_EBUS_SINGLE_ADDRESS(_API, a) \
+namespace AZ \
+{ \
+    extern template class EBus<a, a>; \
+}
+ 
+//! Explicitly instantiates an EBus which was declared with the function directly above
+#define AZ_INSTANTIATE_EBUS_SINGLE_ADDRESS(_API, a) \
+namespace AZ \
+{ \
+    template class EBus<a, a>; \
+}
+ 
+//! Declares an EBus class template, which uses an address policy different from EBusAddressPolicy::Single and is instantiated in a shared
+//! library, as extern using only the interface argument for both the EBus Interface and BusTraits template parameters
+#define AZ_DECLARE_EBUS_MULTI_ADDRESS(_API, a) \
+namespace AZ \
+{ \
+    extern template class EBus<a, a>; \
+}
+
+//! Explicitly instantiates an EBus which was declared with the function directly above
+#define AZ_INSTANTIATE_EBUS_MULTI_ADDRESS(_API, a) \
+namespace AZ \
+{ \
+    template class EBus<a, a>; \
+}
+
+//! Declares an EBus class template, which uses EBusAddressPolicy::Single and is instantiated in a shared library, as extern with both the
+//! interface and bus traits arguments
+#define AZ_DECLARE_EBUS_SINGLE_ADDRESS_WITH_TRAITS(_API, a, b) \
+namespace AZ \
+{ \
+    extern template class EBus<a, b>; \
+}
+
+//! Explicitly instantiates an EBus which was declared with the function directly above
+#define AZ_INSTANTIATE_EBUS_SINGLE_ADDRESS_WITH_TRAITS(_API, a, b) \
+namespace AZ \
+{ \
+    template class EBus<a, b>; \
+}
+
+//! Declares an EBus class template, which uses an address policy different from EBusAddressPolicy::Single and is instantiated in a shared
+//! library, as extern with both the interface and bus traits arguments
+#define AZ_DECLARE_EBUS_MULTI_ADDRESS_WITH_TRAITS(_API, a, b) \
+namespace AZ \
+{ \
+    extern template class EBus<a, b>; \
+}
+
+//! Explicitly instantiates an EBus which was declared with the function directly above
+#define AZ_INSTANTIATE_EBUS_MULTI_ADDRESS_WITH_TRAITS(_API, a, b) \
+namespace AZ \
+{ \
+    template class EBus<a, b>; \
+}
+
+#else
+
 //! Declares an EBus class template, which uses EBusAddressPolicy::Single and is instantiated in a shared library, as extern using only the
 //! interface argument for both the EBus Interface and BusTraits template parameters
-#define DECLARE_EBUS_EXTERN_DLL_SINGLE_ADDRESS(a) \
+#define AZ_DECLARE_EBUS_SINGLE_ADDRESS(_API, a) \
 namespace AZ \
 { \
-   extern template class AZCORE_API_EXTERN EBus<a, a>; \
+   extern template class _API EBus<a, a>; \
    AZ_PUSH_DISABLE_DLL_EXPORT_BASECLASS_WARNING \
-   extern template class AZCORE_API_EXTERN Internal::NonIdHandler<a, a, EBus<a, a>::BusesContainer>; \
-   extern template struct AZCORE_API_EXTERN Internal::EBusCallstackStorage<Internal::CallstackEntryBase<a, a>, true>; \
+   extern template class _API Internal::NonIdHandler<a, a, EBus<a, a>::BusesContainer>; \
+   extern template struct _API Internal::EBusCallstackStorage<Internal::CallstackEntryBase<a, a>, true>; \
    AZ_POP_DISABLE_DLL_EXPORT_BASECLASS_WARNING \
 }
 
 //! Explicitly instantiates an EBus which was declared with the function directly above
-#define DECLARE_EBUS_INSTANTIATION_DLL_SINGLE_ADDRESS(a) \
+#define AZ_INSTANTIATE_EBUS_SINGLE_ADDRESS(_API, a) \
 namespace AZ \
 { \
    template class AZ_DLL_EXPORT EBus<a, a>; \
@@ -2272,19 +1998,19 @@ namespace AZ \
 
 //! Declares an EBus class template, which uses an address policy different from EBusAddressPolicy::Single and is instantiated in a shared
 //! library, as extern using only the interface argument for both the EBus Interface and BusTraits template parameters
-#define DECLARE_EBUS_EXTERN_DLL_MULTI_ADDRESS(a) \
+#define AZ_DECLARE_EBUS_MULTI_ADDRESS(_API, a) \
 namespace AZ \
 { \
-   extern template class AZCORE_API_EXTERN EBus<a, a>;  \
+   extern template class _API EBus<a, a>;  \
    AZ_PUSH_DISABLE_DLL_EXPORT_BASECLASS_WARNING \
-   extern template class AZCORE_API_EXTERN Internal::IdHandler<a, a, EBus<a, a>::BusesContainer>; \
-   extern template class AZCORE_API_EXTERN Internal::MultiHandler<a, a, EBus<a, a>::BusesContainer>; \
-   extern template struct AZCORE_API_EXTERN Internal::EBusCallstackStorage<Internal::CallstackEntryBase<a, a>, true>; \
+   extern template class _API Internal::IdHandler<a, a, EBus<a, a>::BusesContainer>; \
+   extern template class _API Internal::MultiHandler<a, a, EBus<a, a>::BusesContainer>; \
+   extern template struct _API Internal::EBusCallstackStorage<Internal::CallstackEntryBase<a, a>, true>; \
    AZ_POP_DISABLE_DLL_EXPORT_BASECLASS_WARNING \
 }
 
 //! Explicitly instantiates an EBus which was declared with the function directly above
-#define DECLARE_EBUS_INSTANTIATION_DLL_MULTI_ADDRESS(a) \
+#define AZ_INSTANTIATE_EBUS_MULTI_ADDRESS(_API, a) \
 namespace AZ \
 { \
    template class AZ_DLL_EXPORT EBus<a, a>; \
@@ -2297,18 +2023,18 @@ namespace AZ \
 
 //! Declares an EBus class template, which uses EBusAddressPolicy::Single and is instantiated in a shared library, as extern with both the
 //! interface and bus traits arguments
-#define DECLARE_EBUS_EXTERN_DLL_SINGLE_ADDRESS_WITH_TRAITS(a, b) \
+#define AZ_DECLARE_EBUS_SINGLE_ADDRESS_WITH_TRAITS(_API, a, b) \
 namespace AZ \
 { \
-   extern template class AZCORE_API_EXTERN EBus<a, b>;     \
+   extern template class _API EBus<a, b>;     \
    AZ_PUSH_DISABLE_DLL_EXPORT_BASECLASS_WARNING \
-   extern template class AZCORE_API_EXTERN Internal::NonIdHandler<a, b, EBus<a, b>::BusesContainer>; \
-   extern template struct AZCORE_API_EXTERN Internal::EBusCallstackStorage<Internal::CallstackEntryBase<a, b>, true>; \
+   extern template class _API Internal::NonIdHandler<a, b, EBus<a, b>::BusesContainer>; \
+   extern template struct _API Internal::EBusCallstackStorage<Internal::CallstackEntryBase<a, b>, true>; \
    AZ_POP_DISABLE_DLL_EXPORT_BASECLASS_WARNING \
 }
 
 //! Explicitly instantiates an EBus which was declared with the function directly above
-#define DECLARE_EBUS_INSTANTIATION_DLL_SINGLE_ADDRESS_WITH_TRAITS(a, b) \
+#define AZ_INSTANTIATE_EBUS_SINGLE_ADDRESS_WITH_TRAITS(_API, a, b) \
 namespace AZ \
 { \
    template class AZ_DLL_EXPORT EBus<a, b>; \
@@ -2320,19 +2046,19 @@ namespace AZ \
 
 //! Declares an EBus class template, which uses an address policy different from EBusAddressPolicy::Single and is instantiated in a shared
 //! library, as extern with both the interface and bus traits arguments
-#define DECLARE_EBUS_EXTERN_DLL_MULTI_ADDRESS_WITH_TRAITS(a, b) \
+#define AZ_DECLARE_EBUS_MULTI_ADDRESS_WITH_TRAITS(_API, a, b) \
 namespace AZ \
 { \
-   extern template class AZCORE_API_EXTERN EBus<a, b>;  \
+   extern template class _API EBus<a, b>;  \
    AZ_PUSH_DISABLE_DLL_EXPORT_BASECLASS_WARNING \
-   extern template class AZCORE_API_EXTERN Internal::IdHandler<a, b, EBus<a, b>::BusesContainer>; \
-   extern template class AZCORE_API_EXTERN Internal::MultiHandler<a, b, EBus<a, b>::BusesContainer>; \
-   extern template struct AZCORE_API_EXTERN Internal::EBusCallstackStorage<Internal::CallstackEntryBase<a, b>, true>; \
+   extern template class _API Internal::IdHandler<a, b, EBus<a, b>::BusesContainer>; \
+   extern template class _API Internal::MultiHandler<a, b, EBus<a, b>::BusesContainer>; \
+   extern template struct _API Internal::EBusCallstackStorage<Internal::CallstackEntryBase<a, b>, true>; \
    AZ_POP_DISABLE_DLL_EXPORT_BASECLASS_WARNING \
 }
 
 //! Explicitly instantiates an EBus which was declared with the function directly above
-#define DECLARE_EBUS_INSTANTIATION_DLL_MULTI_ADDRESS_WITH_TRAITS(a, b) \
+#define AZ_INSTANTIATE_EBUS_MULTI_ADDRESS_WITH_TRAITS(_API, a, b) \
 namespace AZ \
 { \
    template class AZ_DLL_EXPORT EBus<a, b>; \
@@ -2342,3 +2068,5 @@ namespace AZ \
    template struct AZ_DLL_EXPORT Internal::EBusCallstackStorage<Internal::CallstackEntryBase<a, b>, true>; \
    AZ_POP_DISABLE_DLL_EXPORT_BASECLASS_WARNING \
 }
+
+#endif //defined(AZ_MONOLITHIC_BUILD)

+ 2 - 1
Code/Framework/AzCore/AzCore/EBus/EBusEnvironment.cpp

@@ -38,7 +38,8 @@ namespace AZ
         }
 
         //////////////////////////////////////////////////////////////////////////
-        AZ_THREAD_LOCAL EBusEnvironment* EBusEnvironmentTLSAccessors::s_tlsCurrentEnvironment = nullptr;
+
+        static AZ_THREAD_LOCAL EBusEnvironment* s_tlsCurrentEnvironment = nullptr; ///< Pointer to the current environment for the current thread.
 
         //////////////////////////////////////////////////////////////////////////
         EBusEnvironmentTLSAccessors::EBusEnvironmentTLSAccessors()

+ 3 - 5
Code/Framework/AzCore/AzCore/EBus/Environment.h

@@ -30,7 +30,7 @@ namespace AZ
         /**
         * Base for EBus<T>::Context. We use it to support multiple EBusEnvironments (have collection of contexts and manage state).
         */
-        class ContextBase
+        class AZCORE_API ContextBase
         {
             template<class Context>
             friend struct AZ::EBusEnvironmentStoragePolicy;
@@ -57,7 +57,7 @@ namespace AZ
         * If this happens make sure you create this structure in the environment from the main executable
         * or a module that will be loaded before and unloaded before any EBuses are used.
         */
-        struct EBusEnvironmentTLSAccessors
+        struct AZCORE_API EBusEnvironmentTLSAccessors
         {
             EBusEnvironmentTLSAccessors();
 
@@ -70,8 +70,6 @@ namespace AZ
             static void SetTLSEnvironment(EBusEnvironment* environment);
 
             AZStd::atomic_int m_numUniqueEBuses; ///< Used to provide unique index for the TLS table
-
-            static AZ_THREAD_LOCAL EBusEnvironment* s_tlsCurrentEnvironment; ///< Pointer to the current environment for the current thread.
         };
 
         using EBusEnvironmentAllocator = AZStd::stateless_allocator;
@@ -85,7 +83,7 @@ namespace AZ
      * EBusEnvironment is very similar to the way OpenGL contexts operate. You can manage their livecycle from any thread at anytime by calling EBusEnvironment::Create/Destroy. You can activate/deactivate an environment by calling
      * ActivateOnCurrentThread/DeactivateOnCurrentThread. Every EBusEnvironment can be activated to only one thread at a time.
      */
-    class EBusEnvironment
+    class AZCORE_API EBusEnvironment
     {
         template<class Context>
         friend struct EBusEnvironmentStoragePolicy;

+ 1 - 1
Code/Framework/AzCore/AzCore/EBus/EventSchedulerSystemComponent.h

@@ -44,7 +44,7 @@ namespace AZ
 
     //! @class EventSchedulerSystemComponent
     //! @brief This is scheduled event queue class to run all scheduled events at appropriate intervals.
-    class EventSchedulerSystemComponent
+    class AZCORE_API EventSchedulerSystemComponent
         : public Component
         , public TickBus::Handler
         , public IEventSchedulerRequestBus::Handler

+ 299 - 32
Code/Framework/AzCore/AzCore/EBus/Internal/Handlers.h

@@ -144,16 +144,87 @@ namespace AZ
         public:
             using BusType = AZ::EBus<Interface, Traits>;
 
-            NonIdHandler();
-            NonIdHandler(const NonIdHandler& rhs);
-            NonIdHandler& operator=(const NonIdHandler& rhs);
-            NonIdHandler(NonIdHandler&& rhs);
-            NonIdHandler& operator=(NonIdHandler&& rhs);
-            virtual ~NonIdHandler();
+            AZ_FORCE_INLINE NonIdHandler()
+                : m_node(nullptr)
+            {
+            }
+
+            AZ_FORCE_INLINE NonIdHandler(const NonIdHandler& rhs)
+                : m_node(nullptr)
+            {
+                *this = rhs;
+            }
+
+            AZ_FORCE_INLINE NonIdHandler& operator=(const NonIdHandler& rhs)
+            {
+                BusDisconnect();
+                if (rhs.BusIsConnected())
+                {
+                    BusConnect();
+                }
+                return *this;
+            }
+
+            AZ_FORCE_INLINE NonIdHandler(NonIdHandler&& rhs)
+                : m_node(nullptr)
+            {
+                *this = AZStd::move(rhs);
+            }
+
+            AZ_FORCE_INLINE NonIdHandler& operator=(NonIdHandler&& rhs)
+            {
+                BusDisconnect();
+                if (rhs.BusIsConnected())
+                {
+                    rhs.BusDisconnect();
+                    BusConnect();
+                }
+                return *this;
+            }
 
-            void BusConnect();
-            void BusDisconnect();
-            bool BusIsConnected() const;
+            AZ_FORCE_INLINE virtual ~NonIdHandler()
+            {
+                AZ_PUSH_DISABLE_WARNING(
+                    4127, "-Wunknown-warning-option") // conditional expression is constant (for Traits::LocklessDispatch in asserts)
+                AZ_Assert(
+                    (!AZStd::is_polymorphic<typename BusType::InterfaceType>::value ||
+                     AZStd::is_same<typename BusType::MutexType, AZ::NullMutex>::value || !BusIsConnected()),
+                    "EBus handlers must be disconnected prior to destruction on multi-threaded buses with virtual functions");
+                AZ_POP_DISABLE_WARNING
+
+                if (BusIsConnected())
+                {
+                    BusDisconnect();
+                }
+                EBUS_ASSERT(!BusIsConnected(), "Internal error: Bus was not properly disconnected!");
+            }
+
+            AZ_FORCE_INLINE void BusConnect()
+            {
+                typename BusType::Context& context = BusType::GetOrCreateContext();
+                typename BusType::Context::ConnectLockGuard contextLock(context.m_contextMutex);
+                if (!BusIsConnected())
+                {
+                    typename Traits::BusIdType id{};
+                    m_node = this;
+                    BusType::ConnectInternal(context, m_node, contextLock, id);
+                }
+            }
+            AZ_FORCE_INLINE void BusDisconnect()
+            {
+                if (typename BusType::Context* context = BusType::GetContext())
+                {
+                    typename BusType::Context::ConnectLockGuard contextLock(context->m_contextMutex);
+                    if (BusIsConnected())
+                    {
+                        BusType::DisconnectInternal(*context, m_node);
+                    }
+                }
+            }
+            AZ_FORCE_INLINE bool BusIsConnected() const
+            {
+                return static_cast<Interface*>(m_node) != nullptr;
+            }
 
         private:
             // Must be a member and not a base type so that Interface may be an incomplete type.
@@ -173,18 +244,118 @@ namespace AZ
         public:
             using BusType = AZ::EBus<Interface, Traits>;
 
-            IdHandler();
-            IdHandler(const IdHandler& rhs);
-            IdHandler& operator=(const IdHandler& rhs);
-            IdHandler(IdHandler&& rhs);
-            IdHandler& operator=(IdHandler&& rhs);
-            virtual ~IdHandler();
+            AZ_FORCE_INLINE IdHandler()
+                : m_node(nullptr)
+            {
+            }
+
+            AZ_FORCE_INLINE IdHandler(const IdHandler& rhs)
+                : m_node(nullptr)
+            {
+                *this = rhs;
+            }
+
+            AZ_FORCE_INLINE IdHandler& operator=(const IdHandler& rhs)
+            {
+                BusDisconnect();
+                if (rhs.BusIsConnected())
+                {
+                    BusConnect(rhs.m_node.GetBusId());
+                }
+                return *this;
+            }
+
+            AZ_FORCE_INLINE IdHandler(IdHandler&& rhs)
+                : m_node(nullptr)
+            {
+                *this = AZStd::move(rhs);
+            }
+
+            AZ_FORCE_INLINE IdHandler& operator=(IdHandler&& rhs)
+            {
+                BusDisconnect();
+                if (rhs.BusIsConnected())
+                {
+                    IdType id = rhs.m_node.GetBusId();
+                    rhs.BusDisconnect(id);
+                    BusConnect(id);
+                }
+                return *this;
+            }
+
+            AZ_FORCE_INLINE virtual ~IdHandler()
+            {
+                AZ_PUSH_DISABLE_WARNING(
+                    4127, "-Wunknown-warning-option") // conditional expression is constant (for Traits::LocklessDispatch in asserts)
+                AZ_Assert(
+                    (!AZStd::is_polymorphic<typename BusType::InterfaceType>::value ||
+                     AZStd::is_same_v<typename BusType::MutexType, AZ::NullMutex> || !BusIsConnected()),
+                    "EBus handlers must be disconnected prior to destruction on multi-threaded buses with virtual functions");
+                AZ_POP_DISABLE_WARNING
+
+                if (BusIsConnected())
+                {
+                    BusDisconnect();
+                }
+                EBUS_ASSERT(!BusIsConnected(), "Internal error: Bus was not properly disconnected!");
+            }
+
+            AZ_FORCE_INLINE void BusConnect(const IdType& id)
+            {
+                typename BusType::Context& context = BusType::GetOrCreateContext();
+                typename BusType::Context::ConnectLockGuard contextLock(context.m_contextMutex);
+                if (BusIsConnected())
+                {
+                    // Connecting on the BusId that is already connected is a no-op
+                    if (m_node.GetBusId() == id)
+                    {
+                        return;
+                    }
+                    AZ_Assert(
+                        false,
+                        "Connecting to a different id on this bus without disconnecting first! Please ensure you call BusDisconnect before "
+                        "calling BusConnect again, or if multiple connections are desired you must use a MultiHandler instead.");
+                    BusType::DisconnectInternal(context, m_node);
+                }
+
+                m_node = this;
+                BusType::ConnectInternal(context, m_node, contextLock, id);
+            }
+
+            AZ_FORCE_INLINE void BusDisconnect(const IdType& id)
+            {
+                if (typename BusType::Context* context = BusType::GetContext())
+                {
+                    typename BusType::Context::ConnectLockGuard contextLock(context->m_contextMutex);
+                    if (BusIsConnectedId(id))
+                    {
+                        BusType::DisconnectInternal(*context, m_node);
+                    }
+                }
+            }
+
+            AZ_FORCE_INLINE void BusDisconnect()
+            {
+                if (typename BusType::Context* context = BusType::GetContext())
+                {
+                    typename BusType::Context::ConnectLockGuard contextLock(context->m_contextMutex);
+                    if (BusIsConnected())
+                    {
+                        BusType::DisconnectInternal(*context, m_node);
+                    }
+                }
+            }
+
+            AZ_FORCE_INLINE bool BusIsConnectedId(const IdType& id) const
+            {
+                return BusIsConnected() && m_node.GetBusId() == id;
+            }
+
+            AZ_FORCE_INLINE bool BusIsConnected() const
+            {
+                return m_node.m_holder != nullptr;
+            }
 
-            void BusConnect(const IdType& id);
-            void BusDisconnect(const IdType& id);
-            void BusDisconnect();
-            bool BusIsConnectedId(const IdType& id) const;
-            bool BusIsConnected() const;
 
         private:
             // Must be a member and not a base type so that Interface may be an incomplete type.
@@ -205,18 +376,114 @@ namespace AZ
         public:
             using BusType = AZ::EBus<Interface, Traits>;
 
-            MultiHandler();
-            MultiHandler(const MultiHandler& rhs);
-            MultiHandler& operator=(const MultiHandler& rhs);
-            MultiHandler(MultiHandler&& rhs);
-            MultiHandler& operator=(MultiHandler&& rhs);
-            virtual ~MultiHandler();
-
-            void BusConnect(const IdType& id);
-            void BusDisconnect(const IdType& id);
-            void BusDisconnect();
-            bool BusIsConnectedId(const IdType& id) const;
-            bool BusIsConnected() const;
+            AZ_FORCE_INLINE MultiHandler() = default;
+
+            AZ_FORCE_INLINE MultiHandler(const MultiHandler& rhs)
+            {
+                *this = rhs;
+            }
+
+            AZ_FORCE_INLINE MultiHandler& operator=(const MultiHandler& rhs)
+            {
+                BusDisconnect();
+                for (const auto& nodePair : rhs.m_handlerNodes)
+                {
+                    BusConnect(nodePair.first);
+                }
+                return *this;
+            }
+
+            AZ_FORCE_INLINE MultiHandler(MultiHandler&& rhs)
+            {
+                *this = AZStd::move(rhs);
+            }
+
+            AZ_FORCE_INLINE MultiHandler& operator=(MultiHandler&& rhs)
+            {
+                BusDisconnect();
+                for (const auto& nodePair : rhs.m_handlerNodes)
+                {
+                    BusConnect(nodePair.first);
+                }
+                rhs.BusDisconnect();
+                return *this;
+            }
+
+            AZ_FORCE_INLINE virtual ~MultiHandler()
+            {
+                AZ_PUSH_DISABLE_WARNING(
+                    4127, "-Wunknown-warning-option") // conditional expression is constant (for Traits::LocklessDispatch in asserts)
+                AZ_Assert(
+                    (!AZStd::is_polymorphic<typename BusType::InterfaceType>::value ||
+                     AZStd::is_same<typename BusType::MutexType, AZ::NullMutex>::value || !BusIsConnected()),
+                    "EBus handlers must be disconnected prior to destruction on multi-threaded buses with virtual functions");
+                AZ_POP_DISABLE_WARNING
+
+                if (BusIsConnected())
+                {
+                    BusDisconnect();
+                }
+                EBUS_ASSERT(!BusIsConnected(), "Internal error: Bus was not properly disconnected!");
+            }
+
+            AZ_FORCE_INLINE void BusConnect(const IdType& id)
+            {
+                typename BusType::Context& context = BusType::GetOrCreateContext();
+                typename BusType::Context::ConnectLockGuard contextLock(context.m_contextMutex);
+                if (m_handlerNodes.find(id) == m_handlerNodes.end())
+                {
+                    void* handlerNodeAddr =
+                        m_handlerNodes.get_allocator().allocate(sizeof(HandlerNode), AZStd::alignment_of<HandlerNode>::value);
+                    auto handlerNode = new (handlerNodeAddr) HandlerNode(this);
+                    m_handlerNodes.emplace(id, AZStd::move(handlerNode));
+                    BusType::ConnectInternal(context, *handlerNode, contextLock, id);
+                }
+            }
+            AZ_FORCE_INLINE void BusDisconnect(const IdType& id)
+            {
+                if (typename BusType::Context* context = BusType::GetContext())
+                {
+                    typename BusType::Context::ConnectLockGuard contextLock(context->m_contextMutex);
+                    auto nodeIt = m_handlerNodes.find(id);
+                    if (nodeIt != m_handlerNodes.end())
+                    {
+                        HandlerNode* handlerNode = nodeIt->second;
+                        BusType::DisconnectInternal(*context, *handlerNode);
+                        m_handlerNodes.erase(nodeIt);
+                        handlerNode->~HandlerNode();
+                        m_handlerNodes.get_allocator().deallocate(handlerNode, sizeof(HandlerNode), alignof(HandlerNode));
+                    }
+                }
+            }
+
+            AZ_FORCE_INLINE void BusDisconnect()
+            {
+                decltype(m_handlerNodes) handlerNodesToDisconnect;
+                if (typename BusType::Context* context = BusType::GetContext())
+                {
+                    typename BusType::Context::ConnectLockGuard contextLock(context->m_contextMutex);
+                    handlerNodesToDisconnect = AZStd::move(m_handlerNodes);
+
+                    for (const auto& nodePair : handlerNodesToDisconnect)
+                    {
+                        BusType::DisconnectInternal(*context, *nodePair.second);
+
+                        nodePair.second->~HandlerNode();
+                        handlerNodesToDisconnect.get_allocator().deallocate(
+                            nodePair.second, sizeof(HandlerNode), AZStd::alignment_of<HandlerNode>::value);
+                    }
+                }
+            }
+
+            AZ_FORCE_INLINE bool BusIsConnectedId(const IdType& id) const
+            {
+                return m_handlerNodes.end() != m_handlerNodes.find(id);
+            }
+
+            AZ_FORCE_INLINE bool BusIsConnected() const
+            {
+                return !m_handlerNodes.empty();
+            }
 
         private:
             AZStd::unordered_map<IdType, HandlerNode*, AZStd::hash<IdType>, AZStd::equal_to<IdType>, typename Traits::AllocatorType> m_handlerNodes;

+ 1 - 1
Code/Framework/AzCore/AzCore/EBus/ScheduledEvent.h

@@ -22,7 +22,7 @@ namespace AZ
     //! Total time duration between queuing and the scheduled event triggering is not guaranteed, and will at least be quantized to frametime.
     //! This event can trigger continuously at the specified interval in ms if set with the auto-re-queue function.
     //! This event should be declared as a member of class, not in a local function as it will not trigger if it goes out of scope.
-    class ScheduledEvent
+    class AZCORE_API ScheduledEvent
     {
     public:
         //! Default constructor only for AZStd::deque compatibility.

+ 1 - 1
Code/Framework/AzCore/AzCore/EBus/ScheduledEventHandle.h

@@ -17,7 +17,7 @@ namespace AZ
     //! @struct ScheduledEventHandle
     //! This is a handle class that wraps a scheduled event.
     //! This is created inside of EventSchedulerSystemComponent and deleted in EventSchedulerSystemComponent::OnTick()
-    class ScheduledEventHandle
+    class AZCORE_API ScheduledEventHandle
     {
     public:
         //! Default constructor for AZStd::deque compatibility.

+ 6 - 4
Code/Framework/AzCore/AzCore/IO/AnsiTerminalUtils.h

@@ -8,19 +8,21 @@
 
 #pragma once
 
+#include <AzCore/base.h>
+
 namespace AZ::IO::Posix
 {
     //! Enables Virtual Terminal Processing on Windows for th specified file descriptor
     //! This allows ANSI escapes to be supported
     //! https://learn.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences
-    void EnableVirtualTerminalProcessing(int fileDescriptor);
+    AZCORE_API void EnableVirtualTerminalProcessing(int fileDescriptor);
 
     //! return true the terminal supports color ANSI escape codes
-    bool TerminalSupportsColor();
+    AZCORE_API bool TerminalSupportsColor();
 
     //! return true if the open file descriptor is a terminal
-    bool IsATty(int fileDescriptor);
+    AZCORE_API bool IsATty(int fileDescriptor);
 
     //! return true if the file descriptor supports ANSI escape sequences
-    bool SupportsAnsiEscapes(int fileDescriptor);
+    AZCORE_API bool SupportsAnsiEscapes(int fileDescriptor);
 }

+ 2 - 0
Code/Framework/AzCore/AzCore/IO/CompressionBus.cpp

@@ -8,6 +8,8 @@
 
 #include <AzCore/IO/CompressionBus.h>
 
+AZ_INSTANTIATE_EBUS_SINGLE_ADDRESS(AZCORE_API, AZ::IO::Compression);
+
 namespace AZ::IO
 {
     CompressionInfo::CompressionInfo(CompressionInfo&& rhs)

+ 5 - 3
Code/Framework/AzCore/AzCore/IO/CompressionBus.h

@@ -79,7 +79,9 @@ namespace AZ
 
         namespace CompressionUtils
         {
-            bool FindCompressionInfo(CompressionInfo& info, const AZ::IO::PathView filePath);
+            AZCORE_API bool FindCompressionInfo(CompressionInfo& info, const AZ::IO::PathView filePath);
         }
-    }
-}
+    } // namespace IO
+} // namespace AZ
+
+AZ_DECLARE_EBUS_SINGLE_ADDRESS(AZCORE_API, AZ::IO::Compression);

+ 3 - 3
Code/Framework/AzCore/AzCore/IO/Compressor.h

@@ -17,7 +17,7 @@ namespace AZ::IO
      * Compressor/Decompressor base interface.
      * Used for all stream compressors.
      */
-    class Compressor
+    class AZCORE_API Compressor
     {
     public:
         typedef AZ::u64 SizeType;
@@ -45,7 +45,7 @@ namespace AZ::IO
     /**
      * Base compressor data assigned for all compressors.
      */
-    class CompressorData
+    class AZCORE_API CompressorData
     {
     public:
         virtual ~CompressorData() {}
@@ -57,7 +57,7 @@ namespace AZ::IO
     /**
      * All data is stored in network order (big endian).
      */
-    struct  CompressorHeader
+    struct AZCORE_API CompressorHeader
     {
         CompressorHeader()      { m_azcs[0] = 0; m_azcs[1] = 0; m_azcs[2] = 0; m_azcs[3] = 0; }
 

+ 1 - 1
Code/Framework/AzCore/AzCore/IO/CompressorStream.h

@@ -23,7 +23,7 @@ namespace AZ
          * CompressorStream wrap a GenericStream and runs the streaming functions through the supplied compressor
          *
          */
-        class CompressorStream
+        class AZCORE_API CompressorStream
             : public GenericStream
         {
         public:

+ 2 - 2
Code/Framework/AzCore/AzCore/IO/CompressorZLib.h

@@ -41,7 +41,7 @@ namespace AZ
         /**
          * ZLib compressor per stream data.
          */
-        class CompressorZLibData
+        class AZCORE_API CompressorZLibData
             : public CompressorData
         {
         public:
@@ -78,7 +78,7 @@ namespace AZ
          * caching functionality into the base Compressor class to be shared. Please do so when you have
          * an actual need to implement another compressor, don't just copy and paste.
          */
-        class CompressorZLib
+        class AZCORE_API CompressorZLib
             : public Compressor
         {
         public:

+ 2 - 2
Code/Framework/AzCore/AzCore/IO/CompressorZStd.h

@@ -42,7 +42,7 @@ namespace AZ
         /**
          * ZStd compressor per stream data.
          */
-        class CompressorZStdData
+        class AZCORE_API CompressorZStdData
             : public CompressorData
         {
         public:
@@ -69,7 +69,7 @@ namespace AZ
             SeekPointArray    m_seekPoints;               ///< List of seek points for the archive, we must have at least one!
         };
 
-        class CompressorZStd
+        class AZCORE_API CompressorZStd
             : public Compressor
         {
         public:

+ 7 - 7
Code/Framework/AzCore/AzCore/IO/FileIO.h

@@ -31,11 +31,11 @@ namespace AZ
         /// return true if name of file matches glob filter.
         /// glob filters are MS-DOS (or windows) findNextFile style filters
         /// like "*.bat" or "blah??.pak" or "test*.exe" and such.
-        bool NameMatchesFilter(AZStd::string_view name, AZStd::string_view filter);
+        AZCORE_API bool NameMatchesFilter(AZStd::string_view name, AZStd::string_view filter);
 
         //! Converts the operating-specific values returned by AZ::IO::FileIO API
         //! to independent units representing the milliseconds since 1/1/1970 0:00 UTC
-        AZ::u64 FileTimeToMSecsSincePosixEpoch(AZ::u64 fileTime);
+        AZCORE_API AZ::u64 FileTimeToMSecsSincePosixEpoch(AZ::u64 fileTime);
 
         using HandleType = AZ::u32;
         static const HandleType InvalidHandle = 0;
@@ -47,8 +47,8 @@ namespace AZ
             SeekFromEnd
         };
 
-        SeekType GetSeekTypeFromFSeekMode(int mode);
-        int GetFSeekModeFromSeekType(SeekType type);
+        AZCORE_API SeekType GetSeekTypeFromFSeekMode(int mode);
+        AZCORE_API int GetFSeekModeFromSeekType(SeekType type);
 
         enum class ResultCode : AZ::u32
         {
@@ -59,7 +59,7 @@ namespace AZ
         };
 
         // a function which returns a result code and supports operator bool explicitly
-        class Result
+        class AZCORE_API Result
         {
         public:
             Result(ResultCode resultCode)
@@ -86,7 +86,7 @@ namespace AZ
         };
 
         /// The base class for file IO stack classes
-        class FileIOBase
+        class AZCORE_API FileIOBase
         {
         public:
             virtual ~FileIOBase()
@@ -242,7 +242,7 @@ namespace AZ
          * Stream implementation for reading/writing to/from a FileIO handle.
          * This may be used alongside ObjectStream, or in async asset tasks.
          */
-        class FileIOStream
+        class AZCORE_API FileIOStream
             : public GenericStream
         {
         public:

+ 1 - 1
Code/Framework/AzCore/AzCore/IO/FileReader.h

@@ -20,7 +20,7 @@ namespace AZ::IO
     //! to either the FileIOBase or SystemFile classes based if a FileIOBase* instance has been supplied
     //! to the FileSystemReader class
     //! the SettingsRegistry option to use FileIO
-    class FileReader
+    class AZCORE_API FileReader
     {
         using HandleType = AZ::u32;
         using FileHandleType = AZStd::variant<AZStd::monostate, AZ::IO::SystemFile, HandleType>;

+ 4 - 4
Code/Framework/AzCore/AzCore/IO/GenericStreams.h

@@ -20,7 +20,7 @@ namespace AZ::IO
     /*
      * Base Class interface for implementing AZ::IO streams
      */
-    class GenericStream
+    class AZCORE_API GenericStream
     {
     public:
         enum SeekMode
@@ -62,7 +62,7 @@ namespace AZ::IO
     /*
      * Wraps around a SystemFile
      */
-    class SystemFileStream
+    class AZCORE_API SystemFileStream
         : public GenericStream
     {
     public:
@@ -112,7 +112,7 @@ namespace AZ::IO
     /*
      * Wraps around a memory buffer
      */
-    class MemoryStream
+    class AZCORE_API MemoryStream
         : public GenericStream
     {
     public:
@@ -167,7 +167,7 @@ namespace AZ::IO
     * that can write raw data to stdout file descriptor
     * Read operations are not supported
     */
-    class StdoutStream
+    class AZCORE_API StdoutStream
         : public GenericStream
     {
     public:

+ 1 - 1
Code/Framework/AzCore/AzCore/IO/IOUtils.cpp

@@ -7,8 +7,8 @@
  */
 #include <AzCore/base.h>
 #include <AzCore/IO/FileIO.h>
+#include <AzCore/IO/IOUtils.h>
 #include <AzCore/std/parallel/thread.h> /// this_thread sleep_for.
-
 namespace AZ::IO
 {
     bool RetryOpenStream(FileIOStream& stream, int numRetries, int delayBetweenRetry)

+ 3 - 1
Code/Framework/AzCore/AzCore/IO/IOUtils.h

@@ -7,6 +7,8 @@
  */
 #pragma once
 
+#include <AzCore/base.h>
+
 namespace AZ
 {
     namespace IO
@@ -18,7 +20,7 @@ namespace AZ
         * lock on a file stream.
         * returns false if the stream is not open at the end of the retries.
         */
-        bool RetryOpenStream(FileIOStream& stream, int numRetries = 10, int delayBetweenRetry = 250);
+       AZCORE_API bool RetryOpenStream(FileIOStream& stream, int numRetries = 10, int delayBetweenRetry = 250);
     }   // namespace IO
    
 }   // namespace AZ

+ 9 - 9
Code/Framework/AzCore/AzCore/IO/IStreamerTypes.h

@@ -37,7 +37,7 @@ namespace AZ::IO::IStreamerTypes
     inline constexpr static Priority s_priorityLowest = 0;
 
     //! Provides configuration recommendations for using the file streaming system.
-    struct Recommendations
+    struct AZCORE_API Recommendations
     {
         //! The minimal memory alignment that's required to avoid intermediate buffers. If the memory
         //! provided to the read request isn't aligned to this size it may require a temporary or cached buffer
@@ -91,7 +91,7 @@ namespace AZ::IO::IStreamerTypes
             //!< the allocator provided to request to later release this memory.
     };
 
-    struct RequestMemoryAllocatorResult
+    struct AZCORE_API RequestMemoryAllocatorResult
     {
         void* m_address; //!< The address to the reserved memory.
         size_t m_size; //!< The actual amount of memory that was reserved.
@@ -108,7 +108,7 @@ namespace AZ::IO::IStreamerTypes
     //! The functions in the RequestMemoryAllocator can be called from various threads and may prevent the Streamer from continuing
     //! processing. (Similar to the completion callbacks in the requests). It's recommended to spend as little time as possible in these
     //! callbacks and defer work to jobs where possible.
-    class RequestMemoryAllocator
+    class AZCORE_API RequestMemoryAllocator
     {
     public:
         virtual ~RequestMemoryAllocator() = default;
@@ -133,7 +133,7 @@ namespace AZ::IO::IStreamerTypes
 
     //! Default memory allocator for file requests. This allocator is a wrapper around the standard memory allocator and can be used
     //! if only delayed memory allocations are needed but no special memory requirements.
-    class DefaultRequestMemoryAllocator final
+    class AZCORE_API DefaultRequestMemoryAllocator final
         : public RequestMemoryAllocator
     {
     public:
@@ -165,11 +165,11 @@ namespace AZ::IO::IStreamerTypes
 
     // The following alignment functions are put here until they're available in AzCore's math library.
 
-    constexpr bool IsPowerOf2(AZ::u64 value);
-    constexpr bool IsAlignedTo(AZ::u64 value, AZ::u64 alignment);
-    inline bool IsAlignedTo(void* address, AZ::u64 alignment);
-    inline AZ::u64 GetAlignment(AZ::u64 value);
-    inline AZ::u64 GetAlignment(void* address);
+    AZCORE_API constexpr bool IsPowerOf2(AZ::u64 value);
+    AZCORE_API constexpr bool IsAlignedTo(AZ::u64 value, AZ::u64 alignment);
+    AZCORE_API inline bool IsAlignedTo(void* address, AZ::u64 alignment);
+    AZCORE_API inline AZ::u64 GetAlignment(AZ::u64 value);
+    AZCORE_API inline AZ::u64 GetAlignment(void* address);
 
 } // namespace AZ::IO::IStreamer
 

+ 4 - 4
Code/Framework/AzCore/AzCore/IO/OpenMode.h

@@ -45,17 +45,17 @@ namespace AZ::IO
 
     AZ_DEFINE_ENUM_BITWISE_OPERATORS(OpenMode)
 
-    OpenMode GetOpenModeFromStringMode(const char* mode);
+    AZCORE_API OpenMode GetOpenModeFromStringMode(const char* mode);
 
-    const char* GetStringModeFromOpenMode(OpenMode mode);
+    AZCORE_API const char* GetStringModeFromOpenMode(OpenMode mode);
 
     // when reading, we ignore text mode requests, because text mode will not be supported from reading from
     // odd devices such as pack files, remote reads, and within compressed volumes anyway.  This makes it behave the same as
     // pak mode as it behaves loose.  In practice, developers should avoid depending on text mode for reading, specifically depending
     // on the platform-specific concept of removing '\r' characters from a text stream.
     // having the OS swallow characters without letting us know also messes up things like lookahead cache, optimizing functions like FGetS and so on.
-    void UpdateOpenModeForReading(OpenMode& mode);
+    AZCORE_API void UpdateOpenModeForReading(OpenMode& mode);
 
-    int TranslateOpenModeToSystemFileMode(const char* path, OpenMode mode);
+    AZCORE_API int TranslateOpenModeToSystemFileMode(const char* path, OpenMode mode);
 
 }   // namespace AZ::IO

+ 21 - 21
Code/Framework/AzCore/AzCore/IO/Path/Path.cpp

@@ -74,42 +74,42 @@ namespace AZ::IO
     }
     
     // Class template instantations
-    template class BasicPath<AZStd::string>;
-    template class BasicPath<FixedMaxPathString>;
-    template class PathIterator<const PathView>;
-    template class PathIterator<const Path>;
-    template class PathIterator<const FixedMaxPath>;
+    template class AZCORE_API_EXPORT BasicPath<AZStd::string>;
+    template class AZCORE_API_EXPORT BasicPath<FixedMaxPathString>;
+    template class AZCORE_API_EXPORT PathIterator<const PathView>;
+    template class AZCORE_API_EXPORT PathIterator<const Path>;
+    template class AZCORE_API_EXPORT PathIterator<const FixedMaxPath>;
 
     // Swap function instantiations
-    template void swap<AZStd::string>(Path& lhs, Path& rhs) noexcept;
-    template void swap<FixedMaxPathString>(FixedMaxPath& lhs, FixedMaxPath& rhs) noexcept;
+    template void AZCORE_API_EXPORT swap<AZStd::string>(Path& lhs, Path& rhs) noexcept;
+    template void AZCORE_API_EXPORT swap<FixedMaxPathString>(FixedMaxPath& lhs, FixedMaxPath& rhs) noexcept;
 
     // Hash function instantiations
-    template size_t hash_value<AZStd::string>(const Path& pathToHash);
-    template size_t hash_value<FixedMaxPathString>(const FixedMaxPath& pathToHash);
+    template AZCORE_API_EXPORT size_t hash_value<AZStd::string>(const Path& pathToHash);
+    template AZCORE_API_EXPORT size_t hash_value<FixedMaxPathString>(const FixedMaxPath& pathToHash);
 
     // Append operator instantiations
-    template BasicPath<AZStd::string> operator/<AZStd::string>(const BasicPath<AZStd::string>& lhs, const PathView& rhs);
-    template BasicPath<FixedMaxPathString> operator/<FixedMaxPathString>(const BasicPath<FixedMaxPathString>& lhs, const PathView& rhs);
-    template BasicPath<AZStd::string> operator/<AZStd::string>(const BasicPath<AZStd::string>& lhs, AZStd::string_view rhs);
-    template BasicPath<FixedMaxPathString> operator/<FixedMaxPathString>(const BasicPath<FixedMaxPathString>& lhs, AZStd::string_view rhs);
-    template BasicPath<AZStd::string> operator/<AZStd::string>(const BasicPath<AZStd::string>& lhs,
+    template AZCORE_API_EXPORT BasicPath<AZStd::string> operator/<AZStd::string>(const BasicPath<AZStd::string>& lhs, const PathView& rhs);
+    template AZCORE_API_EXPORT BasicPath<FixedMaxPathString> operator/<FixedMaxPathString>(const BasicPath<FixedMaxPathString>& lhs, const PathView& rhs);
+    template AZCORE_API_EXPORT BasicPath<AZStd::string> operator/<AZStd::string>(const BasicPath<AZStd::string>& lhs, AZStd::string_view rhs);
+    template AZCORE_API_EXPORT BasicPath<FixedMaxPathString> operator/<FixedMaxPathString>(const BasicPath<FixedMaxPathString>& lhs, AZStd::string_view rhs);
+    template AZCORE_API_EXPORT BasicPath<AZStd::string> operator/<AZStd::string>(const BasicPath<AZStd::string>& lhs,
         const typename BasicPath<AZStd::string>::value_type* rhs);
-    template BasicPath<FixedMaxPathString> operator/<FixedMaxPathString>(const BasicPath<FixedMaxPathString>& lhs,
+    template AZCORE_API_EXPORT BasicPath<FixedMaxPathString> operator/<FixedMaxPathString>(const BasicPath<FixedMaxPathString>& lhs,
         const typename BasicPath<FixedMaxPathString>::value_type* rhs);
 
     // Iterator compare instantiations
-    template bool operator==<const PathView>(const PathIterator<const PathView>& lhs,
+    template AZCORE_API_EXPORT bool operator== <const PathView>(const PathIterator<const PathView>& lhs,
         const PathIterator<const PathView>& rhs);
-    template bool operator==<const Path>(const PathIterator<const Path>& lhs,
+    template AZCORE_API_EXPORT bool operator== <const Path>(const PathIterator<const Path>& lhs,
         const PathIterator<const Path>& rhs);
-    template bool operator==<const FixedMaxPath>(const PathIterator<const FixedMaxPath>& lhs,
+    template AZCORE_API_EXPORT bool operator== <const FixedMaxPath>(const PathIterator<const FixedMaxPath>& lhs,
         const PathIterator<const FixedMaxPath>& rhs);
-    template bool operator!=<const PathView>(const PathIterator<const PathView>& lhs,
+    template AZCORE_API_EXPORT bool operator!= <const PathView>(const PathIterator<const PathView>& lhs,
         const PathIterator<const PathView>& rhs);
-    template bool operator!=<const Path>(const PathIterator<const Path>& lhs,
+    template AZCORE_API_EXPORT bool operator!= <const Path>(const PathIterator<const Path>& lhs,
         const PathIterator<const Path>& rhs);
-    template bool operator!=<const FixedMaxPath>(const PathIterator<const FixedMaxPath>& lhs,
+    template AZCORE_API_EXPORT bool operator!= <const FixedMaxPath>(const PathIterator<const FixedMaxPath>& lhs,
         const PathIterator<const FixedMaxPath>& rhs);
 }
 

+ 9 - 9
Code/Framework/AzCore/AzCore/IO/Path/Path.h

@@ -112,7 +112,7 @@ namespace AZ::IO
     //! root-name -> root-directory -> file name(0 or more times)
     //! directory separators are skipped except for the one that represents the root directory
     //! A iterated path element is never empty
-    class PathView
+    class AZCORE_API PathView
     {
     public:
         using string_view_type = AZStd::string_view;
@@ -383,21 +383,21 @@ namespace AZ::IO
         value_type m_preferred_separator = AZ_TRAIT_OS_PATH_SEPARATOR;
     };
 
-    constexpr void swap(PathView& lhs, PathView& rhs) noexcept;
+    AZCORE_API constexpr void swap(PathView& lhs, PathView& rhs) noexcept;
 
     //! Hashes a value in a manner that if two paths are equal,
     //! then their hash values are also equal
     //! For example : path "a//b" equals  "a/b", the
     //! hash value of "a//b" would also equal the hash value of "a/b"
-    constexpr size_t hash_value(const PathView& pathToHash) noexcept;
+    AZCORE_API constexpr size_t hash_value(const PathView& pathToHash) noexcept;
 
     // path.comparison
-    constexpr bool operator==(const PathView& lhs, const PathView& rhs) noexcept;
-    constexpr bool operator!=(const PathView& lhs, const PathView& rhs) noexcept;
-    constexpr bool operator<(const PathView& lhs, const PathView& rhs) noexcept;
-    constexpr bool operator<=(const PathView& lhs, const PathView& rhs) noexcept;
-    constexpr bool operator>(const PathView& lhs, const PathView& rhs) noexcept;
-    constexpr bool operator>=(const PathView& lhs, const PathView& rhs) noexcept;
+    AZCORE_API constexpr bool operator==(const PathView& lhs, const PathView& rhs) noexcept;
+    AZCORE_API constexpr bool operator!=(const PathView& lhs, const PathView& rhs) noexcept;
+    AZCORE_API constexpr bool operator<(const PathView& lhs, const PathView& rhs) noexcept;
+    AZCORE_API constexpr bool operator<=(const PathView& lhs, const PathView& rhs) noexcept;
+    AZCORE_API constexpr bool operator>(const PathView& lhs, const PathView& rhs) noexcept;
+    AZCORE_API constexpr bool operator>=(const PathView& lhs, const PathView& rhs) noexcept;
 }
 
 namespace AZ::IO

+ 7 - 7
Code/Framework/AzCore/AzCore/IO/Path/Path.inl

@@ -1532,7 +1532,7 @@ namespace AZ::IO
     extern template size_t hash_value<FixedMaxPathString>(const FixedMaxPath& pathToHash);
 
     // Append operator explicit declarations
-    extern template BasicPath<AZStd::string> operator/<AZStd::string>(const BasicPath<AZStd::string>& lhs, const PathView& rhs);
+    extern template BasicPath<AZStd::string> operator/ <AZStd::string>(const BasicPath<AZStd::string>& lhs, const PathView& rhs);
     extern template BasicPath<FixedMaxPathString> operator/<FixedMaxPathString>(const BasicPath<FixedMaxPathString>& lhs, const PathView& rhs);
     extern template BasicPath<AZStd::string> operator/<AZStd::string>(const BasicPath<AZStd::string>& lhs, AZStd::string_view rhs);
     extern template BasicPath<FixedMaxPathString> operator/<FixedMaxPathString>(const BasicPath<FixedMaxPathString>& lhs, AZStd::string_view rhs);
@@ -1542,17 +1542,17 @@ namespace AZ::IO
         const typename BasicPath<FixedMaxPathString>::value_type* rhs);
 
     // Iterator compare explicit declarations
-    extern template bool operator==<const PathView>(const PathIterator<const PathView>& lhs,
+    extern template AZCORE_API bool operator==<const PathView>(const PathIterator<const PathView>& lhs,
         const PathIterator<const PathView>& rhs);
-    extern template bool operator==<const Path>(const PathIterator<const Path>& lhs,
+    extern template AZCORE_API bool operator== <const Path>(const PathIterator<const Path>& lhs,
         const PathIterator<const Path>& rhs);
-    extern template bool operator==<const FixedMaxPath>(const PathIterator<const FixedMaxPath>& lhs,
+    extern template AZCORE_API bool operator==<const FixedMaxPath>(const PathIterator<const FixedMaxPath>& lhs,
         const PathIterator<const FixedMaxPath>& rhs);
-    extern template bool operator!=<const PathView>(const PathIterator<const PathView>& lhs,
+    extern template AZCORE_API bool operator!=<const PathView>(const PathIterator<const PathView>& lhs,
         const PathIterator<const PathView>& rhs);
-    extern template bool operator!=<const Path>(const PathIterator<const Path>& lhs,
+    extern template AZCORE_API bool operator!= <const Path>(const PathIterator<const Path>& lhs,
         const PathIterator<const Path>& rhs);
-    extern template bool operator!=<const FixedMaxPath>(const PathIterator<const FixedMaxPath>& lhs,
+    extern template AZCORE_API bool operator!=<const FixedMaxPath>(const PathIterator<const FixedMaxPath>& lhs,
         const PathIterator<const FixedMaxPath>& rhs);
 }
 

+ 1 - 1
Code/Framework/AzCore/AzCore/IO/Path/PathReflect.cpp

@@ -7,13 +7,13 @@
  */
 
 #include <AzCore/IO/Path/Path.h>
+#include <AzCore/IO/Path/PathReflect.h>
 #include <AzCore/RTTI/BehaviorContext.h>
 #include <AzCore/Serialization/Json/RegistrationContext.h>
 #include <AzCore/Serialization/Json/PathSerializer.h>
 #include <AzCore/Serialization/SerializeContext.h>
 #include <AzCore/std/functional.h>
 #include <AzCore/StringFunc/StringFunc.h>
-
 namespace AZ::IO
 {
     template <typename PathType>

+ 3 - 1
Code/Framework/AzCore/AzCore/IO/Path/PathReflect.h

@@ -8,6 +8,8 @@
 
 #pragma once
 
+#include <AzCore/base.h>
+
 namespace AZ
 {
     class ReflectContext;
@@ -15,5 +17,5 @@ namespace AZ
 
 namespace AZ::IO
 {
-    void PathReflect(AZ::ReflectContext* context);
+    AZCORE_API void PathReflect(AZ::ReflectContext* context);
 }

+ 2 - 2
Code/Framework/AzCore/AzCore/IO/Streamer/BlockCache.h

@@ -28,7 +28,7 @@ namespace AZ::IO
         struct ReportData;
     }
 
-    struct BlockCacheConfig final :
+    struct AZCORE_API BlockCacheConfig final :
         public IStreamerStackConfig
     {
         AZ_RTTI(AZ::IO::BlockCacheConfig, "{70120525-88A4-40B6-A75B-BAA7E8FD77F3}", IStreamerStackConfig);
@@ -57,7 +57,7 @@ namespace AZ::IO
         BlockSize m_blockSize{ BlockSize::MemoryAlignment };
     };
 
-    class BlockCache
+    class AZCORE_API BlockCache
         : public StreamStackEntry
     {
     public:

Unele fișiere nu au fost afișate deoarece prea multe fișiere au fost modificate în acest diff