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