Recent

Author Topic: MacOS post compilation script  (Read 62 times)

marcou

  • New Member
  • *
  • Posts: 11
MacOS post compilation script
« on: June 09, 2026, 07:30:07 pm »
Dear friends,

on MacOS, I have noticed a few problems with Lazarus 4.6 and I would like to share some workaround.

First issue is the management of icons. Mac uses a format .icns that contains several versions of the icon.

The workaround proposed by Claude (it works but the size is interpreted as 0x0 and it does not display if Project Options -> Application):

Code: Bash  [Select][+][-]
  1. # 1. Convert .ico to .png as needed
  2. sips -s format png MyIcon.ico --out MyIcon.png
  3.  
  4. # 2. Create the iconset directory
  5. mkdir MyIcon.iconset
  6.  
  7. # 3. Produce icons of different sizes from the png
  8. sips -z 16 16     MyIcon.png --out MyIcon.iconset/icon_16x16.png
  9. sips -z 32 32     MyIcon.png --out MyIcon.iconset/icon_16x16@2x.png
  10. sips -z 32 32     MyIcon.png --out MyIcon.iconset/icon_32x32.png
  11. sips -z 64 64     MyIcon.png --out MyIcon.iconset/icon_32x32@2x.png
  12. sips -z 128 128   MyIcon.png --out MyIcon.iconset/icon_128x128.png
  13. sips -z 256 256   MyIcon.png --out MyIcon.iconset/icon_128x128@2x.png
  14. sips -z 256 256   MyIcon.png --out MyIcon.iconset/icon_256x256.png
  15. sips -z 512 512   MyIcon.png --out MyIcon.iconset/icon_256x256@2x.png
  16. sips -z 512 512   MyIcon.png --out MyIcon.iconset/icon_512x512.png
  17. sips -z 1024 1024 MyIcon.png --out MyIcon.iconset/icon_512x512@2x.png
  18.  
  19. # 4. Create the .icns
  20. iconutil -c icns MyIcon.iconset -o MyIcon.icns

Then, the bundle produced by Lazarus does not work because it is not signed, the executable is not copied in the MacOS directrory of the bundle and the icon is not properly located in the Resource directory. And of course, the Info.plist must be updated accordingly. To solve these issues I propose the following post-build script -thanks to Claude:

Code: Pascal  [Select][+][-]
  1. #!/bin/bash
  2. # Usage: ./MacPostBuild.sh <ProjPath> <TargetFile> <IconFile> <BundleIdentifier>
  3. # Example: ./MacPostBuild.sh "$ProjPath" "$TargetFile" "MyIcon" "com.mycompany.myapp"
  4.  
  5. set -e
  6.  
  7. export ProjPath=${1%/}
  8. export TargetFile=${2%/}
  9. export IconFile=$3
  10. export BundleID=$4
  11.  
  12. cp "$ProjPath/$IconFile.icns" "$TargetFile.app/Contents/Resources/" || { echo "ERROR: copy of the icon failed"; exit 1; }
  13.  
  14. # Replace the symbolic link with a true copy
  15. rm "$TargetFile.app/Contents/MacOS/$(basename $TargetFile)"
  16. cp "$TargetFile" "$TargetFile.app/Contents/MacOS/" || { echo "ERROR: copy of the executable code failed"; exit 1; }
  17.  
  18. /usr/libexec/PlistBuddy -c "Add :CFBundleIdentifier string $BundleID" "$TargetFile.app/Contents/Info.plist" 2>/dev/null || \
  19. /usr/libexec/PlistBuddy -c "Set :CFBundleIdentifier $BundleID" "$TargetFile.app/Contents/Info.plist"
  20.  
  21. /usr/libexec/PlistBuddy -c "Add :CFBundleIconFile string $IconFile" "$TargetFile.app/Contents/Info.plist" 2>/dev/null || \
  22. /usr/libexec/PlistBuddy -c "Set :CFBundleIconFile $IconFile" "$TargetFile.app/Contents/Info.plist"
  23.  
  24. codesign --force --deep -s - "$TargetFile.app" 2>/dev/null || { echo "ERROR: signing app failed"; exit 1; }
  25.  
  26. # Force refresh of the icon display
  27. touch "$TargetFile.app"

The last touch command will force the refresh of the icon in Finder, so the compiled .app display correctly.

The script have to be called as post-build :

Code: Bash  [Select][+][-]
  1. /bin/bash $(ProjPath)/MacPostBuild.sh "$(ProjPath)" "$(TargetFile)" "MyIcon" "com.mycompany.myapp"

I hope this can be of some help to Mac users and sorry if it is a duplicate in another place of the forum.

Ciao,
Gilles Marcou

 

TinyPortal © 2005-2018