dylib #executable_path path issue in a plug-in bundle - xcode

I am developing a plug-in bundle, say MyPlugIn.bundle for an application, say BigApp.app. This bundle requires a dylib, say MyPlugIn.bundle/Contents/Resources/library.dylib. I have relocated paths for library.dylib, as I would have done for a simple application bundle:
$ otool -L MyPlugIn.bundle/Contents/MacOS/MyPlugIn
MyPlugIn.bundle/Contents/MacOS/MyPlugIn:
#executable_path/../Resources/library.dylib (compatibility version 0.0.0, current version 0.0.0)
[...]
$ otool -L MyPlugIn.bundle/Contents/Resources/library.dylib
MyPlugIn.bundle/Contents/Resources/library.dylib:
#executable_path/../Resources/library.dylib (compatibility version 0.0.0, current version 0.0.0)
[...]
But BigApp.app fails to load this bundle, and Mac OS X's Console.app logs what follows:
19/01/10 15:42:59 BigApp[51516] Error loading /Library/Application Support/BigApp/Plug-Ins/MyPlugIn.bundle/Contents/MacOS/MyPlugIn: dlopen(/Library/Application Support/BigApp/Plug-Ins/MyPlugIn.bundle/Contents/MacOS/MyPlugIn, 262): Library not loaded: #executable_path/../Resources/library.dylib
Referenced from: /Library/Application Support/BigApp/Plug-Ins/MyPlugIn.bundle/Contents/MacOS/MyPlugIn
Reason: image not found
It seems that #executable_path is not replaced by the MyPlugIn.bundle executable path but by the BigApp.app executable path.
Any workaround to that, without absolute path and so that it will work on Mac OS X 10.4 (Tiger)? Thanks.

From the web and other SO questions: use #loader_path/.. instead of #executable_path/... See:
http://developer.apple.com/mac/library/documentation/Darwin/Reference/ManPages/man1/dyld.1.html
http://lapcatsoftware.com/blog/2007/08/11/embedding-frameworks-in-loadable-bundles/
How to distribute a Mac OS X with dependent libraries?
Installing IB plugin

Related

How to link .dylib libraries after installing an application

This is my first time creating an installer for an application and I need some advice.
This application depends on A.dylib, and A.dylib depends on two other libraries: libstdc++.6.dylib and libgomp.1.dylib which all come from the gcc folder. When I do otool -L on A.dylib, this is what I get :
A.dylib (compatibility version 0.0.0, current version 0.0.0)
/opt/homebrew/opt/gcc/lib/gcc/10/libstdc++.6.dylib (compatibility version 7.0.0, current version 7.28.0)
/opt/homebrew/opt/gcc/lib/gcc/10/libgomp.1.dylib (compatibility version 2.0.0, current version 2.0.0)
Which means that if these two libraries aren't in there, the application won't launch at all. So my problem is with the installer, am I supposed to install libstdc++.6.dylib and libgomp.1.dylib in /opt/homebrew/opt/gcc/lib/gcc/10/ for the user? Even if they don't have a gcc installed there, or at all?
Another option is to install the libraries under say /Library/Application Support/, but then this would mean that the path A.dylib is linked to won't be correct anymore. How do I change the linking path automatically after I install those libraries? What is the best way to go beyond this?

Setting INSTALL_RPATH no longer works when I start using a custom toolchain file

To make my library target link with another dynamic library I am using the following commands:
set_target_properties(MyTarget PROPERTIES INSTALL_RPATH "${MyTargetRPaths}")
This works perfectly until I introduce a custom toolchain file.
I have read Mac OSX and the RPATH wiki and tried all possible combinations of settings suggested there (some of their descriptions are quite obscure) and still I am seeing:
dyld: Library not loaded: #rpath/libstd-a260b5db713b337f.dylib
Referenced from: /Users/Stanislaw/Projects/mull/BuildXcode/unittests/Debug/MullUnitTests
Reason: image not found
otool -L command shows me that rpaths to the libraries I need no longer expand to the full paths of these libraries and I see LD_RUNPATH_SEARCH_PATHS empty.
$ otool -L mylib.dylib
#rpath/libstd-a260b5db713b337f.dylib (compatibility version 0.0.0, current version 0.0.0)
#rpath/libtest-551a7b69d9c2ff2f.dylib (compatibility version 0.0.0, current version 0.0.0)
I still cannot find how presence of -DCMAKE_TOOLCHAIN_FILE=$(myfile) changes the setup of *RPATH* settings in CMake.

install_name_tool reporting malformed object

Everytime I try to use install_name_tool on my machine it reports the following
install_name_tool: object: Abacate malformed object (unknown load command 4)
I read that it could be an error when building the binary. In order to check I create the simplest hello world c++ program and try to change something using install_name_tool. Didn't work. What Am I doing wrong?
Currently I have XCode 4.2 running Snow Leopard OS.
Apparently install_name_tool is not updated when XCode is updated. You need to install the Command Line Tools from XCode Preferences. See also install_name_tool on OS X Lion. This resolved the same error for me.
Managed to make it work with Mac OS 10.9.3
https://github.com/Homebrew/homebrew/issues/26544
$$:~ otool -L /usr/bin/install_name_tool
/usr/bin/install_name_tool: /usr/lib/libxcselect.dylib (compatibility
version 1.0.0, current version 1.0.0) /usr/lib/libSystem.B.dylib
(compatibility version 1.0.0, current version 1197.1.1)
$$:~ pkgutil --file-info /usr/bin/install_name_tool
volume: / path:
/usr/bin/install_name_tool
pkgid: com.apple.pkg.Essentials pkg-version: 10.9.0.1.1.1306847324
install-time: 1390577801 uid: 0 gid: 0 mode: 755
No more errors on wget:
$$:~ wget dyld: Library not loaded:
##HOMEBREW_PREFIX##/opt/openssl/lib/libssl.1.0.0.dylib Referenced
from: /usr/local/bin/wget Reason: image not found

