MantisBT - CMake
View Issue Details
0006195CMakeCMakepublic2007-12-21 12:102009-02-19 11:06
Sean McBride 
David Cole 
normalminoralways
closedfixed 
Mac OS XMac OS X10.5
 
 
0006195: Add a "CMAKE_OSX_DEPLOYMENT_TARGET" to pass -mmin-macosx-version to gcc
On Mac OS X, CMake currently provides CMAKE_OSX_ARCHITECTURES and CMAKE_OSX_SYSROOT. The former to select which architectures to build for, the latter to select the Mac OS SDK to use.

These were both added to support Universal Binaries. However, they are in fact more generally useful. For example, I may want to build as 64 bit only, in which case I would set my architecture to "ppc64". Or I may want to build against the 10.2 SDK to ensure that I don't accidently use new API that were added in newer OSes.

There is a 3rd very important setting: the 'deployment target'. It allows you to specify the oldest version of Mac OS that you wish to support. This influences weak linking.

Think of it all like this: Any function that is supported on your deployment target or earlier are hard linked (and your software won't load on earlier versions of the OS). Any functions that were introduced after your deployment target are weak linked. Any functions introduced after your SDK version are unavailable.

An example: Let's say I set my deployment target to 10.2 and I set the SDK to the 10.3 SDK. I am building on 10.5. If I use an API introduced in 10.4, I will get a compile error because the prototype isn't in the 10.3 SDK. If I use an API introduced in 10.2 or earlier there is no problem. If I use an API introduced in 10.3, it will compile because the prototype is in the 10.3 SDK, but it will be weak linked (since it's not available in 10.2).

Generally, one will always want to explicitly set all 3. Therefore, I propose adding CMAKE_OSX_DEPLOYMENT_TARGET to allow this to be more easily set. Possible values are (currently): 10.1, 10.2, 10.3, 10.4, 10.5. 10.6 will one day be valid also.

All you need to do is pass -mmin-macosx-version to gcc, like so "-mmacosx-version-min=10.5"

If this flag is not passed at all, the deployment target default depends on the OS:
 OS 10.5: defaults to 10.5
 OS 10.4 intel: defaults to 10.4
 OS 10.4 & older PowerPC: defaults to 10.1

"OTHER C FLAGS" is of course a workaround for the lack of CMAKE_OSX_DEPLOYMENT_TARGET.

But this setting is so important, and normally used in conjunction with the sdk and architecture settings which CMake already has.
No tags attached.
related to 0009959closed David Cole new CMAKE_OSX_DEPLOYMENT_TARGET should set smarter if CMAKE_OSX_SYSROOT is defined 
related to 0009125closed David Cole Add support to set GCC Version and Deployment Target for XCode projects 
txt CMake_Patch.txt (2,961) 2008-09-17 22:00
https://public.kitware.com/Bug/file/1723/CMake_Patch.txt
txt Darwin_cmake_Patch.txt (10,496) 2008-09-17 22:00
https://public.kitware.com/Bug/file/1724/Darwin_cmake_Patch.txt
txt Darwin_cmake_Patch-1.txt (7,001) 2008-09-18 15:17
https://public.kitware.com/Bug/file/1726/Darwin_cmake_Patch-1.txt
txt Darwin_cmake_Patch-2.txt (8,532) 2008-09-19 11:04
https://public.kitware.com/Bug/file/1727/Darwin_cmake_Patch-2.txt
txt Source_Patch-2.txt (2,957) 2008-09-19 11:05
https://public.kitware.com/Bug/file/1728/Source_Patch-2.txt
diff Darwin.cmake-3.diff (8,727) 2008-10-07 09:20
https://public.kitware.com/Bug/file/1756/Darwin.cmake-3.diff
Issue History
2007-12-21 12:10Sean McBrideNew Issue
2008-02-15 10:45Bill HoffmanStatusnew => assigned
2008-02-15 10:45Bill HoffmanAssigned To => Bill Hoffman
2008-04-02 10:43Sean McBrideNote Added: 0011030
2008-04-02 10:48Bill HoffmanNote Added: 0011033
2008-08-14 11:32Sean McBrideNote Added: 0013010
2008-08-18 15:16Bill HoffmanNote Added: 0013054
2008-09-17 17:37Mike JacksonNote Added: 0013498
2008-09-17 18:51Mike JacksonNote Added: 0013499
2008-09-17 22:00Mike JacksonFile Added: CMake_Patch.txt
2008-09-17 22:00Mike JacksonFile Added: Darwin_cmake_Patch.txt
2008-09-17 22:03Mike JacksonNote Added: 0013502
2008-09-18 10:02Sean McBrideNote Added: 0013508
2008-09-18 10:50Mike JacksonNote Added: 0013512
2008-09-18 11:08Mike JacksonNote Added: 0013514
2008-09-18 15:17Mike JacksonFile Added: Darwin_cmake_Patch-1.txt
2008-09-18 15:19Mike JacksonNote Added: 0013519
2008-09-18 17:20Sean McBrideNote Added: 0013521
2008-09-19 11:04Mike JacksonFile Added: Darwin_cmake_Patch-2.txt
2008-09-19 11:05Mike JacksonFile Added: Source_Patch-2.txt
2008-09-19 11:06Mike JacksonNote Added: 0013524
2008-09-19 11:50Sean McBrideNote Added: 0013527
2008-10-07 09:19Mike JacksonNote Added: 0013745
2008-10-07 09:20Mike JacksonFile Added: Darwin.cmake-3.diff
2008-10-07 09:36Sean McBrideNote Added: 0013748
2008-10-07 13:05Sean McBrideNote Added: 0013753
2008-10-07 13:14Mike JacksonNote Added: 0013754
2008-10-09 19:38Bill HoffmanAssigned ToBill Hoffman => David Cole
2009-01-27 10:31David ColeNote Added: 0014684
2009-01-27 10:31David ColeStatusassigned => resolved
2009-01-27 10:31David ColeResolutionopen => fixed
2009-01-27 11:51David ColeNote Added: 0014687
2009-01-27 11:51David ColeStatusresolved => feedback
2009-01-27 11:51David ColeResolutionfixed => reopened
2009-01-27 14:44Sean McBrideNote Added: 0014688
2009-01-27 15:53David ColeNote Added: 0014689
2009-01-28 06:11David ColeNote Added: 0014690
2009-01-29 14:58David ColeNote Added: 0014726
2009-02-11 19:54Sean McBrideNote Added: 0014906
2009-02-12 07:07David ColeNote Added: 0014909
2009-02-19 10:27David ColeNote Added: 0015214
2009-02-19 10:27David ColeStatusfeedback => resolved
2009-02-19 10:27David ColeResolutionreopened => fixed
2009-02-19 11:06Sean McBrideNote Added: 0015220
2009-02-19 11:06Sean McBrideStatusresolved => closed
2009-11-24 08:02Brad KingRelationship addedrelated to 0009959
2010-02-12 16:21David ColeRelationship addedrelated to 0009125

Notes
(0011030)
Sean McBride   
2008-04-02 10:43   
Any chance of this getting into 2.6?
(0011033)
Bill Hoffman   
2008-04-02 10:48   
Not real likely without a patch from one of you. :)
(0013010)
Sean McBride   
2008-08-14 11:32   
OK, could you give me some info to get going? Which files would I need to poke around in?
(0013054)
Bill Hoffman   
2008-08-18 15:16   
I would just grep for CMAKE_OSX_ARCHITECTURES and CMAKE_OSX_SYSROOT. I think
cmLocalGenerator.cxx cmGlobalXCodeGenerator.cxx and cmCoreTryCompile.cxx are the files that would be affected.
(0013498)
Mike Jackson   
2008-09-17 17:37   
I was starting to hack on this bug and I am getting a bit confused trying to follow what is going on. Basically I am detecting the current version of OS X that cmake is being run on, then setting CMAKE_OSX_DEPLOYMENT_TARGET to that value but putting CMAKE_OSX_DEPLOYMENT_TARGET into the cache so that the user can change it if needed. That part works. What I can not figure out now is how to make -mmacosx-version-min=${CMAKE_OSX_DEPLOYMENT_TARGET} part of the default compile flags? I also noted that unless you change the CMAKE_OSX_SYSROOT to something else (say the 10.4u while on 10.5) the -isysroot does not get added to the compile line. I was going to try to figure out where that was inserted into the compile flags but grepping for CMAKE_OSX_SYSROOT only shows up in the Darwin.cmake file and no where else.

Someone want to give me a hint?
(0013499)
Mike Jackson   
2008-09-17 18:51   
Ok.. more hacking on the cmLocalGenerator.cxx file to add in CMAKE_OSX_DEPLOYMENT_TARGET functionality. Couple of Questions:

Playing with Xcode the rule is basically the Deployment Target must be an equal or LESSER OS X version than the SDK version.

Allowed: 10.5 SDK with a Deployment target of 10.4 (someone explain that to me.. )
NOT allowed: 10.4u SDK with a Deployment target of 10.5 (which makes no sense either)

Not knowing all the intricacies of all this my vote is for a simple implementation where the SDK version = Deployment version.

We would have to allow for the checking of environment variables also but that should be straight forward.

Also the flag is "-mmacosx-version-min" not what is stated in the subject.. At least on 10.5..
Any thoughts on that?
(0013502)
Mike Jackson   
2008-09-17 22:03   
Added to patch files for CMake cvs HEAD. One is for cmLocalGenerator.cxx cmGlobalXCodeGenerator.cxx

The other is for the Darwin.cmake module. I realize the code style may not quite match but I tested the patch as best I could and believe it to be pretty solid. Any one want to test it some more?

Hopefully this can make it into a CMake Release sooner rather than later.

Mike Jackson
(0013508)
Sean McBride   
2008-09-18 10:02   
Hey Mike! Thanks for looking at this.

Alas "SDK version = Deployment version" is no good at all. :( Perhaps rereading my original bug description will help, but if not I can try to explain further. These settings are commonly misunderstood by many, there are scores of posts on the xcode list about the differences. Maybe Apple's words are better:

http://developer.apple.com/documentation/DeveloperTools/Conceptual/XcodeProjectManagement/070-Building_Products/chapter_8_section_12.html [^]

Your example: "Allowed: 10.5 SDK with a Deployment target of 10.4" makes perfect sense, and is probably the most common real-world usage currently.

-mmacosx-version-min is correct, whoops. Dyslexia cure for found. :)
(0013512)
Mike Jackson   
2008-09-18 10:50   
OK. I took out the sanity check and set my Deployment Target to 10.4 and the SDK to 10.5.sdk and it all actually compiled. I was getting an error yesterday during linking which was like the following:

http://lists.apple.com/archives/Xcode-users/2007/Oct/msg00686.html [^] was what I was originally getting by trying to just set the SDK to 10.4u while running 10.5.x.


http://lists.apple.com/archives/Xcode-users/2007/Oct/msg00699.html [^] has a good explanation. I don't really understand the weak linking but I am going to assume that if someone is going to start setting environment variables to control this stuff they know what they are doing.

According to your example above, I could use an API from 10.3 and still deploy on 10.2.. What happens if someone runs on the program on 10.2 which hits an API from 10.3? I would assume bad things, at least in C++. Maybe this works better with Cocoa where Obj-C handles missing methods better than C++?

Without the sanity checks in place things still seem to compile ok.

So, If I can set the SDK to 10.5 and the deployment to 10.4 in order to run on 10.4, why do I need the 10.4u SDK again?

Is it that I would get compile errors if I used an API that is NOT is 10.4 and used the 10.4u SDK versus I would get runtime errors if I used the 10.5 SDK?

Sorry for all the questions but I just want to understand so I can get this fixed as I need to make sure all my code still runs on 10.4 and it seems like I need these settings..

Mike
(0013514)
Mike Jackson   
2008-09-18 11:08   
I'll Answer my own question. If I use the 10.4u SDk then I can ONLY deploy on 10.4 NOT 10.5. Huh..

Mike
(0013519)
Mike Jackson   
2008-09-18 15:19   
Attached a reworked patch that sets the SYSROOT and DEPLOYMENT target either through defaults based on the current OS version or through environment variables. I only sanity check to make sure the DEPLOYMENT_TARGET is NOT newer than the SDK being used.

Patch is attached.
(0013521)
Sean McBride   
2008-09-18 17:20   
Mike, I think you are catching on... :)

