This is an automated email from the ASF dual-hosted git repository.

markt pushed a commit to branch 9.0.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git


The following commit(s) were added to refs/heads/9.0.x by this push:
     new 1dc412b8b0 Add makensis as an option for building the Windows installer
1dc412b8b0 is described below

commit 1dc412b8b0fe55cb0a994fc26bb995b7e02d4599
Author: Mark Thomas <ma...@apache.org>
AuthorDate: Wed Feb 12 10:14:58 2025 +0000

    Add makensis as an option for building the Windows installer
---
 BUILDING.txt               |  78 ++++++++++++++++++++---
 build.properties.default   |   3 +
 build.xml                  | 154 ++++++++++++++++++++++++---------------------
 res/install-win/tomcat.nsi |  37 +++--------
 webapps/docs/changelog.xml |   8 +++
 5 files changed, 170 insertions(+), 110 deletions(-)

diff --git a/BUILDING.txt b/BUILDING.txt
index 4fd85f1266..b45b83a72e 100644
--- a/BUILDING.txt
+++ b/BUILDING.txt
@@ -248,19 +248,42 @@ You can build them by using the following commands:
     cd ${tomcat.source}
     ant embed
 
+(5.4) Building the Windows installer
+
+The Windows installer uses the NSIS installer framework.
+It can be build on Windows, on any other platform which provides
+the Wine Windows emulator or the NSIS binary "makensis".
+
+Linux and MacOS are platforms, on which you can install Wine or
+"makensis".
+
+Selecting between Wine and makensis on non-Windows platforms can
+be done by setting the ant property "nsis.tool" to either "wine"
+or "makensis" in build.properties.
+
+If you want to sign the installer, you will need to set some
+properties with names prefixed with "codesigning" in your build.properties.
+For details see the targets "jsign-installer" and "jsign-uninstaller"
+in build.xml and the default property values in build.properties.default.
+
 
 (6) Building a full release (as provided via the ASF download pages)
 
+ 1. Remark on building the Windows installer
+
     A full release includes the Windows installer which requires a Windows
-    environment to be available to create it. If not building in a Windows
-    environment, the build scripts assume that Wine is available. If this is 
not
-    the case, the skip.installer property may be set to skip the creation of 
the
-    Windows installer.
+    environment, an installed Wine emulator or an installed native
+    "makensis" binary from the NSIS project. Creating a reproducible
+    installer using the "makensis" option needs a special build of "makensis".
+    For details see below.
 
-    Provided that Wine is available on non-Windows platforms, a full release
-    build may be made on Windows, Linux or MacOS.
+    Provided that Wine or "makensis" is available on non-Windows platforms,
+    a full release build may be made on Windows, Linux or MacOS.
 
- 1. Configure GPG, if needed
+    If you do not want to build the Windows installer, the skip.installer
+    property may be set to skip the creation of the Windows installer.
+
+ 2. Configure GPG, if needed
 
     If the released artifacts have to be cryptographically signed with a
     PGP signature, like the official ASF releases are, the following
@@ -277,14 +300,14 @@ You can build them by using the following commands:
     You will be prompted for the GPG passphrase when the release build
     starts, unless "gpg.passphrase" property is set.
 
- 2. If building the Windows installer
+ 3. If building the Windows installer on Windows
 
     If running the build in a UAC enabled environment, building the Windows
     installer requires elevated privileges. The simplest way to do this is to
     open the command prompt used for the build with the "Run as administrator"
     option.
 
- 3. Configure the code signing service
+ 4. Configure the code signing service
 
     ASF committers performing official releases will need to configure the code
     signing service so that the Windows installer is signed during the build
@@ -299,7 +322,42 @@ You can build them by using the following commands:
 
     Release managers will be provided with the necessary credentials by the 
PMC.
 
