Page 1 of 2

How to make .app with dynamic lib. ?

Posted: Tue Nov 08, 2022 8:54 pm
by dibor
Hello.
I am new in the programming for MacOS.
I have write small programs compiled them to executables and all works good.
Now I made program and use dynamic lib.
Program works when I run it from IDE but program is crashed(segmentation fault) when I run created stand alone application(.app)
I have put .dylib together with binary file.
What I do wrong?

Best Wishes.

Re: How to make .app with dynamic lib. ?

Posted: Tue Nov 08, 2022 9:31 pm
by mk-soft
What is your dylib code doing

Re: How to make .app with dynamic lib. ?

Posted: Tue Nov 08, 2022 10:08 pm
by dibor
Hi.
Tnx for quick answer.
This is not my .dylib
.dylib from chilkat and provide SSH functions.

Re: How to make .app with dynamic lib. ?

Posted: Sat Nov 12, 2022 2:25 am
by dibor
Any thinк, thoughts, idea?

Re: How to make .app with dynamic lib. ?

Posted: Sat Nov 12, 2022 7:00 am
by fsw
dibor wrote: Tue Nov 08, 2022 8:54 pm I am new in the programming for MacOS.
...
Now I made program and use dynamic lib.
Program works when I run it from IDE but program is crashed(segmentation fault) when I run created stand alone application(.app)
I have put .dylib together with binary file.
You mention that you are new on MacOS programming:

When you say that you put the ".dylib together with binary file" do you mean you put the ".dylib" into the same directory as the ".app", or that you put it inside the ".app"?

Maybe you do not know, but on macOS the ".app" is a directory with a certain structure, so the ".dylib" needs to be copied into the ".app" next to the executable file:
*.app -> Contents -> MacOS -> executable file

Re: How to make .app with dynamic lib. ?

Posted: Sat Nov 12, 2022 11:42 am
by mk-soft
App Path structure ...

Only files for reading belong here.
MyApp.app/Contents/MacOS/MyApp ; Only the program 'MyApp'
MyApp.app/Contents/Resources/ ; Any static data files
MyApp.app/Contents/Library/ ; Any own dylib

See IDE Tool MyAppData and PathHelper.pb

Re: How to make .app with dynamic lib. ?

Posted: Sat Nov 12, 2022 10:37 pm
by dibor
Hello.
Thanks for answers!
@ fsw
I put it inside the ".app", .dylib to Contents -> MacOS, where located app binary(executable) file.

