Debugging QuickLook plug-in with 'bundle is damaged' error - objective-c

We're adding a QuickLook plug-in to our project.
Everything is fine until macOS trying to invoke our plug-in, at which point we're getting the beloved The bundle couldn’t be loaded because it is damaged or missing necessary resources error.
We've checked with otool -L on the plug-in's binary that all dependencies are in place, however as soon as the OS is asking our plug-in for a preview for the file type supported by us we get:
22/04/17 12:03:05,716 quicklookd[55323]:
[QL] Can't load plug-in at file:///Users/myname/Library/Developer/Xcode/DerivedData/The_Project-gpihzjouhxvifqcslmywktktizer/Build/Products/Debug/MyApp.app/Contents/Library/QuickLook/SomeQuickLookPlugIn.qlgenerator/:
The bundle “SomeQuickLookPlugIn” couldn’t be loaded because it is damaged or missing necessary resources.
The one thing we're not quite sure about is the dependency to our internal frameworks.
We've set up the plug-in similar to our main app, i.e. the private framework dependency resolves to:
#executable_path/../Frameworks/MyFW.framework/Versions/A/MyFW (compatibility version 1.0.0, current version 1.0.0)
..which would work OK if #executable_path were either the main app's binary or the plug-in's main binary as we copied the frameworks in both places in the bundle.
Any thoughts?
Ideally we would like the OS to tell us which dependency it failed to resolve -
is there any debug flag that can be set..?

As per https://www.mikeash.com/pyblog/friday-qa-2009-11-06-linking-and-install-names.html and http://www.dribin.org/dave/blog/archives/2009/11/15/rpath/ you should
set the Installation Directory for your referenced framework(s) to #rpath
in the app set Runtime Search Paths to #loader_path/../Frameworks
and in the QuickLook plug-in set Runtime Search Paths to #loader_path/../../../../../Frameworks as suggested by catlan -
that way you don't need to duplicate referenced frameworks inside the QuickLook plug-in
Compile, run, and everything should just work if everything else is set up correctly.
In addition you might want to check the code-signing settings in your plug-in to make sure there's no problems there.
One thing you can do is remove (or turn-off) code signing from your app and then see if it will load the plug-in…
To check if code-signing is the problem you can turn it off temporarily for your app using the Terminal to codesign --remove-signature YourApp.app and see if it works..

Run Search Paths should be #loader_path/../../../../../Frameworks because it is installed into Main.app/Contents/Library/QuickLook/QuickLookPlugin.qlgenerator/Contents/Mac/QuickLookPlugin, so we need to go five folders down from the #loader_path to find the frameworks folder.

Related

Cocoa Screensaver plugin with bundled custom frameworks

My app is partitioned into a number of frameworks.
Each framework has its Installation Directory set to #executable_path/../Frameworks, is linked and copied to the main executables Frameworks folder. All is working great.
Now some of the same frameworks are used in a separate screen saver executable.
The frameworks are linked, copied, present in the actual binary -
yet the screensaver module will fail to load with the following error:
Error loading /Users/someuser/Library/Screen Savers/MyScreenSaver.saver/Contents/MacOS/MyScreenSaver: dlopen(/Users/someuser/Library/Screen Savers/MyScreenSaver.saver/Contents/MacOS/MyScreenSaver, 265): Library not loaded: #executable_path/../Frameworks/BusinessBase.framework/Versions/A/BusinessBase
Referenced from: /Users/someuser/Library/Screen Savers/MyScreenSaver.saver/Contents/MacOS/MyScreenSaver
Reason: image not found
Looks like the screen saver (loaded as a plugin) cannot find the frameworks referenced by itself.
I've tried setting the screen savers Framework Search Path to both #loader_path/../Frameworks and #executable_path/../Frameworks.
No luck.
Any ideas what else to try..?
FWIW I've managed to fix this issue with some install_name_tool magic in a post build script:
The key was to change executable_path to loader_path and use the correct relative paths for the binary calling the respective framework.
For a screensaver plugin, #executable_path is the path to the ScreenSaverEngine executable that's loading your screensaver, or to System Preferences if it's running as a preview. It is not the path to your screensaver module! For that, you will need to use #loader_path.

MonoGame not able to find dylib files, throwing DllNotFoundException