- 4. Build the release:
+    If you want to verify the installer from a release by rebuilding it,
+    you can use the detached signatures provided in the official releases.
+    In this case you have to use the sources from the source release
+    archive, which contains these signatures. You also have to build
+    on Windows, or use Wine, or use a special build of makensis to
+    create a reproducible installer, that fits the signature files.
+
+ 5. Using a special "makensis" build on non-Windows (optional)
+
+    If you want to build a reproducible installer on non-Windows
+    by using "makensis" instead of "Wine", you need to build
+    "makensis" from a source download yourself using the following
+    recipe. To build makensis, you need python, scons and a C compiler.
+
+    First detect the needed version by looking for nsis.version
+    in build.properties.default.
+
+    Download and extract NSIS for Windows by running "ant download-dist". Note
+    the NSIS installation PATH from the output or by checking "nsis.home" in
+    build.properties.default. For example:
+    /home/myuser/tomcat-build-libs/nsis-3.10
+
+    Download the correct sources from the same site and run the
+    following command in the extracted source directory:
+
+        scons UNICODE=yes PREFIX=/home/myuser/tomcat-build-libs/nsis-3.10/Bin 
SKIPPLUGINS=all SKIPUTILS=all SKIPMISC=all NSIS_CONFIG_CONST_DATA_PATH=no 
VERSION=3.10 install-compiler
+
+    You need to specify the correct value in VERSION (this ends up in the 
installer binary
+    so it needs to match). The PREFIX needs to be the bin directory of the NSIS
+    binary distribution that "ant download-dist" installed.
+
+    Use this "makensis" binary by making sure, that it gets found by setting
+    an appropriate PATH environment variable. In addition set the ant property
+    "nsis.tool" to "makensis" in build.properties.
+
+ 6. Build the release:
 
     Apache Tomcat releases are fully reproducible.
 
diff --git a/build.properties.default b/build.properties.default
index 468ad54d06..5d33c82b3a 100644
--- a/build.properties.default
+++ b/build.properties.default
@@ -36,6 +36,9 @@ version.dev=-dev
 
 # ----- Build tools -----
 ant.version.required=1.10.2
+# Which tool to use for building Windows installer
+# on unix platform: wine or makensis.
+nsis.tool=wine
 
 # ----- Build control flags -----
 compile.debug=true
diff --git a/build.xml b/build.xml
index fe4624313b..8b9f85e0cd 100644
--- a/build.xml
+++ b/build.xml
@@ -301,6 +301,11 @@
     <filter token="JASPIC_SPEC_VERSION" value="${jaspic.spec.version}"/>
   </filterset>
 
+  <!-- Path filter set -->
+  <filterset id="path.filters">
+    <filter token="BASEDIR" value="${basedir}"/>
+  </filterset>
+
   <!-- Files to change line endings for depending on target platform -->
   <patternset id="text.files" >
     <include name="**/INSTALLLICENSE"/>
@@ -2589,19 +2594,35 @@ Apache Tomcat ${version} native binaries for Win64 
AMD64/EMT64 platform.
   <target name="-installer-pre-init">
     <property environment="env" />
     <condition property="wine.ok">
+      <or>
+        <and>
+          <equals arg1="${nsis.tool}" arg2="wine" forcestring="true"/>
+          <available file="wine" filepath="${env.PATH}" />
+        </and>
+      </or>
+    </condition>
+    <condition property="makensis.ok">
+      <or>
+        <and>
+          <equals arg1="${nsis.tool}" arg2="makensis" forcestring="true"/>
+          <available file="makensis" filepath="${env.PATH}" />
+        </and>
+      </or>
+    </condition>
+    <condition property="installer.ok">
       <or>
         <os family="windows" />
-        <available file="wine" filepath="${env.PATH}" />
-        <isset property="skip.installer"/>
+        <isset property="wine.ok"/>
+        <isset property="makensis.ok"/>
       </or>
     </condition>
   </target>
 
-  <target name="-installer-init" depends="-installer-pre-init" 
unless="${wine.ok}">
-    <fail message="The executable wine was not found on the current path.
-Wine is required to build the Windows installer when running a release build on
-a non-Windows platform. To skip building the Windows installer, set the
-skip.installer property in build.properties" />
+  <target name="-installer-init" depends="-installer-pre-init" 
unless="${installer.ok}">
+    <fail message="The executable ${nsis.tool} was not found on the current 
path.
+Either wine or makensis are required to build the Windows installer on a 
non-Windows platform.
+Choose the tool by setting property nsis.tool in build.properties.
+To skip building the Windows installer, set the skip.installer property in 
build.properties" />
   </target>
 
   <target name="-installer-prep"
@@ -2612,13 +2633,8 @@ skip.installer property in build.properties" />
         <include name="*.bmp" />
         <include name="*.ico" />
         <include name="*.xml" />
-        <include name="Uninstall.exe.sig" />
       </fileset>
     </copy>
-    <copy file="res/install-win/tomcat-installer.exe.sig"
-        tofile="${tomcat.release}/v${version}/bin/${final.name}.exe.sig"
-        failonerror="false"
-        quiet="true" />
     <copy file="${nsis.installoptions.dll}" todir="${tomcat.dist}" />
     <copy file="${nsis.nsexec.dll}" todir="${tomcat.dist}" />
     <copy file="${nsis.nsisdl.dll}" todir="${tomcat.dist}" />
