From ebfffc609e2bfe974a0f56b64285089e7eac4257 Mon Sep 17 00:00:00 2001
From: Johnny Jazeix <jazeix@gmail.com>
Date: Thu, 2 Jan 2020 22:27:31 +0100
Subject: CPack/NSIS: Add option for setting MUI_HEADERIMAGE_BITMAP

Fixes: #20120
---
 Help/cpack_gen/nsis.rst                            |   4 ++
 Help/release/dev/cpack-nsis-headerimage_var.rst    |   7 ++++
 Source/CPack/cmCPackNSISGenerator.cxx              |  13 ++++--
 Tests/CMakeLists.txt                               |  21 ++++++++++
 Tests/CPackNSISGenerator/CMakeLists.txt            |  20 +++++++++
 .../CPackNSISGenerator/RunCPackVerifyResult.cmake  |  46 +++++++++++++++++++++
 Tests/CPackNSISGenerator/header-icon.bmp           | Bin 0 -> 28166 bytes
 Tests/CPackNSISGenerator/header-image.bmp          | Bin 0 -> 28166 bytes
 Tests/CPackNSISGenerator/install.ico               | Bin 0 -> 838 bytes
 Tests/CPackNSISGenerator/main.cpp                  |   4 ++
 Tests/CPackNSISGenerator/uninstall.ico             | Bin 0 -> 838 bytes
 11 files changed, 111 insertions(+), 4 deletions(-)
 create mode 100644 Help/release/dev/cpack-nsis-headerimage_var.rst
 create mode 100644 Tests/CPackNSISGenerator/CMakeLists.txt
 create mode 100644 Tests/CPackNSISGenerator/RunCPackVerifyResult.cmake
 create mode 100644 Tests/CPackNSISGenerator/header-icon.bmp
 create mode 100644 Tests/CPackNSISGenerator/header-image.bmp
 create mode 100644 Tests/CPackNSISGenerator/install.ico
 create mode 100644 Tests/CPackNSISGenerator/main.cpp
 create mode 100644 Tests/CPackNSISGenerator/uninstall.ico

diff --git a/Help/cpack_gen/nsis.rst b/Help/cpack_gen/nsis.rst
index dc65249..a310e9f 100644
--- a/Help/cpack_gen/nsis.rst
+++ b/Help/cpack_gen/nsis.rst
@@ -149,3 +149,7 @@ on Windows Nullsoft Scriptable Install System.
 .. variable:: CPACK_NSIS_FINISH_TITLE_3LINES
 
  Display the title in the finish page on 3 lines instead of 2.
+
+.. variable:: CPACK_NSIS_MUI_HEADERIMAGE
+
+ The image to display on the header of installers pages.
diff --git a/Help/release/dev/cpack-nsis-headerimage_var.rst b/Help/release/dev/cpack-nsis-headerimage_var.rst
new file mode 100644
index 0000000..d44686b
--- /dev/null
+++ b/Help/release/dev/cpack-nsis-headerimage_var.rst
@@ -0,0 +1,7 @@
+cpack-nsis-headerimage_var
+--------------------------
+
+* The :cpack_gen:`CPack NSIS Generator` gained a new variable
+  :variable:`CPACK_NSIS_MUI_HEADERIMAGE` to set the header image.
+  To not break existing setups, it still defaults to
+  :variable:`CPACK_PACKAGE_ICON` if the new variable is not set.
diff --git a/Source/CPack/cmCPackNSISGenerator.cxx b/Source/CPack/cmCPackNSISGenerator.cxx
index 4702639..363f536 100644
--- a/Source/CPack/cmCPackNSISGenerator.cxx
+++ b/Source/CPack/cmCPackNSISGenerator.cxx
@@ -139,10 +139,15 @@ int cmCPackNSISGenerator::PackageFiles()
     this->SetOptionIfNotSet("CPACK_NSIS_INSTALLER_MUI_ICON_CODE",
                             installerIconCode.c_str());
   }
