diff options
Diffstat (limited to 'Source/cmXCodeScheme.cxx')
-rw-r--r-- | Source/cmXCodeScheme.cxx | 167 |
1 files changed, 167 insertions, 0 deletions
diff --git a/Source/cmXCodeScheme.cxx b/Source/cmXCodeScheme.cxx index f1dce64..58cb9c9 100644 --- a/Source/cmXCodeScheme.cxx +++ b/Source/cmXCodeScheme.cxx @@ -143,6 +143,41 @@ void cmXCodeScheme::WriteLaunchAction(cmXMLWriter& xout, xout.Attribute("debugServiceExtension", "internal"); xout.Attribute("allowLocationSimulation", "YES"); + // Diagnostics tab begin + + bool useAddressSanitizer = WriteLaunchActionAttribute( + xout, "enableAddressSanitizer", + "XCODE_SCHEME_ADDRESS_SANITIZER"); // not allowed with + // enableThreadSanitizer=YES + WriteLaunchActionAttribute( + xout, "enableASanStackUseAfterReturn", + "XCODE_SCHEME_ADDRESS_SANITIZER_USE_AFTER_RETURN"); + + bool useThreadSanitizer = false; + if (!useAddressSanitizer) { + useThreadSanitizer = WriteLaunchActionAttribute( + xout, "enableThreadSanitizer", + "XCODE_SCHEME_THREAD_SANITIZER"); // not allowed with + // enableAddressSanitizer=YES + } + + WriteLaunchActionAttribute(xout, "stopOnEveryThreadSanitizerIssue", + "XCODE_SCHEME_THREAD_SANITIZER_STOP"); + + WriteLaunchActionAttribute(xout, "enableUBSanitizer", + "XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER"); + WriteLaunchActionAttribute( + xout, "stopOnEveryUBSanitizerIssue", + "XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER_STOP"); + + WriteLaunchActionAttribute( + xout, "disableMainThreadChecker", + "XCODE_SCHEME_DISABLE_MAIN_THREAD_CHECKER"); // negative enabled! + WriteLaunchActionAttribute(xout, "stopOnEveryMainThreadCheckerIssue", + "XCODE_SCHEME_MAIN_THREAD_CHECKER_STOP"); + + // Diagnostics tab end + if (IsExecutable(this->Target)) { xout.StartElement("BuildableProductRunnable"); xout.BreakAttributes(); @@ -156,12 +191,144 @@ void cmXCodeScheme::WriteLaunchAction(cmXMLWriter& xout, xout.EndElement(); // MacroExpansion + // Info tab begin + + if (const char* exe = + this->Target->GetTarget()->GetProperty("XCODE_SCHEME_EXECUTABLE")) { + + xout.StartElement("PathRunnable"); + xout.BreakAttributes(); + + xout.Attribute("runnableDebuggingMode", "0"); + xout.Attribute("FilePath", exe); + + xout.EndElement(); // PathRunnable + } + + // Info tab end + + // Arguments tab begin + + if (const char* argList = + this->Target->GetTarget()->GetProperty("XCODE_SCHEME_ARGUMENTS")) { + std::vector<std::string> arguments; + cmSystemTools::ExpandListArgument(argList, arguments); + if (!arguments.empty()) { + xout.StartElement("CommandLineArguments"); + + for (auto argument : arguments) { + xout.StartElement("CommandLineArgument"); + xout.BreakAttributes(); + + xout.Attribute("argument", argument); + xout.Attribute("isEnabled", "YES"); + + xout.EndElement(); // CommandLineArgument + } + + xout.EndElement(); // CommandLineArguments + } + } + + if (const char* envList = + this->Target->GetTarget()->GetProperty("XCODE_SCHEME_ENVIRONMENT")) { + std::vector<std::string> envs; + cmSystemTools::ExpandListArgument(envList, envs); + if (!envs.empty()) { + xout.StartElement("EnvironmentVariables"); + + for (auto env : envs) { + + xout.StartElement("EnvironmentVariable"); + xout.BreakAttributes(); + + std::string envValue; + const auto p = env.find_first_of('='); + if (p != std::string::npos) { + envValue = env.substr(p + 1); + env.resize(p); + } + + xout.Attribute("key", env); + xout.Attribute("value", envValue); + xout.Attribute("isEnabled", "YES"); + + xout.EndElement(); // EnvironmentVariable + } + + xout.EndElement(); // EnvironmentVariables + } + } + + // Arguments tab end + xout.StartElement("AdditionalOptions"); + + if (!useThreadSanitizer) { + WriteLaunchActionAdditionalOption(xout, "MallocScribble", "", + "XCODE_SCHEME_MALLOC_SCRIBBLE"); + } + + if (!useThreadSanitizer && !useAddressSanitizer) { + WriteLaunchActionAdditionalOption(xout, "MallocGuardEdges", "", + "XCODE_SCHEME_MALLOC_GUARD_EDGES"); + } + + if (!useThreadSanitizer && !useAddressSanitizer) { + WriteLaunchActionAdditionalOption(xout, "DYLD_INSERT_LIBRARIES", + "/usr/lib/libgmalloc.dylib", + "XCODE_SCHEME_GUARD_MALLOC"); + } + + WriteLaunchActionAdditionalOption(xout, "NSZombieEnabled", "YES", + "XCODE_SCHEME_ZOMBIE_OBJECTS"); + + if (!useThreadSanitizer && !useAddressSanitizer) { + WriteLaunchActionAdditionalOption(xout, "MallocStackLogging", "", + "XCODE_SCHEME_MALLOC_STACK"); + } + + WriteLaunchActionAdditionalOption(xout, "DYLD_PRINT_APIS", "", + "XCODE_SCHEME_DYNAMIC_LINKER_API_USAGE"); + + WriteLaunchActionAdditionalOption(xout, "DYLD_PRINT_LIBRARIES", "", + "XCODE_SCHEME_DYNAMIC_LIBRARY_LOADS"); + xout.EndElement(); xout.EndElement(); // LaunchAction } +bool cmXCodeScheme::WriteLaunchActionAttribute(cmXMLWriter& xout, + const std::string& attrName, + const std::string& varName) +{ + if (Target->GetTarget()->GetPropertyAsBool(varName)) { + xout.Attribute(attrName.c_str(), "YES"); + return true; + } + return false; +} + +bool cmXCodeScheme::WriteLaunchActionAdditionalOption( + cmXMLWriter& xout, const std::string& key, const std::string& value, + const std::string& varName) +{ + if (Target->GetTarget()->GetPropertyAsBool(varName)) { + xout.StartElement("AdditionalOption"); + xout.BreakAttributes(); + + xout.Attribute("key", key); + xout.Attribute("value", value); + xout.Attribute("isEnabled", "YES"); + + xout.EndElement(); // AdditionalOption + + return true; + } + return false; +} + void cmXCodeScheme::WriteProfileAction(cmXMLWriter& xout, const std::string& configuration) { |