123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190 |
- #include "SourceFile.h"
-
- #include <iostream>
- #include <fstream>
- #include <sstream>
- #include <string.h>
-
- #include "toolchain.h"
- #include "logger.h"
- #include "globals.h"
-
- static bool startsWith(BBParser &parser, const char *str) {
- for (size_t i = 0; str[i] != '\0'; ++i) {
- if (parser.peek() != str[i])
- return false;
- parser.skip();
- }
-
- return true;
- }
-
- SourceFile::FileType SourceFile::fileTypeFrom(const std::string &name) {
- size_t idx = name.find_last_of('.');
- if (idx >= std::string::npos) {
- return FileType::UNKNOWN;
- }
-
- char ext[16] = { 0 };
- strncpy(ext, name.c_str() + idx, sizeof(ext) - 1);
-
- if (strcmp(ext, ".c") == 0) {
- return FileType::C;
- } else if (
- (strcmp(ext, ".C") == 0) ||
- (strcmp(ext, ".cc") == 0) ||
- (strcmp(ext, ".cpp") == 0) ||
- (strcmp(ext, ".cxx") == 0)) {
- return FileType::CXX;
- }
-
- return FileType::UNKNOWN;
- }
-
- SourceFile::SourceFile(
- std::string dir, std::string name,
- FileType type, BBParser::Variables vars):
- dir_(std::move(dir)), name_(std::move(name)),
- type_(type), vars_(std::move(vars)) {
-
- std::ifstream file(dir_ + "/" + name_);
- BBParser parser(file, BBParser::FLAG_ONE_LINE);
-
- while (file.good()) {
- if (startsWith(parser, "//#bb")) {
- parser.parse(vars_);
- } else {
- while (file.good() && parser.get() != '\n');
- }
- }
- }
-
- std::string SourceFile::objectPath(const std::string &outDir) const {
- return toolchain::objectFilePath(dir(), name(), outDir);
- }
-
- const std::vector<std::string> *SourceFile::variable(const std::string &name) const {
- auto it = vars_.find(name);
- if (it == vars_.end()) {
- return nullptr;
- }
-
- return &it->second;
- }
-
- const std::vector<std::string> &SourceFile::compileFlags() const {
- if (hasCompileFlags_) {
- return compileFlags_;
- }
-
- const std::vector<std::string> *pkgs = variable("pkgs");
- if (pkgs != nullptr) {
- toolchain::getPkgConfigFlags(*pkgs, compileFlags_);
- }
-
- const std::vector<std::string> *cflags = nullptr;
- switch (type_) {
- case SourceFile::FileType::C:
- cflags = variable("cflags");
- break;
-
- case SourceFile::FileType::CXX:
- cflags = variable("cxxflags");
- break;
-
- case SourceFile::FileType::UNKNOWN:
- break;
- }
-
- if (cflags != nullptr) {
- for (const std::string &flag: *cflags) {
- compileFlags_.push_back(flag);
- }
- }
-
- hasCompileFlags_ = true;
- return compileFlags_;
- }
-
- std::vector<std::string> SourceFile::ldFlags() const {
- std::vector<std::string> ldFlags;
-
- const std::vector<std::string> *flags = variable("ldflags");
- if (flags != nullptr) {
- for (const std::string &flag: *flags) {
- ldFlags.push_back(std::move(flag));
- }
- }
-
- return ldFlags;
- }
-
- std::vector<std::string> SourceFile::ldLibs() const {
- std::vector<std::string> ldLibs;
-
- const std::vector<std::string> *pkgs = variable("pkgs");
- if (pkgs != nullptr) {
- toolchain::getPkgConfigLDLibs(*pkgs, ldLibs);
- }
-
- const std::vector<std::string> *libs = variable("ldlibs");
- if (libs != nullptr) {
- for (const std::string &flag: *libs) {
- ldLibs.push_back(std::move(flag));
- }
- }
-
- return ldLibs;
- }
-
- std::vector<std::string> SourceFile::dependencies() const {
- std::vector<std::string> deps;
- toolchain::getDependencies(compileFlags(), type_, dir_, name_, deps);
- return deps;
- }
-
- bool SourceFile::needsRecompile(const std::string &outDir) const {
- std::string outPath = objectPath(outDir);
- if (!sys::fileExists(outPath)) {
- return true;
- }
-
- sys::FileInfo outInfo = sys::fileInfo(outPath);
-
- std::vector<std::string> deps = dependencies();
- for (std::string &dep: deps) {
- sys::FileInfo depInfo = sys::fileInfo(dep);
-
- if (depInfo.mTimeSec > outInfo.mTimeSec || (
- depInfo.mTimeSec == outInfo.mTimeSec &&
- depInfo.mTimeNsec > outInfo.mTimeNsec)) {
- return true;
- }
- }
-
- return false;
- }
-
- void SourceFile::compile(const std::string &outDir) const {
- if (global::verbose == 0) {
- logger::log("Compile " + objectPath(outDir));
- }
-
- toolchain::compile(compileFlags(), type_, dir_, name_, outDir);
-
- // Nothing will need compile flags after it's compiled, so no reason to
- // keep it around in memory
- compileFlags_.clear();
- hasCompileFlags_ = false;
- }
-
- std::vector<std::string> SourceFile::compileCommand(const std::string &outDir) const {
- auto res = toolchain::getCompileCommand(compileFlags(), type_, dir_, name_, outDir);
-
- // Nothing will need compile flags after this, so no reason to
- // keep it around in memory
- compileFlags_.clear();
- hasCompileFlags_ = false;
-
- return res;
- }
|