MantisBT - CMake
View Issue Details
0014324CMakeCMakepublic2013-07-30 19:232014-06-02 08:38
John Ralls 
Brad King 
normalblockhave not tried
closedfixed 
MacOS X10.8.4
CMake 2.8.11.2 
CMake 2.8.12CMake 2.8.12 
0014324: bootstrap fails when CMAKE_OSX_DEPLOYMENT_TARGET is set and CFLAGS has -isysroot
When bootstrapping cmake with pre-XCode-4.3 compilers (in this case Xcode-3.2.2), CMAKE_OSX_SYSROOT isn't set, resulting in this error:
CMake Error at Modules/Platform/Darwin.cmake:196 (message):
  CMAKE_OSX_DEPLOYMENT_TARGET is '10.5' but CMAKE_OSX_SYSROOT:

   ""

  is not set to a MacOSX SDK with a recognized version. Either set
  CMAKE_OSX_SYSROOT to a valid SDK or set CMAKE_OSX_DEPLOYMENT_TARGET to
  empty.
With a pre-Xcode-4.3 Xcode installed and configured with xcode-select, run bootstrap.

Set $SDKROOT to the path for the appropriate SDK in the environment and try again. Both attempts fail.
There are in fact two problems: The first is at Darwin.cmake line 123:
    foreach(d Platforms/MacOSX.platform/Developer/SDKs SDKs)
The path 'Platforms/MacOSX.platform/Developer/SDKs' applies only to Xcode-4.3 and later, those where Xcode is a self-contained application bundle. Earlier versions of Xcode, those distributed as a .mpkg, installed to $DEVELOPER_DIR/SDKs, where $DEVELOPER_DIR defaults to /Developer.

The second problem is that set(foo bar CACHE baz "waldo") seems to not work with the gcc-4.2.1 provided with Xcode before version 4. This can be observed by instrumenting Darwin.cmake as follows:
diff --git a/Modules/Platform/Darwin.cmake b/Modules/Platform/Darwin.cmake
index f0652b9..3ccff88 100644
--- a/Modules/Platform/Darwin.cmake
+++ b/Modules/Platform/Darwin.cmake
@@ -150,8 +150,12 @@ foreach(v CMAKE_OSX_SYSROOT _CMAKE_OSX_SYSROOT_DEFAULT)
     break()
   endif()
 endforeach()
+message(STATUS "CMAKE_OSX_SYSROOT: ${CMAKE_OSX_SYSROOT}")
+message(STATUS "_CMAKE_OSX_SYSROOT_DEFAULT: ${_CMAKE_OSX_SYSROOT_DEFAULT}")
 set(CMAKE_OSX_SYSROOT "${_CMAKE_OSX_SYSROOT_DEFAULT}" CACHE ${_CMAKE_OSX_SYSROOT_TYPE}
   "The product will be built against the headers and libraries located inside the indicated SDK.")
+message(STATUS "CMAKE_OSX_SYSROOT: ${CMAKE_OSX_SYSROOT}")
+message(STATUS "_CMAKE_OSX_SYSROOT_DEFAULT: ${_CMAKE_OSX_SYSROOT_DEFAULT}")

 # Transform the cached value to something we can use.
 set(_CMAKE_OSX_SYSROOT_ORIG "${CMAKE_OSX_SYSROOT}")

Which produces this output with Xcode-3.2.2:
-- CMAKE_OSX_SYSROOT:
-- _CMAKE_OSX_SYSROOT_DEFAULT: /Volumes/Data/XCode3/SDKs/MacOSX10.5.sdk
-- CMAKE_OSX_SYSROOT:
-- _CMAKE_OSX_SYSROOT_DEFAULT: /Volumes/Data/XCode3/SDKs/MacOSX10.5.sdk

