OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "tools/gn/visual_studio_writer.h" | 5 #include "tools/gn/visual_studio_writer.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <map> | 8 #include <map> |
9 #include <set> | 9 #include <set> |
10 #include <string> | 10 #include <string> |
11 | 11 |
12 #include "base/logging.h" | 12 #include "base/logging.h" |
13 #include "base/memory/scoped_ptr.h" | 13 #include "base/memory/scoped_ptr.h" |
| 14 #include "base/strings/string_split.h" |
14 #include "base/strings/string_util.h" | 15 #include "base/strings/string_util.h" |
15 #include "base/strings/utf_string_conversions.h" | 16 #include "base/strings/utf_string_conversions.h" |
16 #include "tools/gn/builder.h" | 17 #include "tools/gn/builder.h" |
| 18 #include "tools/gn/commands.h" |
17 #include "tools/gn/config.h" | 19 #include "tools/gn/config.h" |
18 #include "tools/gn/config_values_extractors.h" | 20 #include "tools/gn/config_values_extractors.h" |
19 #include "tools/gn/filesystem_utils.h" | 21 #include "tools/gn/filesystem_utils.h" |
| 22 #include "tools/gn/label_pattern.h" |
20 #include "tools/gn/parse_tree.h" | 23 #include "tools/gn/parse_tree.h" |
21 #include "tools/gn/path_output.h" | 24 #include "tools/gn/path_output.h" |
22 #include "tools/gn/source_file_type.h" | 25 #include "tools/gn/source_file_type.h" |
23 #include "tools/gn/standard_out.h" | 26 #include "tools/gn/standard_out.h" |
24 #include "tools/gn/target.h" | 27 #include "tools/gn/target.h" |
25 #include "tools/gn/variables.h" | 28 #include "tools/gn/variables.h" |
26 #include "tools/gn/visual_studio_utils.h" | 29 #include "tools/gn/visual_studio_utils.h" |
27 #include "tools/gn/xml_element_writer.h" | 30 #include "tools/gn/xml_element_writer.h" |
28 | 31 |
29 #if defined(OS_WIN) | 32 #if defined(OS_WIN) |
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
207 | 210 |
208 VisualStudioWriter::~VisualStudioWriter() { | 211 VisualStudioWriter::~VisualStudioWriter() { |
209 STLDeleteContainerPointers(projects_.begin(), projects_.end()); | 212 STLDeleteContainerPointers(projects_.begin(), projects_.end()); |
210 STLDeleteContainerPointers(folders_.begin(), folders_.end()); | 213 STLDeleteContainerPointers(folders_.begin(), folders_.end()); |
211 } | 214 } |
212 | 215 |
213 // static | 216 // static |
214 bool VisualStudioWriter::RunAndWriteFiles(const BuildSettings* build_settings, | 217 bool VisualStudioWriter::RunAndWriteFiles(const BuildSettings* build_settings, |
215 Builder* builder, | 218 Builder* builder, |
216 Version version, | 219 Version version, |
| 220 const std::string& sln_name, |
| 221 const std::string& dir_filters, |
217 Err* err) { | 222 Err* err) { |
218 std::vector<const Target*> targets = builder->GetAllResolvedTargets(); | 223 std::vector<const Target*> targets; |
| 224 if (dir_filters.empty()) { |
| 225 targets = builder->GetAllResolvedTargets(); |
| 226 } else { |
| 227 std::vector<std::string> tokens = base::SplitString( |
| 228 dir_filters, ";", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY); |
| 229 SourceDir root_dir = |
| 230 SourceDirForCurrentDirectory(build_settings->root_path()); |
| 231 |
| 232 std::vector<LabelPattern> filters; |
| 233 for (const std::string& token : tokens) { |
| 234 LabelPattern pattern = |
| 235 LabelPattern::GetPattern(root_dir, Value(nullptr, token), err); |
| 236 if (err->has_error()) |
| 237 return false; |
| 238 filters.push_back(pattern); |
| 239 } |
| 240 |
| 241 commands::FilterTargetsByPatterns(builder->GetAllResolvedTargets(), filters, |
| 242 &targets); |
| 243 } |
219 | 244 |
220 const char* config_platform = "Win32"; | 245 const char* config_platform = "Win32"; |
221 | 246 |
222 // Assume the "target_cpu" variable does not change between different | 247 // Assume the "target_cpu" variable does not change between different |
223 // toolchains. | 248 // toolchains. |
224 if (!targets.empty()) { | 249 if (!targets.empty()) { |
225 const Scope* scope = targets.front()->settings()->base_config(); | 250 const Scope* scope = targets.front()->settings()->base_config(); |
226 const Value* target_cpu_value = scope->GetValue(variables::kTargetCpu); | 251 const Value* target_cpu_value = scope->GetValue(variables::kTargetCpu); |
227 if (target_cpu_value != nullptr && | 252 if (target_cpu_value != nullptr && |
228 target_cpu_value->string_value() == "x64") | 253 target_cpu_value->string_value() == "x64") |
(...skipping 23 matching lines...) Expand all Loading... |
252 } | 277 } |
253 | 278 |
254 // Sort projects so they appear always in the same order in solution file. | 279 // Sort projects so they appear always in the same order in solution file. |
255 // Otherwise solution file is rewritten and reloaded by Visual Studio. | 280 // Otherwise solution file is rewritten and reloaded by Visual Studio. |
256 std::sort(writer.projects_.begin(), writer.projects_.end(), | 281 std::sort(writer.projects_.begin(), writer.projects_.end(), |
257 [](const SolutionEntry* a, const SolutionEntry* b) { | 282 [](const SolutionEntry* a, const SolutionEntry* b) { |
258 return a->path < b->path; | 283 return a->path < b->path; |
259 }); | 284 }); |
260 | 285 |
261 writer.ResolveSolutionFolders(); | 286 writer.ResolveSolutionFolders(); |
262 return writer.WriteSolutionFile(err); | 287 return writer.WriteSolutionFile(sln_name, err); |
263 } | 288 } |
264 | 289 |
265 bool VisualStudioWriter::WriteProjectFiles(const Target* target, Err* err) { | 290 bool VisualStudioWriter::WriteProjectFiles(const Target* target, Err* err) { |
266 std::string project_name = target->label().name(); | 291 std::string project_name = target->label().name(); |
267 const char* project_config_platform = config_platform_; | 292 const char* project_config_platform = config_platform_; |
268 if (!target->settings()->is_default()) { | 293 if (!target->settings()->is_default()) { |
269 project_name += "_" + target->toolchain()->label().name(); | 294 project_name += "_" + target->toolchain()->label().name(); |
270 const Value* value = | 295 const Value* value = |
271 target->settings()->base_config()->GetValue(variables::kCurrentCpu); | 296 target->settings()->base_config()->GetValue(variables::kCurrentCpu); |
272 if (value != nullptr && value->string_value() == "x64") | 297 if (value != nullptr && value->string_value() == "x64") |
(...skipping 310 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
583 } | 608 } |
584 cl_item->SubElement("Filter")->Text(filter_path); | 609 cl_item->SubElement("Filter")->Text(filter_path); |
585 } | 610 } |
586 } | 611 } |
587 } | 612 } |
588 } | 613 } |
589 | 614 |
590 project.Text(files_out.str()); | 615 project.Text(files_out.str()); |
591 } | 616 } |
592 | 617 |
593 bool VisualStudioWriter::WriteSolutionFile(Err* err) { | 618 bool VisualStudioWriter::WriteSolutionFile(const std::string& sln_name, |
| 619 Err* err) { |
| 620 std::string name = sln_name.empty() ? "all" : sln_name; |
594 SourceFile sln_file = build_settings_->build_dir().ResolveRelativeFile( | 621 SourceFile sln_file = build_settings_->build_dir().ResolveRelativeFile( |
595 Value(nullptr, "all.sln"), err); | 622 Value(nullptr, name + ".sln"), err); |
596 if (sln_file.is_null()) | 623 if (sln_file.is_null()) |
597 return false; | 624 return false; |
598 | 625 |
599 base::FilePath sln_path = build_settings_->GetFullPath(sln_file); | 626 base::FilePath sln_path = build_settings_->GetFullPath(sln_file); |
600 | 627 |
601 std::stringstream string_out; | 628 std::stringstream string_out; |
602 WriteSolutionFileContents(string_out, sln_path.DirName()); | 629 WriteSolutionFileContents(string_out, sln_path.DirName()); |
603 | 630 |
604 // Only write the content to the file if it's different. That is | 631 // Only write the content to the file if it's different. That is |
605 // both a performance optimization and more importantly, prevents | 632 // both a performance optimization and more importantly, prevents |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
697 size_t common_prefix_len = 0; | 724 size_t common_prefix_len = 0; |
698 size_t max_common_length = | 725 size_t max_common_length = |
699 std::min(root_folder_path_.size(), folder_path.size()); | 726 std::min(root_folder_path_.size(), folder_path.size()); |
700 size_t i; | 727 size_t i; |
701 for (i = common_prefix_len; i < max_common_length; ++i) { | 728 for (i = common_prefix_len; i < max_common_length; ++i) { |
702 if (IsSlash(root_folder_path_[i]) && IsSlash(folder_path[i])) | 729 if (IsSlash(root_folder_path_[i]) && IsSlash(folder_path[i])) |
703 common_prefix_len = i + 1; | 730 common_prefix_len = i + 1; |
704 else if (root_folder_path_[i] != folder_path[i]) | 731 else if (root_folder_path_[i] != folder_path[i]) |
705 break; | 732 break; |
706 } | 733 } |
707 if (i == max_common_length) | 734 if (i == max_common_length && |
| 735 (i == folder_path.size() || IsSlash(folder_path[i]))) |
708 common_prefix_len = max_common_length; | 736 common_prefix_len = max_common_length; |
709 if (common_prefix_len < root_folder_path_.size()) { | 737 if (common_prefix_len < root_folder_path_.size()) { |
710 if (IsSlash(root_folder_path_[common_prefix_len - 1])) | 738 if (IsSlash(root_folder_path_[common_prefix_len - 1])) |
711 --common_prefix_len; | 739 --common_prefix_len; |
712 root_folder_path_ = root_folder_path_.substr(0, common_prefix_len); | 740 root_folder_path_ = root_folder_path_.substr(0, common_prefix_len); |
713 } | 741 } |
714 } | 742 } |
715 } | 743 } |
716 } | 744 } |
717 | 745 |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
762 } | 790 } |
763 } | 791 } |
764 | 792 |
765 std::string VisualStudioWriter::GetNinjaTarget(const Target* target) { | 793 std::string VisualStudioWriter::GetNinjaTarget(const Target* target) { |
766 std::ostringstream ninja_target_out; | 794 std::ostringstream ninja_target_out; |
767 DCHECK(!target->dependency_output_file().value().empty()); | 795 DCHECK(!target->dependency_output_file().value().empty()); |
768 ninja_path_output_.WriteFile(ninja_target_out, | 796 ninja_path_output_.WriteFile(ninja_target_out, |
769 target->dependency_output_file()); | 797 target->dependency_output_file()); |
770 return ninja_target_out.str(); | 798 return ninja_target_out.str(); |
771 } | 799 } |
OLD | NEW |