I'm trying to build and run my program in C++ from inside Xcode.
I'm using wxWidgets which I build myself inside ~/wxwidgets/buildOSX.
An Xcode project linker option set to use that location in order to build my program.
I also made a little script in the Xcode project->Build Phases, which copies all the dylibs into the Bundle and uses install_name_tool -change to redirect ldd to load the libraries from the new location.
However, what I see in the Debug Console when I press Command + R is that all the libraries including wx one are loaded twice - first from the Bundle and then from the location I build them from. And so I end up with 2 copy of every single library
How do I mitigate that?
P.S.: I believe that this is the reason for Crash in Xcode but success from Terminal. And so fixing it will resolve the crash here.
Related
I am developing a plugin for a third-party host application on MacOS that compiles as a .dylib (with associated DSYM directory). The .dylib and DSYM directory is automatically copied to the host's plugin directory by a supplied build script. The build script uses clang to build the .dylib. The host application is able to open the plugin.
With Xcode, I am able to debug the .dylib with lldb within Xcode, because Xcode is somehow able to identify that the sources match the dylib once it is loaded.
I wish to set up a similar system with CLion, however I have not been able to get CLion to associate the breakpoint lines in the source with the dylib. When I create a breakpoint in the source it warns me that "Breakpoint will not currently be hit. No executable code is associated with this line". I almost expect this kind of warning because the image hasn't been loaded into the host application yet. However loading the plugin does not trigger the breakpoints.
I tried setting the Configuration's Executable to the .dylib, and setting the working directory to the location of the .dylib and the DSYM directory (this is what I have to do when running lldb manually), and this does not seem to help.
My questions are:
Does CLion use lldb internally?
Is what I am trying to do possible with CLion?
If so, what is the correct configuration for this situation?
One important thing to note is that I am not building the .dylib with CLion directly, it is build by an external build system, I am just trying to debug the resulting image with CLion, which I understand should work (it works with Xcode & lldb at least). I have a basic CMakeLists.txt that is sufficient for CLion to understand the code base, but it is not used to build it (beyond any background compilation that CLion might do to check syntax etc).
I am new to cocoa and mac development. I have written an application which is combination of objective-c using cocoa framework and backend written in C++ library dylib.
I am using xcode 4.6 and have the above two projects Cocoa app and my C++ library. C++ is also my own project.
Now it is time for deployment. I want to make a pkg installer for it.
I could run/debug it in the xcode 4.6 because I had added search library path in the object-c project settings to be the output directory of the C++ project. Therefore it could find the dependency and run without crash.
Now in the Objective-C project tree inside the xcode I see products -> mysoftware.app file. if I find the location of this mysoftware.app file in the finder and run it, it crashes. I open the package contents of this app files and I see contentsfollowing structure
contents\(info.plist, MacOS, pkginfo, resources )
I do not see my C++ library in there, when I run mysoftware.app directly double clicking it crashes as it can not find the dylib I see the stack trace in the report window it can not find dylib, complaning that library not found usr/local/lib/mylib.dylib
I have also manually put the dylib file in the .app within the MacOS where my executable is, hoping that it will find the lib from the same directory, it did not , gave the same message above and looking from the the sane location /usr/local/lib/mylib.dylib
So my question is how do I resolve dependency of .app package for deployment, should I need to put the dylib inside the .app package ? how do I do that and then my next step would be to put this single .app thing in the pkg installer,
Thanks
This is what worked for me:
Drag the dylib into your Frameworks.
Add a Copy Files build phase, destination Frameworks and put the dylib there.
Add a Run Script phase which has the following script:
MYLIBNAME=libmylib.dylib
install_name_tool -change /usr/local/lib/$MYLIBNAME #executable_path/../Frameworks/$MYLIBNAME "$BUILT_PRODUCTS_DIR/$EXECUTABLE_PATH"
That's it. The script tells your app to load the dylib from the right place - otherwise it will complain about not finding the dylib at runtime.
Note that you don't need to change anything in the dylib itself - it could be supplied from elsewhere.
I resolved it so I am putting up this answer to help others who want to do the same.
The dylib has to go in one of the sub folders within the application bundle (i.e. mysoftware.app). Could be MacOS, Frameworks or any sub folder we decide to put it in.
The first step is in the target settings of our dylib, we set the install path to be relative to the app bundle (mysoftware.app), so in Xcode target settings of lib I set it to:
#executable_path/../frameworks
You can also use #rpath (You might want to research on that, I think it is more flexible than #executable_path)
Xcode will change the install name as well for our dylib.
Then in the Objective-C project using our dylib in the Project settings -> Build phases -> Link -> we drag our dylib here from the products node of the dylib project.
In the Objective-C/Cocoa project, the last step is to add a build step named copy files, and it should show a combo box telling you the target folder of the bundle. I set it to frameworks (this will depend on that relative path you choose when setting install path of your dylib) . The second part of the 'Copy Files' build step is to provide the souce file to copy. That's our dylib file that we want to pack in the bundle's Frameworks folder. So drag the dylib file from the products (of your dylib project) to the source file of the build step.
And that's it.
Now when we build the Objective-C or Cocoa project, if our build steps and install_path , etc are correctly configured, it should build fine. After a successfull build of the Cocoa project, go to Products -> mysoftware.app -> Locate in the Finder and when you run it, it should run fine. Since the dependency dylib is in the Frameworks folder of the bundle and correctly linked. You can see the package contents of the bundle to see if the Frameworks folder contains your dylib file.
To my surprise, the path where a dylib is stored has to be part of the dylib. So when a project links to this dylib it will copy the same path in itself, so when we run the Cocoa app which was linked to that dylib, it will look for it at exactly the same path which it copied from inside the dylib and we are responsible for telling the dylib where it exists. In the form of install_path, etc.
There are tools to manually update the dylib's install path stored in the Cocoa project using that dylib. If update the path of an existing bundle using these tools it should be changed in the client of the dylib, not required in the dylib itself.
If we've the code then we can change it in Xcode as instructed above.
otool -L my.dylib for example can be used to see the dylib install path of an existing binary lib
install_name_tool -change can be used to update the install path of existing binary lib
I have a Cocoa application as XCode project that has several supplementary bits of functionality as dylib targets.
When XCode builds the project, it places all the build outputs in a single folder: The .app bundle and the dylib files. And when executed from the XCode debugger, the .app launches.
I can't however launch the application from finder.
How do I setup XCode to 'deploy' the app in a standalone state? I have found that I can use ld on the actual app binary to contain a relative path to the dylibs: #executable_path/../../mylib.dylib
Running a script after each build seems wrong: there must be some way (that Im totally missing) to do this easily from inside XCode - it must be a common issue surely?
It looks like that XCode supports having #executable_path, #loader_path and #rpath used in the Target Info > Build > Linking > Dynamic Library Install Name setting (LD_DYLIB_INSTALL_NAME) setting.
The help text says: "Sets an internal "install path" (LC_ID_DYLIB) in a dynamic library. Any clients linked against the library will record that path as the way dyld should locate this library"
This seems very promising, but usability is a problem if I need to link dylibs in multiple paths against a common library - the relative path is going to be different each time.
Running my testapp from finder, I get the following (relevant) error text
Dyld Error Message:
Library not loaded: #executable_path/../../util.dylib
Referenced from: /Volumes/data/Code/TestApp/build/Debug/TestApp.app/Contents/MacOS/TestApp
Reason: image not found
util.dylib is in /Volumes/data/Code/TestApp/build/Debug/ so I am confused :/
You should use a Copy Files build phase to copy the dylib to the app's bundle when building the app. You'll want to copy it to Frameworks. You can then set the install path to #executable_path/../Frameworks/mylib.dylib.
I've looked at a few related questions and cannot seem to find a solution for myself.
Basically I'm using the libmp3lame.dylib in my Xcode project. The install process for lame produced the .dylib and placed it in usr/local/lib and to get Xcode to build and run the project I changed the Library Search Paths to include the above folder. This works fine.
Now it's come to producing a release version and I want to include the .dylib in the bundle so that the user doesn't have to put up with an install phase or anything similar. I created a copy files phase of the target and this dumps the .dylib into the Frameworks folder in the contents of the bundle. However, running otool on the binary shows that instead of using the .dylib inside the bundle, the compiler has linked it to the usr/local/lib version (even if I delete that version).
Looking at the other results in the otool output I have other frameworks being linked to inside the bundle, just not the .dylib. Looking at the properties for both these frameworks and the .dylib in Xcode I can't see any differences other than file type.
My searching suggests I need to use rpath or similar, but I've no clue where to apply this in Xcode.
My workaround for this issue was to do the following in terminal (I've used Automator to, well, automate this):
install_name_tool -id #executable_path/../Frameworks/libmp3lame.0.0.0.dylib ~/path/to/lib/in/app/libmp3lame.0.0.0.dylib
install_name_tool -change /usr/local/lib/libmp3lame.0.dylib #executable_path/../Frameworks/libmp3lame.0.0.0.dylib ~/path/to/app/Contents/MacOS/AppName
Basically swapping the path to the library from the one in the usr local lib to the one included in the bundle.
My tip is to look at the build output, how does it actually run ld?
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"