Summary
I want to run my cross-compiled application against the 10.5 libraries. Is there an environmental variable that allows this to work?
Longer version
I cross-compiled my OS X C++ application for a 10.5 target, on a 10.6 host. It compiles fine. The compiled application is linked against libraries like /usr/lib/libstdc++.6.dylib. When I run it on my system, it will use the 'host' version of libraries, which are 10.6. I'd like to test it against the 10.5 versions, which are all contained in the `/Developer/SDKs/MacOSX10.5.sdk directory. How do I do this?
I tried various flavours of DYLD_LIBRARY_PATH, DYLD_ROOT_PATH, etc, as documented in the manual, but I haven't managed to get it working.
Use install_name_tool to change the path. You may not be able to squeeze in a longer path if the linker didn't add padding, but you can use an rpath instead. For example, I changing the load path for an app on my system to use the 10.5 SDK by doing:
install_name_tool -change /usr/lib/libstdc++.6.dylib #rpath/libstdc++.6.dylib /path/to/executable
install_name_tool -add_rpath /Developer/SDKs/MacOSX10.5.sdk/usr/lib /path/to/executable
and it ran fine after the fact. I wouldn't want to make any assurances, but assuming you compiled against the 10.5 SDK initially, you've got a shot.
If you need to see the paths the executable is using, otool -L will list them.
It is unlikely that this is possible, given that OS X does not have a stable kernel ABI. Instead, the stable ABI is the one provided by the system libraries. Therefore, using system libraries of a different version than the kernel may break. (I do not know to what degree it breaks.)
See http://developer.apple.com/library/mac/#qa/qa2001/qa1118.html
Try this:
Open your project in Xcode.
Under Executables in the Groups & Files column, right-click on your application's executable and select Get Info
Select the Arguments tab
In the bottom half of the window, under "Variables to be set in the environment:", click the + button.
In the row that shows up in the table, enter DYLD_LIBRARY_PATH under Name, and enter the path (e.g. /Developer/SDKs/MacOSX10.5.sdk/usr/lib) under Value.
Now you've got your link path environment variable set up. This environment variable will be set for you when you run that executable from within Xcode. To test your app, just go to the Run menu and select "Run". If you run the app by double-clicking it directly in the Finder, you won't get this environment variable set for you. The setting only takes effect when you run from Xcode.
Here's Apple's documentation on this process:
http://developer.apple.com/library/mac/#documentation/DeveloperTools/Conceptual/XcodeProjectManagement/230-Defining_Executable_Environments/executable_environments.html
Related
I've got C++ application which is using Qt, I'm building it with cmake and linking using following:
target_link_libraries(myApp Qt5::Widgets Qt5::OpenGL ...)
it works fine but when I'm trying to distribute it it's failing because of missing qt libraries.
I was trying to get libraries from my local qt installation Qt/5.4/clang_64/lib/QtCore.Framework/Versions/5/QtCore and other with similar paths and put them near myApp but it doesn't help. It's still trying to get those libraries from local qt installation and if I rename folder of local qt installation it fails.
How to distribute my applications which is using qt libraries on OSX/Mac?
Qt 5.5 comes with a helper tool called macdeployqt. You can run it from the command line, it will produce a valid .app (or even a .dmg containing the app if you ask for it). It's fairly straightforward to use, there are only a few options (like creating a dmg output, using debug libraries...) if you depend only on Qt.
If you have more dependancies that are dynamically linked, then you'll probably need to embed them as well in the application bundle (the .app folder).
From the QT site:
But when you are deploying the application, your users may not have the Qt frameworks installed in the specified location. For that reason, you must either provide the frameworks in an agreed upon location, or store the frameworks in the bundle itself. Regardless of which solution you choose, you must make sure that the frameworks return the proper identification name for themselves, and that the application will look for these names. Luckily we can control this with the install_name_tool command-line tool.
The install_name_tool works in two modes, -id and -change. The -id mode is for libraries and frameworks, and allows us to specify a new identification name. We use the -change mode to change the paths in the application.
Let's test this out by copying the Qt frameworks into the Plug & Paint bundle. Looking at otool's output for the bundle, we can see that we must copy both the QtCore and QtGui frameworks into the bundle. We will assume that we are in the directory where we built the bundle.
mkdir plugandpaint.app/Contents/Frameworks cp -R
/path/to/Qt/lib/QtCore.framework
plugandpaint.app/Contents/Frameworks cp -R /path/to/Qt/lib/QtGui.framework
plugandpaint.app/Contents/Frameworks
First we create a Frameworks directory inside the bundle. This follows the Mac OS X application convention. We then copy the frameworks into the new directory. Since frameworks contain symbolic links, and we want to preserve them, we use the -R option.
install_name_tool -id
#executable_path/../Frameworks/QtCore.framework/Versions/4.0/QtCore
plugandpaint.app/Contents/Frameworks/QtCore.framework/Versions/4.0/QtCore
install_name_tool -id
#executable_path/../Frameworks/QtGui.framework/Versions/4.0/QtGui
plugandpaint.app/Contents/Frameworks/QtGui.framework/Versions/4.0/QtGui
Then we run install_name_tool to set the identification names for the frameworks. The first argument after -id is the new name, and the second argument is the framework which identification we wish to change. The text #executable_path is a special dyld variable telling dyld to start looking where the executable is located. The new names specifies that these frameworks will be located "one directory up and over" in the Frameworks directory.
install_name_tool -change
path/to/Qt/lib/QtCore.framework/Versions/4.0/QtCore
#executable_path/../Frameworks/QtCore.framework/Versions/4.0/QtCore
plugandpaint.app/Contents/MacOs/plugandpaint install_name_tool -change path/to/qt/lib/QtGui.framework/Versions/4.0/QtGui
#executable_path/../Frameworks/QtGui.framework/Versions/4.0/QtGui
plugandpaint.app/Contents/MacOs/plugandpaint
Now, the dynamic linker knows where to look for QtCore and QtGui. Then we must make the application aware of the library locations as well using install_name_tool's -change mode. This basically comes down to string replacement, to match the identification names that we set for the frameworks.
Finally, since the QtGui framework depends on QtCore, we must remember to change the reference for QtGui:
install_name_tool -change
path/to/Qt/lib/QtCore.framework/Versions/4.0/QtCore
#executable_path/../Frameworks/QtCore.framework/Versions/4.0/QtCore
plugandpaint.app/Contents/Frameworks/QtGui.framework/Versions/4.0/QtGui
After all this we can run otool again and see that the application
will look in the right locations.
Just recently I installed Ubuntu and with it: Eclipse Version: Luna Service Release 2 (4.4.2) Build id: 20150219-0600. I've installed the MinGW GCC compiler via the command line option Ubuntu provides for my 64-bit system.
sudo apt-get install mingw-w64
When I made my project, Eclipse started to whine. It kept saying Toolchain "MinGW GCC" is not detected. It, however, does still find errors in my code. No errors are produced about it not being able to find the path of g++ or gcc, though. So I was searching Google and many sources said I would need to set the PATH variable of my installation. However I cannot find the installation path of MinGW-w64. How can I find what this path should be in Ubuntu 14.04 and set the path variable that needs to be set.
Additioanl information:
-At the end of this path Window->Preferences->C/C++->Build->Settings->Discovery->CDT GCC Built-in Compiler Settings has the command to get compiler specs as ${COMMAND} ${FLAGS} -E -P -v -dD "${INPUTS}"
-At the end of this path Window->Preferences->C/C++->Build->Environment has no Environment variables set at all, including the PATH variable.
-Under the following Project Properties->C/C++ Build both check marks are chosen.
->Build Variables is empty.
->Environment has the value of MINGW_HOME as /usr. The value of MSYS_HOME is blank. The value of PATH is ${MINGW_HOME}/bin:${MSYS_HOME}/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games.
->Tool Chain Editor has the check mark set to display compatible toolchains only, yet it seems to not have any effect on the which toolchain I can select in the following drop down menu. My current toolchain is set to MinGW GCC and my current builder is set to Gnu Make Builder
So again, my question is what gives? Why can't eclipse see the complier that I installed to my copy of Ubuntu? And how can I not only set my PATH variable, but I also must need to know what to set it to because I don't know where the terminal installed the /bin directory of mingw-w64?
First you need to understand mingw is a win32 port of the original GNU compiler. So, if you're already in Linux, you preferably will use this latter.
Now, you need to figure out if your system's shell recognizes it, so try tab autocompletion in the shell, wether its mingw or gcc, open up a terminal and type min and then hit Tab.
In case Tab autocompletion worked and you want to know where the command is located, you can use whereis [comand] and shell will return the path from where its running.
If nothing happens, then it's not in your PATH.
PATH is defined primarily in three configuration files: local PATH is in ~/.bashrc and ~/.bash_profile, and system PATH is defined in /etc/environment and /etc/profile but normally you wouldn't need to mess up with there two.
To find or locate anything in your system you can use find.
Normally, in every linux system, all binaries you install end up in /usr/bin,
/bin,
/usr/local/bin
or sometimes in /opt but that one is reserved in case its a third party vendor.
At this point you can do a search like find /usr/bin -name mingw taking the first argument as the path to search within OR you could search directly into your environment variables with env.
If you need to add something to the path I recommend you to create a symbolic link of your binary(no matter where its located) in /usr/bin and then, add that link to your local PATH, that is to say, something like this:
ln -S /opt/file.bin /usr/bin/myBin
echo "export PATH=$PATH:/usr/bin/myBin" >> ~/.profile
Normally after installing gcc eclipse should automatically detect it, but if not, you can set MINGW_HOME with the same code as above, just omit the symbolic link step and set the variable first as follows:
MINGW_HOME=/Path/found/of/mingw/or/gcc
I hope this explanation will help you, if not, feel free to share your thoughts.
I have a Qt application which links to libqjpeg.dylib. On the development machine, the libraries are in /Applications/Qt/Desktop/Qt/4.8.0/gcc/plugins/imageformats. I placed the libraries in the Program.App/Contents/Plugins directory on the target machine.
However, when I run it through strace (dtruss on mac) I can see that the application only stats
/Applications/Qt/Desktop/Qt/4.8.0/gcc/plugins/imageformats/libqjpeg.dylib
/Users/USER/lib/libqjpeg.dylib
/usr/local/lib/libqjpeg.dylib
/usr/lib/libqjpeg.dylib
How can I get it to look for the plugin in the Program.App/Contents/Plugins directory?
First of all, I think it's more standard to put dylibs in Contents/Frameworks rather than Contents/Plugins.
Second, the install path for the dylib is recorded in the dylib itself. You can change that path using the install_name_tool command, like so:
install_name_tool -id #loader_path/../Frameworks/libqjpeg.dylib libqjpeg.dylib
Then link your app against that modified copy of libqjpeg.dylib.
I am trying to use GDB to debug a C++ program, but my system is not recognizing gdb as a command. I installed it, along with many other tools, via MinGW. I have not had any problem with the other features I have used (gcc, g++), so the issue doesn't seem to be with my general set up. I have added the MinGW\bin directory to my PATH. The gdb.exe is in that folder. But it will not run when invoked from my project directory, it simply errors: "'gdb' is not recognized as an internal or external command, operable program, or batch file." Is there some step in setup or invocation that I missed for using GDB?
EDIT: Alright, I think I found the problem: there are two MinGW directories in my PATH, one at C:\MinGW, and another in folder that got installed with some Haskell compilers I used a while ago. It appears to be defaulting to the Haskell folder, perhaps because this directory is listed first. However, this folder contains gcc and g++, but NOT gdb. I was able to get the gdb command working by creating the fstab file in the msys directory, a step I apparently forgot when setting up MinGW. I added my C:\MinGW directory to it, and now the gdb command is working properly! Out of curiosity, what does this file do?
Also, ideally I would like it to look in the C:\MinGW directory first, since this is the folder I plan to keep updated, and the one that contains ALL of the various applications. However, the Haskell directory is specified via the system PATH variable, which I've read it's not a good idea to touch. Would switching the order that they appear even fix my problem?
EDIT 2: Not 100% sure what happened, but the gdb command appears to be working now. I have always been using the Windows cmd prompt to run these tools, so per the answer below (that I should not need to mess with msys) I deleted the fstab file, and lo, it still works! However, my second question above still stands: What is the best way to get the compilers to run out of C:\MinGW\bin instead of C:\Program Files (x86)\Haskell Platform\2013.2.0.0\bin? Is moving the Haskell location out of the system PATH and to the end of the user PATH a viable option?
I had to run pacman -S mingw-w64-x86_64-gdb separately and then gdb showed up in the bin.
You do not have to run gdb (or gcc and all other MinGW tools for that matter) within msys - it is not like Cygwin in that respect. Had you run it from the Windows cmd console, it should work.
The msys shell is useful for running configure scripts generated by Autoconf used by many Linux originated open source projects, but its environment is independent of the Windows environment.
I'm wondering how to "package" a C++ project for release. It uses various libraries, and I don't want a user to have to go through the same setup I did, with putting the right files in the right place and such. I had difficulty researching this, because I'm not sure the technical term for this issue. If I'm using command line compiling on Linux, is there an easy way to do this?
Your approach to this will differ on Windows and Linux because each OS handles this a different way. I'm more familiar with Linux so I'll restrict my answer to just the Linux side of things.
When you link your executable with a library using -l flag the linker defaults to looking in the normal system library directories so there are four approaches here.
Require the user to properly install the libraries themselves. However, it sounds like you don't want to do that.
Have the user add the library location to LD_LIBRARY_PATH variable.
Your third option is force the linker to look in a certain path for the libraries using the -rpath flag. For example, to have the application look in its working directory for a shared library you can compile with: g++ -rpath ./ -l SomeLib -o MyApp myapp.cpp
One other option is to static link your code with their library that way you only have to distribute one executable. If a static library exists you can use g++ -static -l SomeLib -o MyApp myapp.cpp to tell gcc to link statically.
On windows I would recommand wix http://wix.sourceforge.net/ to create the .msi installer
I would like to point out, the lookup path for .dlls I recommand putting all .dll in the same folder as your .exe since this has the highest priority
However, the vc crt (the c/c++ runtime library) should be installed using the redistributional package from microsoft -> updates automatically http://www.microsoft.com/de-de/download/details.aspx?id=5555
Wix can include the redistributional package into the same .msi therefore you have only to deploy a single installer file.
You mean an installer?
On Windows the program that you run to install a new app which outs everything in the correct directory, creates the start menu and lets you un-install it?
There is an installer builder in Visual Studio (might not be in the free express version) which makes .msi installer files. It's fairly easy to use for simple tasks but becomes complicated to do anything more.
Alternatively, to create traditional setup.exe type installs I use the excellent free Innosetup
On linux you would generally create a package using whatever format your distribution uses (.deb / .rpm ). There are lots of instructions on the specifics of each one and the tools to do so will probably already be installed in your Linux system