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
3 // found in the LICENSE file.
4 
5 #ifndef TOOLS_GN_VISUAL_STUDIO_WRITER_H_
6 #define TOOLS_GN_VISUAL_STUDIO_WRITER_H_
7 
8 #include <iosfwd>
9 #include <memory>
10 #include <string>
11 #include <vector>
12 
13 #include "base/gtest_prod_util.h"
14 #include "base/macros.h"
15 #include "gn/path_output.h"
16 
17 namespace base {
18 class FilePath;
19 }
20 
21 class Builder;
22 class BuildSettings;
23 class Err;
24 class SourceFile;
25 class Target;
26 
27 class VisualStudioWriter {
28  public:
29   enum Version {
30     Vs2013 = 1,  // Visual Studio 2013
31     Vs2015,      // Visual Studio 2015
32     Vs2017,      // Visual Studio 2017
33     Vs2019,      // Visual Studio 2019
34   };
35 
36   // Writes Visual Studio project and solution files. |sln_name| is the optional
37   // solution file name ("all" is used if not specified). |filters| is optional
38   // semicolon-separated list of label patterns used to limit the set of
39   // generated projects. Only matching targets and their dependencies (unless
40   // |no_deps| is true) will be included to the solution. On failure will
41   // populate |err| and will return false. |win_sdk| is the Windows SDK version
42   // which will be used by Visual Studio IntelliSense.
43   static bool RunAndWriteFiles(const BuildSettings* build_settings,
44                                const Builder& builder,
45                                Version version,
46                                const std::string& sln_name,
47                                const std::string& filters,
48                                const std::string& win_sdk,
49                                const std::string& ninja_extra_args,
50                                bool no_deps,
51                                Err* err);
52 
53  private:
54   FRIEND_TEST_ALL_PREFIXES(VisualStudioWriterTest, ResolveSolutionFolders);
55   FRIEND_TEST_ALL_PREFIXES(VisualStudioWriterTest,
56                            ResolveSolutionFolders_AbsPath);
57   FRIEND_TEST_ALL_PREFIXES(VisualStudioWriterTest, NoDotSlash);
58 
59   // Solution project or folder.
60   struct SolutionEntry {
61     SolutionEntry(const std::string& name,
62                   const std::string& path,
63                   const std::string& guid);
64     virtual ~SolutionEntry();
65 
66     // Entry name. For projects must be unique in the solution.
67     std::string name;
68     // Absolute project file or folder directory path.
69     std::string path;
70     // GUID-like string.
71     std::string guid;
72     // Pointer to parent folder. nullptr if entry has no parent.
73     SolutionEntry* parent_folder;
74   };
75 
76   struct SolutionProject : public SolutionEntry {
77     SolutionProject(const std::string& name,
78                     const std::string& path,
79                     const std::string& guid,
80                     const std::string& label_dir_path,
81                     const std::string& config_platform);
82     ~SolutionProject() override;
83 
84     // Absolute label dir path.
85     std::string label_dir_path;
86     // Configuration platform. May be different than solution config platform.
87     std::string config_platform;
88   };
89 
90   struct SourceFileCompileTypePair {
91     SourceFileCompileTypePair(const SourceFile* file, const char* compile_type);
92     ~SourceFileCompileTypePair();
93 
94     // Source file.
95     const SourceFile* file;
96     // Compile type string.
97     const char* compile_type;
98   };
99 
100   using SolutionProjects = std::vector<std::unique_ptr<SolutionProject>>;
101   using SolutionFolders = std::vector<std::unique_ptr<SolutionEntry>>;
102   using SourceFileCompileTypePairs = std::vector<SourceFileCompileTypePair>;
103 
104   VisualStudioWriter(const BuildSettings* build_settings,
105                      const char* config_platform,
106                      Version version,
107                      const std::string& win_kit);
108   ~VisualStudioWriter();
109 
110   bool WriteProjectFiles(const Target* target,
111                          const std::string& ninja_extra_args,
112                          Err* err);
113   bool WriteProjectFileContents(std::ostream& out,
114                                 const SolutionProject& solution_project,
115                                 const Target* target,
116                                 const std::string& ninja_extra_args,
117                                 SourceFileCompileTypePairs* source_types,
118                                 Err* err);
119   void WriteFiltersFileContents(std::ostream& out,
120                                 const Target* target,
121                                 const SourceFileCompileTypePairs& source_types);
122   bool WriteSolutionFile(const std::string& sln_name, Err* err);
123   void WriteSolutionFileContents(std::ostream& out,
124                                  const base::FilePath& solution_dir_path);
125 
126   // Resolves all solution folders (parent folders for projects) into |folders_|
127   // and updates |root_folder_dir_|. Also sets |parent_folder| for |projects_|.
128   void ResolveSolutionFolders();
129 
130   std::string GetNinjaTarget(const Target* target);
131 
132   const BuildSettings* build_settings_;
133 
134   // Toolset version.
135   const char* toolset_version_;
136 
137   // Project version.
138   const char* project_version_;
139 
140   // Visual Studio version string.
141   const char* version_string_;
142 
143   // Platform for solution configuration (Win32, x64). Some projects may be
144   // configured for different platform.
145   const char* config_platform_;
146 
147   // All projects contained by solution.
148   SolutionProjects projects_;
149 
150   // Absolute root solution folder path.
151   std::string root_folder_path_;
152 
153   // Folders for all solution projects.
154   SolutionFolders folders_;
155 
156   // Semicolon-separated Windows SDK include directories.
157   std::string windows_kits_include_dirs_;
158 
159   // Path formatter for ninja targets.
160   PathOutput ninja_path_output_;
161 
162   // Windows 10 SDK version string (e.g. 10.0.14393.0)
163   std::string windows_sdk_version_;
164 
165   DISALLOW_COPY_AND_ASSIGN(VisualStudioWriter);
166 };
167 
168 #endif  // TOOLS_GN_VISUAL_STUDIO_WRITER_H_
169