浏览代码

Merge topic 'xcode-optimization-flags'

601e6e1a Xcode: Use regular expression to extract all optimisation flags (#15794)
Brad King 10 年之前
父节点
当前提交
4c4da56b2e

+ 40 - 8
Source/cmGlobalXCodeGenerator.cxx

@@ -1616,6 +1616,39 @@ std::string cmGlobalXCodeGenerator::ExtractFlag(const char* flag,
   return retFlag;
 }
 
+//----------------------------------------------------------------------------
+// This function removes each matching occurrence of the expression and
+// returns the last one (i.e., the dominant flag in GCC)
+std::string cmGlobalXCodeGenerator::ExtractFlagRegex(const char* exp,
+                                                     int matchIndex,
+                                                     std::string& flags)
+{
+  std::string retFlag;
+
+  cmsys::RegularExpression regex(exp);
+  assert(regex.is_valid());
+  if(!regex.is_valid())
+    {
+    return retFlag;
+    }
+
+  std::string::size_type offset = 0;
+
+  while(regex.find(flags.c_str() + offset))
+    {
+    const std::string::size_type startPos = offset + regex.start(matchIndex);
+    const std::string::size_type endPos = offset + regex.end(matchIndex);
+    const std::string::size_type size = endPos - startPos;
+
+    offset = startPos + 1;
+
+    retFlag.assign(flags, startPos, size);
+    flags.replace(startPos, size, size, ' ');
+    }
+
+  return retFlag;
+}
+
 //----------------------------------------------------------------------------
 void
 cmGlobalXCodeGenerator::AddCommandsToBuildPhase(cmXCodeObject* buildphase,
@@ -2232,9 +2265,7 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
   bool same_gflags = true;
   std::map<std::string, std::string> gflags;
   std::string const* last_gflag = 0;
-  char optLevel[2];
-  optLevel[0] = '0';
-  optLevel[1] = 0;
+  std::string optLevel = "0";
 
   // Minimal map of flags to build settings.
   for (std::set<std::string>::iterator li = languages.begin();
@@ -2242,14 +2273,15 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
     {
     std::string& flags = cflags[*li];
     std::string& gflag = gflags[*li];
-    std::string oflag = this->ExtractFlag("-O", flags);
-    if(oflag.size() == 3)
+    std::string oflag =
+      this->ExtractFlagRegex("(^| )(-Ofast|-Os|-O[0-9]*)( |$)", 2, flags);
+    if(oflag.size() == 2)
       {
-      optLevel[0] = oflag[2];
+      optLevel = "1";
       }
-    if(oflag.size() == 2)
+    else if(oflag.size() > 2)
       {
-      optLevel[0] = '1';
+      optLevel = oflag.substr(2);
       }
     gflag = this->ExtractFlag("-g", flags);
     // put back gdwarf-2 if used since there is no way

+ 2 - 0
Source/cmGlobalXCodeGenerator.h

@@ -151,6 +151,8 @@ private:
                            cmXCodeObject* buildSettings,
                            const std::string& buildType);
   std::string ExtractFlag(const char* flag, std::string& flags);
+  std::string ExtractFlagRegex(const char* exp, int matchIndex,
+                               std::string& flags);
   void SortXCodeObjects();
   // delete all objects in the this->XCodeObjects vector.
   void ClearXCodeObjects();

+ 3 - 0
Tests/RunCMake/XcodeProject/RunCMakeTest.cmake

@@ -4,6 +4,9 @@ run_cmake(XcodeFileType)
 run_cmake(XcodeAttributeGenex)
 run_cmake(XcodeAttributeGenexError)
 run_cmake(XcodeObjectNeedsQuote)
+run_cmake(XcodeOptimizationFlags)
+run_cmake(XcodePreserveNonOptimizationFlags)
+run_cmake(XcodePreserveObjcFlag)
 if (NOT XCODE_VERSION VERSION_LESS 6)
   run_cmake(XcodePlatformFrameworks)
 endif()

+ 7 - 0
Tests/RunCMake/XcodeProject/XcodeOptimizationFlags-check.cmake

@@ -0,0 +1,7 @@
+foreach(level 1 2 3 s fast)
+  file(STRINGS ${RunCMake_TEST_BINARY_DIR}/XcodeOptimizationFlags.xcodeproj/project.pbxproj actual-${level}
+       REGEX "GCC_OPTIMIZATION_LEVEL = ${level};" LIMIT_COUNT 1)
+  if(NOT actual-${level})
+    message(SEND_ERROR "Optimization level '${level}' not found in Xcode project.")
+  endif()
+endforeach()

+ 20 - 0
Tests/RunCMake/XcodeProject/XcodeOptimizationFlags.cmake

@@ -0,0 +1,20 @@
+set(CMAKE_CONFIGURATION_TYPES "Release" CACHE INTERNAL "Supported configuration types")
+
+set(CMAKE_CXX_FLAGS_RELEASE "")
+
+project(XcodeOptimizationFlags CXX)
+
+add_library(fooO1 STATIC foo.cpp)
+set_target_properties(fooO1 PROPERTIES COMPILE_OPTIONS -O1)
+
+add_library(fooO2 STATIC foo.cpp)
+set_target_properties(fooO2 PROPERTIES COMPILE_OPTIONS -O2)
+
+add_library(fooO3 STATIC foo.cpp)
+set_target_properties(fooO3 PROPERTIES COMPILE_OPTIONS -O3)
+
+add_library(fooOs STATIC foo.cpp)
+set_target_properties(fooOs PROPERTIES COMPILE_OPTIONS -Os)
+
+add_library(fooOfast STATIC foo.cpp)
+set_target_properties(fooOfast PROPERTIES COMPILE_OPTIONS -Ofast)

+ 8 - 0
Tests/RunCMake/XcodeProject/XcodePreserveNonOptimizationFlags-check.cmake

@@ -0,0 +1,8 @@
+file(STRINGS ${RunCMake_TEST_BINARY_DIR}/XcodePreserveNonOptimizationFlags.xcodeproj/project.pbxproj actual
+     REGEX "OTHER_CPLUSPLUSFLAGS = [^;]*;")
+foreach(expect "-DA" "-DB +-DC" "-DD")
+  if(NOT "${actual}" MATCHES "${expect}")
+    message(SEND_ERROR "The actual project contains the lines:\n ${actual}\n"
+      "which do not match expected regex:\n ${expect}\n")
+  endif()
+endforeach()

+ 12 - 0
Tests/RunCMake/XcodeProject/XcodePreserveNonOptimizationFlags.cmake

@@ -0,0 +1,12 @@
+set(CMAKE_CONFIGURATION_TYPES "Release" CACHE INTERNAL "Supported configuration types")
+
+project(XcodePreserveNonOptimizationFlags CXX)
+
+add_library(preserveStart STATIC foo.cpp)
+set_property(TARGET preserveStart PROPERTY COMPILE_OPTIONS -DA -O1)
+
+add_library(preserveBoth STATIC foo.cpp)
+set_property(TARGET preserveBoth PROPERTY COMPILE_OPTIONS -DB -O1 -DC)
+
+add_library(preserveEnd STATIC foo.cpp)
+set_property(TARGET preserveEnd PROPERTY COMPILE_OPTIONS -O1 -DD)

+ 7 - 0
Tests/RunCMake/XcodeProject/XcodePreserveObjcFlag-check.cmake

@@ -0,0 +1,7 @@
+set(expect "-ObjC")
+file(STRINGS ${RunCMake_TEST_BINARY_DIR}/XcodePreserveObjcFlag.xcodeproj/project.pbxproj actual
+     REGEX "OTHER_CPLUSPLUSFLAGS = [^;]*;" LIMIT_COUNT 1)
+if(NOT "${actual}" MATCHES "${expect}")
+  message(SEND_ERROR "The actual project contains the line:\n ${actual}\n"
+    "which does not match expected regex:\n ${expect}\n")
+endif()

+ 6 - 0
Tests/RunCMake/XcodeProject/XcodePreserveObjcFlag.cmake

@@ -0,0 +1,6 @@
+set(CMAKE_CONFIGURATION_TYPES "Release" CACHE INTERNAL "Supported configuration types")
+
+project(XcodePreserveObjcFlag CXX)
+
+add_library(foo STATIC foo.cpp)
+set_target_properties(foo PROPERTIES COMPILE_OPTIONS -ObjC)