123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134 |
- #include "build.h"
-
- #include <fstream>
- #include <stdexcept>
- #include <algorithm>
- #include <string.h>
-
- #include "sys.h"
- #include "BXParser.h"
- #include "CompileStep.h"
- #include "LinkStep.h"
- #include "logger.h"
-
- static std::string extension(const std::string &path) {
- size_t idx = path.find_last_of('.');
- if (idx >= std::string::npos) {
- return "";
- }
-
- char ext[16] = { 0 };
- strncpy(ext, path.c_str() + idx, sizeof(ext) - 1);
- return ext;
- }
-
- static void addFile(
- std::string path, BXVariables variables,
- std::vector<std::unique_ptr<DepNode>> &deps) {
- toolchain::FileType type;
- std::string ext = extension(path);
- if (ext == ".c") {
- type = toolchain::FileType::C;
- } else if (ext == ".C" || ext == ".cc" || ext == ".cxx" || ext == ".cpp") {
- type = toolchain::FileType::CXX;
- } else {
- return;
- }
-
- deps.push_back(std::make_unique<CompileStep>(std::move(path), type, std::move(variables)));
- }
-
- static void findDeps(
- const std::string &dir, const std::string &name,
- const BXVariables &variables, std::vector<std::unique_ptr<DepNode>> &deps) {
- std::string path = dir + "/" + name;
- sys::FileInfo info;
- try {
- info = sys::fileInfo(path);
- } catch (std::exception &ex) {
- logger::log(ex.what());
- return;
- }
-
- if (info.isDir) {
- // May or may not need to copy variables
- BXVariables subvars;
- const BXVariables *varsptr = &variables;
- std::vector<std::string> subpaths;
-
- // There might be a $path/build.bx. If there is, files in that dir
- // needs a new copy of variables, and that $path/build.bx might contain
- // a files property.
- if (sys::fileExists(path + "/build.bx")) {
- subvars = variables;
- varsptr = &subvars;
-
- std::ifstream stream = sys::ifstream("build.bx");
- BXParser parser(stream, BXParser::FLAG_NONE);
- parser.parse(subvars);
-
- auto it = subvars.find("files");
- if (it == subvars.end()) {
- sys::readDir(path, subpaths);
- } else {
- subpaths = it->second;
- subvars.erase(it);
- }
- } else {
- sys::readDir(path, subpaths);
- }
-
- std::sort(subpaths.begin(), subpaths.end());
- for (auto &subpath: subpaths) {
- findDeps(path, subpath, *varsptr, deps);
- }
- } else {
- addFile(std::move(path), variables, deps);
- }
- }
-
- static std::string findTargetName(const BXVariables &variables) {
- auto it = variables.find("target");
- if (it != variables.end() && it->second.size() != 0) {
- return it->second[0];
- }
-
- // TODO: Find from deps
-
- return "target";
- }
-
- std::unique_ptr<DepNode> buildDepTree(const std::string &outDir, BXVariables variables) {
- // Read config from file
- if (sys::fileExists("build.bx")) {
- std::ifstream stream = sys::ifstream("build.bx");
- BXParser parser(stream, BXParser::FLAG_NONE);
- parser.parse(variables);
- }
-
- // Find source files/dirs
- std::vector<std::string> sourcePaths;
- {
- auto it = variables.find("files");
- if (it == variables.end()) {
- sys::readDir(".", sourcePaths);
- } else {
- sourcePaths = it->second;
- variables.erase(it);
- }
- }
-
- // Find dependencies
- std::vector<std::unique_ptr<DepNode>> deps;
- for (std::string &path: sourcePaths) {
- findDeps(".", path, variables, deps);
- }
-
- std::unique_ptr<LinkStep> link = std::make_unique<LinkStep>(
- findTargetName(variables), toolchain::TargetType::BINARY);
- for (auto &dep: deps) {
- link->addChild(std::move(dep));
- }
-
- return link;
- }
|