cmGlobalVisualStudio71Generator.cxx 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
  2. file Copyright.txt or https://cmake.org/licensing for details. */
  3. #include "cmGlobalVisualStudio71Generator.h"
  4. #include <map>
  5. #include <sstream>
  6. #include "cmGeneratorTarget.h"
  7. #include "cmGlobalGenerator.h"
  8. #include "cmGlobalVisualStudioGenerator.h"
  9. #include "cmList.h"
  10. #include "cmListFileCache.h"
  11. #include "cmLocalGenerator.h"
  12. #include "cmMakefile.h"
  13. #include "cmStringAlgorithms.h"
  14. #include "cmSystemTools.h"
  15. class cmake;
  16. cmGlobalVisualStudio71Generator::cmGlobalVisualStudio71Generator(
  17. cmake* cm, const std::string& platformName)
  18. : cmGlobalVisualStudio7Generator(cm, platformName)
  19. {
  20. this->ProjectConfigurationSectionName = "ProjectConfiguration";
  21. }
  22. void cmGlobalVisualStudio71Generator::WriteSLNFile(
  23. std::ostream& fout, cmLocalGenerator* root,
  24. std::vector<cmLocalGenerator*>& generators)
  25. {
  26. std::vector<std::string> configs =
  27. root->GetMakefile()->GetGeneratorConfigs(cmMakefile::ExcludeEmptyConfig);
  28. // Write out the header for a SLN file
  29. this->WriteSLNHeader(fout);
  30. // Collect all targets under this root generator and the transitive
  31. // closure of their dependencies.
  32. TargetDependSet projectTargets;
  33. TargetDependSet originalTargets;
  34. this->GetTargetSets(projectTargets, originalTargets, root, generators);
  35. OrderedTargetDependSet orderedProjectTargets(
  36. projectTargets, this->GetStartupProjectName(root));
  37. // Generate the targets specification to a string. We will put this in
  38. // the actual .sln file later. As a side effect, this method also
  39. // populates the set of folders.
  40. std::ostringstream targetsSlnString;
  41. this->WriteTargetsToSolution(targetsSlnString, root, orderedProjectTargets);
  42. // Generate folder specification.
  43. bool useFolderProperty = this->UseFolderProperty();
  44. if (useFolderProperty) {
  45. this->WriteFolders(fout);
  46. }
  47. // Now write the actual target specification content.
  48. fout << targetsSlnString.str();
  49. // Write out the configurations information for the solution
  50. fout << "Global\n";
  51. // Write out the configurations for the solution
  52. this->WriteSolutionConfigurations(fout, configs);
  53. fout << "\tGlobalSection(" << this->ProjectConfigurationSectionName
  54. << ") = postSolution\n";
  55. // Write out the configurations for all the targets in the project
  56. this->WriteTargetConfigurations(fout, configs, orderedProjectTargets);
  57. fout << "\tEndGlobalSection\n";
  58. if (useFolderProperty) {
  59. // Write out project folders
  60. fout << "\tGlobalSection(NestedProjects) = preSolution\n";
  61. this->WriteFoldersContent(fout);
  62. fout << "\tEndGlobalSection\n";
  63. }
  64. // Write out global sections
  65. this->WriteSLNGlobalSections(fout, root);
  66. // Write the footer for the SLN file
  67. this->WriteSLNFooter(fout);
  68. }
  69. void cmGlobalVisualStudio71Generator::WriteSolutionConfigurations(
  70. std::ostream& fout, std::vector<std::string> const& configs)
  71. {
  72. fout << "\tGlobalSection(SolutionConfiguration) = preSolution\n";
  73. for (std::string const& i : configs) {
  74. fout << "\t\t" << i << " = " << i << '\n';
  75. }
  76. fout << "\tEndGlobalSection\n";
  77. }
  78. // Write a dsp file into the SLN file,
  79. // Note, that dependencies from executables to
  80. // the libraries it uses are also done here
  81. void cmGlobalVisualStudio71Generator::WriteProject(std::ostream& fout,
  82. const std::string& dspname,
  83. const std::string& dir,
  84. cmGeneratorTarget const* t)
  85. {
  86. // check to see if this is a fortran build
  87. std::string ext = ".vcproj";
  88. const char* project =
  89. R"(Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = ")";
  90. if (this->TargetIsFortranOnly(t)) {
  91. ext = ".vfproj";
  92. project = R"(Project("{6989167D-11E4-40FE-8C1A-2192A86A7E90}") = ")";
  93. }
  94. if (t->IsCSharpOnly()) {
  95. ext = ".csproj";
  96. project = R"(Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = ")";
  97. }
  98. cmValue targetExt = t->GetProperty("GENERATOR_FILE_NAME_EXT");
  99. if (targetExt) {
  100. ext = *targetExt;
  101. }
  102. std::string guid = this->GetGUID(dspname);
  103. fout << project << dspname << "\", \"" << this->ConvertToSolutionPath(dir)
  104. << (!dir.empty() ? "\\" : "") << dspname << ext << "\", \"{" << guid
  105. << "}\"\n";
  106. fout << "\tProjectSection(ProjectDependencies) = postProject\n";
  107. this->WriteProjectDepends(fout, dspname, dir, t);
  108. fout << "\tEndProjectSection\n";
  109. fout << "EndProject\n";
  110. auto ui = this->UtilityDepends.find(t);
  111. if (ui != this->UtilityDepends.end()) {
  112. const char* uname = ui->second.c_str();
  113. /* clang-format off */
  114. fout << R"(Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = ")"
  115. << uname << "\", \""
  116. << this->ConvertToSolutionPath(dir) << (dir[0]? "\\":"")
  117. << uname << ".vcproj" << "\", \"{"
  118. << this->GetGUID(uname) << "}\"\n"
  119. << "\tProjectSection(ProjectDependencies) = postProject\n"
  120. "\t\t{" << guid << "} = {" << guid << "}\n"
  121. "\tEndProjectSection\n"
  122. "EndProject\n";
  123. /* clang-format on */
  124. }
  125. }
  126. // Write a dsp file into the SLN file,
  127. // Note, that dependencies from executables to
  128. // the libraries it uses are also done here
  129. void cmGlobalVisualStudio71Generator::WriteProjectDepends(
  130. std::ostream& fout, const std::string&, const std::string&,
  131. cmGeneratorTarget const* target)
  132. {
  133. VSDependSet const& depends = this->VSTargetDepends[target];
  134. for (std::string const& name : depends) {
  135. std::string guid = this->GetGUID(name);
  136. if (guid.empty()) {
  137. std::string m = cmStrCat("Target: ", target->GetName(),
  138. " depends on unknown target: ", name);
  139. cmSystemTools::Error(m);
  140. }
  141. fout << "\t\t{" << guid << "} = {" << guid << "}\n";
  142. }
  143. }
  144. // Write a dsp file into the SLN file, Note, that dependencies from
  145. // executables to the libraries it uses are also done here
  146. void cmGlobalVisualStudio71Generator::WriteExternalProject(
  147. std::ostream& fout, const std::string& name, const std::string& location,
  148. cmValue typeGuid, const std::set<BT<std::pair<std::string, bool>>>& depends)
  149. {
  150. fout << "Project(\"{"
  151. << (typeGuid ? *typeGuid
  152. : std::string(
  153. cmGlobalVisualStudio71Generator::ExternalProjectType(
  154. location)))
  155. << "}\") = \"" << name << "\", \""
  156. << this->ConvertToSolutionPath(location) << "\", \"{"
  157. << this->GetGUID(name) << "}\"\n";
  158. // write out the dependencies here VS 7.1 includes dependencies with the
  159. // project instead of in the global section
  160. if (!depends.empty()) {
  161. fout << "\tProjectSection(ProjectDependencies) = postProject\n";
  162. for (BT<std::pair<std::string, bool>> const& it : depends) {
  163. std::string const& dep = it.Value.first;
  164. if (this->IsDepInSolution(dep)) {
  165. fout << "\t\t{" << this->GetGUID(dep) << "} = {" << this->GetGUID(dep)
  166. << "}\n";
  167. }
  168. }
  169. fout << "\tEndProjectSection\n";
  170. }
  171. fout << "EndProject\n";
  172. }
  173. // Write a dsp file into the SLN file, Note, that dependencies from
  174. // executables to the libraries it uses are also done here
  175. void cmGlobalVisualStudio71Generator::WriteProjectConfigurations(
  176. std::ostream& fout, const std::string& name, cmGeneratorTarget const& target,
  177. std::vector<std::string> const& configs,
  178. const std::set<std::string>& configsPartOfDefaultBuild,
  179. std::string const& platformMapping)
  180. {
  181. const std::string& platformName =
  182. !platformMapping.empty() ? platformMapping : this->GetPlatformName();
  183. std::string guid = this->GetGUID(name);
  184. for (std::string const& i : configs) {
  185. cmList mapConfig;
  186. const char* dstConfig = i.c_str();
  187. if (target.GetProperty("EXTERNAL_MSPROJECT")) {
  188. if (cmValue m = target.GetProperty(
  189. cmStrCat("MAP_IMPORTED_CONFIG_", cmSystemTools::UpperCase(i)))) {
  190. mapConfig.assign(*m);
  191. if (!mapConfig.empty()) {
  192. dstConfig = mapConfig[0].c_str();
  193. }
  194. }
  195. }
  196. fout << "\t\t{" << guid << "}." << i << ".ActiveCfg = " << dstConfig << '|'
  197. << platformName << std::endl;
  198. auto ci = configsPartOfDefaultBuild.find(i);
  199. if (!(ci == configsPartOfDefaultBuild.end())) {
  200. fout << "\t\t{" << guid << "}." << i << ".Build.0 = " << dstConfig << '|'
  201. << platformName << std::endl;
  202. }
  203. }
  204. }