cmUtilitySourceCommand.cxx 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  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 "cmUtilitySourceCommand.h"
  4. // cmUtilitySourceCommand
  5. bool cmUtilitySourceCommand::InitialPass(std::vector<std::string> const& args,
  6. cmExecutionStatus&)
  7. {
  8. if (this->Disallowed(
  9. cmPolicies::CMP0034,
  10. "The utility_source command should not be called; see CMP0034.")) {
  11. return true;
  12. }
  13. if (args.size() < 3) {
  14. this->SetError("called with incorrect number of arguments");
  15. return false;
  16. }
  17. std::vector<std::string>::const_iterator arg = args.begin();
  18. // The first argument is the cache entry name.
  19. std::string cacheEntry = *arg++;
  20. const char* cacheValue = this->Makefile->GetDefinition(cacheEntry);
  21. // If it exists already and appears up to date then we are done. If
  22. // the string contains "(IntDir)" but that is not the
  23. // CMAKE_CFG_INTDIR setting then the value is out of date.
  24. const char* intDir =
  25. this->Makefile->GetRequiredDefinition("CMAKE_CFG_INTDIR");
  26. bool haveCacheValue = false;
  27. if (this->Makefile->IsOn("CMAKE_CROSSCOMPILING")) {
  28. haveCacheValue = (cacheValue != CM_NULLPTR);
  29. if (!haveCacheValue) {
  30. std::string msg = "UTILITY_SOURCE is used in cross compiling mode for ";
  31. msg += cacheEntry;
  32. msg += ". If your intention is to run this executable, you need to "
  33. "preload the cache with the full path to a version of that "
  34. "program, which runs on this build machine.";
  35. cmSystemTools::Message(msg.c_str(), "Warning");
  36. }
  37. } else {
  38. cmState* state = this->Makefile->GetState();
  39. haveCacheValue =
  40. (cacheValue && (strstr(cacheValue, "(IntDir)") == CM_NULLPTR ||
  41. (intDir && strcmp(intDir, "$(IntDir)") == 0)) &&
  42. (state->GetCacheMajorVersion() != 0 &&
  43. state->GetCacheMinorVersion() != 0));
  44. }
  45. if (haveCacheValue) {
  46. return true;
  47. }
  48. // The second argument is the utility's executable name, which will be
  49. // needed later.
  50. std::string utilityName = *arg++;
  51. // The third argument specifies the relative directory of the source
  52. // of the utility.
  53. std::string relativeSource = *arg++;
  54. std::string utilitySource = this->Makefile->GetCurrentSourceDirectory();
  55. utilitySource = utilitySource + "/" + relativeSource;
  56. // If the directory doesn't exist, the source has not been included.
  57. if (!cmSystemTools::FileExists(utilitySource.c_str())) {
  58. return true;
  59. }
  60. // Make sure all the files exist in the source directory.
  61. while (arg != args.end()) {
  62. std::string file = utilitySource + "/" + *arg++;
  63. if (!cmSystemTools::FileExists(file.c_str())) {
  64. return true;
  65. }
  66. }
  67. // The source exists.
  68. std::string cmakeCFGout =
  69. this->Makefile->GetRequiredDefinition("CMAKE_CFG_INTDIR");
  70. std::string utilityDirectory = this->Makefile->GetCurrentBinaryDirectory();
  71. std::string exePath;
  72. if (this->Makefile->GetDefinition("EXECUTABLE_OUTPUT_PATH")) {
  73. exePath = this->Makefile->GetDefinition("EXECUTABLE_OUTPUT_PATH");
  74. }
  75. if (!exePath.empty()) {
  76. utilityDirectory = exePath;
  77. } else {
  78. utilityDirectory += "/" + relativeSource;
  79. }
  80. // Construct the cache entry for the executable's location.
  81. std::string utilityExecutable = utilityDirectory + "/" + cmakeCFGout + "/" +
  82. utilityName + this->Makefile->GetDefinition("CMAKE_EXECUTABLE_SUFFIX");
  83. // make sure we remove any /./ in the name
  84. cmSystemTools::ReplaceString(utilityExecutable, "/./", "/");
  85. // Enter the value into the cache.
  86. this->Makefile->AddCacheDefinition(cacheEntry, utilityExecutable.c_str(),
  87. "Path to an internal program.",
  88. cmStateEnums::FILEPATH);
  89. // add a value into the cache that maps from the
  90. // full path to the name of the project
  91. cmSystemTools::ConvertToUnixSlashes(utilityExecutable);
  92. this->Makefile->AddCacheDefinition(utilityExecutable, utilityName.c_str(),
  93. "Executable to project name.",
  94. cmStateEnums::INTERNAL);
  95. return true;
  96. }