How do I get back c++0x/c++11 support for Mac OS X 10.6 deployment using Xcode 4.6.2 thru 7.1.1
Asked Answered
R

2

12

I heavily use the c++0x/c++11 features in my project, particularly code blocks and shared pointers. When I upgraded my OS to 10.8 Mountain Lion (Edit: From 10.7), I was forced to upgrade Xcode. In upgrading Xcode, I lost the ability to compile my c++ project for deployment on 10.6 systems as I get the following error.

clang: error: invalid deployment target for -stdlib=libc++ (requires Mac OS X 10.7 or later)

It appears that Apple is trying to force people to upgrade by not allowing developers to support Snow Leopard. This makes me angry. Arrrggg!!!

What can I do?

EDIT: After several comments back and forth, it should be made clear that 10.6 does not ship with system libc++ libraries. As a result, simply being able to build a libc++ project for 10.6 deployment is not enough. You would also need to include libc++ binaries with your 10.6 distribution or statically link to them. So lets continue with the premise that I am already doing that.

UPDATE 1: This question was originally intended for use with Xcode 4.5.2 (the latest version at the time the question was asked). I have since upgraded to Xcode 4.6.3 and have updated the question and answer to reflect that.

UPDATE 2: I've since upgraded to Xcode 5.0.2. The technique listed in the selected answer below still works as expected.

UPDATE 3: I've since upgraded to Xcode 5.1. The technique listed in the answer below does not yet work for this version!

UPDATE 4: I've since upgraded to Xcode 6.0.1. The technique listed in the selected answer below appears to be working again.

UPDATE 5: I've since upgraded to Xcode 7.1.1. The technique listed in the selected answer below appears to be working again, with one important caveat. You must disable Bitcoding used for AppThinning since the opensource LLVM version doesn't support it (nor should it). So you will need to switch between the open source and Apple LLVM clang in order to compile for both 10.6 and tvOS/watchOS (since Bitcoding is required for those OSes).

Republic answered 24/1, 2013 at 5:21 Comment(0)
R
12

Apple has decided to only officially support libc++ on 10.7 or higher. So the version of clang/llvm that ships with Xcode checks to see if the deployment target is set for 10.6 when using libc++, and prevents you from compiling. However, this flag is not included in the open source version of clang/llvm.

Take a look at this thread: http://permalink.gmane.org/gmane.comp.compilers.clang.devel/17557

So, to compile a project that is using c++11 for 10.6 deployment, you need to give Xcode the open source version. Here is one way of doing it:

  1. Download the open source version of clang from here (use LLVM 3.1 for Xcode 4.5.x; use LLVM 3.2 for Xcode 4.6.x; use LLVM 3.3 for Xcode 5.0.x; use LLVM 3.5.0 for XCode 6.0.1; use LLVM 3.7.0 for XCode 7.1.1): http://llvm.org/releases/download.html
  2. Make a backup of Xcode's default clang compiler and put it in a safe place (In case you screw up!) This is located at: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang
  3. Replace the default clang compiler with the one you downloaded from [1]
  4. chown the clang binary for root:wheel with sudo chown root:wheel clang from the bin directory listed in [2].
  5. Startup Xcode and compile!

UPDATE #1: This technique does not currently work for Xcode 5.1 or newer, which relies on LLVM 3.4. When I get some more time, I will try and find a solution to post here. But if someone comes up with a solution before me, they should post it as an answer.

UPDATE #2: Unfortunately I can't remember if I ever found a solution for Xcode 5.1, however I can confirm that the technique does still work for Xcode 6.0.1. I haven't tested on versions newer than that, but it could still work.

UPDATE #3: This technique appears to still work with XCode 7.1.1 using LLVM 3.7.0. However, the open source LLVM clang does not support Bitcoding. So you will need to switch between the open source compiler and Apple's compiler in order to develop for both 10.6 and tvOS/watchOS (which require Bitcoding).

P.S.: The Mac OS X binaries for LLVM 3.4 and 3.5.0 are listed as "Clang for Darwin 10.9" at www.llvm.org/releases/download.html rather than as "Clang Binaries for Mac OS X" in previous versions.

