Re: Xcode, Dyld, External Dynamic Libraries and Setting {DY}LD_LIBRARY_PATH for Running Targets
Re: Xcode, Dyld, External Dynamic Libraries and Setting {DY}LD_LIBRARY_PATH for Running Targets
- Subject: Re: Xcode, Dyld, External Dynamic Libraries and Setting {DY}LD_LIBRARY_PATH for Running Targets
- From: Grant Erickson <email@hidden>
- Date: Fri, 14 Aug 2009 11:34:14 -0700
- Organization: Nuovation System Designs, LLC
- Thread-topic: Xcode, Dyld, External Dynamic Libraries and Setting {DY}LD_LIBRARY_PATH for Running Targets
On 7/25/09 2:35 AM, Ken Thomases wrote:
> On Jul 25, 2009, at 1:17 AM, Grant Erickson wrote:
>> Is such framework and/or dynamic library sharing typically
>> discouraged?
>
> No, not in cases which warrant such sharing. (I would say it's
> discouraged if there's no good reason for it. Put another way, I
> think that self-contained apps and plug-ins are preferred, up to the
> point where that starts to conflict with other design goals.) The
> only reason I suggested preferring a self-contained app bundle is
> because you didn't originally make any mention of the libraries being
> shared across multiple apps/pref panes. It seems you have sound
> reasons to put those shared libraries and frameworks in a common
> location.
>
> In any case, the Run Script build phase and install_name_tool would be
> how you change the library references within your executables to point
> to the ultimate destination, which is what it seemed you were mostly
> looking for. Obviously, you won't be able to use @executable_path in
> your case.
Ken:
The solution I ultimately employed for this ended up being more involved
than I hoped; however, it seemed like the only reasonable solution that A)
preserves the ability for any developer checking out code to debug in a
non-deployment situation B) for the deployed code to work as it should and
C) to minimize version conflicts in upgrade/downgrade situations in the
field.
1) Frameworks
While Xcode doesn't seem to support them fully in a Copy Files phase, I
noted that several Apple and third-party frameworks likely faced similar
problems and embedded their dynamic libraries in a "Libraries" folder/link
in the versioned content area of the framework:
/Library/Application Support/iWork
'09/Frameworks/Inventor.framework/Versions/C/Libraries
/Library/Frameworks/HPServicesInterface.framework/Versions/B/Libraries
/Library/Frameworks/Vertus.framework/Versions/1.0.0/Libraries
/System/Library/Frameworks/JavaVM.framework/Versions/1.3.1/Libraries
/System/Library/Frameworks/JavaVM.framework/Versions/1.4.2/Libraries
/System/Library/Frameworks/JavaVM.framework/Versions/1.5.0/Libraries
/System/Library/Frameworks/JavaVM.framework/Versions/1.6.0/Libraries
/System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries
/System/Library/PrivateFrameworks/PSNormalizer.framework/Versions/A/Librarie
s
So, I created a Copy Files phase for the framework, added the two dynamic
libraries to it and set the Destination to "Executables" and the Path to
"Libraries".
Then, after linking is complete, I added a Run Script phase that does the
various 'install_name_tool' fix-ups.
Because it appears that @loader_path or @executable_path don't work well for
frameworks, depending on whether the phase is being run for "install" or is
a build to the deployment location, I set the base path of the library ID
accordingly.
This phase also adds a convenient symbolic link to Libraries where the "Copy
Files" phase otherwise didn't.
LIBRARIES_FOLDER_PATH=${CONTENTS_FOLDER_PATH}/Libraries
if [ "${ACTION}" = "install" -o "${DEPLOYMENT_LOCATION}" = "YES" ];
TARGET_LIBRARIES_PATH=${INSTALL_PATH}/${LIBRARIES_FOLDER_PATH}
else
TARGET_LIBRARIES_PATH=${CONFIGURATION_BUILD_DIR}/${LIBRARIES_FOLDER_PATH}
fi
ln -sf "Versions/${CURRENT_VERSION}/Libraries"
"${CONFIGURATION_BUILD_DIR}/${WRAPPER_NAME}"
# Fix-up the shared library ID for the Boost Filesystem and System dynamic
libraries
install_name_tool -id "${TARGET_LIBRARIES_PATH}/libboost_filesystem.dylib"
"${CONFIGURATION_BUILD_DIR}/${LIBRARIES_FOLDER_PATH}/libboost_filesystem.dyl
ib"
install_name_tool -id "${TARGET_LIBRARIES_PATH}/libboost_system.dylib"
"${CONFIGURATION_BUILD_DIR}/${LIBRARIES_FOLDER_PATH}/libboost_system.dylib"
# Fix-up the link path for the Boost System dynamic library in theBoost
Filesytem dynamic library
install_name_tool -change "libboost_system.dylib"
"${TARGET_LIBRARIES_PATH}/libboost_system.dylib"
"${CONFIGURATION_BUILD_DIR}/${LIBRARIES_FOLDER_PATH}/libboost_filesystem.dyl
ib"
# Fix-up the link path for the Boost Filesystem and System dynamic
libraries in the wrapper executable
install_name_tool -change "libboost_system.dylib"
"${TARGET_LIBRARIES_PATH}/libboost_system.dylib"
"${CONFIGURATION_BUILD_DIR}/${EXECUTABLE_PATH}"
install_name_tool -change "libboost_filesystem.dylib"
"${TARGET_LIBRARIES_PATH}/libboost_filesystem.dylib"
"${CONFIGURATION_BUILD_DIR}/${EXECUTABLE_PATH}"
2) Application/Agent
This is similar to (1), except "Copy Files" simply dumps the dylibs to
Executables (which ends up being MacOS) with no Path set because the
"Libraries" trick doesn't seem to work for non-framework bundles.
Also, since relative paths work, I simply use "@executable_path/../MacOS" as
the base ID of the shared libraries without the install/deployment
conditional acrobatics.
Some applications (e.g. FileMaker Pro) seem to prefer sticking dynamic
libraries in "Frameworks" within the bundle. I'd prefer "Libraries" but that
doesn't work as well for non-framework bundles (you end up with
MacOS/Libraries), so MacOS will do (iPhoto and Firefox seem to think it an
OK location).
3) Preference Pane
Again, this is similar to (2). However, instead of
"@executable_path/../MacOS", I use "@loader_path/../MacOS" because
"@executable_path/../MacOS" gets the System Preferences executable not the
pane's.
Regards,
Grant
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Xcode-users mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden