From 16031a8ca3e6e36e39b5ac52853f39e559f0460a Mon Sep 17 00:00:00 2001 From: Roland Reichwein Date: Wed, 1 May 2024 21:44:11 +0200 Subject: Create dependencies --- Makefile | 2 +- xmake.cpp | 47 +++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 44 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index 011a775..63816fc 100644 --- a/Makefile +++ b/Makefile @@ -6,7 +6,7 @@ OBJ=$(SRC:.cpp=.o) all: $(PROJECTNAME) -LDLIBS += -lfmt +LDLIBS += -lfmt -lreichwein CXXFLAGS += -std=c++17 $(PROJECTNAME): $(OBJ) diff --git a/xmake.cpp b/xmake.cpp index e4cadfb..4c6fdbe 100644 --- a/xmake.cpp +++ b/xmake.cpp @@ -1,8 +1,10 @@ #include "xmake.h" +#include #include #include #include +#include #include #include #include @@ -15,6 +17,9 @@ #include +#include +#include + namespace fs = std::filesystem; namespace bp = boost::process; namespace pt = boost::property_tree; @@ -69,6 +74,37 @@ namespace { return false; } + std::vector deps_from_depfile(const fs::path& path) { + std::string depfile_content{Reichwein::File::getFile(path)}; + std::vector parts {Reichwein::Stringhelper::split(depfile_content, ":\r\n")}; + if (parts.size() >= 2) { + std::vector deps {Reichwein::Stringhelper::split(parts[1], " ")}; + std::vector 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 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 objects{get_objects(ptree)}; @@ -81,14 +117,14 @@ namespace { std::cout << " " << i << std::endl; } + std::cout << "Calculating dependencies..." << std::endl; std::unordered_map> 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{p}); - // TODO: add headers dependencies: - // g++ -MM -MF -c + std::vector deps {make_depfile_from(p)}; + dependencies.emplace(p_obj, deps); } std::vector 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 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; -- cgit v1.2.3