Xcode: Use regular expression to extract all optimisation flags (#15794)
This commit is contained in:
parent
2f269fdf0c
commit
601e6e1ad1
|
@ -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
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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()
|
|
@ -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)
|
|
@ -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()
|
|
@ -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)
|
|
@ -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()
|
|
@ -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)
|
Loading…
Reference in New Issue