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