I have a project using MonoMac in Xamarin Studio. I'm using [DllImport ("rlimit")] to access a .dylib file. However, even though I have mapped rlimit to rlimit.dylib, a DllNotFoundException is still thrown.
The .dylib files are in the project and should be accessible, however they cannot be found.
I'm guessing that the files are either in the wrong place, or they aren't being detected for some reason.
You need to put the dylib anywhere mono can find it.
You can find out where mono looks for native libraries by doing this:
export MONO_LOG_LEVEL=debug
export MONO_LOG_MASK=dll
mono yourprogram.exe
and verbose lookup output will be printed to the terminal. On my system mono looks first in the directory where the executable is, so putting the dylib there is probably the easiest. Then mono asks the system to find the dylib (by trying to open it without a path). The system typically looks in /usr/lib and maybe a few other places (this is of course system-dependent), but in any case you can add a path for the system to look in by setting LD_LIBRARY_PATH to that path. In this case you'll do this:
export LD_LIBRARY_PATH=/path/to/dylib:$LD_LIBRARY_PATH
mono yourprogram.exe
Note that you do not need the .dllmap, mono will automatically append the appropiate suffix depending on the platform (.dylib on Mac, .so on Linux and .dll on Windows).

Is there any way to change the dynamic library search path in Xcode

Below is my scenario,
In my Application i had to make use of libopus library , i downloaded and install, compile --> install procedure is normal as its for any other open source library,
I linked libopus.a with my application, the way i did is , by default it will get installed in /usr/local/lib, so i drag from there and add it to my application,
Worked fine and no error on my machine,
On Another machine, i was expecting it to be run smoothly as i included this library statically, but its throwing error as
dyld: Library not loaded: /usr/local/lib/libopus.0.dylib
so i concluded, libopus.a somehow including libopus.0.dylib also dynamically,
Now i am able ot add a copy phase in my build setting , so it will get copied in ../Framework folder
if i do otool -L libpus.a then it shows following result
otool -L /usr/local/lib/libopus.a
Archive : /usr/local/lib/libopus.a
/usr/local/lib/libopus.a(bands.o):
/usr/local/lib/libopus.a(celt.o):
/usr/local/lib/libopus.a(cwrs.o):
/usr/local/lib/libopus.a(entcode.o):
/usr/local/lib/libopus.a(entdec.o):
/usr/local/lib/libopus.a(entenc.o):
/usr/local/lib/libopus.a(repacketizer.o):
It doesn't show as its depend upon the dylib library
Now my Question is
How to tell Application to look into this path first
I tried following option,
install_name_tool but it seems it will work on other machine , so the user need to run this script NOT DEVELOPER,
trying to set the some option in the xcode to set the RUNTIME Search path to locate that particular dylib but not getting succeed so far
install_name_tool is run by the developer during the build process, not by the user.
If you're building the library, you should use libtool(1) with the option -install_name #rpath; otherwise, you can use install_name_tool(1) with -id #rpath to do the same thing on the dylib. Then, when you're building your application, set the "Runpath search paths" to the path where you will install the library.
Apple has some good documentation on this in their Mach-O Programming Topics and Dynamic Library Programming Topics.

MinGW-w64's ar.exe can't find libraries when trying to build a static library

