Deploying and creating installers for Windows and MacOS

Hey All

So I have a project that compiles on MacOS and Windows, Great! Now I want to deploy it. What’s the nicest way of doing this. I have found older threads regarding this but seem very dated.

What I’m wanting to do is package my OF project into an installer that installs everything required for it to run just like any other piece of software downloadable from a website.

What’s a nice clean way of deploying projects to the end customers?


Hi, those are two different annoying procedures.
On macos, you would want to sign and notarize your app, for which you will need an Apple developer account. The procedure is the same as with any macos app through Xcode, where you select menu Product > Archive and from there you sign it and notarize.
Considering that by default, the ofApp data folder is outside the app bundle it is better if you put it inside the app bundle. (the apps in macos are simply folders with an “.app” extension), this folder is what we call the app bundle. Look at the following

Remember to move the data into the resources folder.

For windows, the resources folder thing does not work so you will usually need to send the whole bin folder. That’s why you’ll usually make some sort of installer so this folder and all the dependencies are installed somewhere and then you make some aliases to the start menu, desktop etc. I haven’t done this procedure for a while but sure it has not changed much. There are a lot of different installer creators for windows. The important, and tricky thinng here (unless things have changed) is that you need to include in the installer the Visual Studio C++ Redistributable Package, otherwise the installed app will not work.
Hope this helps

1 Like

For macOs I use create-dmg and my own bash script.

Here is an example of the script (just alter to match your app name and copy across all of your resources, as well as create bin/resources/macOS/dmg-background.png and bin/resources/macOS/dmg-background@2x.png and bin/resources/macOS/${APP_NAME}.icns):


APP_NAME="MyApp123" # should match compiled output name

echo "------------------ CREATING '${APP_NAME}' INSTALLER (DMG) ------------------"
rm -rf bin/${APP_NAME}.app/Contents/MacOS/data
mkdir bin/${APP_NAME}.app/Contents/MacOS/data 
mkdir bin/${APP_NAME}.app/Contents/MacOS/data/fonts 
mkdir bin/${APP_NAME}.app/Contents/MacOS/data/ui
mkdir bin/${APP_NAME}.app/Contents/MacOS/data/ui/images
mkdir bin/${APP_NAME}.app/Contents/MacOS/data/ui/svg
mkdir bin/${APP_NAME}.app/Contents/MacOS/data/ui/widgets

# Copy over contents...
echo "Copying resources..."
# data folder
cp bin/data/themes.xml bin/${APP_NAME}.app/Contents/MacOS/data 
# data/fonts folder
cp bin/data/fonts/Verdana.ttf bin/${APP_NAME}.app/Contents/MacOS/data/fonts 
cp bin/data/fonts/Raleway-Bold.ttf bin/${APP_NAME}.app/Contents/MacOS/data/fonts 
cp bin/data/fonts/DejaVuSansMono-Bold.ttf bin/${APP_NAME}.app/Contents/MacOS/data/fonts 

# Data\ui\images folder
cp -r bin/data/ui/images/ bin/${APP_NAME}.app/Contents/MacOS/data/ui/images/ 

# Data\ui\svg folder
cp -r bin/data/ui/svg/ bin/${APP_NAME}.app/Contents/MacOS/data/ui/svg/    

# Data\ui\widgets folder
cp -r bin/data/ui/widgets/ bin/${APP_NAME}.app/Contents/MacOS/data/ui/widgets/     

brew install create-dmg 

cd bin/resources/macOS/
tiffutil -cathidpicheck dmg-background.png dmg-background@2x.png -out dmg-background.tiff
cd ../../../

test -f ${APP_NAME}-Installer.dmg && rm ${APP_NAME}-Installer.dmg
create-dmg \
  --volname "${APP_NAME} Installer" \
  --volicon "bin/resources/macOS/${APP_NAME}.icns" \
  --background "bin/resources/macOS/dmg-background.tiff" \
  --window-pos 200 120 \
  --window-size 512 270 \
  --icon-size 40 \
  --icon "${APP_NAME}.app" 432 35 \
  --hide-extension "${APP_NAME}.app" \
  --app-drop-link 432 187 \
  "${APP_NAME}-Installer.dmg" \

… and for windows, I use Nullsoft Scriptable Install, rcedit-x64.exe and a .bat file

Here’s a sample .bat file:

@echo off 

echo "------------------ CREATING INSTALLER (Windows) ------------------"

echo " Setting Icon using rcedit:"
bin\resources\win\rcedit-x64 "bin\**<APP_NAME_HERE>**.exe" --set-icon "bin\resources\win\<APP_ICON_FILE_NAME>.ico"

echo "Using NSIS: Nullsoft Scriptable Install System:"
"c:\Program Files (x86)\NSIS\makensis.exe" bin\resources\win\installer.nsi

here is an example bin\resources\win\installer.nsi file :

