cmTransformDepfile.cxx 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  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 "cmTransformDepfile.h"
  4. #include <string>
  5. #include <type_traits>
  6. #include <utility>
  7. #include <vector>
  8. #include <cm/optional>
  9. #include "cmsys/FStream.hxx"
  10. #include "cmGccDepfileReader.h"
  11. #include "cmGccDepfileReaderTypes.h"
  12. #include "cmSystemTools.h"
  13. namespace {
  14. void WriteFilenameGcc(cmsys::ofstream& fout, const std::string& filename)
  15. {
  16. for (auto c : filename) {
  17. switch (c) {
  18. case ' ':
  19. fout << "\\ ";
  20. break;
  21. case '\\':
  22. fout << "\\\\";
  23. break;
  24. default:
  25. fout << c;
  26. break;
  27. }
  28. }
  29. }
  30. void WriteGccDepfile(cmsys::ofstream& fout, const cmGccDepfileContent& content)
  31. {
  32. for (auto const& dep : content) {
  33. bool first = true;
  34. for (auto const& rule : dep.rules) {
  35. if (!first) {
  36. fout << " \\\n ";
  37. }
  38. first = false;
  39. WriteFilenameGcc(fout, rule);
  40. }
  41. fout << ':';
  42. for (auto const& path : dep.paths) {
  43. fout << " \\\n ";
  44. WriteFilenameGcc(fout, path);
  45. }
  46. fout << '\n';
  47. }
  48. }
  49. void WriteVsTlog(cmsys::ofstream& fout, const cmGccDepfileContent& content)
  50. {
  51. for (auto const& dep : content) {
  52. fout << '^';
  53. bool first = true;
  54. for (auto const& rule : dep.rules) {
  55. if (!first) {
  56. fout << '|';
  57. }
  58. first = false;
  59. fout << cmSystemTools::ConvertToOutputPath(rule);
  60. }
  61. fout << "\r\n";
  62. for (auto const& path : dep.paths) {
  63. fout << cmSystemTools::ConvertToOutputPath(path) << "\r\n";
  64. }
  65. }
  66. }
  67. }
  68. bool cmTransformDepfile(cmDepfileFormat format, const std::string& prefix,
  69. const std::string& infile, const std::string& outfile)
  70. {
  71. cmGccDepfileContent content;
  72. if (cmSystemTools::FileExists(infile)) {
  73. auto result = cmReadGccDepfile(infile.c_str(), prefix);
  74. if (!result) {
  75. return false;
  76. }
  77. content = *std::move(result);
  78. }
  79. cmsys::ofstream fout(outfile.c_str());
  80. if (!fout) {
  81. return false;
  82. }
  83. switch (format) {
  84. case cmDepfileFormat::GccDepfile:
  85. WriteGccDepfile(fout, content);
  86. break;
  87. case cmDepfileFormat::VsTlog:
  88. WriteVsTlog(fout, content);
  89. break;
  90. }
  91. return true;
  92. }