Xcode: Use regular expression to extract all optimisation flags (#15794)

This commit is contained in:
Gregor Jasny 2015-10-18 21:53:12 +02:00
parent 2f269fdf0c
commit 601e6e1ad1
9 changed files with 106 additions and 9 deletions

View File

@ -1611,6 +1611,39 @@ std::string cmGlobalXCodeGenerator::ExtractFlag(const char* flag,
return retFlag; 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 void
cmGlobalXCodeGenerator::AddCommandsToBuildPhase(cmXCodeObject* buildphase, cmGlobalXCodeGenerator::AddCommandsToBuildPhase(cmXCodeObject* buildphase,
@ -2227,9 +2260,7 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
bool same_gflags = true; bool same_gflags = true;
std::map<std::string, std::string> gflags; std::map<std::string, std::string> gflags;
std::string const* last_gflag = 0; std::string const* last_gflag = 0;
char optLevel[2]; std::string optLevel = "0";
optLevel[0] = '0';
optLevel[1] = 0;
// Minimal map of flags to build settings. // Minimal map of flags to build settings.
for (std::set<std::string>::iterator li = languages.begin(); for (std::set<std::string>::iterator li = languages.begin();
@ -2237,14 +2268,15 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
{ {
std::string& flags = cflags[*li]; std::string& flags = cflags[*li];
std::string& gflag = gflags[*li]; std::string& gflag = gflags[*li];
std::string oflag = this->ExtractFlag("-O", flags); std::string oflag =
if(oflag.size() == 3) this->ExtractFlagRegex("(^| )(-Ofast|-Os|-O[0-9]*)( |$)", 2, flags);
{
optLevel[0] = oflag[2];
}
if(oflag.size() == 2) if(oflag.size() == 2)
{ {
optLevel[0] = '1'; optLevel = "1";
}
else if(oflag.size() > 2)
{
optLevel = oflag.substr(2);
} }
gflag = this->ExtractFlag("-g", flags); gflag = this->ExtractFlag("-g", flags);
// put back gdwarf-2 if used since there is no way // put back gdwarf-2 if used since there is no way

View File

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

View File

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

View File

@ -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()

View File

@ -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)

View File

@ -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()

View File

@ -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)

View File

@ -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()

View File

@ -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)