The SDK selection just chooses which collection of headers to use. The deployment target says "I want my app to work on this OS version and newer".

So if I set the deployment version to 10.2 my app will be able to run on 10.2 and newer. It will not run on 10.1. It will run on 10.2, 10.3, ..., and even 10.7 (since, in general, newer OSs maintain backwards binary compatibility with applications).

If I want my app to run on 10.4, I do _not_ need to use the 10.4 SDK. I could use the 10.2 SDK or the 10.6 SDK. It is the deployment target that's important.

you said "According to your example above, I could use an API from 10.3 and still deploy on 10.2.. What happens if someone runs on the program on 10.2 which hits an API from 10.3? I would assume bad things". That's where weak linking comes in. If I use the 10.3 SDK, 10.3-only function prototypes are in the .h files in the SDK. That means I can use them in my code, and it will compile. At runtime, as you say, those functions do not exist if I'm running on 10.2. So, in your example, for any 10.3-only APIs used, you must check the address of the function. Say:

if (CFCoolNewFunction != NULL)
  CFCoolNewFunction (param);

At runtime, the function's address will be nil on 10.2, but not nil on 10.3. That's weak linking.

See here:
http://developer.apple.com/technotes/tn2002/tn2064.html [^]
(0013524)
Mike Jackson   
2008-09-19 11:06   
Got everything implemented. Added 2 patches (*-2.patch) for files affected. Please review and test on your own projects.
(0013527)
Sean McBride   
2008-09-19 11:50   
Mike,

