cmAddSubDirectoryCommand.cxx 3.3 KB

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