diff options
Diffstat (limited to 'src/task_cc.cc')
-rw-r--r-- | src/task_cc.cc | 235 |
1 files changed, 109 insertions, 126 deletions
diff --git a/src/task_cc.cc b/src/task_cc.cc index 8256c70..c4343b6 100644 --- a/src/task_cc.cc +++ b/src/task_cc.cc @@ -5,132 +5,85 @@ #include <iostream> #include <fstream> +#include <cassert> #include "libctor.h" -#include "settings.h" #include "execute.h" - -namespace -{ -std::string readFile(const std::string &fileName) -{ - std::ifstream ifs(fileName.c_str(), std::ios::in | std::ios::binary | std::ios::ate); - - std::ifstream::pos_type fileSize = ifs.tellg(); - ifs.seekg(0, std::ios::beg); - - std::vector<char> bytes(fileSize); - ifs.read(bytes.data(), fileSize); - - return std::string(bytes.data(), fileSize); -} - -std::vector<std::string> readDeps(const std::string& depFile) -{ - if(!std::filesystem::exists(depFile)) - { - return {}; - } - - auto str = readFile(depFile); - - std::vector<std::string> output; - std::string tmp; - bool start{false}; - bool in_whitespace{false}; - for(const auto& c : str) - { - if(c == '\\' || c == '\n') - { - continue; - } - - if(c == ':') - { - start = true; - continue; - } - - if(!start) - { - continue; - } - - if(c == ' ' || c == '\t') - { - if(in_whitespace) - { - continue; - } - - if(!tmp.empty()) - { - output.push_back(tmp); - } - tmp.clear(); - in_whitespace = true; - } - else - { - in_whitespace = false; - tmp += c; - } - } - - if(!tmp.empty()) - { - output.push_back(tmp); - } - - return output; -} -} // namespace :: +#include "util.h" +#include "tools.h" TaskCC::TaskCC(const BuildConfiguration& config, const Settings& settings, - const std::string& sourceDir, const std::string& source) - : Task(config) + const std::string& sourceDir, const Source& source) + : Task(config, settings, sourceDir) , config(config) , settings(settings) , sourceDir(sourceDir) + , _source(source) { sourceFile = sourceDir; - sourceFile /= source; + sourceFile /= source.file; + + std::filesystem::path base = sourceFile.parent_path(); + std::filesystem::create_directories(std::filesystem::path(settings.builddir) / base); - std::filesystem::path base = settings.builddir; - base /= config.target; + base /= cleanUp(config.target); base += "-"; base += sourceFile.stem(); - if(sourceFile.extension().string() == ".c") + target_type = TargetType::Object; + source_language = source.language; + if(source_language == Language::Auto) { - base += "_c"; + source_language = languageFromExtension(sourceFile); } - else + + switch(source_language) { + case Language::C: + base += "_c"; + break; + case Language::Cpp: base += "_cc"; + break; + case Language::Asm: + base += "_asm"; + break; + case Language::Auto: + assert(0 && "This should never happen"); + break; } - targetFile = base; - targetFile += ".o"; - depsFile = base; - depsFile += ".d"; - flagsFile = base; - flagsFile += ".flags"; - - target_type = TargetType::Object; - if(sourceFile.extension().string() == ".c") + if(source.output.empty()) { - source_language = Language::C; + _targetFile = base; + _targetFile += ".o"; } else { - source_language = Language::Cpp; + _targetFile = source.output; } + depsFile = targetFile().parent_path() / targetFile().stem(); + depsFile += ".d"; + flagsFile = targetFile().parent_path() / targetFile().stem(); + flagsFile += ".flags"; +} + +int TaskCC::registerDepTasksInner(const std::set<std::shared_ptr<Task>>& tasks) +{ + for(const auto& task : tasks) + { + if(*task == _source.file) + { + dependsTasks.insert(task); + } + } + + return 0; } std::string TaskCC::name() const { - return target(); + return {}; } bool TaskCC::dirtyInner() @@ -141,7 +94,7 @@ bool TaskCC::dirtyInner() return true; } - if(!std::filesystem::exists(targetFile)) + if(!std::filesystem::exists(targetFile())) { //std::cout << "Missing targetFile\n"; return true; @@ -179,7 +132,7 @@ bool TaskCC::dirtyInner() for(const auto& dep : depList) { if(!std::filesystem::exists(dep) || - std::filesystem::last_write_time(targetFile) < + std::filesystem::last_write_time(targetFile()) < std::filesystem::last_write_time(dep)) { //std::cout << "The targetFile older than " << std::string(dep) << "\n"; @@ -188,7 +141,7 @@ bool TaskCC::dirtyInner() } if(std::filesystem::last_write_time(sourceFile) > - std::filesystem::last_write_time(targetFile)) + std::filesystem::last_write_time(targetFile())) { //std::cout << "The targetFile older than sourceFile\n"; return true; @@ -214,9 +167,22 @@ int TaskCC::runInner() if(settings.verbose == 0) { - std::cout << compiler() << " " << + switch(sourceLanguage()) + { + case Language::C: + std::cout << "CC "; + break; + case Language::Cpp: + std::cout << "CXX "; + break; + case Language::Auto: + case Language::Asm: + // Only c/c++ handled by this task type. + break; + } + std::cout << sourceFile.lexically_normal().string() << " => " << - targetFile.lexically_normal().string() << "\n"; + targetFile().lexically_normal().string() << "\n"; } return execute(compiler(), args, settings.verbose > 0); @@ -224,10 +190,10 @@ int TaskCC::runInner() int TaskCC::clean() { - if(std::filesystem::exists(targetFile)) + if(std::filesystem::exists(targetFile())) { - std::cout << "Removing " << targetFile.string() << "\n"; - std::filesystem::remove(targetFile); + std::cout << "Removing " << targetFile().string() << "\n"; + std::filesystem::remove(targetFile()); } if(std::filesystem::exists(depsFile)) @@ -252,7 +218,17 @@ std::vector<std::string> TaskCC::depends() const std::string TaskCC::target() const { - return targetFile.string(); + return _targetFile.string(); +} + +std::filesystem::path TaskCC::targetFile() const +{ + return std::filesystem::path(settings.builddir) / _targetFile; +} + +bool TaskCC::derived() const +{ + return true; } std::string TaskCC::toJSON() const @@ -261,7 +237,7 @@ std::string TaskCC::toJSON() const json += "\t{\n"; json += "\t\t\"directory\": \"" + sourceDir.string() + "\",\n"; json += "\t\t\"file\": \"" + sourceFile.lexically_normal().string() + "\",\n"; - json += "\t\t\"output\": \"" + targetFile.string() + "\",\n"; + json += "\t\t\"output\": \"" + targetFile().string() + "\",\n"; json += "\t\t\"arguments\": [ \"" + compiler() + "\""; auto args = getCompilerArgs(); for(const auto& arg : args) @@ -273,14 +249,19 @@ std::string TaskCC::toJSON() const return json; } +std::string TaskCC::source() const +{ + return sourceFile.string(); +} + std::vector<std::string> TaskCC::flags() const { switch(sourceLanguage()) { case Language::C: - return config.cflags; + return config.flags.cflags; case Language::Cpp: - return config.cxxflags; + return config.flags.cxxflags; default: std::cerr << "Unknown CC target type\n"; exit(1); @@ -300,39 +281,41 @@ std::string TaskCC::flagsString() const std::vector<std::string> TaskCC::getCompilerArgs() const { + auto tool_chain = getToolChain(config.system); + auto compiler_flags = flags(); std::vector<std::string> args; - args.push_back("-MMD"); + append(args, getOption(tool_chain, opt::generate_dep_tree)); if(std::filesystem::path(config.target).extension() == ".so") { // Add -fPIC arg to all contained object files - args.push_back("-fPIC"); + append(args, getOption(tool_chain, opt::position_independent_code)); } - args.push_back("-c"); + append(args, getOption(tool_chain, opt::no_link)); args.push_back(sourceFile.string()); - args.push_back("-o"); - args.push_back(targetFile.string()); + append(args, getOption(tool_chain, opt::output, targetFile().string())); for(const auto& flag : compiler_flags) { - // Is arg an added include path? - if(flag.substr(0, 2) == "-I") + auto option = getOption(flag); + switch(option.first) { - std::string include_path = flag.substr(2); - include_path.erase(0, include_path.find_first_not_of(' ')); - std::filesystem::path path(include_path); - - // Is it relative? - if(path.is_relative()) + // Relative include paths has to be altered to be relative to sourceDir + case opt::include_path: { - path = (sourceDir / path).lexically_normal(); - std::string new_include_path = "-I" + path.string(); - args.push_back(new_include_path); - continue; + std::filesystem::path path(option.second); + if(path.is_relative()) + { + path = (sourceDir / path).lexically_normal(); + append(args, getOption(tool_chain, opt::include_path, path.string())); + } } + continue; + default: + break; } args.push_back(flag); |