Using a framework in a PreferencePane - objective-c

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.

Related

HaxeDevelop: cross-platform compilation via default project templates

Trying investigate how to create "Hello world" on different languages via HaxeDevelop. I'm newbie and may be inacurate at terminology.
1) C# project. Pressing F8 gives me error:
haxe -cp src -cs D:/Programs/Projects/CsTestHaxe/bin/ -main Main
Unix.Unix_error(8, "mkdir", "D:/Programs/Projects/CsTestHaxe/bin/")
Build halted with errors (haxe.exe).
Via googling pretty much outdated info at least found solution:
haxe -main Main -cs out
And it works but ouput go to "src" location which is bad. Next googling led me to "Custom build" and using .hxml with pre-build command at project settings.
But why default template/settings not works for such simple thing as "Hello world" (used cs.system.Console)?
How default build may be fixed / probably I've installed or setup something wrong via HaxeDevelop installation?
2) C++ project. Pressing F8 gives me error:
Warning: Could not find environment variables for Visual Studio
Missing HXCPP_VARS
Error: Could not automatically setup MSVC
Error: Build failed
Build halted with errors (haxe.exe).
Using command line (similar to C# above) I can exucute C++ sources, but cant compile it.
Installed Visual Studio Community 2017. Nothing changed, same error. VS provide different own parts for installation. Should I install any specific?
Found also many threads about OpenFL workaround for C++ compilation. But I needn't OpenFL and want to use default Haxe API and tools.
Also OpenFL and C++ always mentioned with Lime. Do I need it too? Installed Lime via command line. But seems nothing changed.
3) Am I right that HaxeDevelop not yet support HashLink?
And if possible couple words about why HashLink appeared if there is Neko affiliated with Haxe?
As a result here an additional question: is it right that Haxe during compilation to target platform only "convert" .hx source to target one and then using third party (target platform) compile?
1) C# project. Pressing F8 gives me error.
This appears to be a known Haxe issue. Since it's been fixed on the dev branch, you could try a nightly build from build.haxe.org. Alternatively, you could also try manually creating the bin directory, since that seems to be what the error is about.
2) C++ project. Pressing F8 gives me error:
The latest Haxelib release of hxcpp (3.4.64) does not support Visual Studio 2017 yet. You could use a development version by installing hxcpp from GitHub, since again, it should be fixed there:
haxelib git hxcpp https://github.com/HaxeFoundation/hxcpp
The alternative is to downgrade Visual Studio.
Also OpenFL and C++ always mentioned with Lime. Do I need it too?
Yes, if you want to use OpenFL, you also need Lime, as OpenFL depends on it.
3) Am I right that HaxeDevelop not yet support HashLink?
Actually, a HashLink project template was added. But to follow the general theme of this answer, it seems it hasn't made it into an official relase yet. You can get a nightly build from here.
And if possible couple words about why HashLink appeared if there is Neko affilated with Haxe?
There is a two-part blog series on haxe.org by HashLink's author: part 1, part 2. The first part has a paragraph talking about this exact topic. Here's an excerpt:
First, let me explain the reasons for writing another virtual machine in replacement of Neko.
[...]
Back then, the Neko virtual machine was not especially designed to run Haxe and suffered from some limitations, the main one being performance.
[...]
And to your final question:
is it right that Haxe during compilation to target platform only "convert" .hx source to target one and then using third party (target platform) compile?
That is true for some targets, but it depends. For C++, C# and Java, Haxe indeeds generates source code for the target language and then invokes the target-native compiler after doing its own compilation (this step is usually called "native compilation").
However, some targets produce byte code directly (SWF and Neko), so there is no native compilation step there. Other target languages are interpreted (JS, PHP, Python and Lua), so there's no native compilation step there either. For HL it actually depends, there is HL/Jit (byte code) and HL/C, which is compiled to native C code.
You can find a comprehensive list of Haxe targets an their characteristics here.
Phew, that was a lot of questions in one. ;)

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

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.

Using the ConnectionKit Framework Within an NSBundle

