Imported Upstream version 4.0
[platform/upstream/ccache.git] / src / Context.hpp
1 // Copyright (C) 2020 Joel Rosdahl and other contributors
2 //
3 // See doc/AUTHORS.adoc for a complete list of contributors.
4 //
5 // This program is free software; you can redistribute it and/or modify it
6 // under the terms of the GNU General Public License as published by the Free
7 // Software Foundation; either version 3 of the License, or (at your option)
8 // any later version.
9 //
10 // This program is distributed in the hope that it will be useful, but WITHOUT
11 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 // more details.
14 //
15 // You should have received a copy of the GNU General Public License along with
16 // this program; if not, write to the Free Software Foundation, Inc., 51
17 // Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18
19 #pragma once
20
21 #include "system.hpp"
22
23 #include "Args.hpp"
24 #include "ArgsInfo.hpp"
25 #include "Config.hpp"
26 #include "Digest.hpp"
27 #include "File.hpp"
28 #include "MiniTrace.hpp"
29 #include "NonCopyable.hpp"
30 #include "ccache.hpp"
31
32 #ifdef INODE_CACHE_SUPPORTED
33 #  include "InodeCache.hpp"
34 #endif
35
36 #include "third_party/nonstd/optional.hpp"
37 #include "third_party/nonstd/string_view.hpp"
38
39 #include <string>
40 #include <unordered_map>
41 #include <vector>
42
43 class SignalHandler;
44
45 class Context : NonCopyable
46 {
47 public:
48   Context();
49   ~Context();
50
51   ArgsInfo args_info;
52   Config config;
53
54   // Current working directory as returned by getcwd(3).
55   std::string actual_cwd;
56
57   // Current working directory according to $PWD (falling back to getcwd(3)).
58   std::string apparent_cwd;
59
60   // The original argument list.
61   Args orig_args;
62
63   // Name (represented as a hash) of the file containing the manifest for the
64   // cached result.
65   const nonstd::optional<Digest>& manifest_name() const;
66
67   // Full path to the file containing the manifest (cachedir/a/b/cdef[...]M), if
68   // any.
69   const nonstd::optional<std::string>& manifest_path() const;
70
71   // Name (represented as a hash) of the file containing the cached result.
72   const nonstd::optional<Digest>& result_name() const;
73
74   // Full path to the file containing the result (cachedir/a/b/cdef[...]R).
75   const nonstd::optional<std::string>& result_path() const;
76
77   // Time of compilation. Used to see if include files have changed after
78   // compilation.
79   time_t time_of_compilation = 0;
80
81   // Files included by the preprocessor and their hashes.
82   std::unordered_map<std::string, Digest> included_files;
83
84   // Uses absolute path for some include files.
85   bool has_absolute_include_headers = false;
86
87   // Have we tried and failed to get colored diagnostics?
88   bool diagnostics_color_failed = false;
89
90   // The name of the temporary preprocessed file.
91   std::string i_tmpfile;
92
93   // The name of the cpp stderr file.
94   std::string cpp_stderr;
95
96   // Compiler guessing is currently only based on the compiler name, so nothing
97   // should hard-depend on it if possible.
98   GuessedCompiler guessed_compiler = GuessedCompiler::unknown;
99
100   // The .gch/.pch/.pth file used for compilation.
101   std::string included_pch_file;
102
103   // Headers (or directories with headers) to ignore in manifest mode.
104   std::vector<std::string> ignore_header_paths;
105
106 #ifdef INODE_CACHE_SUPPORTED
107   // InodeCache that caches source file hashes when enabled.
108   mutable InodeCache inode_cache;
109 #endif
110
111   // Statistics updates which get written into the statistics file belonging to
112   // the result.
113   Counters counter_updates;
114
115   // Statistics updates which get written into the statistics file belonging to
116   // the manifest.
117   Counters manifest_counter_updates;
118
119   // PID of currently executing compiler that we have started, if any. 0 means
120   // no ongoing compilation.
121   pid_t compiler_pid = 0;
122
123   // Files used by the hash debugging functionality.
124   std::vector<File> hash_debug_files;
125
126   // Options to ignore for the hash.
127   const std::vector<std::string>& ignore_options() const;
128   void set_ignore_options(const std::vector<std::string>& options);
129
130   // Original umask before applying the `umask`/`CCACHE_UMASK` configuration, or
131   // `nullopt` if there is no such configuration.
132   nonstd::optional<mode_t> original_umask;
133
134 #ifdef MTR_ENABLED
135   // Internal tracing.
136   std::unique_ptr<MiniTrace> mini_trace;
137 #endif
138
139   void set_manifest_name(const Digest& name);
140   void set_manifest_path(const std::string& path);
141   void set_result_name(const Digest& name);
142   void set_result_path(const std::string& path);
143
144   // Register a temporary file to remove at program exit.
145   void register_pending_tmp_file(const std::string& path);
146
147 private:
148   nonstd::optional<Digest> m_manifest_name;
149   nonstd::optional<std::string> m_manifest_path;
150
151   nonstd::optional<Digest> m_result_name;
152   nonstd::optional<std::string> m_result_path;
153
154   // Options to ignore for the hash.
155   std::vector<std::string> m_ignore_options;
156
157   // [Start of variables touched by the signal handler]
158
159   // Temporary files to remove at program exit.
160   std::vector<std::string> m_pending_tmp_files;
161
162   // [End of variables touched by the signal handler]
163
164   friend SignalHandler;
165   void unlink_pending_tmp_files();
166   void unlink_pending_tmp_files_signal_safe(); // called from signal handler
167 };
168
169 inline const nonstd::optional<Digest>&
170 Context::manifest_name() const
171 {
172   return m_manifest_name;
173 }
174
175 inline const nonstd::optional<std::string>&
176 Context::manifest_path() const
177 {
178   return m_manifest_path;
179 }
180
181 inline const nonstd::optional<Digest>&
182 Context::result_name() const
183 {
184   return m_result_name;
185 }
186
187 inline const nonstd::optional<std::string>&
188 Context::result_path() const
189 {
190   return m_result_path;
191 }
192
193 inline const std::vector<std::string>&
194 Context::ignore_options() const
195 {
196   return m_ignore_options;
197 }
198
199 inline void
200 Context::set_manifest_name(const Digest& name)
201 {
202   m_manifest_name = name;
203 }
204
205 inline void
206 Context::set_manifest_path(const std::string& path)
207 {
208   m_manifest_path = path;
209 }
210
211 inline void
212 Context::set_result_name(const Digest& name)
213 {
214   m_result_name = name;
215 }
216
217 inline void
218 Context::set_result_path(const std::string& path)
219 {
220   m_result_path = path;
221 }