| @@ -345,3 +345,48 @@ void BBParser::parse(BBVariables &vars) { | |||
| doAssignment(); | |||
| } | |||
| void BBWriter::put(char ch) { | |||
| ch_ += 1; | |||
| stream_ << ch; | |||
| } | |||
| void BBWriter::put(const std::string &str) { | |||
| ch_ += str.size(); | |||
| stream_ << str; | |||
| } | |||
| void BBWriter::newline() { | |||
| ch_ = 1; | |||
| line_ += 1; | |||
| stream_ << '\n'; | |||
| } | |||
| void BBWriter::escape(const std::string &str) { | |||
| put('"'); | |||
| for (char ch: str) { | |||
| if (ch == '$' || ch == '"' || ch == '\\') { | |||
| put('\\'); | |||
| } | |||
| put(ch); | |||
| } | |||
| put('"'); | |||
| } | |||
| void BBWriter::write(const BBVariables &vars) { | |||
| for (const auto &pair: vars) { | |||
| put(pair.first); | |||
| put(" :="); | |||
| for (auto &val: pair.second) { | |||
| if (ch_ >= 80) { | |||
| newline(); | |||
| put('\t'); | |||
| } else { | |||
| put(' '); | |||
| } | |||
| escape(val); | |||
| } | |||
| newline(); | |||
| } | |||
| } | |||
| @@ -43,6 +43,7 @@ private: | |||
| EQUALS_PLUS, | |||
| NONE, | |||
| }; | |||
| [[noreturn]] void error(std::string); | |||
| Operator readOperator(); | |||
| @@ -61,3 +62,21 @@ private: | |||
| int ch_; | |||
| std::istream &stream_; | |||
| }; | |||
| class BBWriter { | |||
| public: | |||
| BBWriter(std::ostream &stream, int line = 1, int ch = 1): | |||
| line_(line), ch_(ch), stream_(stream) {} | |||
| void write(const BBVariables &vars); | |||
| private: | |||
| void put(char ch); | |||
| void put(const std::string &str); | |||
| void newline(); | |||
| void escape(const std::string &str); | |||
| int line_; | |||
| int ch_; | |||
| std::ostream &stream_; | |||
| }; | |||
| @@ -29,7 +29,7 @@ bool CompileStep::checkHasChanged(const std::string &outDir) { | |||
| return true; | |||
| } | |||
| std::string bbPath = this->bbPath(); | |||
| std::string bbPath = this->bbPath(outDir); | |||
| if (!sys::fileExists(bbPath)) { | |||
| return true; | |||
| } | |||
| @@ -90,7 +90,9 @@ void CompileStep::doBuild(const std::string &outDir) { | |||
| { "command", command}, | |||
| }; | |||
| // TODO: Write newCachedVars to bbPath() | |||
| std::ofstream f(bbPath(outDir)); | |||
| BBWriter writer(f); | |||
| writer.write(newCachedVars); | |||
| sys::mkdirp(dirPath); | |||
| sys::execute(command, nullptr, global::verbose >= 1); | |||
| @@ -31,5 +31,5 @@ private: | |||
| std::vector<std::string> compileCommand_; | |||
| std::vector<std::string> &compileCommand(const std::string &outDir); | |||
| std::string bbPath() { return path_ + ".bb"; } | |||
| std::string bbPath(const std::string &outDir) { return outDir + '/' + path_ + ".bb"; } | |||
| }; | |||
| @@ -31,7 +31,7 @@ bool DepNode::haveDepsChanged(const std::string &outDir) { | |||
| std::mutex mut; | |||
| std::condition_variable cond; | |||
| std::unique_lock<std::mutex> lock(mut); | |||
| std::unique_lock<std::mutex> lock(mut, std::defer_lock); | |||
| while (it != deps_.end()) { | |||
| lock.lock(); | |||
| if (changed) { | |||
| @@ -14,7 +14,7 @@ bool LinkStep::checkHasChanged(const std::string &outDir) { | |||
| return true; | |||
| } | |||
| std::string bbPath = this->bbPath(); | |||
| std::string bbPath = this->bbPath(outDir); | |||
| if (!sys::fileExists(bbPath)) { | |||
| return true; | |||
| } | |||
| @@ -44,7 +44,19 @@ bool LinkStep::checkHasChanged(const std::string &outDir) { | |||
| void LinkStep::doBuild(const std::string &outDir) { | |||
| logger::log("Link " + path_); | |||
| sys::execute(linkCommand(outDir), nullptr, global::verbose >= 1); | |||
| std::vector<std::string> command = linkCommand(outDir); | |||
| std::string dirPath = sys::dirname(outDir + '/' + path_); | |||
| BBVariables newCachedVars = { | |||
| { "command", command}, | |||
| }; | |||
| std::ofstream f(bbPath(outDir)); | |||
| BBWriter writer(f); | |||
| writer.write(newCachedVars); | |||
| sys::mkdirp(dirPath); | |||
| sys::execute(command, nullptr, global::verbose >= 1); | |||
| } | |||
| std::vector<std::string> &LinkStep::linkCommand(const std::string &outDir) { | |||
| @@ -21,5 +21,5 @@ private: | |||
| std::vector<std::string> linkCommand_; | |||
| std::vector<std::string> &linkCommand(const std::string &outDir); | |||
| std::string bbPath() { return path_ + ".bb"; } | |||
| std::string bbPath(const std::string &outDir) { return outDir + '/' + path_ + ".bb"; } | |||
| }; | |||
| @@ -2,6 +2,7 @@ | |||
| #include <fstream> | |||
| #include <stdexcept> | |||
| #include <algorithm> | |||
| #include <string.h> | |||
| #include "sys.h" | |||
| @@ -70,6 +71,7 @@ static void findDeps( | |||
| sys::readDir(path, subpaths); | |||
| } | |||
| std::sort(subpaths.begin(), subpaths.end()); | |||
| for (auto &subpath: subpaths) { | |||
| findDeps(path, subpath, *varsptr, deps); | |||
| } | |||