@@ -810,6 +810,59 @@ template tryExceptOSErrorMessage(conf: ConfigRef; errorPrefix: string = "", body
810
810
(ose.msg & " " & $ ose.errorCode))
811
811
raise
812
812
813
+ proc createMacAppBundle(conf: ConfigRef; exefile: AbsoluteFile) =
814
+ let (dir, name, _) = splitFile(exefile.string )
815
+ let appBundleName = name & " .app"
816
+ let appBundlePath = dir / appBundleName
817
+ let contentsPath = appBundlePath / " Contents"
818
+ let macosPath = contentsPath / " MacOS"
819
+
820
+ createDir(macosPath)
821
+
822
+ let bundleExePath = macosPath / name
823
+ copyFileWithPermissions(exefile.string , bundleExePath)
824
+
825
+ let infoPlistPath = contentsPath / " Info.plist"
826
+
827
+ proc xmlEscape(s: string ): string =
828
+ result = newStringOfCap(s.len)
829
+ for c in items(s):
830
+ case c:
831
+ of '<' : result .add(" <" )
832
+ of '>' : result .add(" >" )
833
+ of '&' : result .add(" &" )
834
+ of '"' : result .add(" "" )
835
+ of '\' ' : result .add(" '" )
836
+ else :
837
+ if ord(c) < 32 :
838
+ result .add(" &#" & $ ord(c) & ';' )
839
+ else :
840
+ result .add(c)
841
+
842
+ let escapedName = xmlEscape(name)
843
+ let infoPlistContent = """ <?xml version="1.0" encoding="UTF-8"?>
844
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
845
+ <plist version="1.0">
846
+ <dict>
847
+ <key>CFBundleExecutable</key>
848
+ <string>$1</string>
849
+ <key>CFBundleIdentifier</key>
850
+ <string>com.nim.$1</string>
851
+ <key>CFBundleName</key>
852
+ <string>$1</string>
853
+ <key>CFBundlePackageType</key>
854
+ <string>APPL</string>
855
+ <key>LSUIElement</key>
856
+ <string>1</string>
857
+ </dict>
858
+ </plist> """ % [escapedName]
859
+
860
+ writeFile(infoPlistPath, infoPlistContent)
861
+
862
+ removeFile(exefile.string )
863
+
864
+ rawMessage(conf, hintUserRaw, " Created Mac app bundle: " & appBundlePath)
865
+
813
866
proc getExtraCmds(conf: ConfigRef; output: AbsoluteFile): seq [string ] =
814
867
result = @ []
815
868
when defined(macosx):
@@ -994,6 +1047,10 @@ proc callCCompiler*(conf: ConfigRef) =
994
1047
preventLinkCmdMaxCmdLen(conf, linkCmd)
995
1048
for cmd in extraCmds:
996
1049
execExternalProgram(conf, cmd, hintExecuting)
1050
+ # create Mac app bundle for GUI apps on macOS
1051
+ when defined(macosx):
1052
+ if conf.globalOptions * {optGenGuiApp, optGenDynLib, optGenStaticLib} == {optGenGuiApp}:
1053
+ createMacAppBundle(conf, mainOutput)
997
1054
else :
998
1055
linkCmd = " "
999
1056
if optGenScript in conf.globalOptions:
0 commit comments