resolve cyclic dependency with zstd
[platform/upstream/cmake.git] / Source / cmGlobalVisualStudioGenerator.h
1 /* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
2    file Copyright.txt or https://cmake.org/licensing for details.  */
3 #pragma once
4
5 #include "cmConfigure.h" // IWYU pragma: keep
6
7 #include <iosfwd>
8 #include <map>
9 #include <set>
10 #include <string>
11 #include <vector>
12
13 #include "cm_codecvt.hxx"
14
15 #include "cmGlobalGenerator.h"
16 #include "cmTargetDepend.h"
17 #include "cmValue.h"
18
19 class cmCustomCommand;
20 class cmGeneratorTarget;
21 class cmLocalGenerator;
22 class cmMakefile;
23 class cmake;
24
25 /** \class cmGlobalVisualStudioGenerator
26  * \brief Base class for global Visual Studio generators.
27  *
28  * cmGlobalVisualStudioGenerator provides functionality common to all
29  * global Visual Studio generators.
30  */
31 class cmGlobalVisualStudioGenerator : public cmGlobalGenerator
32 {
33 public:
34   /** Known versions of Visual Studio.  */
35   enum class VSVersion : uint16_t
36   {
37     VS9 = 90,
38     VS11 = 110,
39     VS12 = 120,
40     /* VS13 = 130 was skipped */
41     VS14 = 140,
42     VS15 = 150,
43     VS16 = 160,
44     VS17 = 170
45   };
46
47   virtual ~cmGlobalVisualStudioGenerator();
48
49   VSVersion GetVersion() const;
50   void SetVersion(VSVersion v);
51
52   /** Is the installed VS an Express edition?  */
53   bool IsExpressEdition() const { return this->ExpressEdition; }
54
55   void EnableLanguage(std::vector<std::string> const& languages, cmMakefile*,
56                       bool optional) override;
57
58   bool SetGeneratorPlatform(std::string const& p, cmMakefile* mf) override;
59
60   /**
61    * Get the name of the target platform (architecture) for which we generate.
62    * The names are as defined by VS, e.g. "Win32", "x64", "Itanium", "ARM".
63    */
64   std::string const& GetPlatformName() const;
65
66   /**
67    * Configure CMake's Visual Studio macros file into the user's Visual
68    * Studio macros directory.
69    */
70   virtual void ConfigureCMakeVisualStudioMacros();
71
72   /**
73    * Where does this version of Visual Studio look for macros for the
74    * current user? Returns the empty string if this version of Visual
75    * Studio does not implement support for VB macros.
76    */
77   virtual std::string GetUserMacrosDirectory();
78
79   /**
80    * What is the reg key path to "vsmacros" for this version of Visual
81    * Studio?
82    */
83   virtual std::string GetUserMacrosRegKeyBase();
84
85   enum MacroName
86   {
87     MacroReload,
88     MacroStop
89   };
90
91   /**
92    * Call the ReloadProjects macro if necessary based on
93    * GetFilesReplacedDuringGenerate results.
94    */
95   void CallVisualStudioMacro(MacroName m, const std::string& vsSolutionFile);
96
97   // return true if target is fortran only
98   bool TargetIsFortranOnly(const cmGeneratorTarget* gt);
99
100   // return true if target should be included in solution.
101   virtual bool IsInSolution(const cmGeneratorTarget* gt) const;
102
103   // return true if project dependency should be included in solution.
104   virtual bool IsDepInSolution(const std::string& targetName) const;
105
106   /** Get the top-level registry key for this VS version.  */
107   std::string GetRegistryBase();
108
109   /** Get the top-level registry key for the given VS version.  */
110   static std::string GetRegistryBase(const char* version);
111
112   /** Return true if the generated build tree may contain multiple builds.
113       i.e. "Can I build Debug and Release in the same tree?" */
114   bool IsMultiConfig() const override { return true; }
115
116   /** Return true if building for Windows CE */
117   virtual bool TargetsWindowsCE() const { return false; }
118
119   bool IsIncludeExternalMSProjectSupported() const override { return true; }
120
121   /** Get encoding used by generator for generated source files
122    */
123   codecvt::Encoding GetMakefileEncoding() const override
124   {
125     return codecvt::ANSI;
126   }
127
128   class TargetSet : public std::set<cmGeneratorTarget const*>
129   {
130   };
131   class TargetCompare
132   {
133     std::string First;
134
135   public:
136     TargetCompare(std::string const& first)
137       : First(first)
138     {
139     }
140     bool operator()(cmGeneratorTarget const* l,
141                     cmGeneratorTarget const* r) const;
142   };
143   class OrderedTargetDependSet;
144
145   bool FindMakeProgram(cmMakefile*) override;
146
147   std::string ExpandCFGIntDir(const std::string& str,
148                               const std::string& config) const override;
149
150   void ComputeTargetObjectDirectory(cmGeneratorTarget* gt) const override;
151
152   std::string GetStartupProjectName(cmLocalGenerator const* root) const;
153
154   void AddSymbolExportCommand(cmGeneratorTarget*,
155                               std::vector<cmCustomCommand>& commands,
156                               std::string const& configName);
157
158   bool Open(const std::string& bindir, const std::string& projectName,
159             bool dryRun) override;
160
161   bool IsVisualStudio() const override { return true; }
162
163 protected:
164   cmGlobalVisualStudioGenerator(cmake* cm,
165                                 std::string const& platformInGeneratorName);
166
167   void AddExtraIDETargets() override;
168
169   // Does this VS version link targets to each other if there are
170   // dependencies in the SLN file?  This was done for VS versions
171   // below 8.
172   virtual bool VSLinksDependencies() const { return true; }
173
174   const char* GetIDEVersion() const;
175
176   void WriteSLNHeader(std::ostream& fout);
177
178   bool ComputeTargetDepends() override;
179   class VSDependSet : public std::set<std::string>
180   {
181   };
182   class VSDependMap : public std::map<cmGeneratorTarget const*, VSDependSet>
183   {
184   };
185   VSDependMap VSTargetDepends;
186   void ComputeVSTargetDepends(cmGeneratorTarget*);
187
188   bool CheckTargetLinks(cmGeneratorTarget& target, const std::string& name);
189   std::string GetUtilityForTarget(cmGeneratorTarget& target,
190                                   const std::string&);
191   virtual std::string WriteUtilityDepend(cmGeneratorTarget const*) = 0;
192   std::string GetUtilityDepend(const cmGeneratorTarget* target);
193   using UtilityDependsMap = std::map<cmGeneratorTarget const*, std::string>;
194   UtilityDependsMap UtilityDepends;
195
196 protected:
197   VSVersion Version;
198   bool ExpressEdition;
199
200   std::string GeneratorPlatform;
201   std::string DefaultPlatformName;
202   bool PlatformInGeneratorName = false;
203
204 private:
205   virtual std::string GetVSMakeProgram() = 0;
206   void PrintCompilerAdvice(std::ostream&, std::string const&,
207                            cmValue) const override
208   {
209   }
210
211   void FollowLinkDepends(cmGeneratorTarget const* target,
212                          std::set<cmGeneratorTarget const*>& linked);
213
214   class TargetSetMap : public std::map<cmGeneratorTarget*, TargetSet>
215   {
216   };
217   TargetSetMap TargetLinkClosure;
218   void FillLinkClosure(const cmGeneratorTarget* target, TargetSet& linked);
219   TargetSet const& GetTargetLinkClosure(cmGeneratorTarget* target);
220 };
221
222 class cmGlobalVisualStudioGenerator::OrderedTargetDependSet
223   : public std::multiset<cmTargetDepend,
224                          cmGlobalVisualStudioGenerator::TargetCompare>
225 {
226   using derived = std::multiset<cmTargetDepend,
227                                 cmGlobalVisualStudioGenerator::TargetCompare>;
228
229 public:
230   using TargetDependSet = cmGlobalGenerator::TargetDependSet;
231   using TargetSet = cmGlobalVisualStudioGenerator::TargetSet;
232   OrderedTargetDependSet(TargetDependSet const&, std::string const& first);
233   OrderedTargetDependSet(TargetSet const&, std::string const& first);
234 };