Создать аппликацию под macOS довольно таки просто.
Так же, как и аппликацию под Windows или под Linux.
Но если ваша аппликация включает в себя дополнительную библиотеку от стороннего производителя или вашу, то тут уже возникает проблема.
И не все так просто, как кажется.
Так как под Macintosh аппликация это как "упакованная папка", то все библиотеки лежат в папке под названием Library.
Об этом должен знать компайлер во время компиляции.
Для этого нужна какая-то специальная программа или специальная функция, и она есть, которую написал mk-soft
;-TOP ; Comment : Module Path Helper v1.05.2 by mk-soft ; Link : https://www.purebasic.fr/english/viewtopic.php?p=562634#p562634 DeclareModule PathHelper ; Change names CompilerIf Defined(CompanyName, #PB_Constant) = 0 #CompanyName = "mk-soft" CompilerEndIf CompilerIf Defined(ApplicationName, #PB_Constant) = 0 #ApplicationName = "MyApplication" CompilerEndIf Declare.s GetProgramPath() Declare.s GetResourcePath() Declare.s GetLibraryPath() Declare.s GetProgramDataPath() Declare.s GetAllUserDataPath() EndDeclareModule ; ---- Module PathHelper CompilerIf #PB_Compiler_OS = #PB_OS_MacOS Macro CocoaString(NSString) PeekS(CocoaMessage(0, NSString, "UTF8String"), -1, #PB_UTF8) EndMacro CompilerEndIf Procedure.s GetProgramPath() CompilerIf #PB_Compiler_OS = #PB_OS_MacOS Static bundlePath.s Protected bundlePathPtr If Not Bool(bundlePath) bundlePathPtr = CocoaMessage(0,CocoaMessage(0,0,"NSBundle mainBundle"),"bundlePath") If bundlePathPtr bundlePath = CocoaString(bundlePathPtr) + "/" EndIf EndIf ProcedureReturn bundlePath CompilerElse ProcedureReturn GetPathPart(ProgramFilename()) CompilerEndIf EndProcedure ; ---- Procedure.s GetResourcePath() CompilerIf #PB_Compiler_OS = #PB_OS_MacOS Static resourcePath.s Protected resourcePathPtr If Not Bool(resourcePath) resourcePathPtr = CocoaMessage(0,CocoaMessage(0,0,"NSBundle mainBundle"),"resourcePath") If resourcePathPtr resourcePath = CocoaString(resourcePathPtr) + "/" EndIf EndIf ProcedureReturn resourcePath CompilerElse ProcedureReturn GetProgramPath() + "Resources" + #PS$ CompilerEndIf EndProcedure ; ---- Procedure.s GetLibraryPath() Protected librayPath.s CompilerIf #PB_Compiler_OS = #PB_OS_MacOS librayPath = GetProgramPath() + "Contents/Library/" CompilerElse librayPath = GetProgramPath() + "Library" + #PS$ CompilerEndIf ProcedureReturn librayPath EndProcedure ; ---- Procedure.s GetProgramDataPath() Protected basePath.s, subPath.s, dataPath.s CompilerIf #PB_Compiler_OS = #PB_OS_Linux basePath = GetHomeDirectory() subPath = basePath + "." + #CompanyName + #PS$ CompilerElse basePath = GetUserDirectory(#PB_Directory_ProgramData) subPath = basePath + #CompanyName + #PS$ CompilerEndIf dataPath = subPath + #ApplicationName + #PS$ If FileSize(dataPath) <> -2 If FileSize(subPath) <> -2 CreateDirectory(subPath) EndIf If FileSize(dataPath) <> -2 CreateDirectory(dataPath) EndIf EndIf ProcedureReturn dataPath EndProcedure ; ---- Procedure.s GetAllUserDataPath() Protected basePath.s, subPath.s, dataPath.s basePath = GetUserDirectory(#PB_Directory_AllUserData) subPath = basePath + #CompanyName + #PS$ dataPath = subPath + #ApplicationName + #PS$ If FileSize(dataPath) <> -2 If FileSize(subPath) <> -2 CreateDirectory(subPath) EndIf If FileSize(dataPath) <> -2 CreateDirectory(dataPath) EndIf EndIf ProcedureReturn dataPath EndProcedure ; ---- EndModule UseModule PathHelper ; **** CompilerIf #PB_Compiler_IsMainFile Debug "Program Path: " + GetProgramPath() Debug "Program Resources Path: " + GetResourcePath() Debug "Program Libraries Path: " + GetLibraryPath() Debug "Program Data Path: " + GetProgramDataPath() Debug "Program Alluser Data Path: " + GetAllUserDataPath() CompilerEndIf
Можете назвать ее PathHelperp.pbi включить ее в ваш проект(XIncludeFile "PathHelper.pbi") и перед открытием вашей библиотеки сделать следующее:
UseModule PathHelper LibId.i = OpenLibrary(#PB_Any, GetLibraryPath() + "Ваша_библиотека.dylib")
Теперь будет скомпилировано все правильно и запускаемый файл будет правильно обращаться к библиотеке, которая находится в директории Library.
Теперь можно открыть аппликацию посредством нажатия правой клавиши мышки на ней и выбрать Show Package Contents, зайти в Contents, создать папку Library и переписать туда вашу библиотеку.
Но можно этот процесс автоматизировать:
Берем у того же автора прогу MyAppData
;-TOP ; Tool : MyAppData - Copied the folder MyAppData in the APP folder \Contents ; Author : mk-soft ; Version : 1.04.0 ; Create : 10.02.2015 ; Update : 16.01.2022 ; ; Commpilermode : Console ; ; Info.plist ; ; PLIST <key>CFBundleSignature</key> ; PLIST <string>PB-TOOL</string> ; PLIST <key>CFBundleShortVersionString</key> ; PLIST <string>1.2.0.2</string> ; PLIST <key>CFBundleName</key> ; PLIST <string>PB-Tool MyAppData</string> ; PLIST <key>NSHumanReadableCopyright</key> ; PLIST <string>Copyright © 2022 mk-soft. All rights reserved.</string> ; ; *************************************************************************************** ; Configure Tool 1 ; ; Commandline: ; MyAppData ; ; Arguments: ; "%FILE" ; ; Working Directorory ; Nothing ; ; Name: ; MyAppData Run ; ; Event to trigger the tool: ; After Compile/Run ; ; Option: ; Wait until tools quits ; ; --------------------------------------------------------------------------------------- ; ; Configure Tool 2 ; ; Commandline: ; MyAppData ; ; Arguments: ; "%FILE" ; ; Working Directorory ; Nothing ; ; Name: ; MyAppData Executable ; ; Event to trigger the tool: ; After Create Executable ; ; Option: ; Nothing ; ; --------------------------------------------------------------------------------------- ; ; Format for new info.plist ; ; Begin without space '; PLIST {keys and values} ; ; Example ; ; PLIST <key>CFBundleSignature</key> ; ; PLIST <string>PBAPP</string> ; ; PLIST <key>CFBundleShortVersionString</key> ; ; PLIST <string>1.0.1.0</string> ; ; PLIST <key>NSHumanReadableCopyright</key> ; ; PLIST <string>Copyright © 2018 mk-soft. All rights reserved.</string> ; ********************************************** EnableExplicit Structure udtDict key.s List value.s() EndStructure Global NewList plist.s() Global NewList dict.udtDict() Global file_code.s Global file_app.s Global path_contents.s ; --------------------------------------------------------------------------------------- Procedure InitParameters() ; Parameter source file file_code = ProgramParameter() If file_code = "" ProcedureReturn 0 EndIf ; Parameter execute file file_app = GetEnvironmentVariable("PB_TOOL_Executable") If file_app = "" ProcedureReturn 0 EndIf If GetExtensionPart(file_app) <> "app" ProcedureReturn 0 EndIf ; Set path to contents path_contents = file_app + "/Contents/" ProcedureReturn 1 EndProcedure ; --------------------------------------------------------------------------------------- ;- Copy folder MyAppData to Contents Procedure CopyAppData() Protected path_data.s path_data = GetPathPart(file_code) + "MyAppData" If FileSize(path_data) <> -2 ProcedureReturn 0 EndIf If CopyDirectory(path_data, path_contents, "*", #PB_FileSystem_Recursive) = 0 MessageRequester("MyAppData", "Error copy data" + #CR$ + path_data + " to " + path_contents) ProcedureReturn 0 EndIf ProcedureReturn 1 EndProcedure ; --------------------------------------------------------------------------------------- ;- Read info.plist from Application Procedure ReadPList() Protected file_plist.s, text.s, dict.i, key.s, value.s, newkey.i, pos file_plist.s = path_contents + "info.plist" If ReadFile(0, file_plist) While Not Eof(0) text.s = ReadString(0, #PB_UTF8) If Bool(text) If FindString(text, "<dict>") AddElement(plist()) plist() = text dict = #True ElseIf FindString(text, "</dict>") AddElement(plist()) plist() = text dict = #False ElseIf Not dict AddElement(plist()) plist() = text EndIf If dict pos = FindString(text, "<key>") If pos >= 1 And pos <= 3 AddElement(dict()) dict()\key = Trim(text) newkey = #True ElseIf newkey AddElement(dict()\value()) dict()\value() = Trim(text) EndIf EndIf EndIf Wend CloseFile(0) EndIf EndProcedure ;- Read new info.plist from source Procedure ReadInfo() Protected r1, text.s, key.s, lkey.s, value.s, newkey, addkey If ReadFile(0, file_code) While Not Eof(0) text.s = ReadString(0, #PB_UTF8) If Bool(text) If FindString(text, "; PLIST ", 1, #PB_String_NoCase) = 1 r1 = #True text = RTrim(Mid(text, 9)) If FindString(text, "<key>") = 1 ; New key only with first place key = Trim(text) lkey = LCase(key) newkey = #True addkey = #True ForEach dict() If LCase(dict()\key) = lkey ClearList(dict()\value()) addkey = #False Break EndIf Next If addkey ResetList(dict()) AddElement(dict()) dict()\key = key EndIf ElseIf newkey AddElement(dict()\value()) dict()\value() = text EndIf EndIf EndIf Wend CloseFile(0) EndIf ProcedureReturn r1 EndProcedure ;- Write new info.plist Procedure WritePList() Protected file_plist.s file_plist.s = path_contents + "info.plist" If CreateFile(0, file_plist) ForEach plist() WriteStringN(0, plist(), #PB_UTF8) If FindString(plist(), "<dict>") = 1 ForEach dict() WriteStringN(0, #TAB$ + dict()\key, #PB_UTF8) ForEach dict()\value() WriteStringN(0, #TAB$ + dict()\value(), #PB_UTF8) Next Next EndIf Next EndIf EndProcedure ; --------------------------------------------------------------------------------------- ;-Main If InitParameters() CopyAppData() ReadPList() If ReadInfo() WritePList() EndIf EndIf
Компилируем его и создаем консольное приложение.
Создаем два инструмента для PureBasic, один для запуска, другой для создания аппликации. Так как написано в исходникe у автора.
В папке своего проекта создаем папку MyAppData, в ней папки Library и Resource
В Library помещаем библиотеку, ту которая находится в папке проекта.
Запускаем Compile -> Create Executable и получаем готовую аппликацию, которая может запуститься на любом Маке.
Также аппликация MyAppData может изменить некоторые параметры P-листа, в которой может быть указано название программы, автор и так далее.
Надо только в начале исходника вашей программы добавить несколько строк.
Как пример:
; Info.plist ; ; PLIST <key>CFBundleSignature</key> ; PLIST <string>PB-TOOL</string> ; PLIST <key>CFBundleShortVersionString</key> ; PLIST <string>1.2.0.2</string> ; PLIST <key>CFBundleName</key> ; PLIST <string>PB-Tool MyAppData</string> ; PLIST <key>NSHumanReadableCopyright</key> ; PLIST <string>Copyright © 2022 mk-soft. All rights reserved.</string>
Успехов!
Отредактировано dibor (Вчера 20:27:18)