On Thu, Feb 13, 2025 at 6:11 PM <ma...@apache.org> wrote:
>
> 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'

This fails for me with Can't recognize xxx as an internal or external
command, or batch script.
I tried a few things without much success so far.

Rémy

> +
>    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
>

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

Reply via email to