and this with Xcode-4.6.3:
-- CMAKE_OSX_SYSROOT:
-- _CMAKE_OSX_SYSROOT_DEFAULT: /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.8.sdk
-- CMAKE_OSX_SYSROOT: /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.8.sdk
-- _CMAKE_OSX_SYSROOT_DEFAULT: /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.8.sdk
No tags attached.
related to 0014695closed  CMake fails with XCode 4.6 and Qt 4 with CMAKE_OSX_DEPLOYMENT_TARGET 
Issue History
2013-07-30 19:23John RallsNew Issue
2013-07-31 09:32Brad KingNote Added: 0033634
2013-08-01 16:03John RallsNote Added: 0033645
2013-08-01 16:19John RallsNote Added: 0033646
2013-08-01 16:46Brad KingNote Added: 0033647
2013-08-02 13:30John RallsNote Added: 0033649
2013-08-02 13:57Brad KingNote Added: 0033650
2013-08-02 13:59Brad KingNote Added: 0033651
2013-08-02 14:40Brad KingNote Added: 0033652
2013-08-02 14:58John RallsNote Added: 0033653
2013-08-02 15:00John RallsNote Edited: 0033653bug_revision_view_page.php?bugnote_id=33653#r1225
2013-08-02 15:16Brad KingNote Added: 0033654
2013-08-02 15:38John RallsNote Added: 0033655
2013-08-02 15:51Brad KingNote Added: 0033656
2013-08-02 15:52Brad KingSummaryCMAKE_OSX_SYSROOT isn't set with pre-4.3 Xcode => bootstrap fails when CMAKE_OSX_DEPLOYMENT_TARGET is set and CFLAGS has -isysroot
2013-08-02 16:00John RallsNote Added: 0033658
2013-08-02 16:02Brad KingNote Added: 0033659
2013-08-02 16:04Brad KingNote Added: 0033660
2013-08-02 16:04Brad KingAssigned To => Brad King
2013-08-02 16:04Brad KingStatusnew => assigned
2013-08-02 16:04Brad KingTarget Version => CMake 2.8.12
2013-08-02 16:36John RallsNote Added: 0033662
2013-08-05 10:01Brad KingNote Added: 0033667
2013-08-05 10:01Brad KingFixed in Version => CMake 2.8.12
2013-08-05 10:02Brad KingStatusassigned => resolved
2013-08-05 10:02Brad KingResolutionopen => fixed
2014-01-14 09:01Brad KingRelationship addedrelated to 0014695
2014-06-02 08:38Robert MaynardNote Added: 0036075
2014-06-02 08:38Robert MaynardStatusresolved => closed

Notes
(0033634)
Brad King   
2013-07-31 09:32   
CMake is tested regularly with Xcode versions all the way back to 1.5. However, each version tested is hosted on its "natural" version of OS X from around the same time period. I don't think we have any testing of an old Xcode on modern OS X or in a non-standard install location.

For the first problem, we detect the developer root for the current Xcode here:

 http://cmake.org/gitweb?p=cmake.git;a=blob;f=Modules/Platform/Darwin.cmake;hb=v2.8.11.2#l62 [^]

and include a fallback to /Developer. Should that check $ENV{DEVELOPER_DIR} in between? The foreach over the paths to the "SDKs" should find the proper one within whatever developer dir is selected.

For the second problem, do you use an absolutely fresh build tree with no CMakeCache.txt to have an existing value for CMAKE_OSX_SYSROOT? You could run CMake with the "--trace" option to get verbose output about how the variables get set.

In the output you show that _CMAKE_OSX_SYSROOT_DEFAULT is set correctly. Is that only after you set SDKROOT to that path?

Does running CMake with "-DCMAKE_OSX_DEPLOYMENT_TARGET=10.5 -DCMAKE_OSX_SYSROOT=/Volumes/Data/XCode3/SDKs/MacOSX10.5.sdk" work?
(0033645)
John Ralls   
2013-08-01 16:03   
> Should that check $ENV{DEVELOPER_DIR} in between?

That shouldn't be necessary: xcode-select -print-path should return $DEVELOPER_DIR if it's set.

> The foreach over the paths to the "SDKs" should find the proper one within whatever developer dir is selected.