# This installs two files, app.exe and logo.ico, creates a start menu shortcut, builds an uninstaller, and
# adds uninstall information to the registry for Add/Remove Programs
# To get started, put this script into a folder with the two files (app.exe, logo.ico, and license.rtf -
# You'll have to create these yourself) and run makensis on it
# If you change the names "app.exe", "logo.ico", or "license.rtf" you should do a search and replace - they
# show up in a few places.
# All the other settings can be tweaked by editing the !defines at the top of this script
!define APPNAME "Cognition"
!define COMPANYNAME "My Company"
# These three must be integers
# These will be displayed by the "Click here for support information" link in "Add/Remove Programs"
# It is possible to use "mailto:" links in here to open the email client
!define HELPURL "http://..." # "Support Information" link
!define UPDATEURL "http://..." # "Product Updates" link
!define ABOUTURL "http://..." # "Publisher" link
# This is the size (in kB) of all the files copied into "Program Files"
!define INSTALLSIZE 7233
RequestExecutionLevel admin ;Require admin rights on NT6+ (When UAC is turned on)
# rtf or txt file - remember if it is txt, it must be in the DOS text format (\r\n)
# This will be in the installer/uninstaller's title bar
Icon "cognition.ico"
outFile "cognition-installer.exe"
!include LogicLib.nsh
# Just two pages - install location, and installation
page directory
Page instfiles
!macro VerifyUserIsAdmin
pop $0
${If} $0 != "admin" ;Require admin rights on NT4+
        messageBox mb_iconstop "Administrator rights required!"
        setErrorLevel 740 ;ERROR_ELEVATION_REQUIRED
function .onInit
	setShellVarContext all
	!insertmacro VerifyUserIsAdmin
section "install"
	# Files for the install directory - to build the installer, these should be in the same directory as the install script (this file)
	setOutPath $INSTDIR
    SetOverwrite ON 

	# Files added here should be removed by the uninstaller (see section "uninstall")
	file "..\..\**<APP_NAME>**.exe"
	file "**<APP_ICON_NAME>**.ico"
    file "..\..\fmodex.dll"
    file "..\..\libfluidsynth-2.dll"

    # Data folder
    setOutPath "$INSTDIR\\data"  
    file "..\..\data\themes.xml"    
    # Data\fonts folder
    setOutPath "$INSTDIR\\data\fonts"  
    file "..\..\data\fonts\Verdana.ttf"
    file "..\..\data\fonts\Raleway-Bold.ttf"
    file "..\..\data\fonts\DejaVuSansMono-Bold.ttf"

    # Data\ui\images folder
    setOutPath "$INSTDIR\\data\ui\images"  
    file "..\..\data\ui\images\*.*"    

    # Data\ui\svg folder
    setOutPath "$INSTDIR\\data\ui\svg"  
    file "..\..\data\ui\svg\*.*"    
    # Data\ui\widgets folder
    setOutPath "$INSTDIR\\data\ui\widgets"  
    file "..\..\data\ui\widgets\*.*"     	    

	# Add any other files for the install directory (license files, app data, etc) here
	# Uninstaller - See function un.onInit and section "uninstall" for configuration
	writeUninstaller "$INSTDIR\uninstall.exe"
	# Start Menu
	createDirectory "$SMPROGRAMS\${COMPANYNAME}"
	createShortCut "$SMPROGRAMS\${COMPANYNAME}\${APPNAME}.lnk" "$INSTDIR\Cognition.exe" "" "$INSTDIR\logo.ico"
	# Registry information for add/remove programs
	WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${COMPANYNAME} ${APPNAME}" "DisplayName" "${COMPANYNAME} - ${APPNAME} - ${DESCRIPTION}"
	WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${COMPANYNAME} ${APPNAME}" "UninstallString" "$\"$INSTDIR\uninstall.exe$\""
	WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${COMPANYNAME} ${APPNAME}" "QuietUninstallString" "$\"$INSTDIR\uninstall.exe$\" /S"
	WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${COMPANYNAME} ${APPNAME}" "InstallLocation" "$\"$INSTDIR$\""
	WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${COMPANYNAME} ${APPNAME}" "DisplayIcon" "$\"$INSTDIR\logo.ico$\""
	WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${COMPANYNAME} ${APPNAME}" "Publisher" "$\"${COMPANYNAME}$\""
	WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${COMPANYNAME} ${APPNAME}" "HelpLink" "$\"${HELPURL}$\""
	WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${COMPANYNAME} ${APPNAME}" "URLUpdateInfo" "$\"${UPDATEURL}$\""
	WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${COMPANYNAME} ${APPNAME}" "URLInfoAbout" "$\"${ABOUTURL}$\""
	WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${COMPANYNAME} ${APPNAME}" "DisplayVersion" "$\"${VERSIONMAJOR}.${VERSIONMINOR}.${VERSIONBUILD}$\""
	WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${COMPANYNAME} ${APPNAME}" "VersionMajor" ${VERSIONMAJOR}
	WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${COMPANYNAME} ${APPNAME}" "VersionMinor" ${VERSIONMINOR}
	# There is no option for modifying or repairing the install
	WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${COMPANYNAME} ${APPNAME}" "NoModify" 1
	WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${COMPANYNAME} ${APPNAME}" "NoRepair" 1
	# Set the INSTALLSIZE constant (!defined at the top of this script) so Add/Remove Programs can accurately report the size
	WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${COMPANYNAME} ${APPNAME}" "EstimatedSize" ${INSTALLSIZE}
# Uninstaller
function un.onInit
	SetShellVarContext all
	#Verify the uninstaller - last chance to back out
	MessageBox MB_OKCANCEL "Permanantly remove ${APPNAME}?" IDOK next
	!insertmacro VerifyUserIsAdmin
section "uninstall"
	# Remove Start Menu launcher
	# Try to remove the Start Menu folder - this will only happen if it is empty
	# Remove files
	delete $INSTDIR\<APP_NAME>.exe
	delete $INSTDIR\<APP_ICON_NAME>.ico
	# Always delete uninstaller as the last action
	delete $INSTDIR\uninstall.exe
	# Try to remove the install directory - this will only happen if it is empty
	# Remove uninstaller information from the registry
	DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${COMPANYNAME} ${APPNAME}"


Thanks, both of these examples were super useful!

hey @Maker_Bob. I compiled these examples and other related stuff if you are interested:

1 Like