cmAddSubDirectoryCommand.cxx 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  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 "cmAddSubDirectoryCommand.h"
  4. #include <sstream>
  5. #include <string.h>
  6. #include "cmMakefile.h"
  7. #include "cmSystemTools.h"
  8. class cmExecutionStatus;
  9. // cmAddSubDirectoryCommand
  10. bool cmAddSubDirectoryCommand::InitialPass(
  11. std::vector<std::string> const& args, cmExecutionStatus&)
  12. {
  13. if (args.empty()) {
  14. this->SetError("called with incorrect number of arguments");
  15. return false;
  16. }
  17. // store the binpath
  18. std::string const& srcArg = args[0];
  19. std::string binArg;
  20. bool excludeFromAll = false;
  21. // process the rest of the arguments looking for optional args
  22. std::vector<std::string>::const_iterator i = args.begin();
  23. ++i;
  24. for (; i != args.end(); ++i) {
  25. if (*i == "EXCLUDE_FROM_ALL") {
  26. excludeFromAll = true;
  27. continue;
  28. }
  29. if (binArg.empty()) {
  30. binArg = *i;
  31. } else {
  32. this->SetError("called with incorrect number of arguments");
  33. return false;
  34. }
  35. }
  36. // Compute the full path to the specified source directory.
  37. // Interpret a relative path with respect to the current source directory.
  38. std::string srcPath;
  39. if (cmSystemTools::FileIsFullPath(srcArg)) {
  40. srcPath = srcArg;
  41. } else {
  42. srcPath = this->Makefile->GetCurrentSourceDirectory();
  43. srcPath += "/";
  44. srcPath += srcArg;
  45. }
  46. if (!cmSystemTools::FileIsDirectory(srcPath)) {
  47. std::string error = "given source \"";
  48. error += srcArg;
  49. error += "\" which is not an existing directory.";
  50. this->SetError(error);
  51. return false;
  52. }
  53. srcPath = cmSystemTools::CollapseFullPath(srcPath);
  54. // Compute the full path to the binary directory.
  55. std::string binPath;
  56. if (binArg.empty()) {
  57. // No binary directory was specified. If the source directory is
  58. // not a subdirectory of the current directory then it is an
  59. // error.
  60. if (!cmSystemTools::IsSubDirectory(
  61. srcPath, this->Makefile->GetCurrentSourceDirectory())) {
  62. std::ostringstream e;
  63. e << "not given a binary directory but the given source directory "
  64. << "\"" << srcPath << "\" is not a subdirectory of \""
  65. << this->Makefile->GetCurrentSourceDirectory() << "\". "
  66. << "When specifying an out-of-tree source a binary directory "
  67. << "must be explicitly specified.";
  68. this->SetError(e.str());
  69. return false;
  70. }
  71. // Remove the CurrentDirectory from the srcPath and replace it
  72. // with the CurrentOutputDirectory.
  73. const char* src = this->Makefile->GetCurrentSourceDirectory();
  74. const char* bin = this->Makefile->GetCurrentBinaryDirectory();
  75. size_t srcLen = strlen(src);
  76. size_t binLen = strlen(bin);
  77. if (srcLen > 0 && src[srcLen - 1] == '/') {
  78. --srcLen;
  79. }
  80. if (binLen > 0 && bin[binLen - 1] == '/') {
  81. --binLen;
  82. }
  83. binPath = std::string(bin, binLen) + srcPath.substr(srcLen);
  84. } else {
  85. // Use the binary directory specified.
  86. // Interpret a relative path with respect to the current binary directory.
  87. if (cmSystemTools::FileIsFullPath(binArg)) {
  88. binPath = binArg;
  89. } else {
  90. binPath = this->Makefile->GetCurrentBinaryDirectory();
  91. binPath += "/";
  92. binPath += binArg;
  93. }
  94. }
  95. binPath = cmSystemTools::CollapseFullPath(binPath);
  96. // Add the subdirectory using the computed full paths.
  97. this->Makefile->AddSubDirectory(srcPath, binPath, excludeFromAll, true);
  98. return true;
  99. }