Ah, sorry, I misunderstood that code and didn't test it properly. It does work correctly.

> For the second problem, do you use an absolutely fresh build tree with no CMakeCache.txt to have an existing value for CMAKE_OSX_SYSROOT?

Yes.

> You could run CMake with the "--trace" option to get verbose output about how the variables get set.

That only prints out the line, it doesn't reveal any details of why the "set" command fails.

> In the output you show that _CMAKE_OSX_SYSROOT_DEFAULT is set correctly. Is that only after you set SDKROOT to that path?

Yes. Well, sort of. Without setting SDKROOT I was able to get it to print
-- _CMAKE_OSX_SYSROOT_DEFAULT: /Volumes/Data/XCode3/SDKs/MacOSX10.8.sdk
which of course wouldn't work.

> Does running CMake with "-DCMAKE_OSX_DEPLOYMENT_TARGET=10.5 -DCMAKE_OSX_SYSROOT=/Volumes/Data/XCode3/SDKs/MacOSX10.5.sdk" work?

Yes. But it gets weird here, because running cmake *without* that works too.
If I start with
  rm -rf * && SDKROOT=/Volumes/Data/XCode3/SDKs/MacOSX10.5.sdk $SRCROOT/cmake/bootstrap
it fails as noted in the original report, but if I immediately run
  SDKROOT=/Volumes/Data/XCode3/SDKs/MacOSX10.5.sdk Bootstrap.cmk/cmake $SRCROOT/gnucash-git/CMakeLists.txt
it works:
-- The C compiler identification is GNU 4.2.1
-- The CXX compiler identification is GNU 4.2.1
-- Begin CMAKE_OSX_SYSROOT:
-- Before CMAKE_OSX_SYSROOT:
-- _CMAKE_OSX_SYSROOT_DEFAULT: /Volumes/Data/XCode3/SDKs/MacOSX10.5.sdk
-- After CMAKE_OSX_SYSROOT: /Volumes/Data/XCode3/SDKs/MacOSX10.5.sdk
-- _CMAKE_OSX_SYSROOT_DEFAULT: /Volumes/Data/XCode3/SDKs/MacOSX10.5.sdk
-- Checking whether C compiler has -isysroot
(0033646)
John Ralls   
2013-08-01 16:19   
> -- _CMAKE_OSX_SYSROOT_DEFAULT: /Volumes/Data/XCode3/SDKs/MacOSX10.8.sdk

That's because of line 137:
    set(_CMAKE_OSX_SDKS_VER ${_CURRENT_OSX_VERSION}${_CMAKE_OSX_SDKS_VER_SUFFIX_${_CURRENT_OSX_VERSION}})

You don't really want to do that, because if the project links shared libraries from $SDKROOT/usr/lib, linking at runtime will fail on a version of OSX older than the one on which it was built. Apple's backwards compatibility magic only works on programs whose dependencies are only Frameworks. I doubt that many such projects would bother with CMake, since they're inherently not portable to other operating systems. Of course, many of the libraries in /usr/lib do link Frameworks, so one can't have OSX_DEPLOYMENT_TARGET greater than the SDK version, either, but you already test for that.

