-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathprogram_wrapper.hpp
More file actions
185 lines (158 loc) · 7.57 KB
/
program_wrapper.hpp
File metadata and controls
185 lines (158 loc) · 7.57 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
//--------------------------------------------------------------------------------------------------
// Copyright (c) 2018 Marcus Geelnard
//
// This software is provided 'as-is', without any express or implied warranty. In no event will the
// authors be held liable for any damages arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose, including commercial
// applications, and to alter it and redistribute it freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not claim that you wrote
// the original software. If you use this software in a product, an acknowledgment in the
// product documentation would be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not be misrepresented as
// being the original software.
//
// 3. This notice may not be removed or altered from any source distribution.
//--------------------------------------------------------------------------------------------------
#ifndef BUILDCACHE_PROGRAM_WRAPPER_HPP_
#define BUILDCACHE_PROGRAM_WRAPPER_HPP_
#include <base/file_utils.hpp>
#include <base/string_list.hpp>
#include <cache/cache.hpp>
#include <cache/expected_file.hpp>
#include <sys/sys_utils.hpp>
#include <string>
namespace bcache {
/// @brief The base class for all program wrappers.
///
/// Specialized program wrappers inherit from this class and implement the relevant virtual methods
/// that constitute the "wrapper API".
///
/// This class also implements the entire program wrapping mechanism, with cache lookups etc.
class program_wrapper_t {
public:
virtual ~program_wrapper_t() = default;
/// @brief Try to wrap a program command.
/// @param[out] return_code The command return code (if handled).
/// @returns true if the command was recognized and handled.
bool handle_command(int& return_code);
/// @brief Check if this class implements a wrapper for the given command.
/// @returns true if this wrapper can handle the command.
virtual bool can_handle_command() = 0;
protected:
/// @brief A helper class for managing wrapper capabilities.
class capabilities_t {
public:
capabilities_t() = default;
capabilities_t(const string_list_t& cap_strings);
bool create_target_dirs() const {
return m_create_target_dirs;
}
bool direct_mode() const {
return m_direct_mode;
}
bool hard_links() const {
return m_hard_links;
}
private:
bool m_create_target_dirs = false;
bool m_direct_mode = false;
bool m_hard_links = false;
};
// This constructor is called by derived classes.
program_wrapper_t(const file::exe_path_t& exe_path, const string_list_t& args);
/// @brief Resolve arguments on the command line.
///
/// This method is called after @c can_handle_command, but before calling other methods that rely
/// on the command line arguments. This gives a wrapper the opportunity to resolve special
/// arguments so that they can be properly interpretade by later steps.
///
/// The primary use case of this method is to implement support for so called response files,
/// which contain further command line arguments (this is common on Windows to work around the
/// relativlely small command line length limit).
///
/// @throws runtime_error if the request could not be completed.
virtual void resolve_args();
/// @brief Generate a list of supported capabilites.
///
/// The list of capabilites can contain zero or more of the following (case sensitive) strings:
///
/// | String | Meaning |
/// | ------------------ | --------------------------------------- |
/// | create_target_dirs | Request creation of missing output dirs |
/// | direct_mode | Supports direct mode |
/// | force_direct_mode | Turns on direct mode for the wrapper |
/// | hard_links | Can use hard links for cached files |
///
/// In order to support direct mode, @c get_input_files() and @c get_implicit_input_files() need
/// to be implemented.
///
/// @returns a list of supported capabilites.
/// @throws runtime_error if the request could not be completed.
/// @note Capabilites are "opt-in". If this method is not implemented or returns an empty list,
/// all capabilites will be treated as "not supported".
virtual string_list_t get_capabilities();
/// @brief Get the paths to the files that are to be generated by the command.
/// @returns the files that are expected to be generated by this command.
/// @throws runtime_error if the request could not be completed.
virtual std::map<std::string, expected_file_t> get_build_files();
/// @brief Get a string that uniquely identifies the program.
/// @returns a program ID string.
/// @throws runtime_error if the request could not be completed.
virtual std::string get_program_id();
/// @brief Get relevant command line arguments for hashing.
/// @returns filtered command line arguments.
/// @throws runtime_error if the request could not be completed.
///
/// @note The purpose of this function is to create a list of arguments that is suitable for
/// hashing (i.e. uniquely identifying) the program options. As such, things like absolute file
/// paths and compilation defines should be excluded (since they are resolved in the preprocess
/// step).
virtual string_list_t get_relevant_arguments();
/// @brief Get relevant environment variables for hashing.
/// @returns relevant environment variables and their values.
/// @throws runtime_error if the request could not be completed.
///
/// @note The purpose of this function is to create a list of environment variables that may
/// affect program output.
virtual std::map<std::string, std::string> get_relevant_env_vars();
/// @brief Get the paths to the input files for the command.
/// @returns the files that are used as primary input.
/// @throws runtime_error if the request could not be completed.
/// @note Only used in direct mode.
virtual string_list_t get_input_files();
/// @brief Generate the preprocessed source text.
/// @returns the preprocessed source code file as a string, or an empty string if the operation
/// failed.
/// @throws runtime_error if the request could not be completed.
virtual std::string preprocess_source();
/// @brief Get a list of paths to implicit input files.
///
/// This method is only used in direct mode, and the main use case is for collecting a list of
/// all include files for C/C++ builds.
/// @returns the list of implicit input files.
/// @throws runtime_error if the request could not be completed.
///
/// @note The @c preprocess_source method has been called before calling this method (so the list
/// can be collected during the preprocessing step and later be returned by this method).
/// @note Only used in direct mode.
virtual string_list_t get_implicit_input_files();
/// @brief Run the actual command (when there is a cache miss).
/// @returns the run result for the child process.
virtual sys::run_result_t run_for_miss();
const file::exe_path_t& m_exe_path;
const string_list_t& m_unresolved_args;
string_list_t m_args;
/// @brief Active capabilities
///
/// The capabilities in this object are only active (true) when they are both supported by the
/// wrapper and are active in the user configuration.
capabilities_t m_active_capabilities;
private:
std::string get_program_id_cached();
cache_t m_cache;
};
} // namespace bcache
#endif // BUILDCACHE_PROGRAM_WRAPPER_HPP_