Add addDylib function similar to addFramework
For macOS/iOS Xcode
Currently addons with dylibs cause projects to fail to run as the dlyibs are not copied into the Bundle.
We should add a function similar to addFramework so dylibs are not just linked but added to the Copy File Build Phase.
Good reference here for how to do that: https://github.com/openframeworks/projectGenerator/blob/master/ofxProjectGenerator/src/projects/xcodeProject.cpp#L422-L509
Hello @ofTheo I'm wondering if maybe it is best avoid copying dylibs to inside the app for now. I'm trying to untangle some mess in ofxHapPlayer but I've noticed some complex stuff, like some dylibs have some preferential path inside which includes some other folders, like '@rpath/ffmpeg/lib/osx/libavutil.56.dylib'
I've tried to use install_name_tool to simplify, so all libs could work in the same folder, but there are some libraries that calls other ones by this kind of relative paths, so there is not an easy way to solve it automatically.
I can comment out the "copy files" phase if you agree
Hmm. Without those changes does ofxHap work without issue?
I’d love to either fix it or find any easy way to toggle it off.
Is there an easy reproducible example I can try?
Thanks!! Theo
Hey @dimitre
I just tied ofxHapPlayer and I think in this case we should probably ask @bangnoise to have the path be @executable_path/dylibName.dylib or even @rpath/dylibName.dylib now that we are bundling the dylibs in the app.
However with how it is right now adding this to the osx Xcode scripts makes it work in and out of the app ( thanks chatgpt : )
bundle_dylibs() {
if [ -z "$OF_BUNDLE_DYLIBS" ] ; then
msg "Bundling dylibs disabled \ncan be enabled with OF_BUNDLE_DYLIBS=1 in Project.xcconfig ";
cd $TARGET_BUILD_DIR/$PRODUCT_NAME.app/Contents/MacOS/
# Loop through each dylib file in the folder
for dylib_file in *.dylib
do
# Check if the file is not a symbolic link
if [[ ! -L "$dylib_file" ]]
then
# Use otool to extract the input file name
input_file_name=$(otool -D "$dylib_file" | grep "@rpath" | sort -u)
# Use install_name_tool to change the loader path
install_name_tool -change "$input_file_name" "@executable_path/$dylib_file" $PRODUCT_NAME;
install_name_tool -change "$input_file_name" "@executable_path/$dylib_file" "$dylib_file";
fi
done
else
could you see if that works for you?
Note: the above will probably solve 80-90% of dylib issues with the more involved OF_BUNDLE_DYLIBS for the more extreme cases.
Also note: we should prob do bundle_dylibs before code_sign
cc @artificiel
@ofTheo after a while I could get it running with your script. It works OK if we change the "Copy Files" phase to "products directory" so the dylibs are being copied in the .app folder, and not inside it.
Yes we should do this before code sign:
/Users/z/Desktop/OF_DesktopTest/install_name_tool:1:1 changes being made to the file will invalidate the code signature in: libavcodec.58.134.100.dylib (for architecture x86_64)
but I confirm it works. Yes, the best option would change paths on the addon itself, so less changes / code sign when developing
Thanks @dimitre!
Weird that you had to change the Copy Files I thought dylibs were getting copied to MyApp.app/Contents/MacOS/ already by default. ( At least they did for me with the test I tried ).
Where were they getting copied to for you?
Yes they are being copied to this directory but then I have this error
dyld[12984]: Library not loaded: '@rpath/libavutil.56.70.100.dylib'
Referenced from: '/Users/z/Desktop/OF_DesktopTest/bin/OF_DesktopTestDebug.app/Contents/MacOS/OF_DesktopTestDebug'
Reason: tried: '/Users/z/Desktop/OF_DesktopTest/bin/libavutil.56.70.100.dylib' (no such file), '/usr/lib/system/introspection/libavutil.56.70.100.dylib' (no such file), '/Users/z/Desktop/OF_DesktopTest/bin/OF_DesktopTestDebug.app/Contents/MacOS/../Frameworks/libavutil.56.70.100.dylib' (no such file), '/Users/z/Desktop/OF_DesktopTest/bin/OF_DesktopTestDebug.app/Contents/MacOS/../Frameworks/libavutil.56.70.100.dylib' (no such file), '/usr/local/lib/libavutil.56.70.100.dylib' (no such file), '/usr/lib/libavutil.56.70.100.dylib' (no such file)
so I'm wondering if executable path is "bin" folder only, because it works if I change to that.
oh weird - it shouldn't be setting it to @rpath/libavutil.56.70.100.dylib
is this when running app from Xcode or running from Finder?
could you try changing the script lines to:
# Use install_name_tool to change the loader path
install_name_tool -change "$input_file_name" "$dylib_file" $PRODUCT_NAME;
install_name_tool -change "$input_file_name" "$dylib_file" "$dylib_file";
or
# Use install_name_tool to change the loader path
install_name_tool -change "@loader_path/$input_file_name" "$dylib_file" $PRODUCT_NAME;
install_name_tool -change "@loader_path/$input_file_name" "$dylib_file" "$dylib_file";
from xcode. I'll be testing this soon
We use a similar script approach for ofxTensorFlow2: https://github.com/zkmkarlsruhe/ofxTensorFlow2/blob/main/scripts/macos_install_libs.sh
UPDATE: We install to Contents/Frameworks as a convention.
We have to double check to see if it is now copying over in latest PG