|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176 |
- #include "CompileStep.h"
-
- #include <fstream>
-
- #include "sys.h"
- #include "toolchain.h"
- #include "logger.h"
- #include "globals.h"
-
- static bool startsWith(BXParser &parser, const char *str) {
- for (size_t i = 0; str[i] != '\0'; ++i) {
- if (parser.peek() != str[i])
- return false;
- parser.skip();
- }
-
- return true;
- }
-
- bool CompileStep::checkHasChanged(const std::string &outDir) {
- std::string objPath = toolchain::objectFilePath(path_, outDir);
- if (!sys::fileExists(objPath)) {
- return true;
- }
-
- sys::FileInfo objInfo = sys::fileInfo(objPath);
- sys::FileInfo sourceInfo = sys::fileInfo(path_);
- if (objInfo.isOlderThan(sourceInfo)) {
- return true;
- }
-
- std::string confPath = this->confPath(outDir);
- if (!sys::fileExists(confPath)) {
- return true;
- }
-
- BXVariables cachedVariables;
- try {
- bufio::IFStream f(confPath);
- BXParser parser(f);
- parser.parse(cachedVariables);
- } catch (BXParseError &err) {
- logger::log(confPath + ": " + err.what());
- return true;
- }
-
- // We can trust the cached "deps" value here, because we know
- // the object file hasn't actually changed.
- auto depsIt = cachedVariables.find("deps");
- if (depsIt == cachedVariables.end()) {
- logger::log(confPath + ": Missing 'deps' field");
- return true;
- }
-
- const std::vector<std::string> &deps = depsIt->second;
- for (const auto &dep: deps) {
- if (!sys::fileExists(dep)) {
- return true;
- }
-
- sys::FileInfo depInfo = sys::fileInfo(dep);
- if (objInfo.isOlderThan(depInfo)) {
- return true;
- }
- }
-
- // Maybe the build command has changed?
- auto commandIt = cachedVariables.find("command");
- if (commandIt == cachedVariables.end()) {
- logger::log(confPath + ": Missing 'command' field");
- return true;
- }
-
- if (compileCommand(outDir) != commandIt->second) {
- return true;
- }
-
- return false;
- }
-
- void CompileStep::doBuild(const std::string &outDir) {
-
- std::string objPath = toolchain::objectFilePath(path_, outDir);
- std::string dirPath = sys::dirname(objPath);
- std::vector<std::string> command = compileCommand(outDir);
-
- BXVariables newCachedVars = {
- { "deps", toolchain::getDependencies(flags(), type_, path_) },
- { "command", command},
- };
-
- sys::mkdirp(dirPath);
-
- bufio::OFStream f(confPath(outDir));
- BXWriter writer(f);
- writer.write(newCachedVars);
-
- sys::ProcConf conf;
- conf.print = true;
-
- switch (type_) {
- case toolchain::FileType::C:
- conf.prefix = "(CC)";
- break;
-
- case toolchain::FileType::CXX:
- conf.prefix = "(CXX)";
- break;
- }
-
- sys::execute(command, conf);
- }
-
- void CompileStep::doWriteCompDB(const std::string &outDir, compdb::Writer &w) {
- w.write(sys::cwd(), path_, compileCommand(outDir));
- }
-
- std::vector<std::string> CompileStep::getPublicLDFlags(const std::string &outDir) {
- BXVariables &vars = variables();
- std::vector<std::string> flags;
- toolchain::getLDFlags(vars, flags);
- return flags;
- }
-
- std::vector<std::string> CompileStep::getPublicLDLibs(const std::string &outDir) {
- BXVariables &vars = variables();
- std::vector<std::string> libs;
- toolchain::getLDLibs(vars, libs);
- return libs;
- }
-
- std::vector<std::string> CompileStep::getPublicObjects(const std::string &outDir) {
- return std::vector<std::string>{ toolchain::objectFilePath(path_, outDir) };
- }
-
- BXVariables &CompileStep::variables() {
- if (hasVariables_) {
- return variables_;
- }
-
- bufio::IFStream f(path_);
- BXParser parser(f);
-
- while (parser.peek() != EOF) {
- if (startsWith(parser, "//#bx")) {
- parser.parseLine(variables_);
- } else {
- while (parser.peek() != EOF && parser.get() != '\n');
- }
- }
-
- hasVariables_ = true;
- return variables_;
- }
-
- std::vector<std::string> &CompileStep::flags() {
- if (hasFlags_) {
- return flags_;
- }
-
- BXVariables &vars = variables();
-
- toolchain::getFlags(vars, type_, flags_);
- hasFlags_ = true;
- return flags_;
- }
-
- std::vector<std::string> &CompileStep::compileCommand(const std::string &outDir) {
- if (hasCompileCommand_) {
- return compileCommand_;
- }
-
- compileCommand_ = toolchain::getCompileCommand(flags(), type_, path_, outDir);
- hasCompileCommand_ = true;
- return compileCommand_;
- }
|