| // 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 "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]; |
| } |
| } |