// -*- c++ -*- // Distributed under the BSD 2-Clause License. // See accompanying file LICENSE for details. #include "deps.h" #include "util.h" #include #include 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 readDepsMake(const std::string& dep_file) { auto str = readFile(dep_file); std::vector 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 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 deps; for(const auto& dep : inner_value) { deps.emplace_back(dep); } return deps; } } } } return {}; } } std::vector 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 {}; }