cmLocalVisualStudioGenerator.cxx 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. /*=========================================================================
  2. Program: CMake - Cross-Platform Makefile Generator
  3. Module: $RCSfile$
  4. Language: C++
  5. Date: $Date$
  6. Version: $Revision$
  7. Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved.
  8. See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
  9. This software is distributed WITHOUT ANY WARRANTY; without even
  10. the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  11. PURPOSE. See the above copyright notices for more information.
  12. =========================================================================*/
  13. #include "cmLocalVisualStudioGenerator.h"
  14. #include "cmGlobalGenerator.h"
  15. #include "cmMakefile.h"
  16. #include "cmSourceFile.h"
  17. #include "cmSystemTools.h"
  18. //----------------------------------------------------------------------------
  19. cmLocalVisualStudioGenerator::cmLocalVisualStudioGenerator()
  20. {
  21. this->WindowsShell = true;
  22. this->WindowsVSIDE = true;
  23. }
  24. //----------------------------------------------------------------------------
  25. cmLocalVisualStudioGenerator::~cmLocalVisualStudioGenerator()
  26. {
  27. }
  28. //----------------------------------------------------------------------------
  29. bool cmLocalVisualStudioGenerator::SourceFileCompiles(const cmSourceFile* sf)
  30. {
  31. // Identify the language of the source file.
  32. if(const char* lang = this->GetSourceFileLanguage(*sf))
  33. {
  34. // Check whether this source will actually be compiled.
  35. return (!sf->GetCustomCommand() &&
  36. !sf->GetPropertyAsBool("HEADER_FILE_ONLY") &&
  37. !sf->GetPropertyAsBool("EXTERNAL_OBJECT"));
  38. }
  39. else
  40. {
  41. // Unknown source file language. Assume it will not be compiled.
  42. return false;
  43. }
  44. }
  45. //----------------------------------------------------------------------------
  46. void cmLocalVisualStudioGenerator::ComputeObjectNameRequirements
  47. (std::vector<cmSourceGroup> const& sourceGroups)
  48. {
  49. // Clear the current set of requirements.
  50. this->NeedObjectName.clear();
  51. // Count the number of object files with each name. Note that
  52. // windows file names are not case sensitive.
  53. std::map<cmStdString, int> objectNameCounts;
  54. for(unsigned int i = 0; i < sourceGroups.size(); ++i)
  55. {
  56. cmSourceGroup sg = sourceGroups[i];
  57. std::vector<const cmSourceFile*> const& srcs = sg.GetSourceFiles();
  58. for(std::vector<const cmSourceFile*>::const_iterator s = srcs.begin();
  59. s != srcs.end(); ++s)
  60. {
  61. const cmSourceFile* sf = *s;
  62. if(this->SourceFileCompiles(sf))
  63. {
  64. std::string objectName =
  65. cmSystemTools::LowerCase(
  66. cmSystemTools::GetFilenameWithoutLastExtension(
  67. sf->GetFullPath().c_str()));
  68. objectName += ".obj";
  69. objectNameCounts[objectName] += 1;
  70. }
  71. }
  72. }
  73. // For all source files producing duplicate names we need unique
  74. // object name computation.
  75. for(unsigned int i = 0; i < sourceGroups.size(); ++i)
  76. {
  77. cmSourceGroup sg = sourceGroups[i];
  78. std::vector<const cmSourceFile*> const& srcs = sg.GetSourceFiles();
  79. for(std::vector<const cmSourceFile*>::const_iterator s = srcs.begin();
  80. s != srcs.end(); ++s)
  81. {
  82. const cmSourceFile* sf = *s;
  83. if(this->SourceFileCompiles(sf))
  84. {
  85. std::string objectName =
  86. cmSystemTools::LowerCase(
  87. cmSystemTools::GetFilenameWithoutLastExtension(
  88. sf->GetFullPath().c_str()));
  89. objectName += ".obj";
  90. if(objectNameCounts[objectName] > 1)
  91. {
  92. this->NeedObjectName.insert(sf);
  93. }
  94. }
  95. }
  96. }
  97. }
  98. //----------------------------------------------------------------------------
  99. std::string
  100. cmLocalVisualStudioGenerator
  101. ::ConstructScript(const cmCustomCommandLines& commandLines,
  102. const char* workingDirectory,
  103. bool escapeOldStyle,
  104. bool escapeAllowMakeVars,
  105. const char* newline_text)
  106. {
  107. // Avoid leading or trailing newlines.
  108. const char* newline = "";
  109. // Store the script in a string.
  110. std::string script;
  111. if(workingDirectory)
  112. {
  113. script += newline;
  114. newline = newline_text;
  115. script += "cd ";
  116. script += this->Convert(workingDirectory, START_OUTPUT, SHELL);
  117. }
  118. // for visual studio IDE add extra stuff to the PATH
  119. // if CMAKE_MSVCIDE_RUN_PATH is set.
  120. if(this->Makefile->GetDefinition("MSVC_IDE"))
  121. {
  122. const char* extraPath =
  123. this->Makefile->GetDefinition("CMAKE_MSVCIDE_RUN_PATH");
  124. if(extraPath)
  125. {
  126. script += newline;
  127. newline = newline_text;
  128. script += "set PATH=";
  129. script += extraPath;
  130. script += ";%PATH%";
  131. }
  132. }
  133. // Write each command on a single line.
  134. for(cmCustomCommandLines::const_iterator cl = commandLines.begin();
  135. cl != commandLines.end(); ++cl)
  136. {
  137. // Start a new line.
  138. script += newline;
  139. newline = newline_text;
  140. // Start with the command name.
  141. const cmCustomCommandLine& commandLine = *cl;
  142. if(!workingDirectory)
  143. {
  144. script += this->Convert(commandLine[0].c_str(),START_OUTPUT,SHELL);
  145. }
  146. else
  147. {
  148. script += this->Convert(commandLine[0].c_str(),NONE,SHELL);
  149. }
  150. // Add the arguments.
  151. for(unsigned int j=1;j < commandLine.size(); ++j)
  152. {
  153. script += " ";
  154. if(escapeOldStyle)
  155. {
  156. script += this->EscapeForShellOldStyle(commandLine[j].c_str());
  157. }
  158. else
  159. {
  160. script += this->EscapeForShell(commandLine[j].c_str(),
  161. escapeAllowMakeVars);
  162. }
  163. }
  164. }
  165. return script;
  166. }