Skip to content

Commit

Permalink
make the installer a Meson target
Browse files Browse the repository at this point in the history
  • Loading branch information
guijan committed Dec 29, 2024
1 parent d33822e commit 80a4556
Show file tree
Hide file tree
Showing 4 changed files with 135 additions and 171 deletions.
9 changes: 4 additions & 5 deletions .github/workflows/build-and-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ jobs:
- name: test
run: meson test -C build
- name: installer
run: src/dictpw_installer.sh -o 'build\setup-dictpw-${{matrix.sys}}.exe'
run: meson compile installer -C build
- uses: actions/[email protected]
if: always()
with:
Expand All @@ -189,7 +189,7 @@ jobs:
if: success()
with:
name: setup-${{matrix.sys}}
path: build/setup-*.exe
path: build/setup-dictpw.exe

netbsd:
runs-on: ubuntu-latest
Expand Down Expand Up @@ -254,9 +254,8 @@ jobs:
run: meson test -C build
- name: inst
run: |
$out = "..\build\setup-dictpw-vs-${{matrix.cc}}-${{matrix.arch}}.exe"
makensis -DOUTFILE="$out" src/dictpw.nsi
ls build/
meson compile installer -C build
ls -R build/
- uses: actions/[email protected]
if: always()
with:
Expand Down
61 changes: 45 additions & 16 deletions meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

project('dictpw', 'c', version: '1.2.0', license: 'ISC',
default_options: ['c_std=c99', 'warning_level=3'])
default_options: ['c_std=c99', 'warning_level=3'],
meson_version: '>=1.4.0')