Cool, you seem to have added non-standard dev tool install location support! Nice.

All the stuff that tries to decide the default SDK and deployment target looks a little fragile to me (not that I have a better implementation). But if all it does is choose a default, that's no big deal, as long as I can always specify the setting I want.

You changed the 'UI help string' (or whatever its called) for CMAKE_OSX_SYSROOT from "isysroot used for universal binary support" to "Maximum supported version to deploy your compiled code". I propose using what Xcode's Research Assistant says, but shorter:

"The name or path of the base SDK being used during the build. The product will be built against the headers and libraries located inside the indicated SDK. This path will be prepended to all search paths, and will be passed through the environment to the compiler and linker."

maybe "SDK path to built against; uses headers/libraries located inside SDK."

And for deployment target:

"Code will load on this and later versions of Mac OS X. Framework APIs that are unavailable in earlier versions will be weak-linked; your code should check for null function pointers or specific system versions before calling newer APIs."

maybe "Minimum OS X version to target for deployment (at runtime); newer APIs weak linked."

I'll have time to actually _try_ this next week...
(0013745)
Mike Jackson   
2008-10-07 09:19   
OK. Corrected the Help strings to what you suggested.

As far as finding the SDK I created a test cmake file to set a "fake" SDK root and deployment target to known good values, and wild future values (like 10.9 with an SDK of 10.23) and also set the Developer installation to /Something/Stupid/With/Developer/in/The/Name/Developer/SDKs/MacOSX10.3.9.sdk and it seemed to pick everything up ok. I also experimented with various environment variables to make sure those worked.

