1 /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
2 file Copyright.txt or https://cmake.org/licensing for details. */
5 #include "cmConfigure.h" // IWYU pragma: keep
13 #include "cm_codecvt.hxx"
15 #include "cmGlobalGenerator.h"
16 #include "cmTargetDepend.h"
19 class cmCustomCommand;
20 class cmGeneratorTarget;
21 class cmLocalGenerator;
25 /** \class cmGlobalVisualStudioGenerator
26 * \brief Base class for global Visual Studio generators.
28 * cmGlobalVisualStudioGenerator provides functionality common to all
29 * global Visual Studio generators.
31 class cmGlobalVisualStudioGenerator : public cmGlobalGenerator
34 /** Known versions of Visual Studio. */
35 enum class VSVersion : uint16_t
41 /* VS13 = 130 was skipped */
48 virtual ~cmGlobalVisualStudioGenerator();
50 VSVersion GetVersion() const;
51 void SetVersion(VSVersion v);
53 /** Is the installed VS an Express edition? */
54 bool IsExpressEdition() const { return this->ExpressEdition; }
56 void EnableLanguage(std::vector<std::string> const& languages, cmMakefile*,
57 bool optional) override;
59 bool SetGeneratorPlatform(std::string const& p, cmMakefile* mf) override;
62 * Get the name of the target platform (architecture) for which we generate.
63 * The names are as defined by VS, e.g. "Win32", "x64", "Itanium", "ARM".
65 std::string const& GetPlatformName() const;
68 * Configure CMake's Visual Studio macros file into the user's Visual
69 * Studio macros directory.
71 virtual void ConfigureCMakeVisualStudioMacros();
74 * Where does this version of Visual Studio look for macros for the
75 * current user? Returns the empty string if this version of Visual
76 * Studio does not implement support for VB macros.
78 virtual std::string GetUserMacrosDirectory();
81 * What is the reg key path to "vsmacros" for this version of Visual
84 virtual std::string GetUserMacrosRegKeyBase();
93 * Call the ReloadProjects macro if necessary based on
94 * GetFilesReplacedDuringGenerate results.
96 void CallVisualStudioMacro(MacroName m, const std::string& vsSolutionFile);
98 // return true if target is fortran only
99 bool TargetIsFortranOnly(const cmGeneratorTarget* gt);
101 // return true if target should be included in solution.
102 virtual bool IsInSolution(const cmGeneratorTarget* gt) const;
104 // return true if project dependency should be included in solution.
105 virtual bool IsDepInSolution(const std::string& targetName) const;
107 /** Get the top-level registry key for this VS version. */
108 std::string GetRegistryBase();
110 /** Get the top-level registry key for the given VS version. */
111 static std::string GetRegistryBase(const char* version);
113 /** Return true if the generated build tree may contain multiple builds.
114 i.e. "Can I build Debug and Release in the same tree?" */
115 bool IsMultiConfig() const override { return true; }
117 /** Return true if building for Windows CE */
118 virtual bool TargetsWindowsCE() const { return false; }
120 bool IsIncludeExternalMSProjectSupported() const override { return true; }
122 /** Get encoding used by generator for generated source files
124 codecvt::Encoding GetMakefileEncoding() const override
126 return codecvt::ANSI;
129 class TargetSet : public std::set<cmGeneratorTarget const*>
137 TargetCompare(std::string const& first)
141 bool operator()(cmGeneratorTarget const* l,
142 cmGeneratorTarget const* r) const;
144 class OrderedTargetDependSet;
146 bool FindMakeProgram(cmMakefile*) override;
148 std::string ExpandCFGIntDir(const std::string& str,
149 const std::string& config) const override;
151 void ComputeTargetObjectDirectory(cmGeneratorTarget* gt) const override;
153 std::string GetStartupProjectName(cmLocalGenerator const* root) const;
155 void AddSymbolExportCommand(cmGeneratorTarget*,
156 std::vector<cmCustomCommand>& commands,
157 std::string const& configName);
159 bool Open(const std::string& bindir, const std::string& projectName,
160 bool dryRun) override;
162 bool IsVisualStudio() const override { return true; }
165 cmGlobalVisualStudioGenerator(cmake* cm,
166 std::string const& platformInGeneratorName);
168 void AddExtraIDETargets() override;
170 // Does this VS version link targets to each other if there are
171 // dependencies in the SLN file? This was done for VS versions
173 virtual bool VSLinksDependencies() const { return true; }
175 const char* GetIDEVersion() const;
177 void WriteSLNHeader(std::ostream& fout);
179 bool ComputeTargetDepends() override;
180 class VSDependSet : public std::set<std::string>
183 class VSDependMap : public std::map<cmGeneratorTarget const*, VSDependSet>
186 VSDependMap VSTargetDepends;
187 void ComputeVSTargetDepends(cmGeneratorTarget*);
189 bool CheckTargetLinks(cmGeneratorTarget& target, const std::string& name);
190 std::string GetUtilityForTarget(cmGeneratorTarget& target,
192 virtual std::string WriteUtilityDepend(cmGeneratorTarget const*) = 0;
193 std::string GetUtilityDepend(const cmGeneratorTarget* target);
194 using UtilityDependsMap = std::map<cmGeneratorTarget const*, std::string>;
195 UtilityDependsMap UtilityDepends;
201 std::string GeneratorPlatform;
202 std::string DefaultPlatformName;
203 bool PlatformInGeneratorName = false;
206 virtual std::string GetVSMakeProgram() = 0;
207 void PrintCompilerAdvice(std::ostream&, std::string const&,
208 cmValue) const override
212 void FollowLinkDepends(cmGeneratorTarget const* target,
213 std::set<cmGeneratorTarget const*>& linked);
215 class TargetSetMap : public std::map<cmGeneratorTarget*, TargetSet>
218 TargetSetMap TargetLinkClosure;
219 void FillLinkClosure(const cmGeneratorTarget* target, TargetSet& linked);
220 TargetSet const& GetTargetLinkClosure(cmGeneratorTarget* target);
223 class cmGlobalVisualStudioGenerator::OrderedTargetDependSet
224 : public std::multiset<cmTargetDepend,
225 cmGlobalVisualStudioGenerator::TargetCompare>
227 using derived = std::multiset<cmTargetDepend,
228 cmGlobalVisualStudioGenerator::TargetCompare>;
231 using TargetDependSet = cmGlobalGenerator::TargetDependSet;
232 using TargetSet = cmGlobalVisualStudioGenerator::TargetSet;
233 OrderedTargetDependSet(TargetDependSet const&, std::string const& first);
234 OrderedTargetDependSet(TargetSet const&, std::string const& first);