Mac OS X libcurl dylib compatibility version

My application builds and runs fine on 10.6. I have Base SDK set to 10.6 and Mac OS X Deployment Target set to 10.5.
My application uses the system libcurl.dylib — instead of adding the dylib to the project, I just add -lcurl to the linker flags in build settings. (Though I have tried it both ways.)
When I launch the application on 10.5.8, I get the following error
Dyld Error Message: Library not loaded: /usr/lib/libcurl.4.dylib
Referenced from: /Applications/My Application.app/Contents/MacOS/MyApplication
Reason: Incompatible library version:
MyApplication requires version 6.0.0 or
later, but libcurl.4.dylib provides
version 5.0.0
Sure enough, if I otool -L the application's binary, I get the following for libcurl:
/usr/lib/libcurl.4.dylib (compatibility version 6.0.0, current version 6.1.0)
Is there any way around this, or should I just statically link my own libcurl build?
Have you tried setting the Base SDK to 10.5 as well?
$ otool -L /Developer/SDKs/MacOSX10.6.sdk/usr/lib/libcurl.4.dylib
/Developer/SDKs/MacOSX10.6.sdk/usr/lib/libcurl.4.dylib:
/usr/lib/libcurl.4.dylib (compatibility version 6.0.0, current version 6.1.0)
...]
$ otool -L /Developer/SDKs/MacOSX10.5.sdk/usr/lib/libcurl.4.dylib
/Developer/SDKs/MacOSX10.5.sdk/usr/lib/libcurl.4.dylib:
/usr/lib/libcurl.4.dylib (compatibility version 5.0.0, current version 5.0.0)
[...]

How do I bundle a library within a Cocoa application?

I have the library libmysqlclient.16.dylib, which I need to have on the computer where my application is running, or I will get the following error:
Dyld Error Message: Library not
loaded:
/usr/local/mysql/lib/libmysqlclient_r.16.dylib
Referenced from: /Users/alex/snow
server 3.app/Contents/MacOS/snow
server Reason: image not found
This is very strange, because I linked the binary with this library.
If the same dylib exists on the target computer, but in a different version (for example, Snow Leopard Server), I get an error like the following:
Dyld Error Message: Library not
loaded:
/usr/local/mysql/lib/libmysqlclient_r.16.dylib
Referenced from: /Users/alex/snow
server 3.app/Contents/MacOS/snow
server Reason: no suitable image
found. Did find:
/usr/local/mysql/lib/libmysqlclient_r.16.dylib:
mach-o, but wrong architecture
I'd like to link against this library, but not have to use the local copy of it. Is this possible?
UPDATE - when i try to using install_name_tool i don't have any changes:
bash-3.2# otool -L
libmysqlclient.16.dylib
libmysqlclient.16.dylib:
libmysqlclient.16.dylib
(compatibility version 16.0.0, current
version 16.0.0)
/usr/lib/libSystem.B.dylib
(compatibility version 1.0.0, current
version 123.0.0)
/usr/lib/libz.1.dylib (compatibility
version 1.0.0, current version 1.2.3)
/usr/lib/libstdc++.6.dylib
(compatibility version 7.0.0, current
version 7.9.0) bash-3.2#
install_name_tool -change
libmysqlclient.16.dylib
#executable_path/../Frameworks/libmysqlclient.16.dylib
Usage: install_name_tool [-change old
new] ... [-rpath old new] ...
[-add_rpath new] ... [-delete_rpath
old] ... [-id name] input bash-3.2#
install_name_tool -change
libmysqlclient.16.dylib
#executable_path/../Frameworks/libmysqlclient.16.dylib
libmysqlclient.16.dylib bash-3.2#
otool -L libmysqlclient.16.dylib
libmysqlclient.16.dylib:
libmysqlclient.16.dylib
(compatibility version 16.0.0, current
version 16.0.0)
/usr/lib/libSystem.B.dylib
(compatibility version 1.0.0, current
version 123.0.0)
/usr/lib/libz.1.dylib (compatibility
version 1.0.0, current version 1.2.3)
/usr/lib/libstdc++.6.dylib
(compatibility version 7.0.0, current
version 7.9.0)
SOLUTION
i was add a script into build phase:
install_name_tool -change libmysqlclient.16.dylib #executable_path/../Frameworks/libmysqlclient.16.dylib $CONFIGURATION_BUILD_DIR/$PRODUCT_NAME.app/Contents/MacOS/$PRODUCT_NAME
this was fixed a libpath for executive product and working fine with lib in bundle.
First, you'll want to make sure that you're copying this library into your application bundle so that it will be available on the user's machine. To do this, add a new Copy Files build phase for your application to copy bundled frameworks. Within the properties of that build phase, make sure that the destination is Frameworks. Drag your library from your project into that build phase to make sure that it is packaged with your application.
You may also need to modify the library itself so that it points to the correct location within the application bundle. In the past, I've done this by making a copy of the library within my project's directory, then using the following command to modify where the library expects to find itself:
install_name_tool -id #executable_path/../Frameworks/libftd2xx.0.1.0.dylib libftd2xx.0.1.0.dylib
In this case, the library being modified was called libftd2xx.0.1.0.dylib.
You can use the command
otool -L [library filename]
to see the path where the library expects itself to be found and determine if this change needs to be made.
Make sure that you change the path on the library within your Xcode project so that you will be linking against this new, modified version of the library residing within your project directory.

Resources