@mk-soft
Have move dylib to /Contents/Library/
Application still to crash :(
But application works when I compile and run it from IDE.

I am absolutely do not understand where a problem :(

Re: How to make .app with dynamic lib. ?

Posted: Sat Nov 12, 2022 11:57 pm
by mk-soft
Maybe:
- Right Path to Library
- Check library ist loaded
- No Debug with function (Debug AnyFunction() its removed)

Re: How to make .app with dynamic lib. ?

Posted: Sun Nov 13, 2022 1:29 am
by dibor
I put dylib to /Contents/Library/
Also have check lib

Code: Select all

If OpenLibrary(#PB_Any, "./Library/libchilkatPb-9_5_0.dylib") = 0
    MessageRequester("Error", "Library do not exist", #PB_MessageRequester_Error)
    quitMainWindow=1
EndIf
So, if dylib is not in the Contents/Library/ - I got error message, if dylib in right place - application is crashed. :(

Same code works with DLL on Windows machines and with .so lib on Linux RPi machine.
Only on MacOS I can not to run my program :(

Re: How to make .app with dynamic lib. ?

Posted: Sun Nov 13, 2022 10:26 am
by mk-soft
I have tried the example with GZIP.
Crashes here also under PB v5.73 and v6.00

No idea why
System Integrity Protection: enabled

Crashed Thread: 0 Dispatch queue: com.apple.main-thread

Exception Type: EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: KERN_INVALID_ADDRESS at 0x0000000000000000
Exception Codes: 0x0000000000000001, 0x0000000000000000
Exception Note: EXC_CORPSE_NOTIFY

Termination Reason: Namespace SIGNAL, Code 11 Segmentation fault: 11
Terminating Process: exc handler [25766]

Re: How to make .app with dynamic lib. ?

Posted: Sun Nov 13, 2022 11:07 am
by mk-soft
Ok .. bug found

The path to dylib does not fit ...

If you have packed the dylib into the app folder as with my IDE tool. You must specify the entire path.
For this I have rewritten my PathHelper as a module.

The following adjustment like the CkGzip.pb files

Code: Select all


Module CkGzip
  
  ...
  PrototypeC.i cksPropGet(obj.i)
  ...
  
  ;- **** Addes by mk-soft **** 
  UseModule PathHelper
  ; ****
  
CompilerIf #PB_Compiler_ExecutableFormat = #PB_Compiler_DLL
   Procedure ckInitGlobal()
CompilerEndIf

  CompilerSelect #PB_Compiler_OS
    CompilerCase #PB_OS_Windows
      CompilerIf #PB_Compiler_Processor = #PB_Processor_x86
        CkGzipLibId.i = OpenLibrary(#PB_Any, "chilkatPb32-9_5_0.dll")
      CompilerElse
        CkGzipLibId.i = OpenLibrary(#PB_Any, "chilkatPb-9_5_0.dll")
      CompilerEndIf
    CompilerCase #PB_OS_MacOS
        CkGzipLibId.i = OpenLibrary(#PB_Any, GetLibraryPath() + "libchilkatPb-9_5_0.dylib")
    CompilerCase #PB_OS_Linux
      CompilerIf #PB_Compiler_Processor = #PB_Processor_x86
        CkGzipLibId.i = OpenLibrary(#PB_Any, "libchilkatPb32-9_5_0.so")
      CompilerElse
        CkGzipLibId.i = OpenLibrary(#PB_Any, "libchilkatPb-9_5_0.so")
      CompilerEndIf
  CompilerEndSelect
  
  If Not CkGzipLibId
    MessageRequester("Error", "Can't load childkat libray! Program end!")
    End
  EndIf
  
Module PathHelper

Code: Select all

;-TOP

; Comment : Module Path Helper v1.05.1 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
    
    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

; ****
For this to work in debug mode, I recommend loading and compiling the tool. Then set it up as a tool twice according to the instructions.
In this way, data is always copied into the app after the compilers and before the app is started.
Link: PB-IDE Tool MyAppData

Re: How to make .app with dynamic lib. ?

Posted: Sun Nov 13, 2022 8:25 pm
by dibor
Hello mk-soft
Thank you for the Module PathHelper !!

PB-IDE Tool MyAppData doesn't works for me.
I have compiled MyAppData as console application and configure IDE tools as shown in the source.
As result impossible to use Run/Debug and executable application do not has library file, MyAppData tool do not copy lib to the application.

So, after creating executable file I have open package contents and make folder Library and put inside it libchilkatPb-9_5_0.dylib.
After that my applications is WORKS :)
But why in the PureBasic for MacOS this is too complicate ?

I do something wrong or do not understand how to works with MyAppData tool.

Re: How to make .app with dynamic lib. ?

Posted: Sun Nov 13, 2022 8:53 pm
by Wolfram
Hello dibor,

please try my plist tool.This copy's recourses and other content too.
Maybe this works for you.

viewtopic.php?p=585319#top

Re: How to make .app with dynamic lib. ?

Posted: Sun Nov 13, 2022 9:10 pm
by dibor
Hello Wolfram
Your tool also doesnt works.
Tool do not copy .dylib to the right place :(

Re: How to make .app with dynamic lib. ?

Posted: Sun Nov 13, 2022 9:22 pm
by mk-soft
dibor wrote: Sun Nov 13, 2022 8:25 pm Hello mk-soft
Thank you for the Module PathHelper !!

PB-IDE Tool MyAppData doesn't works for me.
I have compiled MyAppData as console application and configure IDE tools as shown in the source.
As result impossible to use Run/Debug and executable application do not has library file, MyAppData tool do not copy lib to the application.

So, after creating executable file I have open package contents and make folder Library and put inside it libchilkatPb-9_5_0.dylib.
After that my applications is WORKS :)
But why in the PureBasic for MacOS this is too complicate ?

I do something wrong or do not understand how to works with MyAppData tool.
Have create the help folders in same folder where ist then main pb file of your project
Code
./yourcode.pb
Folders
./MyAppData
./MyAppData/Library
./MyAppData/Resources

Copied dylib into ./MyAppData/Library