What's the best way to set MACOSX_DEPLOYMENT_TARGET? - macos

The Perl community has relied on MACOSX_DEPLOYMENT_TARGET=10.3 for all builds of Perl for, well, a long time. But now, with the El Capitan beta, it no longer works. It seems as though they should bump it up, but to what? Is there a way to programmatically set it to whatever is the earliest version supported by the release of OS X on which Perl is currently being built? Or is there some other way to set it dynamically? Or must it be static and updated periodically? If the latter, how does it affect builds on older versions of OS X?

This should be a fairly simple change in hints/darwin.sh, that checks what OSX version is running and sets MACOSX_DEPLOYMENT_TARGET accordingly.
Perl is an Open Source project, and as such always short on developer time. If you were to make a patch for this and submit it to p5p, I'm sure it would be greatly appreciated.

Accepted #Calle-Dybedahl's answer, as it's technically correct. Perl 5 Core Hacker Jarkko Hietaniemi pushed this solution, which proved to be a bit more complicated than you might expect at a glance. The basic recipe he came down on was:
For OS X 10.6 or above, do not any more use the MACOSX_DEPLOYMENT_TARGET,
the toolchains should work fine without. Until now the deployment target
was hardwired to 10.3. This logic comes from
RT#117433.
For OS X releases from 10.3 until 10.5, no change, still using
the MACOSX_DEPLOYMENT_TARGET=10.3 for linking.
For OS X releases before 10.3, no change, still not using
the MACOSX_DEPLOYMENT_TARGET=10.3.
New: always add -mmacosx-version-min to ccflags and ldflags from
the env var $MACOSX_DEPLOYMENT_TARGET, if set. If the var is not set,
set the min from the OS X version, from sw_vers(1). Setting the var
should become handy for people building and packaging Perl for earlier
OS X versions.

Related

What is the difference between MACOSX_DEPLOYMENT_TARGET and -mmacosx-version-min?

I often need to target Mac OS X versions that are older than the one I'm currently running. As I prefer to work with a bash shell and Makefiles, I do not use Xcode. Apple explicitly supports targeting older OS X versions, but I've always been confused by the redundancy of the two configuration steps that are usually taken to target older platforms:
gcc is started using --macosx-version-min:
gcc --mmacosx-version-min=10.6 ....
The MACOSX_DEPLOYMENT_TARGET environment variable is set to the desired platform, e.g.
export MACOSX_DEPLOYMENT_TARGET=10.6
When trying to figure out the actual difference between the two by searching, you'll come up with different answers. Some people say that they do exactly the same, so it's only necessary to use one of the two. However, there are also voices which say that it's necessary to do both: start gcc with --macosx-version-min and set the environment variable.
Are these two things exactly the same? Is it only necessary to use one of the two but not both? Is there some official documentation available somewhere? Apple mentions MACOSX_DEPLOYMENT_TARGET but doesn't mention --macosx-version-min at all, even though it seems to be much more common.
The man pages of gcc on Mac OS X say that they're synonymous:
-mmacosx-version-min=version
The earliest version of MacOS X that this executable will run on is
version. Typical values of version include 10.1, 10.2, and 10.3.9.
This value can also be set with the MACOSX_DEPLOYMENT_TARGET environment
variable. If both the command-line option is specified and the
environment variable is set, the command-line option will take precedence.
Keep in mind, that apple changed default compiler to clang. Currently clang tries to translate gcc flags to his own. But it doesn't cover 100%. So it might happen that -mmacosx-version-min will stop working one day.

confusion of how to make osx app backward compatible & how to test them

