summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorRoland Reichwein <mail@reichwein.it>2024-05-01 21:44:11 +0200
committerRoland Reichwein <mail@reichwein.it>2024-05-01 21:44:11 +0200
commit16031a8ca3e6e36e39b5ac52853f39e559f0460a (patch)
treee8bb388355606c0f44899f87558bba69e5fdd82b
parent623def43b2ae0cd23ecef6688257c540e3118856 (diff)
Create dependencies
-rw-r--r--Makefile2
-rw-r--r--xmake.cpp47
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 <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;