Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2013-06

Packaging shared libraries for OSX, recommendations?

7 messages · 2 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Bruce Tulloch

What is the *recommended* way to build and package a shared library for OSX?

Our aim is that ordinary users can "just install it" such that other applications that depend on the library "just run" (without requiring authors of those other applications to include a copy of the library in their bundle or users to fiddle with command line command to configure them if they don't).

This library facilitates low level I/O. There are no UI or other resources but it has headers for those who want to build apps against it. If this were just UNIX we'd put under /usr/lib (and /use/include and perhaps /usr/share) but doing this this seems to be discouraged when reading the Apple's developer docs.

We don't want to depend on MacPorts, Fink or Brew etc. Should we be packaging this as a framework, albeit a simple one? What do Mac users (and Mac app programmers) prefer or expect when using shared libraries these days?

Thanks, Bruce.

Reply by email

Jonas Maebe
to Bruce Tulloch
Bruce Tulloch wrote 10 lines
What is the *recommended* way to build and package a shared library for OSX? Our aim is that ordinary users can "just install it" such that other applications that depend on the library "just run" (without requiring authors of those other applications to include a copy of the library in their bundle or users to fiddle with command line command to configure them if they don't).

The above is the non-recommended way. The recommended way is to have application packagers include the library (or framework) within their application bundle in order to prevent version conflicts or the absence of the correct version on the system to cause problems. And to give them the ability to just copy the application from one system to another and have it keep working without having to hunt everywhere for other components they also have to copy (although this is not possible for all applications, for most it is).

Show quoted text 8 lines
This library facilitates low level I/O. There are no UI or other resources but it has headers for those who want to build apps against it. If this were just UNIX we'd put under /usr/lib (and /use/include and perhaps /usr/share) but doing this this seems to be discouraged when reading the Apple's developer docs.

Under Mac OS X (and *BSD, and probably even most Linux distributions these days), you would put it under /usr/local/[lib,include,share]. / usr/lib etc are reserved for system usage.

We don't want to depend on MacPorts, Fink or Brew etc. Should we be packaging this as a framework, albeit a simple one?

If you absolutely want to distribute it as a standalone framework, you would generally install it under /Library/Frameworks or under /Library/ Application Support/YourProductName.

Jonas

Reply by email

Bruce Tulloch
to Jonas Maebe

On Mon, Jun 10, 2013 at 6:59 PM, Jonas Maebe wrote:

Under Mac OS X (and *BSD, and probably even most Linux distributions these

days), you would put it under /usr/local/[lib,include,share].

Understood. So if we install our library, headers etc to /usr/local/[lib,include,share] is it true that like any UN*X, in OSX:

- Command line programs *and* GUI apps will be able to use our library,

- XCode will be able to find and access the headers and,

- XCode App programmers can copy the .dylib file (from /usr/local/lib/libMyLib.dylib) to their project to include the library and avoid the need to redistribute our package?

Presuming the answers are all yes, is packagemaker the tool we should be using to package the library for distribution?

Bruce.

Reply by email

Jonas Maebe
to Bruce Tulloch
Bruce Tulloch wrote 12 lines
On Mon, Jun 10, 2013 at 6:59 PM, Jonas Maebe < >wrote: > Under Mac OS X (and *BSD, and probably even most Linux > distributions these > days), you would put it under /usr/local/[lib,include,share]. Understood. So if we install our library, headers etc to /usr/local/[lib,include,share] is it true that like any UN*X, in OSX: - Command line programs *and* GUI apps will be able to use our library,

There is no difference between the two as far as the dynamic linker is concerned.

- XCode will be able to find and access the headers and,

Yes.

- XCode App programmers can copy the .dylib file (from /usr/local/lib/libMyLib.dylib) to their project to include the library and avoid the need to redistribute our package?

The last part is incorrect. See e.g. http://qin.laya.com/tech_coding_help/dylib_linking.html and https://blogs.oracle.com/dipol/entry/dynamic_libraries_rpath_and_mac for more information. You need at least two versions of your library, or tell developers that want to include the library in their program to adapt the library's path with install_name_tool and compile/ link against this modified version because otherwise their application will still insist on only looking for the /usr/local/lib version (which is why distributing a /usr/local/lib version is such a bad idea, because developers won't notice on their own machine if they make a mistake since that version can be used without them realising it)

Presuming the answers are all yes, is packagemaker the tool we should be using to package the library for distribution?

Yes.

Jonas

Reply by email

Bruce Tulloch
to Jonas Maebe

Okay, got it, thanks Jonas. -b

Jonas Maebe wrote 57 lines
On 10 Jun 2013, at 11:41, Bruce Tulloch wrote: On Mon, Jun 10, 2013 at 6:59 PM, Jonas Maebe * > *wrote: > > Under Mac OS X (and *BSD, and probably even most Linux distributions >> these >> days), you would put it under /usr/local/[lib,include,share]**. >> > > Understood. So if we install our library, headers etc to > /usr/local/[lib,include,share] is it true that like any UN*X, in OSX: > > - Command line programs *and* GUI apps will be able to use our library, > There is no difference between the two as far as the dynamic linker is concerned. - XCode will be able to find and access the headers and, > Yes. - XCode App programmers can copy the .dylib file (from > > /usr/local/lib/libMyLib.dylib) to their project to include the library > and > avoid the need to redistribute our package? > The last part is incorrect. See e.g. http://qin.laya.com/tech_** coding_help/dylib_linking.html<http://qin.laya.com/tech_coding_help/dylib_linking.html>and https://blogs.oracle.com/**dipol/entry/dynamic_libraries_**rpath_and_mac<https://blogs.oracle.com/dipol/entry/dynamic_libraries_rpath_and_mac>for more information. You need at least two versions of your library, or tell developers that want to include the library in their program to adapt the library's path with install_name_tool and compile/link against this modified version because otherwise their application will still insist on only looking for the /usr/local/lib version (which is why distributing a /usr/local/lib version is such a bad idea, because developers won't notice on their own machine if they make a mistake since that version can be used without them realising it) Presuming the answers are all yes, is packagemaker the tool we should be > using to package the library for distribution? > Yes. Jonas ______________________________**_________________ fpc-pascal maillist - http://lists.freepascal.org/**mailman/listinfo/fpc-pascal<http://lists.freepascal.org/mailman/listinfo/fpc-pascal>

Reply by email

Bruce Tulloch
to Jonas Maebe: There is no difference between the two as far as the dynamic linker is concerned. Yes.…

So just to be clear, if we create a framework designed for others to bundle with their own apps where our framework (for the library) looks like this:

MyFramework.framework
|-- MyFramework -> Versions/Current/MyFramework
|-- Headers -> Versions/Current/Headers
|-- Resources -> Versions/Current/Resources
`-- Versions
|-- A
| |-- MyFramework
| |-- Headers
| | |-- MyFramework.h
| | `-- MyFramework.pas
| `-- Resources
| |-- English.lproj
| | `-- Documentation
| | `-- MyFrameworkAPI.html
| `-- Info.plist
`-- Current -> A

Xcode users of our library just include the framework binary (i.e. the dylib, also called MyFramework in this example) in their project. However, as part of our library build process we MUST use install_name_tool to modify the canonic path in the dylib to be relative to the executable location in the app bundle created by Xcode (when they build their app) and this relative location will always be as described in the linked examples you referred us to (i.e. @executable_path/../Frameworks/MyFramework).

Have we understood this correctly?

Can you give me some background on why it works this way? My understanding is that even if an app finds the dylib it needs in its own bundled Frameworks folder, ld refuses to load it because the dylib says its canonic home is somewhere else and this therefore requires the publisher of that dylib to modify the path to be where any app that uses it expects to locate the dylib even if said app already knows the location of the necessary dylib. This seems to be a rule (or bug?) which is apparently more inflexible than the standard UNIX way ld uses to locate libraries.

Thanks for your pearls of wisdom on this strange (to us) topic :-)

Cheers, Bruce.

Jonas Maebe wrote 57 lines
On 10 Jun 2013, at 11:41, Bruce Tulloch wrote: On Mon, Jun 10, 2013 at 6:59 PM, Jonas Maebe * > *wrote: > > Under Mac OS X (and *BSD, and probably even most Linux distributions >> these >> days), you would put it under /usr/local/[lib,include,share]**. >> > > Understood. So if we install our library, headers etc to > /usr/local/[lib,include,share] is it true that like any UN*X, in OSX: > > - Command line programs *and* GUI apps will be able to use our library, > There is no difference between the two as far as the dynamic linker is concerned. - XCode will be able to find and access the headers and, > Yes. - XCode App programmers can copy the .dylib file (from > > /usr/local/lib/libMyLib.dylib) to their project to include the library > and > avoid the need to redistribute our package? > The last part is incorrect. See e.g. http://qin.laya.com/tech_** coding_help/dylib_linking.html<http://qin.laya.com/tech_coding_help/dylib_linking.html>and https://blogs.oracle.com/**dipol/entry/dynamic_libraries_**rpath_and_mac<https://blogs.oracle.com/dipol/entry/dynamic_libraries_rpath_and_mac>for more information. You need at least two versions of your library, or tell developers that want to include the library in their program to adapt the library's path with install_name_tool and compile/link against this modified version because otherwise their application will still insist on only looking for the /usr/local/lib version (which is why distributing a /usr/local/lib version is such a bad idea, because developers won't notice on their own machine if they make a mistake since that version can be used without them realising it) Presuming the answers are all yes, is packagemaker the tool we should be > using to package the library for distribution? > Yes. Jonas ______________________________**_________________ fpc-pascal maillist - http://lists.freepascal.org/**mailman/listinfo/fpc-pascal<http://lists.freepascal.org/mailman/listinfo/fpc-pascal>

Reply by email

Jonas Maebe
to Bruce Tulloch
Bruce Tulloch wrote 12 lines
Xcode users of our library just include the framework binary (i.e. the dylib, also called MyFramework in this example) in their project. However, as part of our library build process we MUST use install_name_tool to modify the canonic path in the dylib to be relative to the executable location in the app bundle created by Xcode (when they build their app) and this relative location will always be as described in the linked examples you referred us to (i.e. @executable_path/../Frameworks/MyFramework). Have we understood this correctly?

Yes, although it's slightly better to use @rpath: http://www.dribin.org/dave/blog/archives/2009/11/15/rpath/

Can you give me some background on why it works this way?

To ensure that every application and library loads only other libraries that the authors intended them to load, rather than arbitrary copies located somewhere on the system (or loaded by other libraries used by that application/library) that may or may not work.

Jonas

Reply by email