4

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...)

Valkea
  • 1,216
  • 1
  • 12
  • 26
  • GCC 4.6.0? That's not a compiler shipped by Apple. Try it with gcc-4.0.1 or gcc-4.2.1 which are the only 2 versions of GCC included in Xcode. – Grant Limberg Jun 16 '11 at 04:28
  • 1
    I need C++0X, and the compilers supported by Xcode doesn't support C++0x. That's why I compile without Xcode and that's also the reason why I use a gcc version greater than 4.4 – Valkea Jun 16 '11 at 04:49
  • Then unfortunately you're probably out of luck until llvm/Clang supports C++0x. – Grant Limberg Jun 16 '11 at 05:34

2 Answers2

4

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-in libstdc++ does not work. You need to ship the libstdc++.dylib you're using inside your application bundle (you can put it in, eg, your.app/Contents/Libraries). Use install_name_tool to make sure it's referenced using a relative path (use @rpath or @executable_path).

LaC
  • 12,624
  • 5
  • 39
  • 38
  • It seems to work from what I can see with otool -L. Unfortunately I crashed the test MacBook (infinite boot loop) and I will have to save datas and to reinstall it to see if it really works when transferred to a 10.5 OsX. I will come back here as soon as I can really verify it works or not. – Valkea Jun 16 '11 at 17:44
  • That didn't solved the problem, but that helped to understand it further so I accept the answer. Thank you. – Valkea Jun 19 '11 at 01:07
  • @Valkea What did solve the problem? I'm having the same one. – Matt Phillips Dec 20 '12 at 00:01
  • @MattPhillips hi, it was a long time ago. Right now I don't remember exaclty... but as I spent about a month to fix this problem, I took a bunch of notes. And indeed I kept those notes. So I will try to take a look at it before leaving for christmas. – Valkea Dec 20 '12 at 03:00
  • I checked my notes and used `otool -L` on my osx project: It seems like I used `install_name_tool -change /opt/local/lib/gcc46/libstdc++.6.dylib @executable_path/libs/libstdc++.6.dylib FILENAME` on the exe file and the ogre plugins (however I am not sure it is mandatory for the plugins...) and placed the gcc46 libstdc++.6.dylib file in the libs folder next to the executable. – Valkea Dec 20 '12 at 03:43
  • @Valkea That's interesting, I didn't think it was necessary but maybe changing `libgcc_s.1.dylib` will help--I've created [a question](http://stackoverflow.com/questions/13964116/deploy-qt-c11-app-on-mac-os-with-older-libstdc) for my version of this problem, by all means post this and anything else you think of, and I'll accept/+1 it accordingly if it works. – Matt Phillips Dec 20 '12 at 03:45
  • Sorry I edited my answer. My notes indicates I needed to use the `install_name_tool -change` on `libgcc_s.1.dylib` but there is no visual confirmation of that on my last OSX version using `otool -L`. So I guess it was useless finally. However using it on dependencies files was a key point I think. Fortunately, I had to do it once on dependencies and I scripted it for the exe file (with CMake command `add_custom_command` and `POST_BUILD`) so it is modified each time I re-compile it. – Valkea Dec 20 '12 at 03:53
1

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.

Jay Freeman -saurik-
  • 1,759
  • 1
  • 13
  • 13