Build tool
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

build.cc 3.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. #include "build.h"
  2. #include <fstream>
  3. #include <stdexcept>
  4. #include <algorithm>
  5. #include <string.h>
  6. #include "sys.h"
  7. #include "BXParser.h"
  8. #include "CompileStep.h"
  9. #include "LinkStep.h"
  10. #include "logger.h"
  11. namespace build {
  12. static std::string extension(const std::string &path) {
  13. size_t idx = path.find_last_of('.');
  14. if (idx >= std::string::npos) {
  15. return "";
  16. }
  17. char ext[16] = { 0 };
  18. strncpy(ext, path.c_str() + idx, sizeof(ext) - 1);
  19. return ext;
  20. }
  21. static void addFile(
  22. std::string path, BXVariables variables,
  23. std::vector<std::unique_ptr<DepNode>> &deps) {
  24. toolchain::FileType type;
  25. std::string ext = extension(path);
  26. if (ext == ".c") {
  27. type = toolchain::FileType::C;
  28. } else if (ext == ".C" || ext == ".cc" || ext == ".cxx" || ext == ".cpp") {
  29. type = toolchain::FileType::CXX;
  30. } else {
  31. return;
  32. }
  33. deps.push_back(std::make_unique<CompileStep>(std::move(path), type, std::move(variables)));
  34. }
  35. static void findDeps(
  36. const std::string &dir, const std::string &name,
  37. const BXVariables &variables, std::vector<std::unique_ptr<DepNode>> &deps) {
  38. std::string path = dir + "/" + name;
  39. sys::FileInfo info;
  40. try {
  41. info = sys::fileInfo(path);
  42. } catch (std::exception &ex) {
  43. logger::log(ex.what());
  44. return;
  45. }
  46. if (info.isDir) {
  47. // May or may not need to copy variables
  48. BXVariables subvars;
  49. const BXVariables *varsptr = &variables;
  50. std::vector<std::string> subpaths;
  51. // There might be a $path/build.bx. If there is, files in that dir
  52. // needs a new copy of variables, and that $path/build.bx might contain
  53. // a files property.
  54. if (sys::fileExists(path + "/build.bx")) {
  55. subvars = variables;
  56. varsptr = &subvars;
  57. bufio::IFStream stream("build.bx");
  58. BXParser parser(stream);
  59. parser.parse(subvars);
  60. auto it = subvars.find("files");
  61. if (it == subvars.end()) {
  62. sys::readDir(path, subpaths);
  63. } else {
  64. subpaths = it->second;
  65. subvars.erase(it);
  66. }
  67. } else {
  68. sys::readDir(path, subpaths);
  69. }
  70. std::sort(subpaths.begin(), subpaths.end());
  71. for (auto &subpath: subpaths) {
  72. findDeps(path, subpath, *varsptr, deps);
  73. }
  74. } else {
  75. addFile(std::move(path), variables, deps);
  76. }
  77. }
  78. std::string findTargetName(const BXVariables &variables) {
  79. auto it = variables.find("target");
  80. if (it != variables.end() && it->second.size() != 0) {
  81. return it->second[0];
  82. }
  83. // TODO: Find from deps
  84. return "target";
  85. }
  86. std::unique_ptr<DepNode> buildDepTree(const std::string &outDir, BXVariables variables) {
  87. // Read config from file
  88. if (sys::fileExists("build.bx")) {
  89. bufio::IFStream stream("build.bx");
  90. BXParser parser(stream);
  91. parser.parse(variables);
  92. }
  93. // Find source files/dirs
  94. std::vector<std::string> sourcePaths;
  95. {
  96. auto it = variables.find("files");
  97. if (it == variables.end()) {
  98. sys::readDir(".", sourcePaths);
  99. } else {
  100. sourcePaths = it->second;
  101. variables.erase(it);
  102. }
  103. }
  104. // Find dependencies
  105. std::vector<std::unique_ptr<DepNode>> deps;
  106. for (std::string &path: sourcePaths) {
  107. findDeps(".", path, variables, deps);
  108. }
  109. std::unique_ptr<LinkStep> link = std::make_unique<LinkStep>(
  110. findTargetName(variables), toolchain::TargetType::BINARY);
  111. for (auto &dep: deps) {
  112. link->addChild(std::move(dep));
  113. }
  114. return link;
  115. }
  116. }