Переглянути джерело

ENH: add support for universal binaries

Bill Hoffman 19 роки тому
батько
коміт
f7c1723135

+ 23 - 0
Modules/Platform/Darwin.cmake

@@ -11,6 +11,29 @@ SET(CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS "-dynamiclib -headerpad_max_install_name
 SET(CMAKE_SHARED_MODULE_CREATE_C_FLAGS "-bundle -headerpad_max_install_names")
 SET(CMAKE_FIND_LIBRARY_SUFFIXES ".dylib" ".so" ".a")
 
+# setup for universal binaries if sysroot exists
+IF(EXISTS /Developer/SDKs/MacOSX10.4u.sdk)
+  # set the sysroot to be used if CMAKE_OSX_ARCHITECTURES
+  # has more than one value
+  SET(CMAKE_OSX_SYSROOT /Developer/SDKs/MacOSX10.4u.sdk CACHE STRING
+    "isysroot used for universal binary support")
+  # set _CMAKE_OSX_MACHINE to umame -m
+  EXEC_PROGRAM(uname ARGS -m OUTPUT_VARIABLE _CMAKE_OSX_MACHINE)
+  # check for Power PC and change to ppc
+  IF("${_CMAKE_OSX_MACHINE}" MATCHES "Power")
+    SET(_CMAKE_OSX_MACHINE ppc)
+  ENDIF("${_CMAKE_OSX_MACHINE}" MATCHES "Power")
+  # check for environment variable CMAKE_OSX_ARCHITECTURES
+  # if it is set.
+  IF(NOT "$ENV{CMAKE_OSX_ARCHITECTURES}" STREQUAL "")
+    SET(_CMAKE_OSX_MACHINE "$ENV{CMAKE_OSX_ARCHITECTURES}")
+  ENDIF(NOT "$ENV{CMAKE_OSX_ARCHITECTURES}" STREQUAL "")
+  # now put _CMAKE_OSX_MACHINE into the cache
+  SET(CMAKE_OSX_ARCHITECTURES ${_CMAKE_OSX_MACHINE}
+    CACHE STRING "Build architectures for OSX")
+ENDIF(EXISTS /Developer/SDKs/MacOSX10.4u.sdk)
+
+
 IF("${CMAKE_BACKWARDS_COMPATIBILITY}" MATCHES "^1\\.[0-6]$")
   SET(CMAKE_SHARED_MODULE_CREATE_C_FLAGS
     "${CMAKE_SHARED_MODULE_CREATE_C_FLAGS} -flat_namespace -undefined suppress")

+ 27 - 10
Source/cmGlobalXCodeGenerator.cxx

@@ -62,9 +62,6 @@ public:
 #endif
 
 
-//TODO
-// add OSX application stuff
-
 //----------------------------------------------------------------------------
 cmGlobalXCodeGenerator::cmGlobalXCodeGenerator()
 {
@@ -1096,16 +1093,12 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
                                   this->CreateString("mh_bundle"));
       buildSettings->AddAttribute("GCC_DYNAMIC_NO_PIC", 
                                   this->CreateString("NO"));
+      buildSettings->AddAttribute("PREBINDING", 
+                                  this->CreateString("NO"));
       buildSettings->AddAttribute("GCC_SYMBOLS_PRIVATE_EXTERN", 
                                   this->CreateString("NO"));
       buildSettings->AddAttribute("GCC_INLINES_ARE_PRIVATE_EXTERN", 
                                   this->CreateString("NO"));
-      std::string outflag = "-o \\\"$(CONFIGURATION_BUILD_DIR)/";
-      outflag += productName;
-      outflag += "\\\"";
-      extraLinkOptions += " ";
-      extraLinkOptions += outflag;
-
       // Add the flags to create an executable.
       std::string createFlags =
         this->LookupFlags("CMAKE_", lang, "_LINK_FLAGS", "");
@@ -1980,7 +1973,31 @@ void cmGlobalXCodeGenerator::CreateXCodeObjects(cmLocalGenerator* root,
   configlist->AddAttribute("defaultConfigurationIsVisible", this->CreateString("0"));
   configlist->AddAttribute("defaultConfigurationName", this->CreateString("Debug"));
   cmXCodeObject* buildSettings =
-    this->CreateObject(cmXCodeObject::ATTRIBUTE_GROUP);
+      this->CreateObject(cmXCodeObject::ATTRIBUTE_GROUP);
+  const char* osxArch = 
+      this->CurrentMakefile->GetDefinition("CMAKE_OSX_ARCHITECTURES");
+  const char* sysroot = 
+      this->CurrentMakefile->GetDefinition("CMAKE_OSX_SYSROOT");
+  if(osxArch && sysroot)
+    {
+    std::vector<std::string> archs;
+    cmSystemTools::ExpandListArgument(std::string(osxArch),
+                                      archs);
+    if(archs.size() > 1)
+      {
+      buildSettings->AddAttribute("SDKROOT", 
+                                  this->CreateString(sysroot));
+      std::string archString;
+      for( std::vector<std::string>::iterator i = archs.begin();
+           i != archs.end(); ++i)
+        {
+        archString += *i;
+        archString += " ";
+        }
+      buildSettings->AddAttribute("ARCHS", 
+                                  this->CreateString(archString.c_str()));
+      }
+    }
   configDebug->AddAttribute("name", this->CreateString("Debug"));
   configDebug->AddAttribute("buildSettings", buildSettings);
   configRelease->AddAttribute("name", this->CreateString("Release"));

+ 25 - 1
Source/cmLocalGenerator.cxx

@@ -40,6 +40,7 @@ cmLocalGenerator::cmLocalGenerator()
   this->IgnoreLibPrefix = false;
   this->UseRelativePaths = false;
   this->Configured = false;
+  this->EmitUniversalBinaryFlags = true;
 }
 
 cmLocalGenerator::~cmLocalGenerator()
@@ -1378,6 +1379,30 @@ void cmLocalGenerator::AddLanguageFlags(std::string& flags,
   std::string flagsVar = "CMAKE_";
   flagsVar += lang;
   flagsVar += "_FLAGS";
+  if(this->EmitUniversalBinaryFlags)
+    {
+    const char* osxArch = 
+      this->Makefile->GetDefinition("CMAKE_OSX_ARCHITECTURES");
+    const char* sysroot = 
+      this->Makefile->GetDefinition("CMAKE_OSX_SYSROOT");
+    if(osxArch && sysroot  && lang && lang[0] =='C')
+      { 
+      std::vector<std::string> archs;
+      cmSystemTools::ExpandListArgument(std::string(osxArch),
+                                        archs);
+      if(archs.size() > 1)
+        {
+        for( std::vector<std::string>::iterator i = archs.begin();
+             i != archs.end(); ++i)
+          {
+          flags += " -arch ";
+          flags += *i;
+          }
+        flags += " -isysroot ";
+        flags += sysroot;
+        }
+      }
+    }
   this->AddConfigVariableFlags(flags, flagsVar.c_str(), config);
 }
 
@@ -1472,7 +1497,6 @@ void cmLocalGenerator::AddConfigVariableFlags(std::string& flags,
   // Add the flags from the variable itself.
   std::string flagsVar = var;
   this->AppendFlags(flags, this->Makefile->GetDefinition(flagsVar.c_str()));
-
   // Add the flags from the build-type specific variable.
   if(config && *config)
     {

+ 1 - 1
Source/cmLocalGenerator.h

@@ -261,7 +261,7 @@ protected:
   bool UseRelativePaths;
   bool IgnoreLibPrefix;
   bool Configured;
-
+  bool EmitUniversalBinaryFlags;
   // Hack for ExpandRuleVariable until object-oriented version is
   // committed.
   std::string TargetImplib;

+ 3 - 0
Source/cmLocalXCodeGenerator.cxx

@@ -2,6 +2,9 @@
 
 cmLocalXCodeGenerator::cmLocalXCodeGenerator()
 {
+  // the global generator does this, so do not
+  // put these flags into the language flags
+  this->EmitUniversalBinaryFlags = false;
 }
 
 cmLocalXCodeGenerator::~cmLocalXCodeGenerator()

+ 14 - 1
Source/cmTryCompileCommand.cxx

@@ -231,7 +231,20 @@ int cmTryCompileCommand::CoreTryCompileCode(
   // actually do the try compile now that everything is setup
   int res = mf->TryCompile(sourceDirectory, binaryDirectory,
                            projectName, targetName, &cmakeFlags, &output);
-  
+  // for the xcode generator 
+  if(strcmp(mf->GetCMakeInstance()->GetGlobalGenerator()->GetName() ,
+            "Xcode") == 0)
+    {
+    int numTrys = 0;
+    while(output.find("/bin/sh: bad interpreter: Text file busy") 
+          != output.npos && numTrys < 4)
+      {
+      output = "";
+      res = mf->TryCompile(sourceDirectory, binaryDirectory,
+                           projectName, targetName, &cmakeFlags, &output);
+      numTrys++;
+      }
+    }
   if ( erroroc )
     {
     cmSystemTools::SetErrorOccured();

+ 10 - 0
Tests/ExternalOBJ/CMakeLists.txt

@@ -1,5 +1,15 @@
 PROJECT (ExternalOBJ)
 
+IF(APPLE)
+  # set _CMAKE_OSX_MACHINE to umame -m
+  EXEC_PROGRAM(uname ARGS -m OUTPUT_VARIABLE _CMAKE_OSX_MACHINE)
+  # check for Power PC and change to ppc
+  IF("${_CMAKE_OSX_MACHINE}" MATCHES "Power")
+    SET(_CMAKE_OSX_MACHINE ppc)
+  ENDIF("${_CMAKE_OSX_MACHINE}" MATCHES "Power")
+  SET(CMAKE_OSX_ARCHITECTURES ${_CMAKE_OSX_MACHINE})
+ENDIF(APPLE)
+
 # Build the external object file.
 TRY_COMPILE(EXTERNAL_OBJECT_BUILT
   ${ExternalOBJ_BINARY_DIR}/Object

+ 9 - 0
Tests/ExternalOBJ/Object/CMakeLists.txt

@@ -1,3 +1,12 @@
 PROJECT(Object)
+IF(APPLE)
+  # set _CMAKE_OSX_MACHINE to umame -m
+  EXEC_PROGRAM(uname ARGS -m OUTPUT_VARIABLE _CMAKE_OSX_MACHINE)
+  # check for Power PC and change to ppc
+  IF("${_CMAKE_OSX_MACHINE}" MATCHES "Power")
+    SET(_CMAKE_OSX_MACHINE ppc)
+  ENDIF("${_CMAKE_OSX_MACHINE}" MATCHES "Power")
+  SET(CMAKE_OSX_ARCHITECTURES ${_CMAKE_OSX_MACHINE})
+ENDIF(APPLE)
 
 ADD_EXECUTABLE(external external_object.cxx external_main.cxx)

+ 12 - 0
Tests/X11/CMakeLists.txt

@@ -6,6 +6,18 @@ MESSAGE("X11_FOUND: ${X11_FOUND}")
 
 ADD_EXECUTABLE (UseX11 X11.c)
 
+# so for universal binaries this test will fail if 
+# 
+IF(APPLE)
+  LIST(LENGTH CMAKE_OSX_ARCHITECTURES NUMARCH)
+  IF(NUMARCH GREATER 1)
+    IF(NOT EXISTS /usr/X11R6/lib//libSM.6.dylib)
+      SET(X11_FOUND FALSE)
+      MESSAGE("disable X11, because of universal binary and sysroot")
+    ENDIF(NOT EXISTS /usr/X11R6/lib//libSM.6.dylib)
+  ENDIF(NUMARCH GREATER 1)
+ENDIF(APPLE)
+
 IF(X11_FOUND)
   ADD_DEFINITIONS(-DCMAKE_HAS_X)
   INCLUDE_DIRECTORIES(${X11_INCLUDE_DIR})