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
40 /* VS13 = 130 was skipped */
47 virtual ~cmGlobalVisualStudioGenerator();
49 VSVersion GetVersion() const;
50 void SetVersion(VSVersion v);
52 /** Is the installed VS an Express edition? */
53 bool IsExpressEdition() const { return this->ExpressEdition; }
55 void EnableLanguage(std::vector<std::string> const& languages, cmMakefile*,
56 bool optional) override;
58 bool SetGeneratorPlatform(std::string const& p, cmMakefile* mf) override;
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".
64 std::string const& GetPlatformName() const;
67 * Configure CMake's Visual Studio macros file into the user's Visual
68 * Studio macros directory.
70 virtual void ConfigureCMakeVisualStudioMacros();
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.
77 virtual std::string GetUserMacrosDirectory();
80 * What is the reg key path to "vsmacros" for this version of Visual
83 virtual std::string GetUserMacrosRegKeyBase();
92 * Call the ReloadProjects macro if necessary based on
93 * GetFilesReplacedDuringGenerate results.
95 void CallVisualStudioMacro(MacroName m, const std::string& vsSolutionFile);
97 // return true if target is fortran only
98 bool TargetIsFortranOnly(const cmGeneratorTarget* gt);
100 // return true if target should be included in solution.
101 virtual bool IsInSolution(const cmGeneratorTarget* gt) const;
103 // return true if project dependency should be included in solution.
104 virtual bool IsDepInSolution(const std::string& targetName) const;
106 /** Get the top-level registry key for this VS version. */
107 std::string GetRegistryBase();
109 /** Get the top-level registry key for the given VS version. */
110 static std::string GetRegistryBase(const char* version);
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; }
116 /** Return true if building for Windows CE */
117 virtual bool TargetsWindowsCE() const { return false; }
119 bool IsIncludeExternalMSProjectSupported() const override { return true; }
121 /** Get encoding used by generator for generated source files
123 codecvt::Encoding GetMakefileEncoding() const override
125 return codecvt::ANSI;
128 class TargetSet : public std::set<cmGeneratorTarget const*>
136 TargetCompare(std::string const& first)
140 bool operator()(cmGeneratorTarget const* l,
141 cmGeneratorTarget const* r) const;
143 class OrderedTargetDependSet;
145 bool FindMakeProgram(cmMakefile*) override;
147 std::string ExpandCFGIntDir(const std::string& str,
148 const std::string& config) const override;
150 void ComputeTargetObjectDirectory(cmGeneratorTarget* gt) const override;
152 std::string GetStartupProjectName(cmLocalGenerator const* root) const;
154 void AddSymbolExportCommand(cmGeneratorTarget*,
155 std::vector<cmCustomCommand>& commands,
156 std::string const& configName);
158 bool Open(const std::string& bindir, const std::string& projectName,
159 bool dryRun) override;
161 bool IsVisualStudio() const override { return true; }
164 cmGlobalVisualStudioGenerator(cmake* cm,
165 std::string const& platformInGeneratorName);
167 void AddExtraIDETargets() override;
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
172 virtual bool VSLinksDependencies() const { return true; }
174 const char* GetIDEVersion() const;
176 void WriteSLNHeader(std::ostream& fout);
178 bool ComputeTargetDepends() override;
179 class VSDependSet : public std::set<std::string>
182 class VSDependMap : public std::map<cmGeneratorTarget const*, VSDependSet>
185 VSDependMap VSTargetDepends;
186 void ComputeVSTargetDepends(cmGeneratorTarget*);
188 bool CheckTargetLinks(cmGeneratorTarget& target, const std::string& name);
189 std::string GetUtilityForTarget(cmGeneratorTarget& target,
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;
200 std::string GeneratorPlatform;
201 std::string DefaultPlatformName;
202 bool PlatformInGeneratorName = false;
205 virtual std::string GetVSMakeProgram() = 0;
206 void PrintCompilerAdvice(std::ostream&, std::string const&,
207 cmValue) const override
211 void FollowLinkDepends(cmGeneratorTarget const* target,
212 std::set<cmGeneratorTarget const*>& linked);
214 class TargetSetMap : public std::map<cmGeneratorTarget*, TargetSet>
217 TargetSetMap TargetLinkClosure;
218 void FillLinkClosure(const cmGeneratorTarget* target, TargetSet& linked);
219 TargetSet const& GetTargetLinkClosure(cmGeneratorTarget* target);
222 class cmGlobalVisualStudioGenerator::OrderedTargetDependSet
223 : public std::multiset<cmTargetDepend,
224 cmGlobalVisualStudioGenerator::TargetCompare>
226 using derived = std::multiset<cmTargetDepend,
227 cmGlobalVisualStudioGenerator::TargetCompare>;
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);