You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

77 lines
2.4KB

  1. #include "./usage_reqs.hpp"
  2. #include <dds/build/plan/compile_file.hpp>
  3. #include <dds/error/errors.hpp>
  4. #include <dds/util/algo.hpp>
  5. #include <fmt/core.h>
  6. #include <stdexcept>
  7. using namespace dds;
  8. const lm::library* usage_requirement_map::get(const lm::usage& key) const noexcept {
  9. auto found = _reqs.find(key);
  10. if (found == _reqs.end()) {
  11. return nullptr;
  12. }
  13. return &found->second;
  14. }
  15. lm::library& usage_requirement_map::add(std::string ns, std::string name) {
  16. auto pair = std::pair(library_key{ns, name}, lm::library{});
  17. auto [inserted, did_insert] = _reqs.try_emplace(library_key{ns, name}, lm::library());
  18. if (!did_insert) {
  19. throw_user_error<errc::dup_lib_name>("More than one library is registered as `{}/{}'",
  20. ns,
  21. name);
  22. }
  23. return inserted->second;
  24. }
  25. usage_requirement_map usage_requirement_map::from_lm_index(const lm::index& idx) noexcept {
  26. usage_requirement_map ret;
  27. for (const auto& pkg : idx.packages) {
  28. for (const auto& lib : pkg.libraries) {
  29. ret.add(pkg.namespace_, lib.name, lib);
  30. }
  31. }
  32. return ret;
  33. }
  34. std::vector<fs::path> usage_requirement_map::link_paths(const lm::usage& key) const {
  35. auto req = get(key);
  36. if (!req) {
  37. throw_user_error<errc::unknown_usage_name>("Unable to find linking requirement '{}/{}'",
  38. key.namespace_,
  39. key.name);
  40. }
  41. std::vector<fs::path> ret;
  42. if (req->linkable_path) {
  43. ret.push_back(*req->linkable_path);
  44. }
  45. for (const auto& dep : req->uses) {
  46. extend(ret, link_paths(dep));
  47. }
  48. for (const auto& link : req->links) {
  49. extend(ret, link_paths(link));
  50. }
  51. return ret;
  52. }
  53. std::vector<fs::path> usage_requirement_map::include_paths(const lm::usage& usage) const {
  54. std::vector<fs::path> ret;
  55. auto lib = get(usage.namespace_, usage.name);
  56. if (!lib) {
  57. throw_user_error<
  58. errc::unknown_usage_name>("Cannot find non-existent usage requirements for '{}/{}'",
  59. usage.namespace_,
  60. usage.name);
  61. }
  62. extend(ret, lib->include_paths);
  63. for (const auto& transitive : lib->uses) {
  64. extend(ret, include_paths(transitive));
  65. }
  66. return ret;
  67. }