SMT-RAT  24.02
Toolbox for Strategic and Parallel Satisfiability-Modulo-Theories Solving
Tool.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include <filesystem>
4 #include <functional>
5 #include <string>
6 #include <stdexcept>
7 #include <vector>
8 #include <regex>
9 
10 #include <boost/functional/hash.hpp>
11 #include <boost/version.hpp>
12 
17 #include <benchmax/utils/execute.h>
18 
19 
20 namespace benchmax {
21 
22 namespace fs = std::filesystem;
23 
24 inline bool is_system_lib(std::string path) {
25  return path.rfind("/usr", 0) == 0 || path.rfind("/lib", 0) == 0;
26 }
27 
28 /**
29  * Base class for any tool.
30  * A tool represents some executable that can be run with some input file.
31  * A tool is responsible for
32  * - deciding it is applicable for a given file extension,
33  * - building a command line to execute it and
34  * - parse additional results from stdout / stderr after it has run.
35  *
36  * A tool is not to be copied or moved around but should only exist a single time.
37  */
38 class Tool {
39 protected:
40  /// (Non-unique) identifier for the tool.
41  std::string mName;
42  /// Path to the binary.
43  fs::path mBinary;
44  /// Command line arguments that should be passed to the binary.
45  std::string mArguments;
46  /// Attributes of the tool obtained by introspection of the binary.
47  std::map<std::string,std::string> mAttributes;
48 public:
49  Tool() = delete;
50  Tool(const Tool&) = delete;
51  Tool(Tool&&) = delete;
52  /// Creates a generic tool from a binary and command line arguments.
53  Tool(const fs::path& binary, const std::string& arguments): Tool("Generic", binary, arguments) {}
54  /// Creates a named tool from a binary and command line arguments.
55  Tool(const std::string& name, const fs::path& binary, const std::string& arguments): mName(name), mBinary(binary), mArguments(arguments) {}
56 
57  virtual ~Tool() = default;
58  Tool& operator=(const Tool&) = delete;
59  Tool& operator=(Tool&&) = delete;
60 
61  /// Common name of this tool.
62  std::string name() const {
63  return mName;
64  }
65 
66  /// Full path to the binary.
67  fs::path binary() const {
68  return mBinary;
69  }
70 
71  /// A set of attributes, for example compilation options.
72  const std::map<std::string,std::string>& attributes() const {
73  return mAttributes;
74  }
75 
76  /// Get dependencies of binary required to run it (via ldd)
77  std::vector<std::string> resolveDependencies() const {
78  std::string output;
79  std::stringstream ss;
80  ss << "ldd " << binary();
81  BENCHMAX_LOG_WARN("benchmax.tool", "Determining dependencies using " << ss.str());
82  int code = call_program(ss.str(), output);
83  if (code == 0) {
84  BENCHMAX_LOG_TRACE("benchmax.tool", "Got dependencies");
85  std::vector<std::string> results;
86  std::regex regex("\\t(.+) => (.+) \\([0-9a-fx]+\\)\\n");
87  auto reBegin = std::sregex_iterator(output.begin(), output.end(), regex);
88  auto reEnd = std::sregex_iterator();
89  for (auto i = reBegin; i != reEnd; ++i) {
90  std::string lib = (*i)[1];
91  std::string path = (*i)[2];
92  if (path == "not found") {
93  BENCHMAX_LOG_WARN("benchmax.tool", "Unmet dependency " << lib);
94  } else {
95  if (!is_system_lib(path)) {
96  BENCHMAX_LOG_TRACE("benchmax.tool", "Found dependency " << lib << " (" << path << ")");
97  results.emplace_back(path);
98  } else {
99  BENCHMAX_LOG_TRACE("benchmax.tool", "Skipping system library " << lib << " (" << path << ")");
100  }
101  }
102  }
103  return results;
104  } else {
105  BENCHMAX_LOG_WARN("benchmax.tool", "Could not determine dependencies of binary");
106  BENCHMAX_LOG_WARN("benchmax.tool", output);
107  return {};
108  }
109  }
110 
111  /// Hash of the attributes.
112  std::size_t attributeHash() const {
113  std::size_t res = 0;
114  for (const auto& it: mAttributes) {
115  boost::hash_combine(res, it.first);
116  boost::hash_combine(res, it.second);
117  }
118  return res;
119  }
120 
121  /// Compose commandline for this tool and the given input file.
122  virtual std::string getCommandline(const std::string& file) const {
123  return mBinary.native() + " " + mArguments + " " + file;
124  }
125  /// Compose commandline for this tool with another binary name and the given input file.
126  virtual std::string getCommandline(const std::string& file, const std::string& localBinary) const {
127  return localBinary + " " + mArguments + " " + file;
128  }
129  /// Compose commandline for this tool and the given input file.
130  virtual std::optional<std::string> parseCommandline(const std::string& cmdline) const {
131  std::regex regex(getCommandline("(.+)"));
132  std::smatch match;
133  if (std::regex_match(cmdline, match, regex)) {
134  assert (match.size() == 2);
135  return match[1].str();
136  } else {
137  return {};
138  }
139  }
140 
141  /// Checks whether this cool can handle this file type.
142  virtual bool canHandle(const fs::path&) const {
143  return true;
144  }
145 
146  /// Compare two tools.
147  friend bool operator<(const Tool& lhs, const Tool& rhs) {
148  return lhs.mBinary < rhs.mBinary;
149  }
150 
151  /// Recover additional results from the tool output.
152  virtual void additionalResults(const fs::path&, BenchmarkResult&) const {}
153 };
154 
155 /// Streaming operator for a generic tool.
156 inline std::ostream& operator<<(std::ostream& os, const Tool& tool) {
157  return os << tool.binary().native();
158 }
159 
160 }
#define BENCHMAX_LOG_WARN(channel, msg)
Log warnings.
Definition: logging.h:51
#define BENCHMAX_LOG_TRACE(channel, msg)
Log trace messages.
Definition: logging.h:57
Base class for any tool.
Definition: Tool.h:38
virtual ~Tool()=default
virtual bool canHandle(const fs::path &) const
Checks whether this cool can handle this file type.
Definition: Tool.h:142
std::map< std::string, std::string > mAttributes
Attributes of the tool obtained by introspection of the binary.
Definition: Tool.h:47
Tool(const std::string &name, const fs::path &binary, const std::string &arguments)
Creates a named tool from a binary and command line arguments.
Definition: Tool.h:55
std::string name() const
Common name of this tool.
Definition: Tool.h:62
std::vector< std::string > resolveDependencies() const
Get dependencies of binary required to run it (via ldd)
Definition: Tool.h:77
virtual std::string getCommandline(const std::string &file) const
Compose commandline for this tool and the given input file.
Definition: Tool.h:122
Tool & operator=(Tool &&)=delete
std::string mName
(Non-unique) identifier for the tool.
Definition: Tool.h:41
const std::map< std::string, std::string > & attributes() const
A set of attributes, for example compilation options.
Definition: Tool.h:72
Tool(const Tool &)=delete
fs::path mBinary
Path to the binary.
Definition: Tool.h:43
std::size_t attributeHash() const
Hash of the attributes.
Definition: Tool.h:112
Tool & operator=(const Tool &)=delete
virtual std::optional< std::string > parseCommandline(const std::string &cmdline) const
Compose commandline for this tool and the given input file.
Definition: Tool.h:130
Tool(const fs::path &binary, const std::string &arguments)
Creates a generic tool from a binary and command line arguments.
Definition: Tool.h:53
fs::path binary() const
Full path to the binary.
Definition: Tool.h:67
virtual std::string getCommandline(const std::string &file, const std::string &localBinary) const
Compose commandline for this tool with another binary name and the given input file.
Definition: Tool.h:126
virtual void additionalResults(const fs::path &, BenchmarkResult &) const
Recover additional results from the tool output.
Definition: Tool.h:152
Tool(Tool &&)=delete
friend bool operator<(const Tool &lhs, const Tool &rhs)
Compare two tools.
Definition: Tool.h:147
std::string mArguments
Command line arguments that should be passed to the binary.
Definition: Tool.h:45
int call_program(const std::string &commandline, std::string &stdout, bool print_to_stdout=false)
Runs an external program from some command line and records the output to stdout.
Definition: execute.h:18
bool is_system_lib(std::string path)
Definition: Tool.h:24
std::ostream & operator<<(std::ostream &os, const BenchmarkResult &results)
Streaming operator for BenchmarkResult.
Results for a single benchmark run.