diff options
Diffstat (limited to 'src/task_cc.cc')
-rw-r--r-- | src/task_cc.cc | 244 |
1 files changed, 163 insertions, 81 deletions
diff --git a/src/task_cc.cc b/src/task_cc.cc index 1db9767..56915f5 100644 --- a/src/task_cc.cc +++ b/src/task_cc.cc @@ -7,88 +7,83 @@ #include <fstream> #include <cassert> -#include "libctor.h" -#include "settings.h" +#include "ctor.h" #include "execute.h" #include "util.h" +#include "tools.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) +TaskCC::TaskCC(const ctor::build_configuration& config, const ctor::settings& settings, + const std::string& sourceDir, const ctor::source& source) + : Task(config, settings, 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(); + std::filesystem::create_directories(std::filesystem::path(settings.builddir) / base); base /= cleanUp(config.target); base += "-"; base += sourceFile.stem(); - target_type = TargetType::Object; + target_type = ctor::target_type::object; 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; + _targetFile += ".o"; + } + else + { + _targetFile = source.output; + } + depsFile = targetFile().parent_path() / targetFile().stem(); depsFile += ".d"; - flagsFile = base; + 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() @@ -99,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; @@ -137,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"; @@ -146,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; @@ -172,9 +167,22 @@ int TaskCC::runInner() if(settings.verbose == 0) { - std::cout << compiler() << " " << + switch(sourceLanguage()) + { + case ctor::language::c: + std::cout << "CC "; + break; + case ctor::language::cpp: + std::cout << "CXX "; + break; + case ctor::language::automatic: + case ctor::language::assembler: + // Only c/c++ handled by this task type. + break; + } + std::cout << sourceFile.lexically_normal().string() << " => " << - targetFile.lexically_normal().string() << "\n"; + targetFile().lexically_normal().string() << std::endl; } return execute(compiler(), args, settings.verbose > 0); @@ -182,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)) @@ -210,7 +218,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 +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) @@ -243,12 +256,23 @@ 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); @@ -268,42 +292,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)); - 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)); + + if(std::filesystem::path(config.target).extension() == ".so") + { + // Add -fPIC arg to all contained object files + append(args, cxx_option(toolchain, + ctor::cxx_opt::position_independent_code)); + } - // Is it relative? - if(path.is_relative()) + 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) { - path = (sourceDir / path).lexically_normal(); - std::string new_include_path = "-I" + path.string(); - args.push_back(new_include_path); - continue; + 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; |