#include "LinkStep.h" #include #include #include "sys.h" #include "logger.h" #include "globals.h" #include "BXParser.h" bool LinkStep::checkHasChanged(const std::string &outDir) { std::string targetPath = toolchain::targetFilePath(type_, path_, outDir); if (!sys::fileExists(targetPath)) { return true; } std::string confPath = this->confPath(outDir); if (!sys::fileExists(confPath)) { return true; } BXVariables cachedVariables; try { std::ifstream f = sys::ifstream(confPath); BXParser parser(f, BXParser::FLAG_NONE); parser.parse(cachedVariables); } catch (BXParseError &err) { logger::log(confPath + ": " + err.what()); return true; } auto commandIt = cachedVariables.find("command"); if (commandIt == cachedVariables.end()) { logger::log(confPath + ": Missing 'command' field"); return true; } if (linkCommand(outDir) != commandIt->second) { return true; } return false; } void LinkStep::doBuild(const std::string &outDir) { logger::log("Link " + path_); std::vector command = linkCommand(outDir); std::string dirPath = sys::dirname(outDir + '/' + path_); BXVariables newCachedVars = { { "command", command}, }; std::ofstream f = sys::ofstream(confPath(outDir)); BXWriter writer(f); writer.write(newCachedVars); sys::mkdirp(dirPath); sys::execute(command, nullptr, global::verbose >= 1); } std::vector &LinkStep::linkCommand(const std::string &outDir) { if (hasLinkCommand_) { return linkCommand_; } std::vector objs; for (auto &dep: deps_) { for (auto &obj: dep->publicObjects(outDir)) { objs.push_back(obj); } } // TODO: Don't use FileType::CXX hard-coded here linkCommand_ = toolchain::getLinkCommand( publicLDFlags(outDir), publicLDLibs(outDir), toolchain::FileType::CXX, type_, objs, path_, outDir); hasLinkCommand_ = true; return linkCommand_; }