Xcode 12 no longer linking to embedded libraries

I have a Mac OS application that's linked against a few dynamic libraries. Previously I hadn't needed to configure anything in particular in XCode. When exporting the application the libraries were automatically copied into the archive in a folder called libs.

When running otool on the version of the app created by XCode 11, I see this:

Code Block
@executable_path/../libs/libsqlite3.0.dylib (compatibility version 9.0.0, current version 9.6.0)
@executable_path/../libs/libcrypto.1.0.0.dylib (compatibility version 1.0.0, current version 1.0.0)


I'm now trying to export my app on Big Sur using Xcode 12. With no configuration changes on my behalf, the libraries were no longer exported at all, so the app wouldn't work on any other machine. To try to fix the issue I'm telling Xcode to embed them from the general settings.

Xcode then adds them to the copy phase, and they are now exported (albeit in the Frameworks folder):

The run path search option it set to:

@loaderpath/../Frameworks
@executable
path/../Frameworks
@executable_path/Frameworks

But despite all this, the main binary still isn't linked against these embedded versions:

Code Block
/opt/local/lib/libsqlite3.0.dylib (compatibility version 9.0.0, current version 9.6.0)
/opt/local/lib/libcrypto.1.0.0.dylib (compatibility version 1.0.0, current version 1.0.0)


If I run otool -D against one of the embedded libraries, I get this:

Code Block
otool -D libcrypto.1.0.0.dylib 
libcrypto.1.0.0.dylib:
/opt/local/lib/libcrypto.1.0.0.dylib


Does anyone know haw to solve this, or have any suggestions to try?


Replies

So, the issue here is with how your embedded libraries are built. Lets look at what happens with libcrypto:
  1. Xcode passes all your libraries to ld64

  2. ld64 finds your copy of libcrypto.1.0.0.dylib, which has an installname of /opt/local/lib/libcrypto.1.0.0.dylib (as you show from otool -D)

  3. ld64 copies that installname into your apps dependency list (as displayed above in your first code block, which I presume you got from otool -L)

In general the best way to fix this is to change how libcrypto.1.0.0.dylib is built so that its installname is something like @rpath/libcrypto.1.0.0.dylib instead of /opt/local/lib/libcrypto.1.0.0.dylib. Then when you link your program it will include the @rpath installname and dyld will search for it at the various runpaths you have configured.


Hi,

Thanks for your reply. I finally realised that I did in fact have a run script that was we calling install_tool on the libraries. I had completely forgotten about it. This no longer worked as intended on Xcode 12.

Tim