| // Copyright 2016 The Chromium Authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style license that can be | |
| // found in the LICENSE file. | |
| #include "tools/gn/visual_studio_utils.h" | |
| #include <vector> | |
| #include "base/md5.h" | |
| #include "base/strings/string_split.h" | |
| #include "base/strings/string_util.h" | |
| CompilerOptions::CompilerOptions() = default; | |
| CompilerOptions::~CompilerOptions() = default; | |
| LinkerOptions::LinkerOptions() = default; | |
| LinkerOptions::~LinkerOptions() = default; | |
| std::string MakeGuid(const std::string& entry_path, const std::string& seed) { | |
| std::string str = base::ToUpperASCII(base::MD5String(seed + entry_path)); | |
| return '{' + str.substr(0, 8) + '-' + str.substr(8, 4) + '-' + | |
| str.substr(12, 4) + '-' + str.substr(16, 4) + '-' + | |
| str.substr(20, 12) + '}'; | |
| } | |
| #define SetOption(condition, member, value) \ | |
| if (condition) { \ | |
| options->member = value; \ | |
| return; \ | |
| } | |
| #define AppendOption(condition, member, value, separator) \ | |
| if (condition) { \ | |
| options->member += value + separator; \ | |
| return; \ | |
| } | |
| void ParseCompilerOption(const std::string& cflag, CompilerOptions* options) { | |
| if (cflag.size() > 2 && cflag[0] == '/') { | |
| switch (cflag[1]) { | |
| case 'F': | |
| AppendOption(cflag.size() > 3 && cflag[2] == 'I', forced_include_files, | |
| cflag.substr(3), ';') | |
| break; | |
| case 'G': | |
| if (cflag[2] == 'S') { | |
| SetOption(cflag.size() == 3, buffer_security_check, "true") | |
| SetOption(cflag.size() == 4 && cflag[3] == '-', | |
| buffer_security_check, "false") | |
| } | |
| break; | |
| case 'M': | |
| switch (cflag[2]) { | |
| case 'D': | |
| SetOption(cflag.size() == 3, runtime_library, "MultiThreadedDLL") | |
| SetOption(cflag.size() == 4 && cflag[3] == 'd', runtime_library, | |
| "MultiThreadedDebugDLL") | |
| break; | |
| case 'T': | |
| SetOption(cflag.size() == 3, runtime_library, "MultiThreaded") | |
| SetOption(cflag.size() == 4 && cflag[3] == 'd', runtime_library, | |
| "MultiThreadedDebug") | |
| break; | |
| } | |
| break; | |
| case 'O': | |
| switch (cflag[2]) { | |
| case '1': | |
| SetOption(cflag.size() == 3, optimization, "MinSpace") | |
| break; | |
| case '2': | |
| SetOption(cflag.size() == 3, optimization, "MaxSpeed") | |
| break; | |
| case 'd': | |
| SetOption(cflag.size() == 3, optimization, "Disabled") | |
| break; | |
| case 'x': | |
| SetOption(cflag.size() == 3, optimization, "Full") | |
| break; | |
| } | |
| break; | |
| case 'T': | |
| // Skip flags that cause treating all source files as C and C++ files. | |
| if (cflag.size() == 3 && (cflag[2] == 'C' || cflag[2] == 'P')) | |
| return; | |
| break; | |
| case 'W': | |
| switch (cflag[2]) { | |
| case '0': | |
| case '1': | |
| case '2': | |
| case '3': | |
| case '4': | |
| SetOption(cflag.size() == 3, warning_level, | |
| std::string("Level") + cflag[2]) | |
| break; | |
| case 'X': | |
| SetOption(cflag.size() == 3, treat_warning_as_error, "true") | |
| break; | |
| } | |
| break; | |
| case 'w': | |
| AppendOption(cflag.size() > 3 && cflag[2] == 'd', | |
| disable_specific_warnings, cflag.substr(3), ';') | |
| break; | |
| } | |
| } | |
| // Put everything else into additional_options. | |
| options->additional_options += cflag + ' '; | |
| } | |
| // Parses |ldflags| value and stores it in |options|. | |
| void ParseLinkerOption(const std::string& ldflag, LinkerOptions* options) { | |
| const char kSubsytemPrefix[] ="/SUBSYSTEM:"; | |
| if (base::StartsWith(ldflag, kSubsytemPrefix, | |
| base::CompareCase::SENSITIVE)) { | |
| const std::string subsystem( | |
| ldflag.begin() + std::string(kSubsytemPrefix).length(), | |
| ldflag.end()); | |
| const std::vector<std::string> tokens = base::SplitString( | |
| subsystem, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY); | |
| if (!tokens.empty()) | |
| options->subsystem = tokens[0]; | |
| } | |
| } |