cmBuildCommand.cxx 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. /*============================================================================
  2. CMake - Cross Platform Makefile Generator
  3. Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
  4. Distributed under the OSI-approved BSD License (the "License");
  5. see accompanying file Copyright.txt for details.
  6. This software is distributed WITHOUT ANY WARRANTY; without even the
  7. implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  8. See the License for more information.
  9. ============================================================================*/
  10. #include "cmBuildCommand.h"
  11. #include "cmLocalGenerator.h"
  12. #include "cmGlobalGenerator.h"
  13. //----------------------------------------------------------------------
  14. bool cmBuildCommand
  15. ::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
  16. {
  17. // Support the legacy signature of the command:
  18. //
  19. if(2 == args.size())
  20. {
  21. return this->TwoArgsSignature(args);
  22. }
  23. return this->MainSignature(args);
  24. }
  25. //----------------------------------------------------------------------
  26. bool cmBuildCommand
  27. ::MainSignature(std::vector<std::string> const& args)
  28. {
  29. if(args.size() < 1)
  30. {
  31. this->SetError("requires at least one argument naming a CMake variable");
  32. return false;
  33. }
  34. // The cmake variable in which to store the result.
  35. const char* variable = args[0].c_str();
  36. // Parse remaining arguments.
  37. const char* configuration = 0;
  38. const char* project_name = 0;
  39. const char* target = 0;
  40. enum Doing { DoingNone, DoingConfiguration, DoingProjectName, DoingTarget };
  41. Doing doing = DoingNone;
  42. for(unsigned int i=1; i < args.size(); ++i)
  43. {
  44. if(args[i] == "CONFIGURATION")
  45. {
  46. doing = DoingConfiguration;
  47. }
  48. else if(args[i] == "PROJECT_NAME")
  49. {
  50. doing = DoingProjectName;
  51. }
  52. else if(args[i] == "TARGET")
  53. {
  54. doing = DoingTarget;
  55. }
  56. else if(doing == DoingConfiguration)
  57. {
  58. doing = DoingNone;
  59. configuration = args[i].c_str();
  60. }
  61. else if(doing == DoingProjectName)
  62. {
  63. doing = DoingNone;
  64. project_name = args[i].c_str();
  65. }
  66. else if(doing == DoingTarget)
  67. {
  68. doing = DoingNone;
  69. target = args[i].c_str();
  70. }
  71. else
  72. {
  73. cmOStringStream e;
  74. e << "unknown argument \"" << args[i] << "\"";
  75. this->SetError(e.str().c_str());
  76. return false;
  77. }
  78. }
  79. const char* makeprogram
  80. = this->Makefile->GetDefinition("CMAKE_MAKE_PROGRAM");
  81. if(!makeprogram)
  82. {
  83. this->Makefile->IssueMessage(
  84. cmake::FATAL_ERROR,
  85. "build_command() requires CMAKE_MAKE_PROGRAM to be defined. "
  86. "Call project() or enable_language() first.");
  87. return true;
  88. }
  89. // If null/empty CONFIGURATION argument, GenerateBuildCommand uses 'Debug'
  90. // in the currently implemented multi-configuration global generators...
  91. // so we put this code here to end up with the same default configuration
  92. // as the original 2-arg build_command signature:
  93. //
  94. if(!configuration || !*configuration)
  95. {
  96. configuration = getenv("CMAKE_CONFIG_TYPE");
  97. }
  98. if(!configuration || !*configuration)
  99. {
  100. configuration = "Release";
  101. }
  102. // If null/empty PROJECT_NAME argument, use the Makefile's project name:
  103. //
  104. if(!project_name || !*project_name)
  105. {
  106. project_name = this->Makefile->GetProjectName();
  107. }
  108. // If null/empty TARGET argument, GenerateBuildCommand omits any mention
  109. // of a target name on the build command line...
  110. //
  111. std::string makecommand = this->Makefile->GetLocalGenerator()
  112. ->GetGlobalGenerator()->GenerateBuildCommand
  113. (makeprogram, project_name, 0, target, configuration, true, false);
  114. this->Makefile->AddDefinition(variable, makecommand.c_str());
  115. return true;
  116. }
  117. //----------------------------------------------------------------------
  118. bool cmBuildCommand
  119. ::TwoArgsSignature(std::vector<std::string> const& args)
  120. {
  121. if(args.size() < 2 )
  122. {
  123. this->SetError("called with less than two arguments");
  124. return false;
  125. }
  126. const char* define = args[0].c_str();
  127. const char* cacheValue
  128. = this->Makefile->GetDefinition(define);
  129. std::string makeprogram = args[1];
  130. std::string configType = "Release";
  131. const char* cfg = getenv("CMAKE_CONFIG_TYPE");
  132. if ( cfg )
  133. {
  134. configType = cfg;
  135. }
  136. std::string makecommand = this->Makefile->GetLocalGenerator()
  137. ->GetGlobalGenerator()->GenerateBuildCommand
  138. (makeprogram.c_str(), this->Makefile->GetProjectName(), 0,
  139. 0, configType.c_str(), true, false);
  140. if(cacheValue)
  141. {
  142. return true;
  143. }
  144. this->Makefile->AddCacheDefinition(define,
  145. makecommand.c_str(),
  146. "Command used to build entire project "
  147. "from the command line.",
  148. cmCacheManager::STRING);
  149. return true;
  150. }