Update
I've since spent time learning how to use install_name_tool & otool to do this properly, and documented the process here: Using Frameworks Within NSBundles
I would like to use the Connection Kit framework within an NSBundle I am making.
To allow my bundle to load the framework successfully, I've changed the dynamic library install name to use #loader_path as opposed to #executable_path.
After building and including the framework in my NSBundle, then building that, running the program that loads my bundle, my bundle fails to load and produces the following output:
Error loading MyBundle.rwplugin/Contents/MacOS/MyBundle: dlopen(/Users/facelap/Library/Developer/Xcode/DerivedData/MyBundle-hiyhdkndcnuhspfqwcuyneqobeou/Build/Products/Debug/MyBundle.rwplugin/Contents/MacOS/MyBundle, 265): Library not loaded: #executable_path/../Frameworks/DAVKit.framework/Versions/A/DAVKit
Referenced from: /Users/facelap/Library/Developer/Xcode/DerivedData/MyBundle-hiyhdkndcnuhspfqwcuyneqobeou/Build/Products/Debug/MyBundle.rwplugin/Contents/MacOS/../Frameworks/Connection.framework/Versions/A/Connection
Reason: image not found
It seems that Connection Kit itself uses a framework.
I also have the source for this framework. I tried setting its dynamic library install name to #loader_path, but this resulted in similar output (and the bundle failed to loar).
What would a sane entry be for the dynamic library install name for a framework within a framework that is to be used within an NSBundle?
Look at the crash log. It says that you bundle can't load DAVKit.framework so the easiest way - its rebuild ConnectionKit framework but instead of embedding DAVKit.xcodeproj insert all sources of DAVKit. Its easiest way but more correctly - its setup install path of ConnectionKit and DAVKit frameworks.
Its link should help you:
embedding frameworks in loadable bundles
You should link your bundle with DAVKit and include it there In the same way as you're including ConnectionKit. This avoids having multiple depths of frameworks being shipped

How to embed app with log4cocoa?

I'm having some trouble to embed my application with the log4cocoa framework.I've embed frameworks in my application before with no trouble, but I cannot fix this one.
First of all, this is my system out:
dyld: Library not loaded: #loader_path/Frameworks/Log4Cocoa.framework/Versions/A/Log4Cocoa
Referenced from: /Users/leandro/Documents/Projects/MLoggerApplication/build/Debug/MLoggerApplication.app/Contents/MacOS/MLoggerApplication
Reason: image not found
Well, I think done all necessary steps to get a framework working fine including the copy files phase and changed the installation directory over the build options to #executable_path/../Frameworks .
I hope problem clear enough to receive your help.
Thanks in advance.
Looks like your framework isn't being copied into your target. If a framework isn't part of the system (ie, you have to distribute it with your app), you need to not only link your executable against the framework but to copy it into your app's ./Frameworks folder.
To do this, add a Copy Files build phase, select "Frameworks" as the build phase's destination, then drag the framework (from your Frameworks folder in your Xcode project) under that Copy Files build phase you just created. If you already have a Copy Files build phase for Frameworks, then just use it instead of creating a new one.
Firstly, i mean, Joshua Nozzi is completely right about how is to embed an app with a framework!
But log4cocoa as a little different and could only realize that because it is an opensource code able for download at http://sourceforge.net/projects/log4cocoa/.
The framework could be used with this configuration by adding a "Copy Files build phase, but instead "Frameworks", select "Products Directory" as the build phase's destination, then drag the framework to that "Copy Files build phase.
The difference among this, and the other frameworks relies in this build variable: installation directory.It has as default value: "/Frameworks .
This variable can be accessed by right clicking on the log4cocoa(first item in the targets list), then select "Get Info" and finally "build".
To use it as "normal" framework rebuild it after you have edited the "installation directory" value to "#executable_path/../Frameworks" or if you are going to embed a framework with it, you would prefer "#loader_path/../Frameworks"

How do I use a dynamically load library in a command line utility? [duplicate]

This question already has answers here:
Closed 13 years ago.
Possible Duplicate:
using frameworks in a command line tool
Hey,
I've written a command line 'foundation tool' that uses the RegexKit.framework extensively. Everything works when run in Xcode but if I compile the release build and try to run it in Terminal I get the following error:
dyld: Library not loaded: #executable_path/../Frameworks/RegexKit.framework/Versions/A/RegexKit
Closer inspection reveals that the RegexKit.framework bundle is sat in the same directory as my executable file... I've done some research and I'm thinking that as command line tools don't use application bundles there's no where for Xcode to copy the framework to. So I'm guessing that I need to compile the framework as a static library and include it in my code... am I right? If so, how do I go about doing this? Is there anything I can do in Terminal to point to the framework externally?
Any help would be very greatly received, I've been banging my head against this for a few days now!
Thanks in advance,
Tom
So... What I did in the end was to recompile the framework with a different Installation Directory (in the Deployment section, under the Build tab in the Target's Info) - I set it to just #executable_path.
I then compiled the framework and replaced the one in my Utilitie's project, I also changed the Copy Files build phase to copy the framework to "Executables" rather than Frameworks.
The good news is that this fixes my original problem - but obviously the framework has to be in the same directory as the executable.
So this got me unstuck but I'd still love to know how to compile RegexKit.framework statically!
You shouldn't be installing the framework in the Executable folder of your bundle. It should be in the Frameworks folder. You need a Copy Files phase in your project that copies the framework and you need to set the Destination to "Frameworks". "Copy only when installing" should be unchecked.
When testing this, you should make sure you perform a clean build. I typically delete the build folder rather than using Xcode's Clean menu option since it's quicker and more comprehensive.
Also: you cannot statically link to a framework. If you want to statically link to something, it needs to be a static library so in this case, you'd need to hack about with RegexKit. Bear in mind that static libraries cannot contain resources, whereas Frameworks, being bundles, can.