1
0

cmAddSubDirectoryCommand.cxx 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  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 <cstring>
  5. #include "cmExecutionStatus.h"
  6. #include "cmMakefile.h"
  7. #include "cmRange.h"
  8. #include "cmStringAlgorithms.h"
  9. #include "cmSystemTools.h"
  10. bool cmAddSubDirectoryCommand(std::vector<std::string> const& args,
  11. cmExecutionStatus& status)
  12. {
  13. if (args.empty()) {
  14. status.SetError("called with incorrect number of arguments");
  15. return false;
  16. }
  17. cmMakefile& mf = status.GetMakefile();
  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. status.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 = cmStrCat(mf.GetCurrentSourceDirectory(), '/', srcArg);
  42. }
  43. if (!cmSystemTools::FileIsDirectory(srcPath)) {
  44. std::string error = cmStrCat("given source \"", srcArg,
  45. "\" which is not an existing directory.");
  46. status.SetError(error);
  47. return false;
  48. }
  49. srcPath =
  50. cmSystemTools::CollapseFullPath(srcPath, mf.GetHomeOutputDirectory());
  51. // Compute the full path to the binary directory.
  52. std::string binPath;
  53. if (binArg.empty()) {
  54. // No binary directory was specified. If the source directory is
  55. // not a subdirectory of the current directory then it is an
  56. // error.
  57. if (!cmSystemTools::IsSubDirectory(srcPath,
  58. mf.GetCurrentSourceDirectory())) {
  59. status.SetError(
  60. cmStrCat("not given a binary directory but the given source ",
  61. "directory \"", srcPath, "\" is not a subdirectory of \"",
  62. mf.GetCurrentSourceDirectory(),
  63. "\". When specifying an "
  64. "out-of-tree source a binary directory must be explicitly "
  65. "specified."));
  66. return false;
  67. }
  68. // Remove the CurrentDirectory from the srcPath and replace it
  69. // with the CurrentOutputDirectory.
  70. const std::string& src = mf.GetCurrentSourceDirectory();
  71. const std::string& bin = mf.GetCurrentBinaryDirectory();
  72. size_t srcLen = src.length();
  73. size_t binLen = bin.length();
  74. if (srcLen > 0 && src.back() == '/') {
  75. --srcLen;
  76. }
  77. if (binLen > 0 && bin.back() == '/') {
  78. --binLen;
  79. }
  80. binPath = bin.substr(0, binLen) + srcPath.substr(srcLen);
  81. } else {
  82. // Use the binary directory specified.
  83. // Interpret a relative path with respect to the current binary directory.
  84. if (cmSystemTools::FileIsFullPath(binArg)) {
  85. binPath = binArg;
  86. } else {
  87. binPath = cmStrCat(mf.GetCurrentBinaryDirectory(), '/', binArg);
  88. }
  89. }
  90. binPath = cmSystemTools::CollapseFullPath(binPath);
  91. // Add the subdirectory using the computed full paths.
  92. mf.AddSubDirectory(srcPath, binPath, excludeFromAll, true);
  93. return true;
  94. }