CBuild
C++ build system with scripts written in c++
Loading...
Searching...
No Matches
mingw-gccmt.hpp
Go to the documentation of this file.
1
21#ifndef CBUILD_MINGW_GCCMT_TOOLCHAIN
22#define CBUILD_MINGW_GCCMT_TOOLCHAIN
23// Project files
24#include "../CBuild_defs.hpp"
25#include "../filesystem++.hpp"
27#include "../print.hpp"
28#include "../register.hpp"
29#include "./Build.hpp"
30#include "atomic"
31#include "thread"
32// Code
33namespace CBuild {
34template <CBuild::HashImpl hash = CBuild::CBuildHashV2>
36 protected:
37 std::string wine;
38
39 public:
45 MINGW_GCCMT(std::string id) {
46 this->id = id;
47 this->name = "";
48 this->linker = "x86_64-w64-mingw32-gcc";
49 this->compiler = "x86_64-w64-mingw32-gcc";
50 this->packer = "x86_64-w64-mingw32-ar cr";
51 this->wine = "wine";
52 this->add_link_arg("-static-libgcc");
53 this->hasher = new hash(this->id);
54 }
61 MINGW_GCCMT(std::string id, std::string name) {
62 this->id = id;
63 this->name = name;
64 this->linker = "x86_64-w64-mingw32-gcc";
65 this->compiler = "x86_64-w64-mingw32-gcc";
66 this->packer = "x86_64-w64-mingw32-ar cr";
67 this->wine = "wine";
68 this->add_link_arg("-static-libgcc");
69 this->hasher = new hash(this->id);
70 }
71
72 protected:
73 // For docs see mingw-g++.hpp
74 void build() override {
75 std::string args;
76 for (auto elem : this->compiler_args) {
77 args += elem;
78 args += " ";
79 }
80 // Get all files
81 auto files = this->gen_file_list(this->force);
82 // Read pointer
83 std::atomic_int64_t read_ptr;
84 read_ptr.store(files.size() - 1);
85 // Get hw thread count
86 unsigned int num_threads = std::thread::hardware_concurrency();
87 // Setup threads
88 std::thread threads[num_threads];
89 for (unsigned int i = 0; i < num_threads; i++) {
90 threads[i] = std::thread([&files, this, &args, &read_ptr](void) -> void {
91 while (true) {
92 // Fetch read pointer
93 int64_t i = read_ptr.fetch_sub(1);
94 if (i < 0) {
95 return;
96 }
97 // Construct command
98 std::string cmd = this->compiler + " -c ";
99 cmd += files.at(i).key;
100 cmd += " ";
101 cmd += args;
102 cmd += " -o ";
103 cmd += files.at(i).data;
104 // Execute command
105 std::this_thread::get_id();
106
107 this->compile(cmd);
108 }
109 });
110 }
111 for (unsigned int i = 0; i < num_threads; i++) {
112 threads[i].join();
113 }
114 }
115 void link() override {
116 std::string args;
117 for (auto elem : this->link_args) {
118 args += elem;
119 args += " ";
120 }
121 // Get files
122 this->gen_file_list_for_linking = true;
123 auto files = this->gen_file_list(true);
124 this->gen_file_list_for_linking = false;
125 std::string flist;
126 for (unsigned int i = 0; i < files.size(); i++) {
127 flist += files.at(i).data;
128 flist += " ";
129 }
130 if (files.size() > 0) {
131 std::string cmd = this->linker + " ";
132 cmd += flist;
133 cmd += " ";
134 cmd += args;
135 cmd += " ";
136 cmd += " -o ";
137 cmd += this->gen_out_name();
138 // CBuild::print(cmd, CBuild::BLUE);
139 this->compile(cmd);
140 }
141 }
142 void link_pack() override {
143 std::string args;
144 for (auto elem : this->link_args) {
145 args += elem;
146 args += " ";
147 }
148 this->gen_file_list_for_linking = true;
149 auto files = this->gen_file_list(true);
150 this->gen_file_list_for_linking = false;
151 std::string flist;
152 for (unsigned int i = 0; i < files.size(); i++) {
153 flist += files.at(i).data;
154 flist += " ";
155 }
156 if (files.size() > 0) {
157 std::string cmd = this->packer + " ";
158 cmd += this->gen_out_name();
159 cmd += " ";
160 cmd += flist;
161 cmd += " ";
162 // CBuild::print(cmd, CBuild::BLUE);
163 this->compile(cmd);
164 }
165 }
166 void post_link() override {
167 for (std::string id : this->depends) {
168 auto target = CBuild::Registry::GetToolchain(id, true);
169 if (target != NULL) {
170 auto out_path = target->gen_out_name(".exe", ".dll");
171 unsigned int end_slash = out_path.find_last_of('/');
172 std::string out = CBUILD_BUILD_DIR + "/" + this->id + "/" + CBUILD_BUILD_OUT_DIR +
173 "/" + out_path.substr(end_slash + 1);
174 CBuild::fs::copy(out_path, out);
175 }
176 }
177 }
178
179 public:
180 std::string gen_out_name(std::string executable = ".exe", std::string dyn_lib = ".dll",
181 std::string stat_lib = ".a") override {
182 std::string base = CBUILD_BUILD_DIR + "/" + this->id + "/" + CBUILD_BUILD_OUT_DIR + "/";
183 if (this->name != std::string("")) {
184 if (this->build_type == CBuild::EXECUTABLE) {
185 base += this->name;
186 base += executable;
187 } else {
188 base += "lib";
189 base += this->name;
190 if (this->build_type == CBuild::DYNAMIC_LIBRARY) {
191 base += dyn_lib;
192 } else {
193 base += stat_lib;
194 }
195 }
196 } else {
197 if (this->build_type == CBuild::EXECUTABLE) {
198 base += this->name;
199 base += executable;
200 } else {
201 base += "lib";
202 base += this->id;
203 if (this->build_type == CBuild::DYNAMIC_LIBRARY) {
204 base += dyn_lib;
205 } else {
206 base += stat_lib;
207 }
208 }
209 }
210 return this->cmd_str(base);
211 }
212 // void call(std::vector<std::string> *args, bool force = false,
213 // bool debug = false) override {
214 // CBuild::print("Starting " + this->id + " toolchain in build mode ",
215 // CBuild::color::RED);
216 // this->args = args;
217 // this->force = force;
218 // if (this->build_type == CBuild::DYNAMIC_LIBRARY)
219 // this->link_args.push_back("-shared");
220 // if (debug)
221 // this->compiler_args.push_back("-g");
222 // this->compiler_args.push_back("-fPIC");
223 // this->init();
224 // CBuild::print("Calling tasks marked as PRE ", CBuild::color::GREEN);
225 // for (unsigned int i = 0; i < this->required.size(); i++) {
226 // auto elem = this->required.at(i);
227 // if (elem.data == CBuild::PRE) {
228 // CBuild::Registry::CallTask(elem.key, {});
229 // }
230 // }
231 // CBuild::print("Calling all required toolchains ",
232 // CBuild::color::GREEN); for (std::string id : this->depends) {
233 // auto target = CBuild::Registry::GetToolchain(id);
234 // if (target != NULL) {
235 // target->call(args, force, debug);
236 // auto out_path = target->gen_out_name();
237 // unsigned int end_slash = out_path.find_last_of('/');
238 // unsigned int end_dot = out_path.find_last_of('.');
239 // std::string out =
240 // out_path.substr(end_slash + 4, end_dot - end_slash - 4);
241 // this->add_library_include(out);
242 // this->add_library_dir(".", CBUILD_BUILD_DIR + "/" + target->get_id() +
243 // "/" + CBUILD_BUILD_OUT_DIR + "/");
244 // }
245 // }
246 // if (!force)
247 // CBuild::print("Using precompiled object were possible ",
248 // CBuild::color::MAGENTA);
249 // CBuild::print("Running pre build tasks ", CBuild::GREEN);
250 // this->pre_build();
251 // CBuild::print("Running build tasks ", CBuild::GREEN);
252 // CBuild::print("Now you can see compiler output", CBuild::MAGENTA);
253 // this->build();
254 // CBuild::print("Running post build tasks ", CBuild::GREEN);
255 // this->post_build();
256 // CBuild::print("Running pre link tasks ", CBuild::GREEN);
257 // this->pre_link();
258 // CBuild::print("Running link tasks ", CBuild::GREEN);
259 // CBuild::print("Now you can see linker output", CBuild::MAGENTA);
260 // if (this->build_type == CBuild::STATIC_LIBRARY) {
261 // this->link_pack();
262 // } else {
263 // this->link();
264 // }
265 // CBuild::print("Running post link tasks ", CBuild::GREEN);
266 // this->post_link();
267 // CBuild::print("Calling tasks marked as POST ", CBuild::GREEN);
268 // for (unsigned int i = 0; i < this->required.size(); i++) {
269 // auto elem = this->required.at(i);
270 // if (elem.data == CBuild::POST) {
271 // CBuild::Registry::CallTask(elem.key, {});
272 // }
273 // }
274 // CBuild::print("End of execution of toolchain " + this->id + " ",
275 // CBuild::RED);
276 // }
277 // void run(std::vector<std::string> *args) override {
278 // CBuild::print("Starting \"" + this->name + "\" ", CBuild::RED);
279 // std::string pargs = "";
280 // if (args != NULL) {
281 // for (auto elem : *args) {
282 // pargs += elem;
283 // pargs += " ";
284 // }
285 // }
286 // std::string cmd;
287 // cmd = this->wine + " ";
288 // cmd += this->gen_out_name();
289 // cmd += " ";
290 // cmd += pargs;
291 // CBuild::print("App output (if any):", CBuild::MAGENTA);
292 // CBuild::system(cmd);
293 // CBuild::print("End of app execution", CBuild::RED);
294 // }
295 void debug(std::vector<std::string>* args, std::vector<std::string>* pargs) override {
296 CBuild::print("It is unimplemented for now!", CBuild::RED);
297 // CBuild::print("Starting \"" + this->id + "\" toolchain in
298 // debug mode ", CBuild::RED); this->call(args, true, true);
299 // CBuild::print("Running builded app with gdb ",
300 // CBuild::GREEN); std::string ppargs = ""; if (pargs != NULL)
301 // {
302 // for (auto elem : *pargs)
303 // {
304 // ppargs += elem;
305 // ppargs += " ";
306 // }
307 // }
308 // std::string cmd;
309 // cmd = "x86_64-w64-mingw32-gdb ";
310 // cmd += this->gen_out_name();
311 // cmd += " ";
312 // cmd += ppargs;
313 // // CBuild::print("Now you can see gdb shell ",
314 // CBuild::MAGENTA); CBuild::system(cmd); CBuild::print("End of
315 // app execution", CBuild::RED);
316 }
317};
318} // namespace CBuild
319#endif // CBUILD_MINGW_GCCMT_TOOLCHAIN
Build toolchain headers.
#define CBUILD_BUILD_OUT_DIR
Build out in build/toolchain.
#define CBUILD_BUILD_DIR
Build directory of CBuild.
Improved CBuild hasher.
std::string gen_out_name(std::string executable=".exe", std::string dyn_lib=".dll", std::string stat_lib=".a") override
Generate output file name (after linking)
void build() override
Build.
void link_pack() override
Linking for static libraries.
MINGW_GCCMT(std::string id, std::string name)
Construct a new MINGW_GCCMT object.
void debug(std::vector< std::string > *args, std::vector< std::string > *pargs) override
Build program in debug mode and after run gdb on it.
void link() override
Linking.
void post_link() override
After linking.
MINGW_GCCMT(std::string id)
Construct a new MINGW_GCCMT object.
Toolchain class.
Definition Build.hpp:65
bool force
Force argument (scratch variable)
Definition Build.hpp:153
std::string packer
ar command for packing static libraries
Definition Build.hpp:106
Hash * hasher
Hasher used here.
Definition Build.hpp:138
virtual void compile(std::string cmd)
Call compiler.
Definition Build.cpp:504
std::string name
Name of output, if undefined (""), for id is used for binary name.
Definition Build.hpp:70
std::vector< std::string > link_args
Linker args (specified and generated)
Definition Build.hpp:94
bool gen_file_list_for_linking
Generate file list for linking - force and no changes to hashes.
Definition Build.hpp:130
virtual lib::map< std::string, std::string > gen_file_list(bool force)
Generate list of files that need to be compiles.
Definition Build.cpp:216
std::string id
Must be initialized in derived classes.
Definition Build.hpp:74
std::vector< std::string > compiler_args
Compiler args (specified and generated)
Definition Build.hpp:90
virtual void add_link_arg(std::string arg)
Add linker arguments.
Definition Build.cpp:44
std::string linker
Linker command.
Definition Build.hpp:102
std::vector< std::string > depends
All other targets, that is needed for this target.
Definition Build.hpp:82
virtual std::string cmd_str(std::string in)
Replace spaces by "\ ".
Definition Build.cpp:443
std::string compiler
Compiler command.
Definition Build.hpp:98
std::vector< std::string > * args
Argument pointer (scratch variable)
Definition Build.hpp:149
filesystem++ api
CBuild::Toolchain * GetToolchain(std::string name, bool force=false)
Get the registered toolchain.
Definition register.cpp:239
bool copy(std::string start, std::string end)
Copy files or directories.
Filebuffer for CBuild ecosystem.
Definition Build.hpp:34
uint64_t hash(std::string str)
FNV-1a hashing function for std::string.
Definition hash.cpp:218
void print(std::string msg, color fg=CBuild::WHITE)
Print colored text to STDOUT.
Definition print.cpp:70
build_type
Definition Build.hpp:55
@ EXECUTABLE
Definition Build.hpp:55
@ DYNAMIC_LIBRARY
Definition Build.hpp:55
@ RED
Definition print.hpp:34
Custom print that support color codes.
Register any things.
Command for compile_commands.json.