#include "DepNode.h" #include #include #include "parallel.h" #include "logger.h" static void maybeAddStrings( std::unordered_set &set, const std::vector &vec, std::vector &out) { for (auto &str: vec) { auto pair = set.emplace(str); bool inserted = pair.second; if (inserted) { out.push_back(str); } } } void DepNode::addChild(std::shared_ptr node) { deps_.push_back(std::move(node)); } bool DepNode::hasChanged(const std::string &outDir) { if (has_changed_ == TriState::TRUE) { return true; } else if (has_changed_ == TriState::FALSE) { return false; } else { for (auto &dep: deps_) { if (dep->hasChanged(outDir)) { has_changed_ = TriState::TRUE; return true; } } if (checkHasChanged(outDir)) { has_changed_ = TriState::TRUE; return true; } has_changed_ = TriState::FALSE; return false; } } void DepNode::startBuild(const std::string &outDir) { std::unique_lock lock(mut_); if (build_complete_|| build_started_) { return; } if (!hasChanged(outDir)) { return; } build_started_ = true; lock.unlock(); for (auto &dep: deps_) { dep->startBuild(outDir); } for (auto &dep: deps_) { dep->joinBuild(); } parallel::run([&] { doBuild(outDir); std::unique_lock lock(mut_); build_complete_ = true; build_cond_.notify_all(); }); } void DepNode::joinBuild() { std::unique_lock lock(mut_); if (build_complete_ || !build_started_) { return; } build_cond_.wait(lock, [this] { return build_complete_; }); } void DepNode::writeCompDB(const std::string &outDir, compdb::Writer &w) { std::unique_lock lock(mut_); doWriteCompDB(outDir, w); lock.unlock(); for (auto &dep: deps_) { dep->writeCompDB(outDir, w); } } std::vector DepNode::publicLDFlags(const std::string &outDir) { std::unordered_set set; std::vector flags; maybeAddStrings(set, getPublicLDFlags(outDir), flags); for (auto &dep: deps_) { maybeAddStrings(set, dep->publicLDFlags(outDir), flags); } return flags; } std::vector DepNode::publicLDLibs(const std::string &outDir) { std::unordered_set set; std::vector libs; maybeAddStrings(set, getPublicLDLibs(outDir), libs); for (auto &dep: deps_) { maybeAddStrings(set, dep->publicLDLibs(outDir), libs); } return libs; } std::vector DepNode::publicObjects(const std::string &outDir) { std::vector objs = getPublicObjects(outDir);; for (auto &dep: deps_) { for (auto &obj: dep->publicObjects(outDir)) { objs.push_back(obj); } } return objs; }