Static linking wxHaskell on Mac OS X - macos

I want to distribute a wxHaskell application on Mac OS X. How do I go about creating a Mac OS X app which can be used standalone without the user having to install any extra libraries?
I noticed the cabal-macosx project which makes .app bundles for Mac OS X. When I built the example wxHello application, the app bundle worked fine on my machine (after adding extra-lib-dirs: /usr/lib to the .cabal file). But when I tried it on another machine, I got the error: Dyld Error Message: Library not loaded: /Users/binil/.cabal/lib/wxc-0.90.0.3/ghc-7.0.4/libwxc.dylib.

You can place the required dylibs in the Contents/Resources folder within your app bundle, as that is part of the search path for dylibs. You can automate this using the project's copy files build phase.
Technically (though this does not always work for all dylibs), you should be able to pull it off "correctly" by converting the dylib to a Framework, then linking against it in your XCode project. There is a conversion script available [note: download].

Related

Tesseract .net on macos, how to reference libdl.dylib on macOS12?

I'm running a .net application that requires a reference to libdl.so
System.DllNotFoundException : Unable to load shared library 'libdl.so' or one of its dependencies. In order to help diagnose loading problems, consider setting the DYLD_PRINT_LIBRARIES environment variable: dlopen(liblibdl.so, 0x0001): tried: 'liblibdl.so' (no such file), '/usr/local/lib/liblibdl.so' (no such file), '/usr/lib/liblibdl.so' (no such file), '/Users/Amplicity/Documents/liblibdl.so' (no such file)
After some light reading, i found that libdl.so is the linux equivalent of libdl.dylib, I then tried to find libdl.dylib on my machine.
➜ lib locate libdl.dylib
/Applications/Xcode.app/Contents/Developer/Platforms/AppleTVOS.platform/Library/Developer/CoreSimulator/Profiles/Runtimes/tvOS.simruntime/Contents/Resources/RuntimeRoot/usr/lib/libdl.dylib
/Applications/Xcode.app/Contents/Developer/Platforms/WatchOS.platform/Library/Developer/CoreSimulator/Profiles/Runtimes/watchOS.simruntime/Contents/Resources/RuntimeRoot/usr/lib/libdl.dylib
/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS.simruntime/Contents/Resources/RuntimeRoot/usr/lib/libdl.dylib
There are only tvos, watchos, and ios signed libdl.dylib's available. Some more light reading reveals that somewhere around xcode 7, .dylib files were replaced with .tbd, which is a text file that references dylibs elsewhere.
➜ lib locate libdl.tbd
/Applications/Xcode.app/Contents/Developer/Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS.sdk/usr/lib/libdl.tbd
/Applications/Xcode.app/Contents/Developer/Platforms/AppleTVSimulator.platform/Developer/SDKs/AppleTVSimulator.sdk/usr/lib/libdl.tbd
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/lib/libdl.tbd
/Applications/Xcode.app/Contents/Developer/Platforms/WatchOS.platform/Developer/SDKs/WatchOS.sdk/usr/lib/libdl.tbd
/Applications/Xcode.app/Contents/Developer/Platforms/WatchSimulator.platform/Developer/SDKs/WatchSimulator.sdk/usr/lib/libdl.tbd
/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/usr/lib/libdl.tbd
/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk/usr/lib/libdl.tbd
/Library/Developer/CommandLineTools/SDKs/MacOSX11.3.sdk/usr/lib/libdl.tbd
/Library/Developer/CommandLineTools/SDKs/MacOSX12.0.sdk/usr/lib/libdl.tbd
/Library/Developer/CommandLineTools/SDKs/MacOSX12.1.sdk/usr/lib/libdl.tbd
/Library/Developer/CommandLineTools/SDKs/MacOSX12.3.sdk/usr/lib/libdl.tbd
I attempted to symlink the .tbd to the .so that my .net application expects, but .net complained that it was net a mach-o file.
I then attempted to symlink the tvos .dylib to the .so, and got a different error stating that it needed to be signed for macos.
How can I find/conjure libdl.dylib on macOS12, so that I may directly reference it in my application?
I suppose you cannot rebuild that application, cause currently libdl.so` would not be requested as it is not deployed anymore as standalone.
Try to make symlink of libdl.so to libc.so (or whichever version is installed with your .net platform package, libc.so.x)

Running Chromium.app crashes as it cannot find some specific system dylibs

I have built chromium from https://chromium.googlesource.com/chromium/src/+/lkcr/docs/mac_build_instructions.md
I am able to successfully build and run on the machine that i built the code but not able to run it on any other mac.
I want to be able to distribute the application file.
The application crashes because its not able to find some system libraries which load dynamically.(libsystem_kernel.dylib , libsystem_pthread.dylib, libsystem_c.dylib ,libdyld.dylib ).
These dylibs can be found in /usr/lib folder on Mac OSX
Any suggestion on distribution of the app?

Trace dylib loading on Mac OSX

I'm trying to build a Qt-based application on Mac OSX, and something in my application bundle is pulling in a Qt library from /Library rather than from the application bundle.
I've done this successfully in the past, so I know about using install_name_tool to link applications and libraries to the bundle versions of libraries. I've done this, but I must be missing something. I've tried setting DYLD_PRINT_LIBRARIES, but I'm not really sure how this helps: I can see which Qt library is being pulled in from /Library first (QtXml), but I don't know which file in the bundle is pulling in this library.
Is there some trick to tracing back which file is loading a particular library?
Use otool utility to see what libraries are used by your app and where the app expects to find them:
otool -L yourApp.app/Contents/MacOS/yourApp

Deploying Qt Frameworks with Mac app and usage of otool

I have a problem deploying Qt frameworks with my Mac app, and I hope some will have a clue why I get this error, when I run the app on clean Mac, i.e. not a developer Mac.
OS: 10.7 .2 and using XCode
Error msg:
Library not loaded: #loader_path/../Frameworks/QtCore.framework/Versions/4.0/QtCore
Referenced from:/Users/someUser/Downloads/MainApp.app/Contents/Resources/Lib/Library.bundle/Contents/MacOS/../Frameworks/../Frameworks/QtXml.framework/Versions/4/QtXml
Clearly something is wrong since the QtXml is referenced from /../Frameworks/../Frameworks, which doesn’t exists.
This is the set up: I have a dylib that uses QtCore and QtXml (not by my choosing, but for now I need those two frameworks), the dylib is used in a NSBundle, which is loaded by the main app, the bundle is located in the resource folder. The dylib is moved by Copy Files Build Phase to the folder Contents/Frameworks and with otool the install_name is set to (as stated by http://doc.qt.digia.com/4.3/deployment-mac.html):
#loader_path/../Frameworks/QtCore.framework/Versions/4.0/QtCore
#loader_path/../Frameworks/QtXml.framework/Versions/4/QtXml
then the Qt frameworks are moved to Contents/Frameworks and the install_name of the is set to:
#executable_path/../Frameworks/QtCore.framework/Versions/4.0/QtCore
and for the QtXml
#executable_path/../Frameworks/QtXml.framework/Versions/4/QtXml
with reference to QtCore:
#executable_path/../Frameworks/QtCore.framework/Versions/4.0/QtCore
Now when I run the app on the developer mac it clearly works since Qt is installed, but when moved to a clean mac I get the error msg, readable in the Console app.
I’ve tried to change the executable_path to loader_path, but this didn’t work.
I have no idea what I’m doing wrong or why it won't for, and have not been able to find anything on Google, of course I could be looking at the wrong places. Any ideas how to fix this problem?
This is the entire error message:
MainApp: Error Domain=NSCocoaErrorDomain Code=3587 "The bundle
“Library” couldn’t be loaded because it is damaged or missing
necessary resources."
(dlopen_preflight(/Users/someUser/Downloads/MainApp.app/Contents/Resources/Lib/Library.bundle/
Contents/MacOS/Library): Library not loaded:
#loader_path/../Frameworks/QtCore.framework/Versions/4.0/QtCore
Referenced from: /Users/ someUser /Downloads/
MainApp.app/Contents/Resources/Lib/Library.bundle/Contents/MacOS/../Frameworks/../Frameworks/QtXml.framework/Versions/4/QtXml
Reason: image not found) UserInfo=0x107c5d5d0
{NSLocalizedFailureReason=The bundle is damaged or missing necessary
resources., NSLocalizedRecoverySuggestion=Try reinstalling the
bundle.,
NSFilePath=/Users/someUser/Downloads/MainApp.app/Contents/Resources/Lib/Library.bundle/Contents/MacOS/Library,
NSDebugDescription=dlopen_preflight(/Users/someUser
/Downloads/MainApp.app/Contents/Resources/Lib/Library.bundle/Contents/MacOS/Library):
Library not loaded:
#loader_path/../Frameworks/QtCore.framework/Versions/4.0/QtCore
Referenced from:
/Users/someUser/Downloads/MainApp.app/Contents/Resources/Lib/Library.bundle/Contents/MacOS/../Frameworks/../Frameworks/QtXml.framework/Versions/4/QtXml
Reason: image not found,
NSBundlePath=/Users/someUser/Downloads/MainApp.app/Contents/Resources/Lib/Library.bundle,
NSLocalizedDescription=The bundle “Library” couldn’t be loaded because
it is damaged or missing necessary resources.}
On the development mac everything works because the Qt libraries are installed. On any mac you ship the app to, though, this likely won't be the case. The Qt suite comes with a tool called macdeployqt to fix this. So in a terminal, after you've compiled your application, do something like:
# cd my-cool-app-Desktop
# macdeployqt my-cool-app.app
Note that it can also be used to create a .dmg file for shipping everything together:
# cd my-cool-app-Desktop
# macdeployqt my-cool-app.app -dmg
Once you've done that, the .app directory or .dmg file can be given to someone else without Qt installed to use and run as they normally would.
The one caveat is that the next time you try to run it on your developer machine, it may complain about multiple shared libraries installed. So once you've copied it else where in order to distribute it, remove the entire .app directory and let qtcreator (or whatever) rebuild it.
UPDATE
As stated compiling QT to static libs is the way to go. With the release of Mavericks (10.9) we need to codesign frameworks as well (http://furbo.org/2013/10/17/code-signing-and-mavericks/), and with QT4.8.5 there are some issues (https://bugreports.qt-project.org/browse/QTBUG-32896). Even with suggested fixes I still had some issues when running the app on a clean machine. Therefore, I ended up with compiling Qt5.2 to staticlibs, link them in the app, and codesign them.
OLD
Problem sovled, I moved the Qt-frameworks into the app bundle in Contents/Frameworks and with otool set the path to #executable_path/../Frameworks, i.e. moved it out of my library bundle. Yes the solution is simple, but I'm still not sure why the library executable couldn't find the frameworks when using #loader_path.
The best solution would probably be to use a static library and not wrap it in a bundle...you learn everyday ;)

Linking Macports libraries to XCode application

I'm trying to distribute my app's dependencies with the app.
I've got the macports packages librsvg, boost, and cairo installed 64-bit-only on my Snow Leopard system. When I create an .app bundle of my program, it does not work on machines without macports and the relevant libraries installed because they are not included with the app, which searches for the libraries in /opt.
I have tried the --static flag for static linking, but that caused libcrt0 errors.
What's the best method for linking MacPorts libraries and their dependencies to an OSX application suitable for lone distribution?
You'll want to copy the libraries into your application bundle, using a Copy Files Build Phase. dylibs should be put in the Frameworks directory in the app bundle. You'll also have to add the libraries to your Xcode project.
Try using py2app to create a stand-alone app.
I had to just do this for jsoncpp. What I did was I went to linker settings under the project > Build Phases > Link Binary With Libraries then used the add other to go to my library's path and add the library from the folder which would be under opt/local/lib in the default setup for macport
getting the header files was a bit more complicated. In this case I had ended up going to usr/Include finding the file/folder with the headers, copying it into my project and in the cpp file I added the include line with quotation marks ("")
e.g., moved /usr/Include/json directory into the RestTemplate Project folder using copy. then added to main.cpp
#include "json/json.h"

Resources