@@ -2626,6 +2642,7 @@ skip.installer property in build.properties" />
     <copy file="${nsis.nsdialogs.dll}" todir="${tomcat.dist}" />
     <copy file="res/install-win/tomcat.nsi" tofile="${tomcat.dist}/tomcat.nsi" 
overwrite="true" encoding="ISO-8859-1">
       <filterset refid="version.filters"/>
+      <filterset refid="path.filters"/>
     </copy>
     <fixcrlf srcdir="${tomcat.dist}" eol="crlf"
         encoding="ISO-8859-1" fixlast="false" >
@@ -2637,44 +2654,54 @@ skip.installer property in build.properties" />
     </touch>
   </target>
 
-  <target name="-installer-create-tempinstaller"
-      unless="skip.installer" depends="-installer-prep">
-    <exec dir="${tomcat.dist}" executable="${nsis.exe}" osfamily="windows">
-      <arg value="/DUNINSTALLONLY" />
+  <target name="-installer-wine" if="${wine.ok}">
+     <exec dir="${tomcat.dist}" executable="wine" osfamily="unix">
+      <arg value="${nsis.exe}" />
       <arg value="/DNSISDIR=${nsis.home}" />
       <arg value="/V2" />
       <arg value="tomcat.nsi" />
     </exec>
-    <exec dir="${tomcat.dist}" executable="wine" osfamily="unix">
-      <arg value="${nsis.exe}" />
-      <arg value="/DUNINSTALLONLY" />
+  </target>
+
+  <target name="-installer-makensis" if="${makensis.ok}">
+    <exec dir="${tomcat.dist}" executable="makensis" osfamily="unix">
+      <arg value="-DNSISDIR=${nsis.home}" />
+      <arg value="-V2" />
+      <arg value="tomcat.nsi" />
+    </exec>
+  </target>
+
+  <target name="-installer" unless="skip.installer"
+      depends="-installer-prep,-installer-wine,-installer-makensis">
+    <exec dir="${tomcat.dist}" executable="${nsis.exe}" osfamily="windows">
       <arg value="/DNSISDIR=${nsis.home}" />
       <arg value="/V2" />
       <arg value="tomcat.nsi" />
     </exec>
   </target>
 
-  <target name="-installer-create-uninstaller"
-      unless="skip.installer" depends="-installer-create-tempinstaller">
-    <!-- Execute the temporary installer to create the uninstaller -->
-    <exec dir="${tomcat.dist}" executable="${tomcat.dist}/tempinstaller.exe"
-        osfamily="windows"  />
-    <exec dir="${tomcat.dist}" executable="wine" osfamily="unix">
-      <arg value="${tomcat.dist}/tempinstaller.exe" />
-    </exec>
-    <!-- Reproducible builds: consistent timestamps for installer files -->
-    <touch datetime="${tstamp.file}" pattern="yyyy-MM-dd HH:mm:ss">
-      <fileset dir="${tomcat.dist}"/>
-    </touch>
+  <target name="installer-sign"
+      description="Builds and optionally signs the Windows installer"
+      depends="-installer"  unless="skip.installer" >
+      <move file="${tomcat.dist}/tomcat-installer.exe" 
tofile="${tomcat.release}/v${version}/bin/${final.name}.exe" />
+      <!-- .exe has changed so need to redo checksums and OpenPGP signature -->
+      <delete file="${tomcat.release}/v${version}/bin/${final.name}.exe.asc" />
+      <delete 
file="${tomcat.release}/v${version}/bin/${final.name}.exe.sha512" />
+      <hashAndSign file="${tomcat.release}/v${version}/bin/${final.name}.exe" 
/>
   </target>
 
