1 | // Copyright 2011 Google Inc. All Rights Reserved. |
2 | // |
3 | // Licensed under the Apache License, Version 2.0 (the "License"); |
4 | // you may not use this file except in compliance with the License. |
5 | // You may obtain a copy of the License at |
6 | // |
7 | // http://www.apache.org/licenses/LICENSE-2.0 |
8 | // |
9 | // Unless required by applicable law or agreed to in writing, software |
10 | // distributed under the License is distributed on an "AS IS" BASIS, |
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
12 | // See the License for the specific language governing permissions and |
13 | // limitations under the License. |
14 | |
15 | #ifndef NINJA_BUILD_LOG_H_ |
16 | #define NINJA_BUILD_LOG_H_ |
17 | |
18 | #include <string> |
19 | #include <stdio.h> |
20 | |
21 | #include "hash_map.h" |
22 | #include "load_status.h" |
23 | #include "timestamp.h" |
24 | #include "util.h" // uint64_t |
25 | |
26 | struct DiskInterface; |
27 | struct Edge; |
28 | |
29 | /// Can answer questions about the manifest for the BuildLog. |
30 | struct BuildLogUser { |
31 | /// Return if a given output is no longer part of the build manifest. |
32 | /// This is only called during recompaction and doesn't have to be fast. |
33 | virtual bool IsPathDead(StringPiece s) const = 0; |
34 | }; |
35 | |
36 | /// Store a log of every command ran for every build. |
37 | /// It has a few uses: |
38 | /// |
39 | /// 1) (hashes of) command lines for existing output files, so we know |
40 | /// when we need to rebuild due to the command changing |
41 | /// 2) timing information, perhaps for generating reports |
42 | /// 3) restat information |
43 | struct BuildLog { |
44 | BuildLog(); |
45 | ~BuildLog(); |
46 | |
47 | /// Prepares writing to the log file without actually opening it - that will |
48 | /// happen when/if it's needed |
49 | bool OpenForWrite(const std::string& path, const BuildLogUser& user, |
50 | std::string* err); |
51 | bool RecordCommand(Edge* edge, int start_time, int end_time, |
52 | TimeStamp mtime = 0); |
53 | void Close(); |
54 | |
55 | /// Load the on-disk log. |
56 | LoadStatus Load(const std::string& path, std::string* err); |
57 | |
58 | struct LogEntry { |
59 | std::string output; |
60 | uint64_t command_hash; |
61 | int start_time; |
62 | int end_time; |
63 | TimeStamp mtime; |
64 | |
65 | static uint64_t HashCommand(StringPiece command); |
66 | |
67 | // Used by tests. |
68 | bool operator==(const LogEntry& o) { |
69 | return output == o.output && command_hash == o.command_hash && |
70 | start_time == o.start_time && end_time == o.end_time && |
71 | mtime == o.mtime; |
72 | } |
73 | |
74 | explicit LogEntry(const std::string& output); |
75 | LogEntry(const std::string& output, uint64_t command_hash, |
76 | int start_time, int end_time, TimeStamp mtime); |
77 | }; |
78 | |
79 | /// Lookup a previously-run command by its output path. |
80 | LogEntry* LookupByOutput(const std::string& path); |
81 | |
82 | /// Serialize an entry into a log file. |
83 | bool WriteEntry(FILE* f, const LogEntry& entry); |
84 | |
85 | /// Rewrite the known log entries, throwing away old data. |
86 | bool Recompact(const std::string& path, const BuildLogUser& user, |
87 | std::string* err); |
88 | |
89 | /// Restat all outputs in the log |
90 | bool Restat(StringPiece path, const DiskInterface& disk_interface, |
91 | int output_count, char** outputs, std::string* err); |
92 | |
93 | typedef ExternalStringHashMap<LogEntry*>::Type Entries; |
94 | const Entries& entries() const { return entries_; } |
95 | |
96 | private: |
97 | /// Should be called before using log_file_. When false is returned, errno |
98 | /// will be set. |
99 | bool OpenForWriteIfNeeded(); |
100 | |
101 | Entries entries_; |
102 | FILE* log_file_; |
103 | std::string log_file_path_; |
104 | bool needs_recompaction_; |
105 | }; |
106 | |
107 | #endif // NINJA_BUILD_LOG_H_ |
108 | |