I will agree that my assumption that Apple standardizes on "MacOSX10.6.sdk" may or may not work. I have no idea unless someone with a developer build of 10.6 Snow Leopard gives me a nod one way or the other.

I could learn some more RegEx and do the old style listing of the SDKs folder and try and parse out the SDK from there but not sure that is any better. It is my opinion that this is no worse than anything that we have already had. At least the 10.3, 10.4 and 10.5 SDKs are a known string and wont change.

Lastly, yes. you can change the SDK and Deployment target in ccmake just like you can change any other variable. I just make the assumption that Apple makes which is you are building and deploying on the system you are compiling for.

Patch attached. Darwin.cmake-3.diff

Mike
(0013748)
Sean McBride   
2008-10-07 09:36   
Mike, all sounds very good. I'll test your patch locally.
(0013753)
Sean McBride   
2008-10-07 13:05   
starting from CVS, which attachments should be used at this point?
(0013754)
Mike Jackson   
2008-10-07 13:14   
Source_Patch-2.txt
Darwin.cmake-3.diff
(0014684)
David Cole   
2009-01-27 10:31   
Fixed in CVS HEAD.

$ cvs commit -m "BUG: Fix issue 0006195. Add CMAKE_OSX_DEPLOYMENT_TARGET cache variable to specify the target deployment runtime OS version of the built executables on Mac OSX. Thanks to Mike Jackson for the patch."

