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

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