-  <target name="-installer-sign-uninstaller"
-      unless="skip.installer" 
depends="-installer-create-uninstaller,setup-jsign"
-      if="${do.codesigning}">
-    <!-- If the detached signature doesn't exist, this will sign the file    
-->
-    <!-- and create the detached signature. If the detached signature does   
-->
-    <!-- exist it will be attached to the file.                              
-->
-    <jsign file="${tomcat.dist}/Uninstall.exe"
+  <!-- Called via a callback in the NSIS installer script -->
+  <target name="jsign-installer"
+      depends="setup-jsign" if="${do.codesigning}" >
+      <echo>Signing ${tomcat.dist}/tomcat-installer.exe</echo>
+      <!-- Copy pre-existing detachced signature to signing directory -->
+      <copy file="res/install-win/tomcat-installer.exe.sig"
+          tofile="${tomcat.dist}/tomcat-installer.exe.sig"
+          failonerror="false" />
+      <!-- If the detached signature doesn't exist, this will sign the file  
-->
+      <!-- and create the detached signature. If the detached signature does 
-->
+      <!-- exist it will be attached to the file.                            
-->
+      <jsign file="${tomcat.dist}/tomcat-installer.exe"
         storepass="${codesigning.storepass}"
         storetype="${codesigning.storetype}"
         keypass="${codesigning.keypass}"
@@ -2683,35 +2710,22 @@ skip.installer property in build.properties" />
         tsaurl="http://ts.ssl.com";
         tsmode="RFC3161"
         detached="true"/>
-    <!-- Copy detached signature to source tree -->
-    <copy file="${tomcat.dist}/Uninstall.exe.sig" todir="res/install-win"/>
-    <!-- Reproducible builds: consistent timestamps for installer files -->
-    <touch datetime="${tstamp.file}" pattern="yyyy-MM-dd HH:mm:ss">
-      <fileset dir="${tomcat.dist}"/>
-    </touch>
-  </target>
-
-  <target name="-installer" unless="skip.installer"
-      depends="-installer-sign-uninstaller">
-    <exec dir="${tomcat.dist}" executable="${nsis.exe}" osfamily="windows">
-      <arg value="/DNSISDIR=${nsis.home}" />
-      <arg value="/V2" />
-      <arg value="tomcat.nsi" />
-    </exec>
-    <exec dir="${tomcat.dist}" executable="wine" osfamily="unix">
-      <arg value="${nsis.exe}" />
-      <arg value="/DNSISDIR=${nsis.home}" />
-      <arg value="/V2" />
-      <arg value="tomcat.nsi" />
-    </exec>
-    <move file="${tomcat.dist}/tomcat-installer.exe" 
tofile="${tomcat.release}/v${version}/bin/${final.name}.exe" />
-    <hashAndSign file="${tomcat.release}/v${version}/bin/${final.name}.exe" />
+      <!-- Move detached signature to source tree -->
+      <move file="${tomcat.dist}/tomcat-installer.exe.sig" 
tofile="res/install-win/tomcat-installer.exe.sig"/>
   </target>
 
-  <target name="installer-sign"
-      description="Builds and optionally signs the Windows installer"
-      depends="-installer,setup-jsign" if="${do.codesigning}" >
-    <jsign file="${tomcat.release}/v${version}/bin/${final.name}.exe"
+  <!-- Called via a callback in the NSIS installer script -->
+  <target name="jsign-uninstaller"
+      depends="setup-jsign" if="${do.codesigning}" >
+      <echo>Signing ${codesigning.file_to_sign}</echo>
+      <!-- Copy pre-existing detachced signature to signing directory -->
+      <copy file="res/install-win/Uninstall.exe.sig"
+          tofile="${codesigning.file_to_sign}.sig"
+          failonerror="false" />
+      <!-- If the detached signature doesn't exist, this will sign the file  
-->
+      <!-- and create the detached signature. If the detached signature does 
-->
+      <!-- exist it will be attached to the file.                            
-->
+      <jsign file="${codesigning.file_to_sign}"
         storepass="${codesigning.storepass}"
         storetype="${codesigning.storetype}"
         keypass="${codesigning.keypass}"
@@ -2720,14 +2734,8 @@ skip.installer property in build.properties" />
         tsaurl="http://ts.ssl.com";
         tsmode="RFC3161"
         detached="true" />
-    <!-- Copy detached signature to source tree -->
-    <copy file="${tomcat.release}/v${version}/bin/${final.name}.exe.sig"
-        tofile="res/install-win/tomcat-installer.exe.sig"/>
-    <delete file="${tomcat.release}/v${version}/bin/${final.name}.exe.sig" />
-    <!-- .exe has changed so need to redo checksums and OpenPGP signature -->
-    <delete file="${tomcat.release}/v${version}/bin/${final.name}.exe.asc" />
-    <delete file="${tomcat.release}/v${version}/bin/${final.name}.exe.sha512" 
/>
-    <hashAndSign file="${tomcat.release}/v${version}/bin/${final.name}.exe" />
+      <!-- Move detached signature to source tree -->
+      <move file="${codesigning.file_to_sign}.sig" 
tofile="res/install-win/Uninstall.exe.sig"/>
   </target>
 
   <target name="-pre-release-lone-target-check">
