summaryrefslogtreecommitdiff
path: root/src/deps.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/deps.cc')
-rw-r--r--src/deps.cc167
1 files changed, 167 insertions, 0 deletions
diff --git a/src/deps.cc b/src/deps.cc
new file mode 100644
index 0000000..736acbf
--- /dev/null
+++ b/src/deps.cc
@@ -0,0 +1,167 @@
+// -*- c++ -*-
+// Distributed under the BSD 2-Clause License.
+// See accompanying file LICENSE for details.
+#include "deps.h"
+
+#include "util.h"
+
+#include <nlohmann/json.hpp>
+
+#include <fstream>
+
+namespace {
+/* Format example:
+build/src/libctor_a-libctor_cc.o: src/libctor.cc \
+ src/getoptpp/getoptpp.hpp src/ctor.h src/configure.h src/rebuild.h \
+ src/tasks.h src/task.h src/build.h src/unittest.h
+ */
+std::vector<std::string> readDepsMake(const std::string& dep_file)
+{
+ auto str = readFile(dep_file);
+
+ std::vector<std::string> output;
+ std::string tmp;
+ bool start{false};
+ bool in_whitespace{false};
+ for(const auto& c : str)
+ {
+ if(c == '\\' || c == '\n')
+ {
+ continue;
+ }
+
+ if(c == ':')
+ {
+ start = true;
+ continue;
+ }
+
+ if(!start)
+ {
+ continue;
+ }
+
+ if(c == ' ' || c == '\t')
+ {
+ if(in_whitespace)
+ {
+ continue;
+ }
+
+ if(!tmp.empty())
+ {
+ output.push_back(tmp);
+ }
+ tmp.clear();
+ in_whitespace = true;
+ }
+ else
+ {
+ in_whitespace = false;
+ tmp += c;
+ }
+ }
+
+ if(!tmp.empty())
+ {
+ output.push_back(tmp);
+ }
+
+ return output;
+}
+
+// https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p1689r5.html
+// https://devblogs.microsoft.com/cppblog/introducing-source-dependency-reporting-with-msvc-in-visual-studio-2019-version-16-7/
+/* Format examples:
+{
+ "Version": "1.1",
+ "Data": {
+ "Source": "z:\\home\\deva\\docs\\c\\ctor\\src\\libctor.cc",
+ "ProvidedModule": "",
+ "Includes": [
+ "c:\\program files (x86)\\microsoft visual studio\\2019\\buildtools\\vc\\tools\\msvc\\14.29.30133\\include\\vector",
+ "c:\\program files (x86)\\microsoft visual studio\\2019\\buildtools\\vc\\tools\\msvc\\14.29.30133\\include\\yvals_core.h",
+ "c:\\program files (x86)\\microsoft visual studio\\2019\\buildtools\\vc\\tools\\msvc\\14.29.30133\\include\\vcruntime.h",
+.
+.
+.
+ "z:\\home\\deva\\docs\\c\\ctor\\src\\unittest.h"
+ ],
+ "ImportedModules": [],
+ "ImportedHeaderUnits": []
+ }
+}
+*/
+/*
+{
+ "Version": "1.2",
+ "Data": {
+ "Source": "c:\\jenkins\\workspace\\ctor-linux64\\src\\build.cc",
+ "ProvidedModule": "",
+ "Includes": [
+ "c:\\jenkins\\workspace\\ctor-linux64\\src\\build.h",
+ "c:\\program files (x86)\\microsoft visual studio\\2022\\buildtools\\vc\\tools\\msvc\\14.42.34433\\include\\string",
+ "c:\\program files (x86)\\microsoft visual studio\\2022\\buildtools\\vc\\tools\\msvc\\14.42.34433\\include\\yvals_core.h",
+.
+.
+.
+ "c:\\program files (x86)\\microsoft visual studio\\2022\\buildtools\\vc\\tools\\msvc\\14.42.34433\\include\\iostream"
+ ],
+ "ImportedModules": [],
+ "ImportedHeaderUnits": []
+ }
+}
+*/
+
+std::vector<std::string> readDepsJson(const std::string& dep_file)
+{
+ std::ifstream stream(dep_file);
+ auto json = nlohmann::json::parse(stream);
+ for(const auto& [key, value] : json.items())
+ {
+ if(key == "Data" && value.is_object())
+ {
+ for(const auto& [inner_key, inner_value] : value.items())
+ {
+ if(inner_key == "Includes" && inner_value.is_array())
+ {
+ std::vector<std::string> deps;
+ for(const auto& dep : inner_value)
+ {
+ deps.emplace_back(dep);
+ }
+ return deps;
+ }
+ }
+ }
+ }
+ return {};
+}
+}
+
+std::vector<std::string> readDeps(const std::string& dep_file,
+ ctor::toolchain toolchain)
+{
+ if(!std::filesystem::exists(dep_file))
+ {
+ return {};
+ }
+
+ switch(toolchain)
+ {
+ case ctor::toolchain::any:
+ case ctor::toolchain::none:
+ return {};
+
+ // json based:
+ case ctor::toolchain::msvc:
+ return readDepsJson(dep_file);
+
+ // makefile .d file based:
+ case ctor::toolchain::gcc:
+ case ctor::toolchain::clang:
+ return readDepsMake(dep_file);
+ }
+
+ return {};
+}