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