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