My recommendation is to have line 137 be
set(_CMAKE_OSX_SDKS_VER ${CMAKE_OSX_DEPLOYMENT_TARGET}${_CMAKE_OSX_SDKS_VER_SUFFIX_${CMAKE_OSX_DEPLOYMENT_TARGET}})
and to make the test at line 208 for inequality rather than for the deployment target > SDK version.
(0033647)
Brad King   
2013-08-01 16:46   
Re 0014324:0033646: The patch you propose for _CMAKE_OSX_SDKS_VER would be something like:
diff --git a/Modules/Platform/Darwin.cmake b/Modules/Platform/Darwin.cmake
index f0652b9..865cc8e 100644
--- a/Modules/Platform/Darwin.cmake
+++ b/Modules/Platform/Darwin.cmake
@@ -132,7 +132,11 @@ elseif("${CMAKE_GENERATOR}" MATCHES Xcode
     # specially named SDKs.
     set(_CMAKE_OSX_SDKS_VER_SUFFIX_10.4 "u")
     set(_CMAKE_OSX_SDKS_VER_SUFFIX_10.3 ".9")
-    set(_CMAKE_OSX_SDKS_VER ${_CURRENT_OSX_VERSION}${_CMAKE_OSX_SDKS_VER_SUFFIX_${_CURRENT_OSX_VERSION}})

+    if(CMAKE_OSX_DEPLOYMENT_TARGET)
+      set(_CMAKE_OSX_SDKS_VER ${CMAKE_OSX_DEPLOYMENT_TARGET}${_CMAKE_OSX_SDKS_VER_SUFFIX_${CMAKE_OSX_DEPLOYMENT_TARGET}})

+    else()
+      set(_CMAKE_OSX_SDKS_VER ${_CURRENT_OSX_VERSION}${_CMAKE_OSX_SDKS_VER_SUFFIX_${_CURRENT_OSX_VERSION}})

+    endif()
     set(_CMAKE_OSX_SYSROOT_DEFAULT
       "${_CMAKE_OSX_SDKS_DIR}/MacOSX${_CMAKE_OSX_SDKS_VER}.sdk")
   else()


However, the second part about the SDK version versus deployment target could break existing builds. It is a sanity check only. IIRC the contributor that supplied this logic in the first place claimed one could build with a newer SDK if the application does not make use of the newer features in it.
(0033649)
John Ralls   
2013-08-02 13:30   
> Patch
Yes, that's about right.

> However, the second part about the SDK version versus deployment target could break existing builds. It is a sanity check only. IIRC the contributor that supplied this logic in the first place claimed one could build with a newer SDK if the application does not make use of the newer features in it.

OK. The contributor is sort of correct. As long as the dependencies are all Apple Frameworks the linker is capable of linking only the functions that are available for the running OS, so long as the calling code is written in Objective-C and can handle missing functions not doing anything, it all works remarkably well. As I said, I doubt that anyone who's writing that kind of code would use CMake, but perhaps you know otherwise.

The more important issue is how to work around the rather strange failure to set CMAKE_OSX_SYSROOT when bootstrapping with gcc-4.2.1.
(0033650)
Brad King   
2013-08-02 13:57   
The bootstrap cache problem is likely due to this change:

 http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=a1c032b9 [^]

The bootstrap script pre-populates the CMAKE_OSX_SYSROOT cache value as empty when "-isysroot" appears in the CFLAGS or CXXFLAGS used to bootstrap. I expect you have those set or the compilers wouldn't work during bootstrap.
(0033651)
Brad King   
2013-08-02 13:59   
For reference, here is the local patch I used to diagnose the caching behavior of CMAKE_OSX_SYSROOT:
diff --git a/Modules/Platform/Darwin.cmake b/Modules/Platform/Darwin.cmake
index 865cc8e..652ab25 100644
--- a/Modules/Platform/Darwin.cmake
+++ b/Modules/Platform/Darwin.cmake
@@ -154,8 +154,14 @@ foreach(v CMAKE_OSX_SYSROOT _CMAKE_OSX_SYSROOT_DEFAULT)
     break()
   endif()
 endforeach()
+get_property(t CACHE CMAKE_OSX_SYSROOT PROPERTY TYPE)
+get_property(v CACHE CMAKE_OSX_SYSROOT PROPERTY VALUE)
+message(STATUS "before: ct=[${t}] cv=[${v}] v=[${CMAKE_OSX_SYSROOT}] d=[${_CMAKE_OSX_SYSROOT_DEFAULT}]")
 
set(CMAKE_OSX_SYSROOT "${_CMAKE_OSX_SYSROOT_DEFAULT}" CACHE ${_CMAKE_OSX_SYSROOT_TYPE}
   "The product will be built against the headers and libraries located inside the indicated SDK.")

+get_property(t CACHE CMAKE_OSX_SYSROOT PROPERTY TYPE)
+get_property(v CACHE CMAKE_OSX_SYSROOT PROPERTY VALUE)
+message(STATUS "after: ct=[${t}] cv=[${v}] v=[${CMAKE_OSX_SYSROOT}] d=[${_CMAKE_OSX_SYSROOT_DEFAULT}]")
 
 
# Transform the cached value to something we can use.
 set(_CMAKE_OSX_SYSROOT_ORIG "${CMAKE_OSX_SYSROOT}")
(0033652)
Brad King   
2013-08-02 14:40   
I've applied the sdk-matches-deployment-target patch:

 http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=95f78e08 [^]
(0033653)
John Ralls   
2013-08-02 14:58   
(edited on: 2013-08-02 15:00)
> The bootstrap script pre-populates the CMAKE_OSX_SYSROOT cache value as empty
> when "-isysroot" appears in the CFLAGS or CXXFLAGS used to bootstrap.

Yes, that sounds like it might be the problem. If -isysroot is set that rather guarantees that MAC_OSX_DEPLOYMENT_TARGET is also set, so having CMAKE_OSX_SYSROOT rather guarantees that the bootstrap will fail.

Can you make it set CMAKE_OSX_SYSROOT to the value of -isysroot?

(0033654)
Brad King   
2013-08-02 15:16   
Re 0014324:0033653: The problem is that when CMAKE_OSX_SYSROOT is set then CMake adds -isysroot flags. In combination with those from CFLAGS we end up with two copies. If CFLAGS have -isysroot what difference does it make during boostrap that CMAKE_OSX_SYSROOT is not set?
(0033655)
John Ralls   
2013-08-02 15:38   
> what difference does it make during boostrap that CMAKE_OSX_SYSROOT is not set?

Bootstrap fails with the error message in the bug description.

> The problem is that when CMAKE_OSX_SYSROOT is set then CMake adds -isysroot
> flags. In combination with those from CFLAGS we end up with two copies.

That's a non-problem, at least for gcc and llvm. The compiler just uses the last value in the command line.

If it really bothers you, I suppose you could set a flag variable and then test it at Darwin.cmake line 196 (now 201, I guess) instead.
(0033656)
Brad King   
2013-08-02 15:51   
Re 0014324:0033655: Okay, so the test case is:

$ SDK="$(xcodebuild -sdk macosx -version Path)" &&
export PATH="$(dirname $(xcrun --find make)):$PATH" &&
export CC="$(xcrun --find cc)" &&
export CXX="$(xcrun --find c++)" &&
export CFLAGS="-isysroot $SDK" &&
export CXXFLAGS="-isysroot $SDK" &&
unset SDK
$ MACOSX_DEPLOYMENT_TARGET=10.7 ../CMake/bootstrap
...
CMake Error at Modules/Platform/Darwin.cmake:199 (message):
  CMAKE_OSX_DEPLOYMENT_TARGET is '10.7' but CMAKE_OSX_SYSROOT:

   ""

  is not set to a MacOSX SDK with a recognized version.  Either set
  CMAKE_OSX_SYSROOT to a valid SDK or set CMAKE_OSX_DEPLOYMENT_TARGET to
  empty.
Call Stack (most recent call first):
  Modules/CMakeSystemSpecificInformation.cmake:36 (include)
  CMakeLists.txt:14 (project)
(0033658)
John Ralls   
2013-08-02 16:00   
OK.
(0033659)
Brad King   
2013-08-02 16:02   
I reverted commit a1c032b9:

 http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=bf5a5bc8 [^]
(0033660)
Brad King   
2013-08-02 16:04   
With these two changes, are all issues covered here now resolved?
(0033662)
John Ralls   
2013-08-02 16:36   
> With these two changes, are all issues covered here now resolved?

Yes, they seem to be, at least on the 'next' branch.
(0033667)
Brad King   
2013-08-05 10:01   
Both changes are now in master and will be in 2.8.12. Thanks for your help!
(0036075)
Robert Maynard   
2014-06-02 08:38   
Closing resolved issues that have not been updated in more than 4 months.