33

I've built a command-line utility (Foundation tool) in Xcode, using Cocoa. The tool makes use of a 3rd party framework.

Everything works OK in Xcode, but how do I deploy this program?

If I run the app from Finder, it can't find the library because it's looking in ../Frameworks/etc. Can I statically link in the 3rd party framework?

Binarian
  • 12,296
  • 8
  • 53
  • 84
Norman
  • 581
  • 1
  • 5
  • 10

4 Answers4

31

Unfortunately, there is no way to bundle a framework with a command-line Utility in OS X and I suspect that the framework you're linking to is expecting to be bundled in the app bundle's Frameworks/ directory. If you have access to the framework source code, you can compile a static library and statically link it to your application (or include the source in your application target directly). If you don't have the source code or you don't want to statically link the library for some reason, there are two remaining options:

  1. If you have access to the system-wide /Library/Frameworks folder, you can install the 3rd party framework there. This require that the framework's Installation Path (the INSTALL_PATH build setting) be set to /Library/Frameworks at build time or that you use the install_name_tool to change the frameworks install path to /Library/Frameworks (if you don't have the framework's source code).

  2. Build an application bundle (as if you were building a GUI app) with your command-line utility as the app bundle's executable (i.e. in AppBundle.app/Contents/MacOS/). You can then copy the 3rd party framework to the app bundle's frameworks directory. You can then put the app bundle anywhere you want and create a symbolic link to the command line utility.

Option 1 is definitely the more accepted approach, but I've used option 2 when there was a valid reason.

You can find more information on building, linking, and installing frameworks in Apple's Frameworks Programming Guide.

zekel
  • 9,227
  • 10
  • 65
  • 96
Barry Wark
  • 107,306
  • 24
  • 181
  • 206
  • #2 is definitely a non-traditional approach, which I always like to see… I'm wondering though - maybe there would be a way to use INSTALL_NAME_TOOL install name tool to do this, as well? What do you think? – Alex Gray Aug 02 '12 at 21:54
  • Might anyone be able to elaborate on _how_ to install a framework project to /Library/Frameworks? In my case I'm hoping to install GRDB.swift for use in another project. – kjb Oct 18 '17 at 06:43
  • This is relevant again because Swift currently requires command line tools to access the Swift Standard Library in a framework, somewhere. kjb, your installer should be able to add to /Library/Frameworks. – balthisar Oct 22 '17 at 14:39
  • Thank you for the detailed answer! Is there any guide to build an app bundle with command-line utility? – derpoliuk Mar 22 '20 at 08:39
  • For anyone curious, here's the answer and it is pretty straightforward: https://stackoverflow.com/a/4540872/1226304 – derpoliuk Mar 22 '20 at 09:57
9

Another way, if you have the source code for the framework, is to add a static library target and build a static lib from it. Then you can statically link it into your command-line tool.

Peter Hosey
  • 95,783
  • 15
  • 211
  • 370
5

As of Xcode 9.3.1, I was able to have the framework added to the command line tool by setting the Mach-O Type to Static Library for the framework. Then in the command line target make sure to add the framework to the Target Dependencies & the Link Binary With Libraries Build Phases. The built executable was then able to run with no issues.

mcm
  • 655
  • 9
  • 10
0

You can use marathon to manage dependencies https://github.com/JohnSundell/Marathon

This would need more thought if you wanted to distribute app. (You would probably want to install into frameworks folder in that use case.) your mileage may vary with this solution.

johndpope
  • 5,035
  • 2
  • 41
  • 43