diff --git a/res/install-win/tomcat.nsi b/res/install-win/tomcat.nsi
index 7a14c58e82..e0cd26e76f 100644
--- a/res/install-win/tomcat.nsi
+++ b/res/install-win/tomcat.nsi
@@ -17,11 +17,7 @@
 
 Unicode true
 
-!ifdef UNINSTALLONLY
-  OutFile "tempinstaller.exe"
-!else
-  OutFile tomcat-installer.exe
-!endif
+OutFile tomcat-installer.exe
 
   ;Compression options
   CRCCheck on
@@ -118,11 +114,9 @@ Var ServiceInstallLog
   Page custom CheckUserType
   !insertmacro MUI_PAGE_FINISH
 
-  !ifdef UNINSTALLONLY
-    ;Uninstall Page order
-    !insertmacro MUI_UNPAGE_CONFIRM
-    !insertmacro MUI_UNPAGE_INSTFILES
-  !endif
+  ;Uninstall Page order
+  !insertmacro MUI_UNPAGE_CONFIRM
+  !insertmacro MUI_UNPAGE_INSTFILES
 
   ;Language
   !insertmacro MUI_LANGUAGE English
@@ -163,6 +157,9 @@ Var ServiceInstallLog
   InstType Minimum
   InstType Full
 
+  !finalize 'ant -f @BASEDIR@/build.xml jsign-installer'
+  !uninstfinalize 'ant -f @BASEDIR@/build.xml -Dcodesigning.file_to_sign=%1 
jsign-uninstaller'
+
   ReserveFile System.dll
   ReserveFile nsDialogs.dll
   ReserveFile tomcat-users_1.xml
@@ -201,6 +198,9 @@ Section "Core" SecTomcatCore
   SetOutPath $INSTDIR\webapps\ROOT
   File /r webapps\ROOT\*.*
 
+  ;Create uninstaller
+  WriteUninstaller "$INSTDIR\Uninstall.exe"
+
   Call configure
 
   DetailPrint "Using Jvm: $JavaHome"
@@ -349,12 +349,6 @@ Section -post
     Call createShortcuts
   ${EndIf}
 
-  !ifndef UNINSTALLONLY
-    SetOutPath $INSTDIR
-    ; this packages the signed uninstaller
-    File Uninstall.exe
-  !endif
-
   WriteRegStr HKLM "SOFTWARE\Apache Software 
Foundation\Tomcat\@VERSION_MAJOR_MINOR@\$TomcatServiceName" "InstallPath" 
$INSTDIR
   WriteRegStr HKLM "SOFTWARE\Apache Software 
Foundation\Tomcat\@VERSION_MAJOR_MINOR@\$TomcatServiceName" "Version" @VERSION@
   WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Apache 
Tomcat @VERSION_MAJOR_MINOR@ $TomcatServiceName" \
@@ -436,14 +430,6 @@ Function ReadFromConfigIni
 FunctionEnd
 
 Function .onInit
-  !ifdef UNINSTALLONLY
-    ; If UNINSTALLONLY is defined, then we aren't supposed to do anything 
except write out
-    ; the installer.  This is better than processing a command line option as 
it means
-    ; this entire code path is not present in the final (real) installer.
-    WriteUninstaller "$EXEDIR\Uninstall.exe"
-    Quit
-  !endif
-
   ${GetParameters} $R0
   ClearErrors
 
@@ -1248,7 +1234,6 @@ FunctionEnd
 ;--------------------------------
 ;Uninstaller Section
 
-!ifdef UNINSTALLONLY
   Section Uninstall
 
     ${If} $TomcatServiceName == ""
@@ -1383,6 +1368,4 @@ FunctionEnd
    FindClose $1
   FunctionEnd
 
-!endif
-
 ;eof
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index 1b5d1c08de..f6bb695ec4 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -105,6 +105,14 @@
   issues do not "pop up" wrt. others).
 -->
 <section name="Tomcat 9.0.101 (remm)" rtext="in development">
+  <subsection name="Other">
+    <changelog>
+      <add>
+        Add <code>makensis</code> as an option for building the Installer for
+        Windows on non-Windows platforms. (rjung/markt)
+      </add>
+    </changelog>
+  </subsection>
 </section>
 <section name="Tomcat 9.0.100 (remm)" rtext="release in progress">
   <subsection name="Catalina">


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to