diff options
Diffstat (limited to 'src/task_cc.cc')
-rw-r--r-- | src/task_cc.cc | 276 |
1 files changed, 186 insertions, 90 deletions
diff --git a/src/task_cc.cc b/src/task_cc.cc index 1db9767..b9edcf7 100644 --- a/src/task_cc.cc +++ b/src/task_cc.cc @@ -6,89 +6,88 @@ #include <iostream> #include <fstream> #include <cassert> +#include <algorithm> -#include "libctor.h" -#include "settings.h" +#include "ctor.h" #include "execute.h" #include "util.h" - -namespace -{ -bool isClean(char c) -{ - return c != '.' && c != '/'; -} - -std::string cleanUp(const std::string& path) -{ - std::string cleaned; - for(const auto& c : path) - { - if(isClean(c)) - { - cleaned += c; - } - else - { - cleaned += '_'; - } - } - return cleaned; -} -} - -TaskCC::TaskCC(const BuildConfiguration& config, const Settings& settings, - const std::string& sourceDir, const Source& source) - : Task(config) - , config(config) - , settings(settings) - , sourceDir(sourceDir) +#include "tools.h" +#include "deps.h" + +TaskCC::TaskCC(const ctor::build_configuration& config_, const ctor::settings& settings_, + const std::string& sourceDir_, const ctor::source& source) + : Task(config_, settings_, sourceDir_) + , sourceFile(sourceDir_) + , config(config_) + , settings(settings_) + , sourceDir(sourceDir_) + , _source(source) { - sourceFile = sourceDir; sourceFile /= source.file; - std::filesystem::path base = settings.builddir; - base /= sourceFile.parent_path(); - std::filesystem::create_directories(base); + std::filesystem::path base = sourceFile.parent_path(); base /= cleanUp(config.target); base += "-"; base += sourceFile.stem(); - target_type = TargetType::Object; + target_type = ctor::target_type::object; + output_system = config.system; source_language = source.language; - if(source_language == Language::Auto) + if(source_language == ctor::language::automatic) { source_language = languageFromExtension(sourceFile); } switch(source_language) { - case Language::C: + case ctor::language::c: base += "_c"; break; - case Language::Cpp: + case ctor::language::cpp: base += "_cc"; break; - case Language::Asm: + case ctor::language::assembler: base += "_asm"; break; - case Language::Auto: + case ctor::language::automatic: assert(0 && "This should never happen"); break; } - targetFile = base; - targetFile += ".o"; - depsFile = base; + if(source.output.empty()) + { + _targetFile = base; + } + else + { + _targetFile = source.output; + } + auto toolchain = getToolChain(config.system); + _targetFile = extension(toolchain, target_type, config.system, _targetFile); + + depsFile = targetFile().parent_path() / targetFile().stem(); depsFile += ".d"; - flagsFile = base; + flagsFile = targetFile().parent_path() / targetFile().stem(); flagsFile += ".flags"; + + std::filesystem::create_directories(targetFile().parent_path()); } -std::string TaskCC::name() const +int TaskCC::registerDepTasksInner(const std::vector<std::shared_ptr<Task>>& tasks) { - return target(); + for(const auto& task : tasks) + { + if(*task == _source.file) + { + if(std::find(dependsTasks.begin(), dependsTasks.end(), task) == dependsTasks.end()) + { + dependsTasks.push_back(task); + } + } + } + + return 0; } bool TaskCC::dirtyInner() @@ -99,7 +98,7 @@ bool TaskCC::dirtyInner() return true; } - if(!std::filesystem::exists(targetFile)) + if(!std::filesystem::exists(targetFile())) { //std::cout << "Missing targetFile\n"; return true; @@ -133,11 +132,12 @@ bool TaskCC::dirtyInner() } } - auto depList = readDeps(depsFile.string()); + auto toolchain = getToolChain(config.system); + auto depList = readDeps(depsFile.string(), toolchain); 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"; @@ -146,7 +146,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; @@ -172,20 +172,41 @@ int TaskCC::runInner() if(settings.verbose == 0) { - std::cout << compiler() << " " << - sourceFile.lexically_normal().string() << " => " << - targetFile.lexically_normal().string() << "\n"; + std::string output; + switch(sourceLanguage()) + { + case ctor::language::c: + output = "CC "; + break; + case ctor::language::cpp: + output = "CXX "; + break; + case ctor::language::automatic: + case ctor::language::assembler: + // Only c/c++ handled by this task type. + break; + } + output += sourceFile.lexically_normal().string() + " => " + + targetFile().lexically_normal().string() + '\n'; + std::cout << output << std::flush; } - return execute(compiler(), args, settings.verbose > 0); + const auto& cfg = ctor::get_configuration(); + auto res = execute(settings, compiler(), args, cfg.env); + if(res != 0) + { + std::filesystem::remove(targetFile()); + } + + return res; } 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)) @@ -210,7 +231,12 @@ 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 @@ -224,7 +250,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) @@ -243,17 +269,29 @@ std::string TaskCC::source() const std::vector<std::string> TaskCC::flags() const { + std::vector<std::string> flags; + auto toolchain = getToolChain(config.system); + switch(sourceLanguage()) { - case Language::C: - return config.flags.cflags; - case Language::Cpp: - return config.flags.cxxflags; + case ctor::language::c: + for(const auto& flag : config.flags.cflags) + { + append(flags, to_strings(toolchain, flag)); + } + return flags; + case ctor::language::cpp: + for(const auto& flag : config.flags.cxxflags) + { + append(flags, to_strings(toolchain, flag)); + } + return flags; default: std::cerr << "Unknown CC target type\n"; exit(1); break; } + } std::string TaskCC::flagsString() const @@ -268,42 +306,100 @@ std::string TaskCC::flagsString() const std::vector<std::string> TaskCC::getCompilerArgs() const { + auto toolchain = getToolChain(config.system); auto compiler_flags = flags(); std::vector<std::string> args; - args.push_back("-MMD"); - if(std::filesystem::path(config.target).extension() == ".so") + switch(sourceLanguage()) { - // Add -fPIC arg to all contained object files - args.push_back("-fPIC"); - } + case ctor::language::c: + { + append(args, c_option(toolchain, ctor::c_opt::generate_dep_tree, depsFile.string())); - args.push_back("-c"); - args.push_back(sourceFile.string()); - args.push_back("-o"); - args.push_back(targetFile.string()); + if(std::filesystem::path(config.target).extension() == ".so") + { + // Add -fPIC arg to all contained object files + append(args, c_option(toolchain, + ctor::c_opt::position_independent_code)); + } - for(const auto& flag : compiler_flags) - { - // Is arg an added include path? - if(flag.substr(0, 2) == "-I") + append(args, c_option(toolchain, ctor::c_opt::no_link)); + args.push_back(sourceFile.string()); + append(args, c_option(toolchain, + ctor::c_opt::output, targetFile().string())); + + // Relative include paths has to be altered to be relative to sourceDir + for(const auto& flag : compiler_flags) + { + auto option = c_option(flag, toolchain); + switch(option.opt) + { + case ctor::c_opt::include_path: + { + std::filesystem::path path(option.arg); + if(path.is_relative()) + { + path = (sourceDir / path).lexically_normal(); + append(args, c_option(toolchain, + ctor::c_opt::include_path, path.string())); + } + } + break; + default: + break; + } + + args.push_back(flag); + } + } + break; + + case ctor::language::cpp: { - std::string include_path = flag.substr(2); - include_path.erase(0, include_path.find_first_not_of(' ')); - std::filesystem::path path(include_path); + append(args, cxx_option(toolchain, ctor::cxx_opt::generate_dep_tree, depsFile.string())); - // Is it relative? - if(path.is_relative()) + if(std::filesystem::path(config.target).extension() == ".so") { - path = (sourceDir / path).lexically_normal(); - std::string new_include_path = "-I" + path.string(); - args.push_back(new_include_path); - continue; + // Add -fPIC arg to all contained object files + append(args, cxx_option(toolchain, + ctor::cxx_opt::position_independent_code)); } + + append(args, cxx_option(toolchain, ctor::cxx_opt::no_link)); + args.push_back(sourceFile.string()); + append(args, cxx_option(toolchain, + ctor::cxx_opt::output, targetFile().string())); + + // Relative include paths has to be altered to be relative to sourceDir + for(const auto& flag : compiler_flags) + { + auto option = cxx_option(flag, toolchain); + switch(option.opt) + { + case ctor::cxx_opt::include_path: + { + std::filesystem::path path(option.arg); + if(path.is_relative()) + { + path = (sourceDir / path).lexically_normal(); + append(args, cxx_option(toolchain, + ctor::cxx_opt::include_path, path.string())); + } + } + break; + default: + break; + } + + args.push_back(flag); + } + } + break; - args.push_back(flag); + default: + break; } return args; |