-  if (this->IsSet("CPACK_PACKAGE_ICON")) {
-    std::string installerIconCode =
-      cmStrCat("!define MUI_HEADERIMAGE_BITMAP \"",
-               this->GetOption("CPACK_PACKAGE_ICON"), "\"\n");
+  std::string installerHeaderImage;
+  if (this->IsSet("CPACK_NSIS_MUI_HEADERIMAGE")) {
+    installerHeaderImage = this->GetOption("CPACK_NSIS_MUI_HEADERIMAGE");
+  } else if (this->IsSet("CPACK_PACKAGE_ICON")) {
+    installerHeaderImage = this->GetOption("CPACK_PACKAGE_ICON");
+  }
+  if (!installerHeaderImage.empty()) {
+    std::string installerIconCode = cmStrCat(
+      "!define MUI_HEADERIMAGE_BITMAP \"", installerHeaderImage, "\"\n");
     this->SetOptionIfNotSet("CPACK_NSIS_INSTALLER_ICON_CODE",
                             installerIconCode.c_str());
   }
diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt
index 59f5c73..4b6bb98 100644
--- a/Tests/CMakeLists.txt
+++ b/Tests/CMakeLists.txt
@@ -989,6 +989,27 @@ ${CMake_SOURCE_DIR}/Utilities/Release/push.bash --dir dev -- '${CMake_BUILD_NIGH
     endif()
   endif()
 
+  # On Windows run the CPackNSISGenerator test
+  # if the nsis is available
+  if(WIN32 AND NSIS_MAKENSIS_EXECUTABLE)
+    add_test(CPackNSISGenerator ${CMAKE_CTEST_COMMAND}
+      -C \${CTEST_CONFIGURATION_TYPE}
+      --build-and-test
+      "${CMake_SOURCE_DIR}/Tests/CPackNSISGenerator"
+      "${CMake_BINARY_DIR}/Tests/CPackNSISGenerator"
+      ${build_generator_args}
+      --build-project CPackNSISGenerator
+      --build-options
+      --test-command ${CMAKE_CMAKE_COMMAND}
+        "-DCPackNSISGenerator_BINARY_DIR:PATH=${CMake_BINARY_DIR}/Tests/CPackNSISGenerator"
+        "-Dconfig=\${CTEST_CONFIGURATION_TYPE}"
+        -P "${CMake_SOURCE_DIR}/Tests/CPackNSISGenerator/RunCPackVerifyResult.cmake")
+
+    set_property(TEST CPackNSISGenerator PROPERTY
+      ATTACHED_FILES_ON_FAIL
+      "${CMake_BINARY_DIR}/Tests/CPackNSISGenerator/_CPack_Packages/win32/NSIS/NSISOutput.log")
+  endif()
+
   if(CTEST_TEST_CPACK)
     add_test(CPackUseDefaultVersion ${CMAKE_CTEST_COMMAND}
       --build-and-test
diff --git a/Tests/CPackNSISGenerator/CMakeLists.txt b/Tests/CPackNSISGenerator/CMakeLists.txt
new file mode 100644
index 0000000..b8b2ed6
--- /dev/null
+++ b/Tests/CPackNSISGenerator/CMakeLists.txt
@@ -0,0 +1,20 @@
+cmake_minimum_required(VERSION 3.16)
+
+project(CPackNSISGenerator)
+
+add_executable(hello main.cpp)
+
+install(TARGETS hello
+  ARCHIVE DESTINATION .
+  RUNTIME DESTINATION .
+  LIBRARY DESTINATION .
+  BUNDLE DESTINATION .)
+
+set(CPACK_NSIS_MUI_HEADERIMAGE "${PROJECT_SOURCE_DIR}\\\\header-image.bmp")
+set(CPACK_PACKAGE_ICON "${PROJECT_SOURCE_DIR}\\\\header-icon.bmp")
+set(CPACK_NSIS_MUI_ICON "${PROJECT_SOURCE_DIR}\\\\install.ico")
+set(CPACK_NSIS_MUI_UNIICON "${PROJECT_SOURCE_DIR}\\\\uninstall.ico")
+set(CPACK_GENERATOR "NSIS")
+set(CPACK_NSIS_ENABLE_UNINSTALL_BEFORE_INSTALL ON)
+
+include(CPack)
diff --git a/Tests/CPackNSISGenerator/RunCPackVerifyResult.cmake b/Tests/CPackNSISGenerator/RunCPackVerifyResult.cmake
new file mode 100644
index 0000000..f70cd24
--- /dev/null
+++ b/Tests/CPackNSISGenerator/RunCPackVerifyResult.cmake
@@ -0,0 +1,46 @@
+message(STATUS "=============================================================")
+message(STATUS "CTEST_FULL_OUTPUT (Avoid ctest truncation of output)")
+message(STATUS "")
+
+if(NOT CPackNSISGenerator_BINARY_DIR)
+  message(FATAL_ERROR "CPackNSISGenerator_BINARY_DIR not set")
+endif()
+
+message(STATUS "CMAKE_COMMAND: ${CMAKE_COMMAND}")
+message(STATUS "CMAKE_CPACK_COMMAND: ${CMAKE_CPACK_COMMAND}")
+message(STATUS "CPackNSISGenerator_BINARY_DIR: ${CPackNSISGenerator_BINARY_DIR}")
+
+if(config)
+  set(_C_config -C ${config})
+endif()
+
+execute_process(COMMAND "${CMAKE_CPACK_COMMAND}"
+                        ${_C_config}
+  RESULT_VARIABLE CPack_result
+  OUTPUT_VARIABLE CPack_output
+  ERROR_VARIABLE CPack_error
+  WORKING_DIRECTORY "${CPackNSISGenerator_BINARY_DIR}")
+
+if(CPack_result)
+  message(FATAL_ERROR "CPack execution went wrong!, CPack_output=${CPack_output}, CPack_error=${CPack_error}")
+else ()
+  message(STATUS "CPack_output=${CPack_output}")
+endif()
+
+set(expected_file_mask "${CPackNSISGenerator_BINARY_DIR}/_CPack_Packages/win32/NSIS/*.nsi")
+file(GLOB project_file "${expected_file_mask}")
+
+message(STATUS "project_file='${project_file}'")
+message(STATUS "expected_file_mask='${expected_file_mask}'")
+
+if(NOT project_file)
+  message(FATAL_ERROR "project_file does not exist.")
+endif()
+
+# should match !define MUI_HEADERIMAGE_BITMAP "${PROJECT_SOURCE_DIR}\header-image.bmp"
+file(STRINGS "${project_file}" line REGEX "^!define MUI_HEADERIMAGE_BITMAP")
+string(FIND "${line}" "header-image.bmp" output_index)
+message(STATUS "Found the bitmap at index ${output_index}")
+if("${output_index}" EQUAL "-1")
+  message(FATAL_ERROR "MUI_HEADERIMAGE_BITMAP not found in the project")
+endif()
diff --git a/Tests/CPackNSISGenerator/header-icon.bmp b/Tests/CPackNSISGenerator/header-icon.bmp
new file mode 100644
index 0000000..ef6a656
Binary files /dev/null and b/Tests/CPackNSISGenerator/header-icon.bmp differ
diff --git a/Tests/CPackNSISGenerator/header-image.bmp b/Tests/CPackNSISGenerator/header-image.bmp
new file mode 100644
index 0000000..15b1730
Binary files /dev/null and b/Tests/CPackNSISGenerator/header-image.bmp differ
diff --git a/Tests/CPackNSISGenerator/install.ico b/Tests/CPackNSISGenerator/install.ico
new file mode 100644
index 0000000..3b1e480
Binary files /dev/null and b/Tests/CPackNSISGenerator/install.ico differ
diff --git a/Tests/CPackNSISGenerator/main.cpp b/Tests/CPackNSISGenerator/main.cpp
new file mode 100644
index 0000000..956f345
--- /dev/null
+++ b/Tests/CPackNSISGenerator/main.cpp
@@ -0,0 +1,4 @@
+int main()
+{
+  return 42;
+}
diff --git a/Tests/CPackNSISGenerator/uninstall.ico b/Tests/CPackNSISGenerator/uninstall.ico
new file mode 100644
index 0000000..c4f6316
Binary files /dev/null and b/Tests/CPackNSISGenerator/uninstall.ico differ
-- 
cgit v0.12