Republic answered 24/1, 2013 at 5:21 Comment(10)
#2,#3 is really ill-formed advice: This is what /usr/local is for, create: /usr/local/src and build llvm/clang/libcxx there; redirect everything to use theseCoppery
@dans3itz: I'm confused on what you mean? I'm not looking to build anything. I just wanted to get Xcode to compile my projects (without changing any project settings) for 10.6 deployment and use Apple's libc++.dylib.Republic
I don't think you can target 10.6 because of ARC / libc++ missing on that platform. There have been a number of compatibility changes. You need to set the SDK to 10.7! and the deployment target to 10.6! -- try it --Coppery
Its working for me. :) My base SDK is actually 10.8 and deployment target is 10.6. I distribute libc++.1.dylib and libc++abi.dylib binaries with my application and link to them directly rather than relying on the presence of libc++ system binaries.Republic
@Coppery assuming I did put clang in /usr/local/bin, how do I make Xcode use it? Setting it as a compiler in "Build Options", I just get an "Invalid compiler" warning.Genuflection
@Republic I followed your instructions, but compilation fails with "Lexical or Preprocessor issue: 'unordered_set' file not found". Setting the Deployment Target to anything other than 10.9 seems to disable C++11 support.Genuflection
@JamieBullock This process does not work with the latest version of XCode (5.1.1). I tried to upgrade but even with my trick I could not get my project to compile. I am currently using version 5.0.2 with the corresponding open source clang compiler (llvm 3.3). I also have to add "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/5.0/include" to the "Header Search Paths" but you may or may not need to do that. When I get some more time, I'll try and figure out the new technique needed for 5.1 support and post it here.Republic
Any updates to this issue? I'd like to support 10.6 in my app. I'm using Xcode 6.3.2 on 10.10.3. Pulled the 10.6 SDK from Xcode 3.2.6 and copied to the Xcode 6 SDKs. I switched on libc++ for Apple LLVM 6.1, and now get the error described in the question here.Saval
I wonder if using Boost libraries instead of STL would work... most of C++11 STL was available in Boost before no?Saval
@Saval I've updated my question and answer. I'm now using Xcode 6.0.1 and the technique is working. Unfortunately I can't say for certain if it will work for 6.3.2. You can certainly give it a try.Republic
B
8

While Xcode 4.5.x is the current default version on OS X 10.8, you can have other, older versions of Xcode, such as Xcode 3.2.6 for OS X 10.6, available on 10.8 as long as you have access to their installers. You will need to ensure you install each one to a unique directory. Also, one thing you can't or shouldn't do is to install the Command Line Tools component or installer package of older Xcodes onto your 10.8 system, i.e. not into /usr or /System/Library. You can use the xcodebuild, xcode-select, and xcrun command line tools to access non-default Xcode components. See their man pages for more info. Older versions of Xcode are available to registered users of developer.apple.com

UPDATE: Based on your subsequent comments, I believe I did miss the point of the question and also that you had answered your own question. I think what you are saying is that you upgraded from 10.7 to 10.8, not from 10.6 to 10.8 as I assumed. You also did not make clear in the original question that you were distributing your own version of Apple's libc++ and friends from 10.7 with your own app. Apple does not make it easy in Xcode to do something like that since it has long been Apple's policy to discourage static linking with libs or distributing duplicate libs (which in some cases could violate license terms). There are good reasons for that policy.

The bottom line is that libc++ is only shipped with OS X 10.7 or later systems. There never was Apple support for libc++ in 10.6, so it's misleading to say it was removed. If you want to supply an app that is deployable on 10.6 and later systems and depends on libc++, the safest approach is to build your own clang/llvm and libc++ targeted for OS X 10.6 and use that to build your project. There are various ways to do that, probably the easiest is to use the MacPorts versions and set the deployment target in MacPorts for 10.6. Or build it all from scratch yourself. But modifying the clang compiler within Xcode 4.5 is a bad idea. And copying Apple libraries to one's app is generally a bad idea.

If you have a solution that works for you, great. But I would not recommend it to others.

Beera answered 24/1, 2013 at 6:10 Comment(5)
What is the advantage of using multiple older versions of Xcode? Older versions of Xcode don't give you access to new SDKs for Mac and iOS. Not to mention this seems like a real headache if your using source control and it complicates the build process.Republic
If there are features that were in the 10.6 SDKs included with Xcode 3.2, you would just build with that SDK. Unless you are using some deprecated API that has been totally removed in 10.8, your project should work on 10.6, 10.7, and 10.8. Another potential solution is to set the deployment target to 10.6 with Xcode 4.5 and/or install a 10.6 SDK but you run the risk of building something that will not work on 10.6. If that's what you need, it's safest to use a 10.6 SDK and toolchain. See, for example, cocoadevblog.avisnocturna.com/2012/09/…Beera
I think you're missing the point of the question. I am using libc++ in my project. You can't set the deployment target to 10.6 with the newest Xcode while using libc++. This feature was removed when Apple decided not to officially support libc++ on 10.6. But in my experience, Apple's official builds of libc++ work just fine on 10.6 so I distribute them with my app. See the comments in my own answer.Republic
Yes, I guess I did miss the point of the question. See updated answer.Beera
Thank you for your comments. Please see updated question. Also, is there perhaps a better way of removing Xcode's limitation without replacing the default compiler and without having to use MacPorts? The main reason I use my solution is because it is simple to do. But if its a bad idea then I'm open to hearing other simple solutions. Why is it a bad idea though?Republic

© 2022 - 2024 — McMap. All rights reserved.