I'm trying to port a C++ project using C++0x and Ogre on Max OS-X and I encounter a portability problem between OS-X versions.
I succeeded in compiling my project on Mac OS-X 10.6 (Snow Leopard) using GCC 4.6.0 (because I needed C++0x). It was hard (probably because I a new OSX user) but it finally compiled it without error.
I included all the required Components, Frameworks, Plugins etc. needed into the Application.app bundle and it does start fine on this Mac OS-X 10.6
But when I transfer the project on my old laptop installed with Mac OS-X 10.5.8 I'm unable to run the application.
If I double click the .app it try to start and finally the Icon disappear from the menu bar and that's all. But if I run the executable file included in the .app directly it returns the following errors:
MacBook-2:~ root# /var/root/Desktop/MyProject.app/Contents/MacOS/MyProject ; exit;
dyld: lazy symbol binding failed: Symbol not found: __ZSt16__ostream_insertIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_PKS3_i
Referenced from: /var/root/Desktop/MyProject.app/Contents/MacOS/../Frameworks/Ogre.framework/Versions/1.7.3/Ogre
Expected in: /usr/lib/libstdc++.6.dylib
dyld: Symbol not found: __ZSt16__ostream_insertIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_PKS3_i
Referenced from: /var/root/Desktop/MyProject.app/Contents/MacOS/../Frameworks/Ogre.framework/Versions/1.7.3/Ogre
Expected in: /usr/lib/libstdc++.6.dylib
Trace/BPT trap
logout
Here is the application bundle tree view.
MyProject.app
- Components
- ... (Ogre components)
- Frameworks
- Ogre.framework
- MacOS
- MyProject (executable)
- Plugins
- ... (Ogre plugins)
- Resources
- ... (Ogre .cfg + my assets)
I told Cmake to use the MacOSX10.5.sdk using (set inside the Cmake GUI, not inside the CMakeList.txt):
- CMAKE_OSX_DEPLOYEMENT_TARGET 10.5
- CMAKE_OSX_SYSROOT /Developer/SDKs/MacOSX10.5.sdk
But it doesn't seems to change anything...
The libstdc++.dylib file, links to libstdc++.6.0.9.dylib on the Mac used to compile the application whereas it links to libstdc++.6.0.4.dylib on the Mac used to test portability.
But as I told it to use the MacOSX10.5.sdk I though it would use the libstdc++.6.0.4.dylib at compile time, so it can run on the Mac installed with 10.5
Indeed the goal is to make it runs on the second Mac (and all Mac using 10.5+) without changing anything on it. Just download and run...
Does anybody can tell my what I'm missing here ? (I don't really feel fluent with the OS-X methods and organisation so I could have missed something very basic, don't fear to be crude ^^).
How do I specify the targeted SDK in Cmake ? (Are the used Cmake commands not sufficient ?)
I use the following to compile my project:
- Mac OS-X 10.6.7
- GCC 4.6.0
- Cmake 2.8-4
- Ogre 1.7.3
I use the following to test the project:
- Mac OS-X 10.5.8 (there is some dev tools installed. I think I must tell it, in case it could interfere with the applications).
Edit:
As I discovered otool here is the log returned
Valkeas-Mac:MacOS root# otool -L MyProject
MyProject:
@executable_path/../Frameworks/Ogre.framework/Versions/1.7.3/Ogre (compatibility version 0.0.0, current version 1.7.3)
@executable_path/../Components/libOgreTerrain.dylib (compatibility version 0.0.0, current version 1.7.3)
/System/Library/Frameworks/Carbon.framework/Versions/A/Carbon (compatibility version 2.0.0, current version 136.0.0)
/System/Library/Frameworks/Cocoa.framework/Versions/A/Cocoa (compatibility version 1.0.0, current version 12.0.0)
/System/Library/Frameworks/IOKit.framework/Versions/A/IOKit (compatibility version 1.0.0, current version 275.0.0)
/opt/local/lib/gcc46/libstdc++.6.dylib (compatibility version 7.0.0, current version 7.15.0)
/usr/lib/libgcc_s.1.dylib (compatibility version 1.0.0, current version 1.0.0)
/opt/local/lib/gcc46/libgcc_s.1.dylib (compatibility version 1.0.0, current version 1.0.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 111.1.4)
/usr/lib/libobjc.A.dylib (compatibility version 1.0.0, current version 227.0.0)
/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation (compatibility version 150.0.0, current version 476.19.0)
/System/Library/Frameworks/AppKit.framework/Versions/C/AppKit (compatibility version 45.0.0, current version 949.54.0)
/System/Library/Frameworks/ApplicationServices.framework/Versions/A/ApplicationServices (compatibility version 1.0.0, current version 34.0.0)
/System/Library/Frameworks/Foundation.framework/Versions/C/Foundation (compatibility version 300.0.0, current version 677.26.0)
Valkeas-Mac:MacOS root#
Obviously it links to the gcc46 libstdc++.6.dylib (probably normal as I guess this file contains the C++0x functions of the GCC 4.6.0).
So is there any solution ? (-static returns an error that tell I need dynamic...)
The
libstdc++
you're using is from gcc 4.6. Since you're using C++0x, which is not available in the version of gcc that ships with OS X, it's no surprise that the built-inlibstdc++
does not work. You need to ship thelibstdc++.dylib
you're using inside your application bundle (you can put it in, eg, your.app/Contents/Libraries). Useinstall_name_tool
to make sure it's referenced using a relative path (use@rpath
or@executable_path
).While the selected answer is probably more practical to many, this is actually a bug in Apple's toolchain that is trivially fixed with a very small patch. It is certainly incorrect to blame the issue on using C++0x, or even to blame the issue on using different versions of gcc: this stuff is generally supposed to work. Given how many people seem to experience this issue as users (judging by a Google search) hopefully this can be fixed upstream in Xcode 5.1 (although given the smug reaction I've gotten in the past from Apple with regards to simple five-minute fixes to better support backwards compatibility, I'm not holding my breath; I am going to file a radar regardless, as I consider this kind of thing really important). The fix is to modify the ostream header to add __TARGETING_4_0_DYLIB guards around the operator<< implementation for strings. I have placed a patch on my website at http://test.saurik.com/apple/ostream1.diff.