after reading the apple SDK guide
https://developer.apple.com/library/mac/#documentation/developertools/conceptual/cross_development/Overview/overview.html
I'm still confused of how to make the mac app backward compatible & how to test them properly
I have an app, I run it and tested it on Mountain Lion 10.8 without any problem, however I want to make this app backward compatible so that other users can run it on a mac 10.6 - 10.7 machine.
I have an apple developer id and I can download the old versions of 10.7 and 10.6, but the problem is, I have a 2011 macbook air which is currently running 10.8, and that's the only apple machine that I have. Can I test the 10.7 and 10.6 by using vmware or parallels?
in my project settings, I set the target deployment to 10.6 (as I want 10.6 users to run my app), but should I set my SDK to 10.8 or 10.7? if I set the SDK to 10.8 but having the target deployment set to 10.6, if I fix all the xcode warnings will it run successfully on 10.6??
from the SDK drop down, I can only set to 10.8 or 10.7, but 10.6 is missing, how do I fix that?
thanks in advance
I develop on a 10.8 box and support back to 10.5. Just a couple of months ago we dropped 10.4 PPC support, and I'm still cleaning out some of the 10.2-specific code. This may get a little rant-y, but I've been doing old versions for a long time. I have some opinions on the matter.
No matter what Apple says in their docs, if you want to support 10.6, then build with the 10.6 SDK. Do not rely on distribution target.
I have had this discussion with the Xcode engineers, and while they hold to Apple's party line that you should always build with the latest SDK, they also acknowledge that it's generally insane to do so. If you build against the 10.8 SDK and mark your deployment target at 10.6, you will get no warnings for using methods that do not exist on 10.6. The only way you will discover that you've used a nonexistent method is that it might give you strange bugs when run on 10.6. That's insane.
Remember, OS X doesn't crash when you send an unknown selector. It just aborts the current runloop. So the bugs are even harder to track down then on iOS, where it crashes the app.
Sure, you can do weak linking. Talk about dangerous.... Yes, there are a few times this is useful, but the compiler gives you no warning if you don't do it correctly. If I'm going to do weak linking like this, I go the other way, linking against the old SDK and copying the new function's prototype into my implementation. That way I have documentation of every function I think I'm going to weak-link.
Download the old SDKs and symlink them into your Xcode distribution.
Guard them jealously. Apple will try to delete them every time you upgrade Xcode. Make your own copies and stick them in /SDKs or somewhere else away from Xcode. I provide a script called fix-xcode to manage the symlinks automatically. Am I bitter at Apple for their relentless insistance on deleting my old SDKs? Yes, I am.
You can run 10.6 Server in a VM legally. You can run 10.7+ Desktop in a VM legally. These are good ways to test your code.
Or you can do what I do and have a small pile of old MacBooks each with two or three partitions on them that you reboot all the time.
Now that 10.7 comes from App Store, it's a little harder to make VMs. My strong recommendation is to snapshot your image immediately after install, and make a clean backup copy of it. You'll want to be able to clone that image from time to time when you need to get back to a "raw" machine.
Get in the habit of squirreling away SDKs as they come out. 10.8 will be old some day. You might as well make a copy now while it's easy.
Whether you support individual dot-releases or not, it can be very helpful to keep around the upgrade packages for individual dot releases. When you encounter customers running non-current releases, it's nice to be able to check whether an "unreproducible" bug in fact is easily reproducible on their specific version. Whether this is worth it or not depends heavily on your product and customers. It was a life-saver for me when 10.4.11 made major changes to WebKit during a dot release...
Invest in a small NAS or a big external USB drive (though I've had trouble with those failing when used extensively, so I prefer a RAID). You'll need the space. You want to hold onto lots of VMs and lots of SDKs and sometimes even old versions of Xcode.
Adding to Rob Napier's great in-depth answer:
To use an old SDK, put the SDK (or a symlink) to it here:
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs
With XCode 7.3 or later, you need you to open this file and change "MinimumSDKVersion" (otherwise XCode will refuse to use the old SDK):
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Info.plist
You can install multiple versions of Mac OS on a single machine, booting between each.
The SDK should be the latest (10.8).
See 2.
One alternative to 1 that I've considered (I am in the same boat) is to create a Snow Leopard Hackintosh using an old PC and just installing Lion and Mountain Lion on my MBP.
You need to do these settings :
1.Set the Base SDK to Current version of Mac (ex. 10.7)
2.Set the Deployment SDK to older version (ex.1.4)

I have an app I made for Lion but I want it to run on Mac OS versions as low as 10.4

I created an application for the latest version of Mac OS X (Lion). My application uses ARC. I would however like it to be able to run on earlier versions of OS X.
My xcode says the earliest deployment target I can go is 10.4
By setting it to 10.4 does that mean I have done all that is required for my application to run on earlier versions of the OS up to 10.4?
Any help would be awesome thanks
There are a ton of API differences between 10.4 and Lion. Without seeing your app I cannot say for sure, but I would expect that it would not work correctly on 10.4 without some major changes. My suggestion is to forget about 10.4. I would be surprised if even 1% of OS X users are still running it. Stick with 10.6+ and you should be fine.
Whatever you do, only support versions that you have the ability to test on. If you don't have the capability to test on 10.6 you might even consider just supporting 10.7. If you cannot test on all of your deployment targets then you are setting yourself up for some pain.
ARC isn't supported for OS X 10.4 or 10.5. ARC is supported on 10.6, but has some problems that are not present on 10.7 (see question on this site). This isn't a show-stopper, but you should be aware of it if you use weak references.
According to Chitika (source), based on web traffic as of November 2011, 94% of Mac users were using 10.5 or newer and 72% were using 10.6 or newer. Those who haven't upgraded to 10.6 are less likely to be paying customers.
In my experience, developing a Mac application against an older SDK generally works without a hitch, but if you don't have access to an older system then you should warn your users that your application is untested on older systems. This is an unfortunate reality for independent developers. For example,
This application has been tested and runs on OS X 10.7. It may also run on OS X 10.6 but it has not been tested. OS X 10.5 and earlier are not supported.
To put it in perspective, OS X 10.4 was released in 2005. The last security update for it was 2009.
I've been developing for the Mac for the last 10 years, and my rule of thumb is it's usually OK to target the current OS version and only the previous one. Maybe even just the current version, if there's a compelling reason (new API) or the public knows a new OS version is coming out soon.
Example: in Spring 2012 everyone knows that OS X 10.8 will be released in the Summer, so new products I'd develop just on 10.7 with an eye towards 10.8.
There are a few markets where you'd want to do anything different (education being one), but these are few, far between, and usually only apply to long standing products.

How to avoid XCode framework weak-linking problems?

I'm building an application that takes advantage of Mac OS X 10.6-only technologies, but without giving up backwards compatibility to 10.5 Leopard.
The way I do this is by setting the 10.6 SDK as the base SDK, weak-linking all frameworks and setting the deployment target to 10.5 as described in:
http://developer.apple.com/mac/library/DOCUMENTATION/MacOSX/Conceptual/BPFrameworks/Concepts/WeakLinking.html
This works fine; before making a call that is Snow Leopard-only I need to check that the selector or indeed the class actually exist. Or I can just check the OS version before making the call.
The problem is that this is incredibly fragile. If I make a single call that is 10.6 only I blow Leopard-compatibility. So using even the normal code code completion feature can be dangerous.
My question: is there any way of checking which calls are not defined on 10.5 before doing a release build? Some kind of static analysis, or even just a trick (a target set the other SDK?) would do.
I obviously should test on a Leopard machine before releasing anything, but even so I can't possibly go through all paths of the program before every release.
Any advice would be appreciated.
Best regards,
Frank
You could change the target SDK to 10.5. The compiler will then output warning: definition for '-snowLeopardOnlyMethod:' not found messages.

Python 3.1.1 on Mac OS X 10.6 Snow Leopard

I've spent some time today playing with getting the source for python 3.1.1 to build on my MacBook Pro using the --enable-framework and --enable-universalsdk options with no success. I will humbly admit that I have no real clue why I can't compile 3.1.1 on Snow Leopard, I did make sure to get the new Xcode version for Snow Leopard, and made sure I also installed the 10.4u SDK. It seems to be choking on the 10.4 SDK during the make stage, and has several error regarding headers for wchar, cursor, and ncursor during the configure stage. I have been able to get a make from a plain configure, and most the test pass, but that just isn't challenging enough. Has anyone else attempted to build python 3.1.1 on a Mac running Snow Leopard
There is an automated installer here: http://python.org/ftp/python/3.1.1/python-3.1.1.dmg
You need to set MACOSX_DEPLOYMENT_TARGET if you actually want to use an older SDK.
If you target 10.6, it may be that PPC building is not supported anymore, according to this bug report. In fact, that may be the case even if you target 10.4, using XCode 3.2 (haven't tried myself).
I don't have 10.6 installed yet so I can't say for sure it will work without issue but, in general, if you want to build a batteries-included framework build optimized for 10.6 of Python on OS X, you're best off using the installer build script in the source tree at Mac/BuildScript/build-installer.py after applying the patch in the bug report Martin referred to. Something like this should work [untested]:
./build-installer.py --sdk-path=/Developer/SDKs/MacOSX10.6.sdk --universal-archs=intel --dep-target=10.6 --src-dir=... --build-dir=...
That will build everything including dependent third-party libraries and the documentation but, be forewarned, you'll probably have to tweak things until you get it right and a few things aren't supported yet in 64-bit, most notably, tkinter. As mentioned above, the standard python.org 3.1.1 installer should likely work OK as long as you don't need 64-bit support.
[EDIT: I should clarify that, WRT 64-bit support, the problem isn't in tkinter, rather that the Apple-supplied versions of Tk in 10.5 and earlier were 32-bit only and so there was code in setup.py to prevent attempting to build a 64-bit version of tkinter on OSX. Perhaps that check can be removed now if the 10.6 Tk is 64-bit.]
Kenneth Reitz's soluton doesn't work for me. In fact, the install works fine but my default PATH still points to /usr/bin/python (v2.6.1.). I vaguely recall that we should be modifying our ~/.profile to point to /.../Frameworks and I expected the installer to do this for me (nope).
Anyway, /Library/Frameworks/Python.framework/Versions/3.1/bin exists so we could add it.
But I'm curious why the python bin in there does a crash and burn on me.
No time to resolve this now. Bye.

Resources