/cvsroot/CMake/CMake/Modules/Platform/Darwin.cmake,v <-- Modules/Platform/Darwin.cmake
new revision: 1.51; previous revision: 1.50
/cvsroot/CMake/CMake/Source/cmGlobalXCodeGenerator.cxx,v <-- Source/cmGlobalXCodeGenerator.cxx
new revision: 1.205; previous revision: 1.204
/cvsroot/CMake/CMake/Source/cmLocalGenerator.cxx,v <-- Source/cmLocalGenerator.cxx
new revision: 1.289; previous revision: 1.288
(0014687)
David Cole   
2009-01-27 11:51   
Also need this to get tests passing on midworld Continuous (Mac OSX 10.3):

$ cvs commit -m "BUG: Only set CMAKE_OSX_DEPLOYMENT_TARGET on Mac OSX 10.4 or later. The gcc that runs on 10.3 and earlier does not understand the compiler flag it maps to..."

/cvsroot/CMake/CMake/Modules/Platform/Darwin.cmake,v <-- Modules/Platform/Darwin.cmake
new revision: 1.52; previous revision: 1.51
(0014688)
Sean McBride   
2009-01-27 14:44   
David, I'm a bit swamped right now, so I didn't look at your changes, but maybe better than checking for 10.4 would be checking the version of gcc. I wonder if icc, for example, accepts the -mmacosx-version-min flag.
(0014689)
David Cole   
2009-01-27 15:53   
Sean, I agree with your note, but cannot do the compiler-based test today. (No try_compile allowed in Modules/Platform/Darwin.cmake...) If I can figure out a good way to do the compiler-based test, then I will. I'll keep this issue open while pondering it.


Next dashboard fix:

$ cvs commit -m "BUG: Try to fix the universal binary continuous dashboard on dashmacmini2. I am deducing that the value of CMAKE_OSX_ARCHITECTURES_DEFAULT is responsible for the failure, although I cannot reproduce it on other builds or even by running the test via ctest interactively *on* the continuous dashboard's build..."

/cvsroot/CMake/CMake/Modules/Platform/Darwin.cmake,v <-- Modules/Platform/Darwin.cmake
new revision: 1.53; previous revision: 1.52
(0014690)
David Cole   
2009-01-28 06:11   
And there was a nasty typo in the last revision...

$ cvs commit -m "BUG: Fix careless typo that only caused test failures on clean builds..."

/cvsroot/CMake/CMake/Modules/Platform/Darwin.cmake,v <-- Modules/Platform/Darwin.cmake
new revision: 1.54; previous revision: 1.53
(0014726)
David Cole   
2009-01-29 14:58   
And maybe this will actually fix the Continuous dashboard on dashmacmini2:

$ cvs commit -m "BUG: Remove unnecessary double quotes from SET statements. Hopefully resolves the strange and difficult to diagnose (or reproduce) test failures on the dashmacmini2 Continuous dashboard." Modules/Platform/Darwin.cmake

/cvsroot/CMake/CMake/Modules/Platform/Darwin.cmake,v <-- Modules/Platform/Darwin.cmake
new revision: 1.56; previous revision: 1.55
(0014906)
Sean McBride   
2009-02-11 19:54   
So I've finally had time to try this... I'm using 2.6.3 rc13... I'm trying to build VTK with CMAKE_OSX_DEPLOYMENT_TARGET. Should I see CMAKE_OSX_DEPLOYMENT_TARGET when I'm running ccmake? I see CMAKE_OSX_ARCHITECTURES and CMAKE_OSX_SYSROOT, but not CMAKE_OSX_DEPLOYMENT_TARGET, even if I "[t]oggle advanced mode". This seems odd.
(0014909)
David Cole   
2009-02-12 07:07   
Sorry, Sean..... These changes have not been merged into the CMake-2-6 branch. You'll have to use CVS CMake to get this functionality.
(0015214)
David Cole   
2009-02-19 10:27   
This is fixed in CVS HEAD of CMake. It will *not* be merged to the CMake-2-6 branch. It will definitely make it into CMake-2-8 when that branch is created in the future...
(0015220)
Sean McBride   
2009-02-19 11:06   
I tried this with CVS HEAD and it seems to work great! Thanks David for all your work on this issue.