13

I've got an application project that depends on a couple of shared libraries that I have created myself. According to the Qt 4.6 documentation "Deploying an Application on Mac OSX":

Note: If you want a 3rd party library to be included in your application bundle, then you must add an excplicit lib entry for that library to your application's .pro file. Otherwise, the macdeployqt tool will not copy the 3rd party .dylib into the bundle.

I have added lib entries to my application's .pro file but the libraries that I have written do not get copied into the bundle when I execute macdeployqt. I have the following in my .pro file:

LIBS += -L../Libraries -lMyLib

Everything builds okay, its just when I try to run from the bundle that I run into problems i.e. "image not found" errors.

Is there a bug in macdeployqt or do I have to something more to my .pro file?

demonplus
  • 5,613
  • 12
  • 49
  • 68
randusr836
  • 445
  • 1
  • 3
  • 16

4 Answers4

21

badcat is correct that the Qt 4.6 documentation has a grossly inflated view of what is possible with macdeployqt tool.

In my experience, the only things that are done by macdeployqt are:

  1. Copy the Qt libraries into your app bundle in the foo.app/Contents/Frameworks/ directory
  2. Adjusts the link libraries of one binary, namely foo.app/Contents/MacOS/foo (must have same name as app bundle, even if you mention another binary in Info.plist)

So, for every other binary and library you want to deploy in your app bundle, you must do the following:

  1. Run macdeployqt to enjoy its useful but feebly inadequate benefits

    macdeployqt <path_to_your_nascent_app_bundle>/foo.app

  2. Install your extra libraries manually

    cp <original_library_path> foo.app/Contents/Frameworks/<lib_name>

  3. Find out what libraries each binary links to.

    otool -L <binary_file_name>

  4. Change the internal libary paths in your binaries

    install_name_tool -change <original_library_path> @executable_path/../Frameworks/<lib_name> <binary_file_name>

I wrote a perl script that automates these steps for my application, but it's a bit too specific to my particular environment to post here.

Christopher Bruns
  • 9,160
  • 7
  • 46
  • 61
  • +1 for "same name as app bundle" part. I had a build number included in my .app name but not in binary. This seem to solve one of my problems. Thanks. – kolenda Apr 23 '15 at 12:06
  • Do you run macdeployqt again once the missing libraries are copied to the app and install_name_toll run on those missing libraries – MistyD Feb 03 '16 at 02:00
  • @MistyD No. macdeployqt, at least how it worked when I wrote this answer, does nothing to those missing libraries. That's why you run install_name_tool manually. – Christopher Bruns Feb 03 '16 at 15:13
  • @ChristopherBruns can you take a look at http://stackoverflow.com/questions/35185147/install-name-tooll-error-message-am-i-using-it-correctly – MistyD Feb 03 '16 at 18:53
  • One important note: `macdeployqt` is very noisy if it sees something in the `Frameworks/` directory that it doesn't recognize. Those errors can safely be ignored if you are copying the third-party library yourself and correcting its RPATH. – Nathan Osman Jun 20 '16 at 21:43
  • Can you please have a look into this : https://stackoverflow.com/questions/46088104/adding-external-libraries-deploying-qt-app-mac-osx – arqam Sep 07 '17 at 10:33
  • otool -l is still showing those as @rpath, which I changed, do I need to do anything else? – arqam Sep 07 '17 at 10:38
5

You don't need to take care about manual deployment of third-party libraries. I am uploading a patch to Qt that makes it possible to specify additional library search paths, so that the macdeployqt tool finds the third-party dependencies: https://codereview.qt-project.org/#change,47906

After this one there will be another commit that will add support for third party libraries' deployment.

Ivan Caravanio
  • 597
  • 1
  • 7
  • 20
  • This will be a great addition to macdeployqt. It's been a pain to manually deploy 3rd-party libraries/frameworks. – Cameron Tinker Apr 10 '13 at 19:32
  • I downloaded this and tried to build it (`qttools.pro`, replacing the qttools folder in my Qt 5.0.2 with the one from git), but get errors regarding qtNomakeTools and (after I comment that out) 'Project has no top-level .qmake.conf file' and `Module version not specified`. Can you help me get the patch working? I'm at my wits' end trying to deploy on a Mac. I've tried Bruns' way but it just led to a huge mess of paths within paths. – Matt Phillips May 23 '13 at 03:07
1

Did you check the .app bundle to see if the libraries are really not there?

If that's the case, I'd assume there really is a bug in macdeployqt, or it simply can't find the library you are linking. Personally I've never seen macdeployqt actually copy any needed 3rd-party libraries into the bundle.

The interesting part is that macdeployqt never ever works directly with the .pro file. It just does some stuff to the produced application bundle. And after a quick glance into the documentation this Qt 4.7 documentation page obviously proves me right:

Note: If you want a 3rd party library to be included in your application bundle, then you must copy the library into the bundle manually, after the bundle is created.

I'd assume there is a bug in the 4.6 documentation. For me macdeployqt never placed any library files in my bundle (except for the Qt* ones, of course).

I did spend a lot of time with this stuff in my past, and ended up writing a simple little (Python) script that packs everything up into my bundle, changes the library names as needed and puts everything in a .dmg file with automatic naming.

Possibly not what you wanted to hear, but it works. ;)

Community
  • 1
  • 1
BastiBen
  • 19,679
  • 11
  • 56
  • 86
0

https://github.com/auriamg/macdylibbundler

dylibbundler is a small command-line programs that aims to make bundling .dylibs as easy as possible. It automatically determines which dylibs are needed by your program, copies these libraries inside the app bundle, and fixes both them and the executable to be ready for distribution... all this with a single command on the teminal! It will also work if your program uses plug-ins that have dependencies too.

maxgalbu
  • 432
  • 3
  • 16