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_Encoding.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
38 /* VS13 = 130 was skipped */
45 ~cmGlobalVisualStudioGenerator() override
;
47 VSVersion
GetVersion() const;
48 void SetVersion(VSVersion v
);
50 /** Is the installed VS an Express edition? */
51 bool IsExpressEdition() const { return this->ExpressEdition
; }
53 void EnableLanguage(std::vector
<std::string
> const& languages
, cmMakefile
*,
54 bool optional
) override
;
56 bool SetGeneratorPlatform(std::string
const& p
, cmMakefile
* mf
) override
;
59 * Get the name of the target platform (architecture) for which we generate.
60 * The names are as defined by VS, e.g. "Win32", "x64", "Itanium", "ARM".
62 std::string
const& GetPlatformName() const;
65 * Configure CMake's Visual Studio macros file into the user's Visual
66 * Studio macros directory.
68 virtual void ConfigureCMakeVisualStudioMacros();
71 * Where does this version of Visual Studio look for macros for the
72 * current user? Returns the empty string if this version of Visual
73 * Studio does not implement support for VB macros.
75 virtual std::string
GetUserMacrosDirectory();
78 * What is the reg key path to "vsmacros" for this version of Visual
81 virtual std::string
GetUserMacrosRegKeyBase();
90 * Call the ReloadProjects macro if necessary based on
91 * GetFilesReplacedDuringGenerate results.
93 void CallVisualStudioMacro(MacroName m
, const std::string
& vsSolutionFile
);
95 // return true if target is fortran only
96 bool TargetIsFortranOnly(const cmGeneratorTarget
* gt
);
98 // return true if target should be included in solution.
99 virtual bool IsInSolution(const cmGeneratorTarget
* gt
) const;
101 // return true if project dependency should be included in solution.
102 virtual bool IsDepInSolution(const std::string
& targetName
) const;
104 /** Get the top-level registry key for this VS version. */
105 std::string
GetRegistryBase();
107 /** Get the top-level registry key for the given VS version. */
108 static std::string
GetRegistryBase(const char* version
);
110 /** Return true if the generated build tree may contain multiple builds.
111 i.e. "Can I build Debug and Release in the same tree?" */
112 bool IsMultiConfig() const override
{ return true; }
114 /** Return true if building for Windows CE */
115 virtual bool TargetsWindowsCE() const { return false; }
117 bool IsIncludeExternalMSProjectSupported() const override
{ return true; }
119 /** Get encoding used by generator for generated source files
121 codecvt_Encoding
GetMakefileEncoding() const override
123 return codecvt_Encoding::ANSI
;
126 class TargetSet
: public std::set
<cmGeneratorTarget
const*>
134 TargetCompare(std::string first
)
135 : First(std::move(first
))
138 bool operator()(cmGeneratorTarget
const* l
,
139 cmGeneratorTarget
const* r
) const;
141 class OrderedTargetDependSet
;
143 bool FindMakeProgram(cmMakefile
*) override
;
145 std::string
ExpandCFGIntDir(const std::string
& str
,
146 const std::string
& config
) const override
;
148 void ComputeTargetObjectDirectory(cmGeneratorTarget
* gt
) const override
;
150 std::string
GetStartupProjectName(cmLocalGenerator
const* root
) const;
152 void AddSymbolExportCommand(cmGeneratorTarget
*,
153 std::vector
<cmCustomCommand
>& commands
,
154 std::string
const& configName
);
156 bool Open(const std::string
& bindir
, const std::string
& projectName
,
157 bool dryRun
) override
;
159 bool IsVisualStudio() const override
{ return true; }
162 cmGlobalVisualStudioGenerator(cmake
* cm
,
163 std::string
const& platformInGeneratorName
);
165 virtual bool InitializePlatform(cmMakefile
* mf
);
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
;
199 std::string GeneratorPlatform
;
200 std::string DefaultPlatformName
;
201 bool PlatformInGeneratorName
= false;
204 virtual std::string
GetVSMakeProgram() = 0;
205 void PrintCompilerAdvice(std::ostream
&, std::string
const&,
206 cmValue
) const override
210 void FollowLinkDepends(cmGeneratorTarget
const* target
,
211 std::set
<cmGeneratorTarget
const*>& linked
);
213 class TargetSetMap
: public std::map
<cmGeneratorTarget
*, TargetSet
>
216 TargetSetMap TargetLinkClosure
;
217 void FillLinkClosure(const cmGeneratorTarget
* target
, TargetSet
& linked
);
218 TargetSet
const& GetTargetLinkClosure(cmGeneratorTarget
* target
);
221 class cmGlobalVisualStudioGenerator::OrderedTargetDependSet
222 : public std::multiset
<cmTargetDepend
,
223 cmGlobalVisualStudioGenerator::TargetCompare
>
225 using derived
= std::multiset
<cmTargetDepend
,
226 cmGlobalVisualStudioGenerator::TargetCompare
>;
229 using TargetDependSet
= cmGlobalGenerator::TargetDependSet
;
230 using TargetSet
= cmGlobalVisualStudioGenerator::TargetSet
;
231 OrderedTargetDependSet(TargetDependSet
const&, std::string
const& first
);
232 OrderedTargetDependSet(TargetSet
const&, std::string
const& first
);