I've now been trying to get MinGW-w64 to work on my system for several days, mainly because it has a more recent GCC version, but I either set things up wrong or there's some strange problem with MinGW-w64 itself.
I've now downloaded i686-w64-mingw32-gcc-4.7.2-release-win32_rubenvb, unpacked it to C:/Dev/mingw-ruben and added the path C:/Dev/mingw-ruben/bin to the $PATH environment variable.
What I'm trying to build is SFML 2 which comes with a CMake file. Running CMake will work just fine, the compiler gets recognized and passes all test. CMake also finds the ar.exe in the C:/Dev/mingw-ruben/binfolder. After generating the MinGW Makefile I switch to the windows command line and run mingw32-make install.
There's where the problem happens, I get the error:
mingw-ruben\bin\ar.exe: mingw-ruben/lib/libopengl32.a: No such file or directory
Or for the network library
mingw-ruben\bin\ar.exe: mingw-ruben/lib/libws2_32.a: No such file or directory
The error seems quite obvious and on check there really is no libopengl32.a or libws2_32.a in mingw-ruben/lib/, but the files is actually located in C:/Dev/mingw-ruben/i686-w64-mingw32/lib.
Now How can I tell ar/make/cmake to not only search in the mingw-ruben/lib directory but also in the mingw-ruben/i686-w64-mingw32/lib?
Would it be a good idea to copy all the content from the i686-w64-mingw32 subfolder to the mingw-ruben root folder?
As a side note: I can call mingw32-make install again and the procedure will continue but up on trying to link my application against SFML, I run into many unresolved symbol errors for the glXYZ functions from within SFML.
Further information: I'm on Windows 8 x64, but I think that doesn't really matter and yes I've tried MSYS but it doesn't resolve any of my issues.
Am I doing something wrong? Do I have to configure things specially?
January 2015 Edit
Now that SFML 2.2 has been released, this is no longer an issue and you have to link SFML's dependencies yourself when linking static.
January 2014 Edit
As of commit 165f2b1888 and f784fe4c07, which is included in the stable version SFML 2.1, MinGW-w64 compilers are supported.
However while discussing further with different parties it came to light, that the sfml_static_add_libraries marco a rather ugly hack was. In short it unpacked the static dependencies and included their obj files into the SFML library itself. This was most noticeable an issue, when trying to use your own version of GLEW, which failed since SFML was using its internal one already. The issue was brought to the forum and was pushed around for quite a bit, until Laurent finally gave in and went with the proper way of linking dependencies, which means you have to link them now on your own.
As of commit dbf01a775b, which is not included in the stable version of SFML 2.1, one has to link the SFML dependencies in the finally application, when linking statically against SFML.
Original
After some chat on the IRC we've figured it out.
It has nothing to do with MinGW but it's all SFML's fault. To reduce the dependencies list for SFML while linking statically the developer decided to manually extract the symbols from each library (opengl32, ws2_32, ...) which obviously isn't how one does things and violates some ODR rules. The actual error then occurs because the developer assumed that the library will be in the folder mingw/libbut with MinGW w64 it's located in a seperate directory mingw/version/lib and so ar.exe didn't find the library.
Solution
Removing the call to the sfml_static_add_libraries macro and then recompile. Afterwards you'll have to link all the dependencies for static linkages, like it should be.
I think it may be well a problem of the gcc distribution you downloaded.
A bit of light into the problem gives ruben's question here:
https://unix.stackexchange.com/questions/45277/executing-binary-file-file-not-found
that seems to me related to that (although it is about linux and not win)
I was having a similar problem (the name of the missing file was different) few months ago with gcc 4.7.0 linux->win crosscompiler. So until now I lived with the standard ubuntu mingw-w64 package and only yesterday I gave another try to i686-w64-mingw32-gcc-4.7.2-release-linux64_rubenvb.tar.xz and it works without issues in otherwise same environment where the previous version was failing with "..ar.exe: ... no such file". Sometimes I develop also in windows, then I use http://www.mingw.org/ that was for me much easier to setup in Win. It supports only 32bit target but for my project it is sufficient.

Using a framework in a PreferencePane

i am currently trying to implement a "third party framework" (FeedbackReporter.Framework) into my preferencepane.
Unfortunately I am getting the following error all the time when trying to launch my preference pane:
16.05.10 23:13:30 System Preferences[32645] dlopen_preflight
failed with
dlopen_preflight(/Users/me/Library/PreferencePanes/myPane.prefPane/Contents/MacOS/myPane):
Library not loaded:
#executable_path/../Frameworks/FeedbackReporter.framework/Versions/A/FeedbackReporter
Referenced from:
/Users/me/Library/PreferencePanes/myPane.prefPane/Contents/MacOS/myPane
Reason: image not found for
/Users/me/Library/PreferencePanes/myPane.prefPane
As far as I read so far, this problem is probably caused because my prefPane is no actual app, but a "plugin" of "System Settings.app" and thus #executable_path resolves to a path within the bundle of this app, instead of the bundle of my prefpane.
But I don't really picked up howto fix this problem. I guess it must be fairly easy since it should be a usual case that people use non-apple-frameworks in PreferencePanes.
Thanks for your hints!
--
Short Update:
As far as I understood tons of docs I read so far, there might be a setting which has to be done in the third-party framework. Obviously the "install path" has to be set to "loader_path" instead to "executable_path" in order to work in a preferencepane.
But since I am using a precompiled framework (FeedbackReporter.framework) this is probably a setting which the author has to change?! and even if i could compile the framework myself, i had no idea where to change this install_path in Xcode.
If you cannot wait for the next release just download the source, change it in
FeedbackReporter.xcodeproj/project.pbxproj
and then open and compile the framework yourself.
Actually, you can change it yourself without recompiling the third party framework. You can use install_name_tool to change where a MachO binary will look for shared object libraries. First use otool -L <binary file for your plugin> to get the paths of where it expects its libraries to be, then use install_name_tool -change ... to change the paths in that file. Repeat for any bundled frameworks.