diff --git a/.gitattributes b/.gitattributes
index d7f9d36c50..2037909dbd 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -115,7 +115,6 @@
*.wav filter=lfs diff=lfs merge=lfs -text
*.webm filter=lfs diff=lfs merge=lfs -text
*.wem filter=lfs diff=lfs merge=lfs -text
-*.wxs filter=lfs diff=lfs merge=lfs -text
*.zip filter=lfs diff=lfs merge=lfs -text
*.tbscene filter=lfs diff=lfs merge=lfs -text
*.spp filter=lfs diff=lfs merge=lfs -text
diff --git a/cmake/Packaging.cmake b/cmake/Packaging.cmake
index 4f6565edc7..ba610b1883 100644
--- a/cmake/Packaging.cmake
+++ b/cmake/Packaging.cmake
@@ -13,7 +13,34 @@ if(NOT PAL_TRAIT_BUILD_CPACK_SUPPORTED)
return()
endif()
-ly_get_absolute_pal_filename(pal_dir ${CMAKE_SOURCE_DIR}/cmake/Platform/${PAL_HOST_PLATFORM_NAME})
+# public facing options will be used for conversion into cpack specific ones below.
+set(LY_INSTALLER_DOWNLOAD_URL "" CACHE STRING "URL embedded into the installer to download additional artifacts")
+set(LY_INSTALLER_LICENSE_URL "" CACHE STRING "Optionally embed a link to the license instead of raw text")
+
+# set all common cpack variable overrides first so they can be accessible via configure_file
+# when the platform specific settings are applied below. additionally, any variable with
+# the "CPACK_" prefix will automatically be cached for use in any phase of cpack namely
+# pre/post build
+set(CPACK_PACKAGE_VENDOR "${PROJECT_NAME}")
+set(CPACK_PACKAGE_VERSION "${LY_VERSION_STRING}")
+set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Installation Tool")
+
+string(TOLOWER ${PROJECT_NAME} _project_name_lower)
+set(CPACK_PACKAGE_FILE_NAME "${_project_name_lower}_${LY_VERSION_STRING}_installer")
+
+set(DEFAULT_LICENSE_NAME "Apache-2.0")
+set(DEFAULT_LICENSE_FILE "${CMAKE_SOURCE_DIR}/LICENSE.txt")
+
+set(CPACK_RESOURCE_FILE_LICENSE ${DEFAULT_LICENSE_FILE})
+set(CPACK_LICENSE_URL ${LY_INSTALLER_LICENSE_URL})
+
+set(CPACK_PACKAGE_INSTALL_DIRECTORY "${CPACK_PACKAGE_VENDOR}/${CPACK_PACKAGE_VERSION}")
+
+# CMAKE_SOURCE_DIR doesn't equate to anything during execution of pre/post build scripts
+set(CPACK_SOURCE_DIR ${CMAKE_SOURCE_DIR}/cmake)
+
+# attempt to apply platform specific settings
+ly_get_absolute_pal_filename(pal_dir ${CPACK_SOURCE_DIR}/Platform/${PAL_HOST_PLATFORM_NAME})
include(${pal_dir}/Packaging_${PAL_HOST_PLATFORM_NAME_LOWERCASE}.cmake)
# if we get here and the generator hasn't been set, then a non fatal error occurred disabling packaging support
@@ -21,20 +48,6 @@ if(NOT CPACK_GENERATOR)
return()
endif()
-set(CPACK_PACKAGE_VENDOR "${PROJECT_NAME}")
-set(CPACK_PACKAGE_VERSION "${LY_VERSION_STRING}")
-set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Installation Tool")
-
-string(TOLOWER ${PROJECT_NAME} _project_name_lower)
-set(CPACK_PACKAGE_FILE_NAME "${_project_name_lower}_installer")
-
-set(DEFAULT_LICENSE_NAME "Apache-2.0")
-set(DEFAULT_LICENSE_FILE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE.txt")
-
-set(CPACK_RESOURCE_FILE_LICENSE ${DEFAULT_LICENSE_FILE})
-
-set(CPACK_PACKAGE_INSTALL_DIRECTORY "${CPACK_PACKAGE_VENDOR}/${CPACK_PACKAGE_VERSION}")
-
# IMPORTANT: required to be included AFTER setting all property overrides
include(CPack REQUIRED)
@@ -76,3 +89,12 @@ ly_configure_cpack_component(
DISPLAY_NAME "${PROJECT_NAME} Core"
DESCRIPTION "${PROJECT_NAME} Headers, Libraries and Tools"
)
+
+if(LY_INSTALLER_DOWNLOAD_URL)
+ # this will set the following variables: CPACK_DOWNLOAD_SITE, CPACK_DOWNLOAD_ALL, and CPACK_UPLOAD_DIRECTORY
+ cpack_configure_downloads(
+ ${LY_INSTALLER_DOWNLOAD_URL}
+ UPLOAD_DIRECTORY ${CMAKE_BINARY_DIR}/_CPack_Uploads # to match the _CPack_Packages directory
+ ALL
+ )
+endif()
diff --git a/cmake/Platform/Windows/PackagingBootstrapper.wxs b/cmake/Platform/Windows/PackagingBootstrapper.wxs
new file mode 100644
index 0000000000..c3d1dd7a7b
--- /dev/null
+++ b/cmake/Platform/Windows/PackagingBootstrapper.wxs
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/cmake/Platform/Windows/PackagingPostBuild.cmake b/cmake/Platform/Windows/PackagingPostBuild.cmake
new file mode 100644
index 0000000000..3ba6ef2096
--- /dev/null
+++ b/cmake/Platform/Windows/PackagingPostBuild.cmake
@@ -0,0 +1,88 @@
+#
+# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
+# its licensors.
+#
+# For complete copyright and license terms please see the LICENSE at the root of this
+# distribution (the "License"). All use of this software is governed by the License,
+# or, if provided, by the license below or the license accompanying this file. Do not
+# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#
+
+# convert the path to a windows style path using string replace because TO_NATIVE_PATH
+# only works on real paths
+string(REPLACE "/" "\\" _fixed_package_install_dir ${CPACK_PACKAGE_INSTALL_DIRECTORY})
+
+# directory where the auto generated files live e.g /_CPack_Package/win64/WIX
+set(_cpack_wix_out_dir ${CPACK_TOPLEVEL_DIRECTORY})
+set(_bootstrap_out_dir "${CPACK_TOPLEVEL_DIRECTORY}/bootstrap")
+
+set(_bootstrap_filename "${CPACK_PACKAGE_FILE_NAME}.exe")
+set(_bootstrap_output_file ${_cpack_wix_out_dir}/${_bootstrap_filename})
+
+set(_ext_flags
+ -ext WixBalExtension
+)
+
+set(_addtional_defines
+ -dCPACK_BOOTSTRAP_UPGRADE_GUID=${CPACK_WIX_BOOTSTRAP_UPGRADE_GUID}
+ -dCPACK_DOWNLOAD_SITE=${CPACK_DOWNLOAD_SITE}
+ -dCPACK_LOCAL_INSTALLER_DIR=${_cpack_wix_out_dir}
+ -dCPACK_PACKAGE_FILE_NAME=${CPACK_PACKAGE_FILE_NAME}
+ -dCPACK_PACKAGE_INSTALL_DIRECTORY=${_fixed_package_install_dir}
+)
+
+if(CPACK_LICENSE_URL)
+ list(APPEND _addtional_defines -dCPACK_LICENSE_URL=${CPACK_LICENSE_URL})
+endif()
+
+set(_candle_command
+ ${CPACK_WIX_CANDLE_EXECUTABLE}
+ -nologo
+ -arch x64
+ "-I${_cpack_wix_out_dir}" # to include cpack_variables.wxi
+ ${_addtional_defines}
+ ${_ext_flags}
+ "${CPACK_SOURCE_DIR}/Platform/Windows/PackagingBootstrapper.wxs"
+ -o "${_bootstrap_out_dir}/"
+)
+
+set(_light_command
+ ${CPACK_WIX_LIGHT_EXECUTABLE}
+ -nologo
+ ${_ext_flags}
+ ${_bootstrap_out_dir}/*.wixobj
+ -o "${_bootstrap_output_file}"
+)
+
+message(STATUS "Creating Bootstrap Installer...")
+execute_process(
+ COMMAND ${_candle_command}
+ COMMAND_ERROR_IS_FATAL ANY
+)
+execute_process(
+ COMMAND ${_light_command}
+ COMMAND_ERROR_IS_FATAL ANY
+)
+
+file(COPY ${_bootstrap_output_file}
+ DESTINATION ${CPACK_PACKAGE_DIRECTORY}
+)
+
+message(STATUS "Bootstrap installer generated to ${CPACK_PACKAGE_DIRECTORY}/${_bootstrap_filename}")
+
+# use the internal default path if somehow not specified from cpack_configure_downloads
+if(NOT CPACK_UPLOAD_DIRECTORY)
+ set(CPACK_UPLOAD_DIRECTORY ${CPACK_PACKAGE_DIRECTORY}/CPackUploads)
+endif()
+
+# copy the artifacts intended to be uploaded to a remote server into the folder specified
+# through cpack_configure_downloads. this mimics the same process cpack does natively for
+# some other frameworks that have built-in online installer support.
+message(STATUS "Copying installer artifacts to upload directory...")
+file(REMOVE_RECURSE ${CPACK_UPLOAD_DIRECTORY})
+file(GLOB _artifacts "${_cpack_wix_out_dir}/*.msi" "${_cpack_wix_out_dir}/*.cab")
+file(COPY ${_artifacts}
+ DESTINATION ${CPACK_UPLOAD_DIRECTORY}
+)
+message(STATUS "Artifacts copied to ${CPACK_UPLOAD_DIRECTORY}")
diff --git a/cmake/Platform/Windows/PackagingTemplate.wxs.in b/cmake/Platform/Windows/PackagingTemplate.wxs.in
index 3e5db03ec2..0b3c597ab6 100644
--- a/cmake/Platform/Windows/PackagingTemplate.wxs.in
+++ b/cmake/Platform/Windows/PackagingTemplate.wxs.in
@@ -12,10 +12,10 @@
Manufacturer="$(var.CPACK_PACKAGE_VENDOR)"
UpgradeCode="$(var.CPACK_WIX_UPGRADE_GUID)">
-
+
-
-
+
+