CBuild
C++ build system with scripts written in c++
Loading...
Searching...
No Matches
gcc_hash.cpp
Go to the documentation of this file.
1
22// C++ libraries
23#include "../../headers/map.hpp"
24#include "fstream"
25#include "sstream"
26#include "string"
27#include "vector"
28// Project includes
35/* Helper code */
36struct extended_metadata {
40};
42 std::vector<extended_metadata>* source_metadata,
44 if (file->old_metadata_available == false) {
45 // printf("File: '%s' -> no_old_meta\n", file->meta.source.c_str());
46 return true;
47 }
48 if (file->meta.object != file->old_meta.object) {
49 // printf("File: '%s' -> mismatch object\n", file->meta.source.c_str());
50 return true;
51 }
52 if (file->meta.hash != file->old_meta.hash) {
53 // printf("File: '%s' -> mismatch hash\n", file->meta.source.c_str());
54 return true;
55 }
56 if (file->meta.deps != file->old_meta.deps) {
57 // printf("File: '%s' -> mismatch deps\n", file->meta.source.c_str());
58 return true;
59 }
60 for (auto dep : file->meta.deps) {
61 auto header = header_metadata->get(dep);
62 if (header != NULL && check_mismatch_recursive(header, source_metadata, header_metadata)) {
63 return true;
64 }
65 for (auto s : *source_metadata) {
66 if (dep == s.meta.source) {
67 if (check_mismatch_recursive(&s, source_metadata, header_metadata)) {
68 return true;
69 }
70 }
71 }
72 }
73 return false;
74}
75/* gcc_hash.hpp */
77 std::vector<std::string> objects_list,
78 std::string target_id) {
79 std::vector<extended_metadata> metadatas;
81 lib::map<std::string, std::string> ret; // source->object
83 // Get some basic metadata structs
84 for (size_t i = 0; i < file_list.size(); i++) {
85 metadatas.push_back({.meta = {.source = file_list.at(i),
86 .object = objects_list.at(i),
87 .deps = {},
88 .hash = 0},
89 .old_meta = {},
90 .old_metadata_available = false});
91 }
92 // Get metadata from files
93 for (size_t i = 0; i < metadatas.size(); i++) {
94 auto meta = &(metadatas.at(i));
95 int err = CBuild::read_file_metadata(target_id, meta->meta.source, &(meta->old_meta));
96 if (err == 0) {
97 meta->old_metadata_available = true;
98 }
99 }
100 // Get toolchain data
101 auto toolchain = CBuild::Registry::GetToolchain(target_id, true);
102 if (toolchain != NULL) {
103 auto cc = toolchain->get_cmds()[0];
104 toolchain->stdargs();
105 auto cargs = toolchain->get_compile_args();
106 for (size_t i = 0; i < metadatas.size(); i++) {
107 auto meta = &metadatas.at(i);
108 // Get dependencies
109 auto file = meta->meta.source;
110 auto cmd = cc + " " + cargs + " " + file + " -MM";
111 auto ret = CBuild::system_piped(cmd, 64 * 1024);
112 std::stringstream ss(ret);
113 std::string tmp;
114 ss >> tmp;
115 ss >> tmp;
116 std::vector<std::string> deps;
117 while (std::getline(ss, tmp, ' ')) {
118 if (tmp != std::string("") && tmp != std::string("\\\n") &&
119 tmp != std::string("\n")) {
120 deps.push_back(tmp);
121 }
122 }
123 lib::map<std::string, bool> deps_selector;
124 for (auto dep : deps) {
125 try {
127 } catch (std::exception& e) {
128 }
129 }
130 for (auto elem : deps_selector) {
131 meta->meta.deps.push_back(elem.key);
132 }
133 if (!(meta->meta.deps.empty())) {
134 meta->meta.deps.back().pop_back();
135 }
136 // Get file hash
137 std::ifstream f(file);
138 std::string content;
139 std::getline(f, content, '\0');
140 meta->meta.hash = CBuild::hash_fnv_1a(content);
141 }
142 // Reset print to normal
144 // Some fancy debug prints and metadat file updates
145 for (auto meta : metadatas) {
146 CBuild::write_file_metadata(target_id, meta.meta.source, &(meta.meta));
147 CBuild::print_full(std::string("File: ") + meta.meta.source +
148 std::string("\nObject: ") + meta.meta.object +
149 std::string("\nDeps [new]:"));
150 for (auto dep : meta.meta.deps) {
152 // Abuse printing code to save headers for processing
153 try {
154 header_metadatas.push_back_check(dep, {});
155 } catch (std::exception& e) {
156 }
157 }
158 CBuild::print_full("Deps [old]:");
159 if (meta.old_metadata_available) {
160 for (auto dep : meta.old_meta.deps) {
162 }
163 } else {
164 CBuild::print_full(" null");
165 }
166 CBuild::print_full(std::string("Hash [new]: ") + std::to_string(meta.meta.hash) +
167 std::string(", Hash [old]: ") +
168 (meta.old_metadata_available ? std::to_string(meta.old_meta.hash)
169 : std::string("null")));
170 }
171 // Disable printing, again
173 // Get metadata for headers
174 for (size_t i = 0; i < header_metadatas.size(); i++) {
175 auto meta = &(header_metadatas.ptr_at(i)->data);
176 // Get dependencies
177 auto file = header_metadatas.at(i).key;
178 auto cmd = cc + " " + cargs + " " + file + " -MM";
179 auto ret = CBuild::system_piped(cmd, 64 * 1024);
180 std::stringstream ss(ret);
181 std::string tmp;
182 ss >> tmp;
183 ss >> tmp;
184 std::vector<std::string> deps;
185 while (std::getline(ss, tmp, ' ')) {
186 if (tmp != std::string("") && tmp != std::string("\\\n") &&
187 tmp != std::string("\n")) {
188 deps.push_back(tmp);
189 }
190 }
191 lib::map<std::string, bool> deps_selector;
192 for (auto dep : deps) {
193 try {
195 } catch (std::exception& e) {
196 }
197 }
198 for (auto elem : deps_selector) {
199 meta->meta.deps.push_back(elem.key);
200 }
201 if (!(meta->meta.deps.empty())) {
202 meta->meta.deps.back().pop_back();
203 }
204 for (auto dep : meta->meta.deps) {
205 try {
206 header_metadatas.push_back_check(dep, {});
207 } catch (std::exception& e) {
208 }
209 }
210 // Get file hash
211 std::ifstream f(file);
212 std::string content;
213 std::getline(f, content, '\0');
214 meta->meta.hash = CBuild::hash_fnv_1a(content);
215 // Get old metadata
216 int err = CBuild::read_file_metadata(target_id, file, &(meta->old_meta));
217 meta->old_metadata_available = (err == 0);
218 // Files
219 meta->meta.source = file;
220 meta->meta.object = "header";
221 }
222 // Reset print to normal, again
224 // Some fancy debug prints and metadat file updates
225 for (auto meta_container : header_metadatas) {
226 auto meta = meta_container.data;
227 CBuild::write_file_metadata(target_id, meta.meta.source, &(meta.meta));
228 CBuild::print_full(std::string("File: ") + meta.meta.source +
229 std::string("\nObject: ") + meta.meta.object +
230 std::string("\nDeps [new]:"));
231 for (auto dep : meta.meta.deps) {
233 }
234 CBuild::print_full("Deps [old]:");
235 if (meta.old_metadata_available) {
236 for (auto dep : meta.old_meta.deps) {
238 }
239 } else {
240 CBuild::print_full(" null");
241 }
242 CBuild::print_full(std::string("Hash [new]: ") + std::to_string(meta.meta.hash) +
243 std::string(", Hash [old]: ") +
244 (meta.old_metadata_available ? std::to_string(meta.old_meta.hash)
245 : std::string("null")));
246 }
247 }
248 // Get files for recompilation
249 for (auto file : metadatas) {
250 if (check_mismatch_recursive(&file, &metadatas, &header_metadatas)) {
251 ret.push_back(file.meta.source, file.meta.object);
252 }
253 }
254 // Generate dependencie
255 return ret;
256}
Build metadata config file.
Simple map implementation with some stack operation added.
Definition map.hpp:79
void push_back_check(lib::mapData< _K, _D > element)
Add data, but check if key exists, if exist - trow exception.
Definition map.hpp:129
lib::mapData< _K, _D > * ptr_at(__SIZE_TYPE__ i)
Array operation, get pointer to an element at specified index.
Definition map.hpp:232
__SIZE_TYPE__ size()
Size of map.
Definition map.hpp:275
void push_back(lib::mapData< _K, _D > element)
Push new element to map, stack operation ! Dangerous not perform chak if this elemnt exists in map.
Definition map.hpp:111
const _D * get(_K key)
Get element by it's key.
Definition map.hpp:159
lib::mapData< _K, _D > at(__SIZE_TYPE__ i)
Array operation, get element at index.
Definition map.hpp:223
filesystem++ api
bool check_mismatch_recursive(const extended_metadata *file, std::vector< extended_metadata > *source_metadata, lib::map< std::string, extended_metadata > *header_metadata)
Definition gcc_hash.cpp:41
GCC hasher low-level implementation.
Custom implementation of map datatype.
CBuild::Toolchain * GetToolchain(std::string name, bool force=false)
Get the registered toolchain.
Definition register.cpp:239
std::string normalize_relative_path(std::string path, std::string base_path="")
Get absolute path to file using relative path and base path.
uint64_t hash_fnv_1a(std::string str)
FNV-1a hashing function for std::string.
Definition hasher.hpp:54
lib::map< std::string, std::string > gcc_hash_impl(std::vector< std::string > file_list, std::vector< std::string > objects_list, std::string target_id)
Implementation of GCC hasher.
Definition gcc_hash.cpp:76
int write_file_metadata(std::string target_id, std::string src_file, CBuild::source_metadata_file *metadata)
Write a metadata for a file to a file.
int read_file_metadata(std::string target_id, std::string src_file, CBuild::source_metadata_file *metadata)
Load metadata for source file.
void print_toggle()
Toogle print betwen none and currently selected level.
Definition print.cpp:104
std::string system_piped(std::string cmd, unsigned int buffsize)
Execute command and return it's output.
Definition system.cpp:58
void print_full(std::string msg, color fg=CBuild::WHITE)
Print colored text to STDOUT if verbose flag is set.
Definition print.cpp:75
Custom print that support color codes.
Register any things.
Command for compile_commands.json.
Metadata for source files (.cpp/.c/etc) Structure of file:
std::string object
Object file name.
std::vector< std::string > deps
On what files this file depends.
uint64_t hash
Hash of this file.
CBuild::source_metadata_file old_meta
CBuild::source_metadata_file meta
Definition gcc_hash.cpp:37
bool old_metadata_available
Definition gcc_hash.cpp:39
Custom system() wraper.