# Makes all functions, including BSD functions, visible on GNU.
args = ['-D_GNU_SOURCE']
Expand All @@ -38,7 +39,7 @@ funcs = {
'strtonum': '#include <stdlib.h>',
'warnx': '#include <err.h>',
}
libbsd_dep = []
libbsd_dep = dependency('', required: false)
foreach func, header : funcs
if not cc.has_function(func, prefix: header, args: args)
libbsd_dep = dependency('libbsd-overlay',
Expand Down Expand Up @@ -103,18 +104,46 @@ if host_machine.system() == 'windows' or host_machine.system() == 'cygwin'

# Put copies of the license and the README with DOS newlines in the build
# directory too.
custom_target('license',
command: [unix2dos],
input: ['LICENSE.md'],
feed: true,
output: ['LICENSE.txt'],
capture: true,
build_by_default: true)
custom_target('readme',
command: [unix2dos],
input: ['README.md'],
feed: true,
output: ['README.txt'],
capture: true,
build_by_default: true)
license = custom_target('license',
command: [unix2dos],
input: ['LICENSE.md'],
feed: true,
output: ['LICENSE.txt'],
capture: true,
build_by_default: true)
readme = custom_target('readme',
command: [unix2dos],
input: ['README.md'],
feed: true,
output: ['README.txt'],
capture: true,
build_by_default: true)

inst_cmd = [find_program('makensis'), '-DMESON=true',
'-DOUTFILE=setup-dictpw.exe', '-DEXEFILE=' + dictpw.full_path(),
'-DDOCFILE=' + man.full_path(),
'-DLICENSE=' + license.full_path(),
'-DREADME=' + readme.full_path()]
if libbsd_dep.found() and libbsd_dep.type_name() == 'internal'
inst_cmd += '-DLIBOBSD_LICENSE=true'
endif
# Programs built in Cygwin and MSYS2's MSYS environment are linked against
# a special DLL with their implementations of Unix inside, distribute it.
if host_machine.system() == 'cygwin'
fs = import('fs')
dlls = ['/usr/bin/msys-2.0.dll', '/bin/cygwin1.dll']
found = false
foreach dll : dlls
if fs.is_file(dll)
fs.copyfile(dll)
inst_cmd += '-DMSYS_DLL=' + fs.name(dll)
found = true
break
endif
endforeach
if not found
error('cygwin/msys2 DLL not found')
endif
endif
run_target('installer', command: inst_cmd)
endif
185 changes: 86 additions & 99 deletions src/dictpw.nsi
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/usr/bin/makensis

# Copyright (c) 2022 Guilherme Janczak <[email protected]>
# Copyright (c) 2022, 2024 Guilherme Janczak <[email protected]>
#
# Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
Expand All @@ -14,28 +14,24 @@
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

# This script isn't meant to be used directly. dictpw_installer.sh is its
# interface.

!include "FileFunc.nsh"

!ifndef EXEFILE
!define EXEFILE "..\build\dictpw.exe"
!endif

!ifndef DOCFILE
!define DOCFILE "..\build\dictpw.txt"
!assert MESON "This NSIS installer is intended to be built by Meson"
!assert OUTFILE "Output file unspecified"
!assert EXEFILE "dictpw.exe unspecified"
!assert DOCFILE "dictpw.txt unspecified"
!assert LICENSE "LICENSE.txt unspecified"
!assert README "README.txt unspecified"
# LIBOBSD_LICENSE is optional, it may not be needed on msys2.
# Meson can't pass files from subprojects, so we get it ourselves.
!ifdef LIBOBSD_LICENSE
!define LIBOBSD_LICENSE "subprojects/libobsd/LICENSE_libobsd.txt"
!endif

!ifndef OUTFILE
!define OUTFILE "..\build\setup-dictpw.exe"
!endif

!define LIBOBSD_LICENSE "..\build\subprojects\libobsd\LICENSE_libobsd.txt"
# MSYS_DLL is optional, only needed on msys2 and Cygwin.

!define MUI_DIRECTORYPAGE_VARIABLE "$INSTDIR"
!include "MUI2.nsh"
!insertmacro MUI_PAGE_LICENSE "..\LICENSE.md"
!insertmacro MUI_PAGE_LICENSE "${LICENSE}"
!insertmacro MUI_PAGE_DIRECTORY
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_UNPAGE_DIRECTORY
Expand All @@ -48,100 +44,91 @@ RequestExecutionLevel admin
showinstdetails show

Section
# Uninstalling previous versions allows changing the installed files
# without leaving any lingering files.
Call UninstPrevious

SetOutPath $INSTDIR
CreateDirectory "$INSTDIR\bin"
File /oname=bin\dictpw.exe "${EXEFILE}"
# Read: If we're building for the MSYS2 environment, distribute the msys DLL.
!ifdef MSYS
File /oname=bin\msys-2.0.dll "${MSYS}"
# Uninstalling previous versions allows changing the installed files
# without leaving any lingering files.
Call UninstPrevious

SetOutPath $INSTDIR
CreateDirectory "$INSTDIR\bin"
File /oname=bin\dictpw.exe "${EXEFILE}"
File "${LICENSE}"
File "${README}"
File "${DOCFILE}"
!ifdef LIBOBSD_LICENSE
File "${LIBOBSD_LICENSE}"
!endif
File "..\build\LICENSE.txt"
!if /FileExists "${LIBOBSD_LICENSE}"
File "${LIBOBSD_LICENSE}"
# Read: If we're building for the MSYS2 or Cygwin environments, distribute their
# DLLs.
!ifdef MSYS_DLL
File /oname="bin\${MSYS_DLL}" "${MSYS_DLL}"
!endif
File "..\build\README.txt"
File "${DOCFILE}"
WriteUninstaller "$INSTDIR\uninstall.exe"

# Add/Remove programs registry
!define UN "Software\Microsoft\Windows\CurrentVersion\Uninstall\dictpw"
WriteRegStr HKLM "${UN}" \
"InstallLocation" "$\"$INSTDIR$\""
WriteRegStr HKLM "${UN}" \
"DisplayName" \
"dictpw -- generate password from dictionary"
WriteRegStr HKLM "${UN}" \
"UninstallString" "$\"$INSTDIR\uninstall.exe$\""
WriteRegStr HKLM "${UN}" \
"QuietUninstallString" \
"$\"$INSTDIR\uninstall.exe$\" /S"
WriteRegStr HKLM "${UN}" \
"URLUpdateInfo" "https://github.com/guijan/dictpw"
WriteRegStr HKLM "${UN}" \
"URLInfoAbout" "https://github.com/guijan/dictpw"
WriteRegDWORD HKLM "${UN}" \
"NoModify" 0x00000001
WriteRegDWORD HKLM "${UN}" \
"NoRepair" 0x00000001

# Windows needs to be told the install size manually.
${GetSize} "$INSTDIR" "/S=0K" $0 $1 $2
IntFmt $0 "0x%08X" $0
WriteRegDWORD HKLM "${UN}" "EstimatedSize" "$0"

# Allows running the program with `start /b /wait dictpw`
!define AP \
"Software\Microsoft\Windows\CurrentVersion\App Paths\dictpw.exe"
WriteRegStr HKLM "${AP}" "" "$INSTDIR\bin\dictpw.exe"
WriteUninstaller "$INSTDIR\uninstall.exe"

# Add/Remove programs registry
!define UN "Software\Microsoft\Windows\CurrentVersion\Uninstall\dictpw"
WriteRegStr HKLM "${UN}" "InstallLocation" "$\"$INSTDIR$\""
WriteRegStr HKLM "${UN}" "DisplayName" \
"dictpw -- generate password from dictionary"
WriteRegStr HKLM "${UN}" "UninstallString" "$\"$INSTDIR\uninstall.exe$\""
WriteRegStr HKLM "${UN}" "QuietUninstallString" \
"$\"$INSTDIR\uninstall.exe$\" /S"
WriteRegStr HKLM "${UN}" "URLUpdateInfo" "https://github.com/guijan/dictpw"
WriteRegStr HKLM "${UN}" "URLInfoAbout" "https://github.com/guijan/dictpw"
WriteRegDWORD HKLM "${UN}" "NoModify" 0x00000001
WriteRegDWORD HKLM "${UN}" "NoRepair" 0x00000001

# Windows needs to be told the install size manually.
${GetSize} "$INSTDIR" "/S=0K" $0 $1 $2
IntFmt $0 "0x%08X" $0
WriteRegDWORD HKLM "${UN}" "EstimatedSize" "$0"

# Allows running the program with `start /b /wait dictpw`
!define AP "Software\Microsoft\Windows\CurrentVersion\App Paths\dictpw.exe"
WriteRegStr HKLM "${AP}" "" "$INSTDIR\bin\dictpw.exe"
SectionEnd

Section "Uninstall"
DeleteRegKey HKLM "${AP}"
DeleteRegKey HKLM "${UN}"
Delete "$INSTDIR\dictpw.txt"
Delete "$INSTDIR\README.txt"
!if /FileExists "${LIBOBSD_LICENSE}"
Delete "$INSTDIR\LICENSE_libobsd.txt"
Delete "$INSTDIR\bin\dictpw.exe"
Delete "$INSTDIR\LICENSE.txt"
Delete "$INSTDIR\README.txt"
Delete "$INSTDIR\dictpw.txt"
!ifdef LIBOBSD_LICENSE
Delete "$INSTDIR\LICENSE_libobsd.txt"
!endif
Delete "$INSTDIR\LICENSE.txt"
!ifdef MSYS
Delete "$INSTDIR\bin\msys-2.0.dll"
!ifdef MSYS_DLL
Delete "$INSTDIR\bin\${MSYS_DLL}"
!endif
Delete "$INSTDIR\bin\dictpw.exe"
RMDir "$INSTDIR\bin"
RMDir "$INSTDIR\bin"

# Make sure to delete uninstall.exe only after everything else is
# deleted.
Delete "$INSTDIR\uninstall.exe"
# Delete uninstall.exe only after everything else is deleted.
Delete "$INSTDIR\uninstall.exe"
RMDir "$INSTDIR"

RMDir "$INSTDIR"
# Remove the registry keys only after the uninstallation is done.
DeleteRegKey HKLM "${AP}"
DeleteRegKey HKLM "${UN}"
SectionEnd


Function UninstPrevious
Push $R0
Push $R1

# References:
# https://nsis.sourceforge.io/Talk:Auto-uninstall_old_before_installing_new
# https://stackoverflow.com/questions/719631/how-do-i-require-user-to-uninstall-previous-version-with-nsis
ReadRegStr $R1 HKLM "${UN}" "InstallLocation"
StrCmp $R1 "" ret
ReadRegStr $R0 HKLM "${UN}" "QuietUninstallString"

# Remove the first and the last characters of InstallLocation, that is,
# its enclosing quotes.
# This is for:
# https://nsis.sourceforge.io/When_I_use_ExecWait_uninstaller.exe_it_doesn%27t_wait_for_the_uninstaller
StrCpy $R1 $R1 "" 1
StrCpy $R1 $R1 -1
ExecWait "$R0 _?=$R1"
Push $R0
Push $R1

# References:
# https://nsis.sourceforge.io/Talk:Auto-uninstall_old_before_installing_new
# https://stackoverflow.com/questions/719631/how-do-i-require-user-to-uninstall-previous-version-with-nsis
ReadRegStr $R1 HKLM "${UN}" "InstallLocation"
StrCmp $R1 "" ret
ReadRegStr $R0 HKLM "${UN}" "QuietUninstallString"

# Remove the first and the last characters of InstallLocation, that is,
# its enclosing quotes.
# This is for:
# https://nsis.sourceforge.io/When_I_use_ExecWait_uninstaller.exe_it_doesn%27t_wait_for_the_uninstaller
StrCpy $R1 $R1 "" 1
StrCpy $R1 $R1 -1
ExecWait "$R0 _?=$R1"

ret:
Pop $R1
Pop $R0
Pop $R1
Pop $R0
FunctionEnd
51 changes: 0 additions & 51 deletions src/dictpw_installer.sh

This file was deleted.

0 comments on commit 80a4556

Please sign in to comment.