diff options
Diffstat (limited to 'xmake.cpp')
-rw-r--r-- | xmake.cpp | 47 |
1 files changed, 43 insertions, 4 deletions
@@ -1,8 +1,10 @@ #include "xmake.h" +#include <algorithm> #include <cstdlib> #include <filesystem> #include <iostream> +#include <iterator> #include <sstream> #include <stdexcept> #include <string> @@ -15,6 +17,9 @@ #include <fmt/format.h> +#include <libreichwein/file.h> +#include <libreichwein/stringhelper.h> + namespace fs = std::filesystem; namespace bp = boost::process; namespace pt = boost::property_tree; @@ -69,6 +74,37 @@ namespace { return false; } + std::vector<fs::path> deps_from_depfile(const fs::path& path) { + std::string depfile_content{Reichwein::File::getFile(path)}; + std::vector<std::string> parts {Reichwein::Stringhelper::split(depfile_content, ":\r\n")}; + if (parts.size() >= 2) { + std::vector<std::string> deps {Reichwein::Stringhelper::split(parts[1], " ")}; + std::vector<fs::path> result; + std::transform(deps.cbegin(), deps.cend(), std::back_inserter(result), [](const std::string& s){ return s; }); + return result; + } else { + throw std::runtime_error("Bad depfile contents: "s + path.string()); + } + } + + // return contained dependencies + // input: cpp + std::vector<fs::path> make_depfile_from(const fs::path& p) { + fs::path depfile{p}; + depfile.replace_extension("d"); + + // check if depfile exists and if it contains up to date info + if (!fs::exists(depfile) || is_outdated(depfile, deps_from_depfile(depfile))) { + // actually create depfile + int result{system(fmt::format("g++ -MM -MF {} -c {}", depfile.string(), p.string()).c_str())}; + if (result != 0) { + throw std::runtime_error(fmt::format("Depfile {} can't be created", depfile.string())); + } + } + + return deps_from_depfile(depfile); + } + void build(const pt::ptree& ptree) { fs::path target{get_target(ptree)}; std::vector<fs::path> objects{get_objects(ptree)}; @@ -81,14 +117,14 @@ namespace { std::cout << " " << i << std::endl; } + std::cout << "Calculating dependencies..." << std::endl; std::unordered_map<fs::path, std::vector<fs::path>> dependencies; dependencies.emplace(target, objects); for (const auto& p: sources) { fs::path p_obj{p}; p_obj.replace_extension("o"); - dependencies.emplace(p_obj, std::vector<fs::path>{p}); - // TODO: add headers dependencies: - // g++ -MM -MF <depsfile> -c <cppfile> + std::vector<fs::path> deps {make_depfile_from(p)}; + dependencies.emplace(p_obj, deps); } std::vector<std::string> commands; @@ -107,7 +143,7 @@ namespace { for (auto &i: objects) { link_command += fmt::format(" {}", i.string()); } - link_command += " -lfmt"; + link_command += " -lfmt -lreichwein"; link_command += fmt::format(" -o {}", target.string()); commands.push_back(link_command); } @@ -138,6 +174,9 @@ namespace { std::vector<std::string> commands; for (auto &i: cleanlist) { commands.push_back(fmt::format("rm -f {}", i.string())); + fs::path dep{i}; + dep.replace_extension("d"); + commands.push_back(fmt::format("rm -f {}", dep.string())); } std::cout << "Running commands: " << std::endl; |