1 /*
2 * This file is part of the Code::Blocks IDE and licensed under the GNU Lesser General Public License, version 3
3 * http://www.gnu.org/licenses/lgpl-3.0.html
4 *
5 * $Revision: 11887 $
6 * $Id: compileoptionsbase.cpp 11887 2019-10-26 09:12:28Z fuscated $
7 * $HeadURL: svn://svn.code.sf.net/p/codeblocks/code/branches/release-20.xx/src/sdk/compileoptionsbase.cpp $
8 */
9
10 #include "sdk_precomp.h"
11
12 #ifndef CB_PRECOMP
13 #include "compileoptionsbase.h"
14 #include "sdk_events.h"
15 #include "manager.h"
16 #include "macrosmanager.h"
17 #endif
18
19 namespace { static const bool s_case_sensitive = platform::windows ? false : true; }
20
CompileOptionsBase()21 CompileOptionsBase::CompileOptionsBase()
22 : m_Platform(spAll),
23 m_LinkerExecutable(LinkerExecutableOption::AutoDetect),
24 m_Modified(false),
25 m_AlwaysRunPostCmds(false)
26 {
27 //ctor
28 }
29
~CompileOptionsBase()30 CompileOptionsBase::~CompileOptionsBase()
31 {
32 //dtor
33 }
34
AddPlatform(int platform)35 void CompileOptionsBase::AddPlatform(int platform)
36 {
37 if (m_Platform & platform)
38 return;
39 m_Platform |= platform;
40 SetModified(true);
41 }
42
RemovePlatform(int platform)43 void CompileOptionsBase::RemovePlatform(int platform)
44 {
45 if (!(m_Platform & platform))
46 return;
47 m_Platform &= ~platform;
48 SetModified(true);
49 }
50
SetPlatforms(int platforms)51 void CompileOptionsBase::SetPlatforms(int platforms)
52 {
53 if (m_Platform == platforms)
54 return;
55 m_Platform = platforms;
56 SetModified(true);
57 }
58
GetPlatforms() const59 int CompileOptionsBase::GetPlatforms() const
60 {
61 return m_Platform;
62 }
63
SupportsCurrentPlatform() const64 bool CompileOptionsBase::SupportsCurrentPlatform() const
65 {
66 if(platform::windows)
67 return m_Platform & spWindows;
68 if(platform::Unix)
69 return m_Platform & spUnix;
70 if(platform::macosx)
71 return m_Platform & spMac;
72
73 return false;
74 }
75
SetLinkerOptions(const wxArrayString & linkerOpts)76 void CompileOptionsBase::SetLinkerOptions(const wxArrayString& linkerOpts)
77 {
78 if (m_LinkerOptions == linkerOpts)
79 return;
80 m_LinkerOptions = linkerOpts;
81 SetModified(true);
82 }
83
GetLinkerOptions() const84 const wxArrayString& CompileOptionsBase::GetLinkerOptions() const
85 {
86 return m_LinkerOptions;
87 }
88
SetLinkLibs(const wxArrayString & linkLibs)89 void CompileOptionsBase::SetLinkLibs(const wxArrayString& linkLibs)
90 {
91 if (m_LinkLibs == linkLibs)
92 return;
93 m_LinkLibs = linkLibs;
94 SetModified(true);
95 }
96
GetLinkLibs() const97 const wxArrayString& CompileOptionsBase::GetLinkLibs() const
98 {
99 return m_LinkLibs;
100 }
101
SetCompilerOptions(const wxArrayString & compilerOpts)102 void CompileOptionsBase::SetCompilerOptions(const wxArrayString& compilerOpts)
103 {
104 if (m_CompilerOptions == compilerOpts)
105 return;
106 m_CompilerOptions = compilerOpts;
107 SetModified(true);
108 }
109
GetCompilerOptions() const110 const wxArrayString& CompileOptionsBase::GetCompilerOptions() const
111 {
112 return m_CompilerOptions;
113 }
114
SetResourceCompilerOptions(const wxArrayString & resourceCompilerOpts)115 void CompileOptionsBase::SetResourceCompilerOptions(const wxArrayString& resourceCompilerOpts)
116 {
117 if (m_ResourceCompilerOptions == resourceCompilerOpts)
118 return;
119 m_ResourceCompilerOptions = resourceCompilerOpts;
120 SetModified(true);
121 }
122
GetResourceCompilerOptions() const123 const wxArrayString& CompileOptionsBase::GetResourceCompilerOptions() const
124 {
125 return m_ResourceCompilerOptions;
126 }
127
SetIncludeDirs(const wxArrayString & includeDirs)128 void CompileOptionsBase::SetIncludeDirs(const wxArrayString& includeDirs)
129 {
130 if (m_IncludeDirs == includeDirs)
131 return;
132
133 // make sure we don't have duplicate entries
134 // that's why we don't assign the array but rather copy it entry by entry...
135
136 m_IncludeDirs.Clear();
137 for (size_t i = 0; i < includeDirs.GetCount(); ++i)
138 {
139 wxString entry = UnixFilename(includeDirs[i]);
140 if (m_IncludeDirs.Index(entry, s_case_sensitive) == wxNOT_FOUND)
141 m_IncludeDirs.Add(entry);
142 }
143 SetModified(true);
144 }
145
GetIncludeDirs() const146 const wxArrayString& CompileOptionsBase::GetIncludeDirs() const
147 {
148 return m_IncludeDirs;
149 }
150
SetResourceIncludeDirs(const wxArrayString & resIncludeDirs)151 void CompileOptionsBase::SetResourceIncludeDirs(const wxArrayString& resIncludeDirs)
152 {
153 if (m_ResIncludeDirs == resIncludeDirs)
154 return;
155
156 // make sure we don't have duplicate entries
157 // that's why we don't assign the array but rather copy it entry by entry...
158
159 m_ResIncludeDirs.Clear();
160 for (size_t i = 0; i < resIncludeDirs.GetCount(); ++i)
161 {
162 wxString entry = UnixFilename(resIncludeDirs[i]);
163 if (m_ResIncludeDirs.Index(entry, s_case_sensitive) == wxNOT_FOUND)
164 m_ResIncludeDirs.Add(entry);
165 }
166 SetModified(true);
167 }
168
GetResourceIncludeDirs() const169 const wxArrayString& CompileOptionsBase::GetResourceIncludeDirs() const
170 {
171 return m_ResIncludeDirs;
172 }
173
SetLibDirs(const wxArrayString & libDirs)174 void CompileOptionsBase::SetLibDirs(const wxArrayString& libDirs)
175 {
176 if (m_LibDirs == libDirs)
177 return;
178
179 // make sure we don't have duplicate entries
180 // that's why we don't assign the array but rather copy it entry by entry...
181
182 m_LibDirs.Clear();
183 for (size_t i = 0; i < libDirs.GetCount(); ++i)
184 {
185 wxString entry = UnixFilename(libDirs[i]);
186 if (m_LibDirs.Index(entry, s_case_sensitive) == wxNOT_FOUND)
187 m_LibDirs.Add(entry);
188 }
189 SetModified(true);
190 }
191
GetLibDirs() const192 const wxArrayString& CompileOptionsBase::GetLibDirs() const
193 {
194 return m_LibDirs;
195 }
196
SetBuildScripts(const wxArrayString & scripts)197 void CompileOptionsBase::SetBuildScripts(const wxArrayString& scripts)
198 {
199 if (m_Scripts == scripts)
200 return;
201
202 // make sure we don't have duplicate entries
203 // that's why we don't assign the array but rather copy it entry by entry...
204
205 m_Scripts.Clear();
206 for (size_t i = 0; i < scripts.GetCount(); ++i)
207 {
208 wxString entry = UnixFilename(scripts[i]);
209 if (m_Scripts.Index(entry, s_case_sensitive) == wxNOT_FOUND)
210 m_Scripts.Add(entry);
211 }
212 SetModified(true);
213 }
214
GetBuildScripts() const215 const wxArrayString& CompileOptionsBase::GetBuildScripts() const
216 {
217 return m_Scripts;
218 }
219
SetCommandsBeforeBuild(const wxArrayString & commands)220 void CompileOptionsBase::SetCommandsBeforeBuild(const wxArrayString& commands)
221 {
222 if (m_CmdsBefore == commands)
223 return;
224 m_CmdsBefore = commands;
225 SetModified(true);
226 }
227
GetCommandsBeforeBuild() const228 const wxArrayString& CompileOptionsBase::GetCommandsBeforeBuild() const
229 {
230 return m_CmdsBefore;
231 }
232
SetCommandsAfterBuild(const wxArrayString & commands)233 void CompileOptionsBase::SetCommandsAfterBuild(const wxArrayString& commands)
234 {
235 if (m_CmdsAfter == commands)
236 return;
237 m_CmdsAfter = commands;
238 SetModified(true);
239 }
240
GetCommandsAfterBuild() const241 const wxArrayString& CompileOptionsBase::GetCommandsAfterBuild() const
242 {
243 return m_CmdsAfter;
244 }
245
GetAlwaysRunPostBuildSteps() const246 bool CompileOptionsBase::GetAlwaysRunPostBuildSteps() const
247 {
248 return m_AlwaysRunPostCmds;
249 }
250
SetAlwaysRunPostBuildSteps(bool always)251 void CompileOptionsBase::SetAlwaysRunPostBuildSteps(bool always)
252 {
253 if (m_AlwaysRunPostCmds == always)
254 return;
255 m_AlwaysRunPostCmds = always;
256 SetModified(true);
257 }
258
GetModified() const259 bool CompileOptionsBase::GetModified() const
260 {
261 return m_Modified;
262 }
263
SetModified(bool modified)264 void CompileOptionsBase::SetModified(bool modified)
265 {
266 m_Modified = modified;
267 }
268
AddLinkerOption(const wxString & option)269 void CompileOptionsBase::AddLinkerOption(const wxString& option)
270 {
271 if (m_LinkerOptions.Index(option, s_case_sensitive) == wxNOT_FOUND)
272 {
273 m_LinkerOptions.Add(option);
274 SetModified(true);
275 }
276 }
277
AddLinkLib(const wxString & option)278 void CompileOptionsBase::AddLinkLib(const wxString& option)
279 {
280 if (m_LinkLibs.Index(option, s_case_sensitive) == wxNOT_FOUND)
281 {
282 m_LinkLibs.Add(option);
283 SetModified(true);
284 }
285 }
286
AddCompilerOption(const wxString & option)287 void CompileOptionsBase::AddCompilerOption(const wxString& option)
288 {
289 if (m_CompilerOptions.Index(option, s_case_sensitive) == wxNOT_FOUND)
290 {
291 m_CompilerOptions.Add(option);
292 SetModified(true);
293 }
294 }
295
AddResourceCompilerOption(const wxString & option)296 void CompileOptionsBase::AddResourceCompilerOption(const wxString& option)
297 {
298 if (m_ResourceCompilerOptions.Index(option, s_case_sensitive) == wxNOT_FOUND)
299 {
300 m_ResourceCompilerOptions.Add(option);
301 SetModified(true);
302 }
303 }
304
AddIncludeDir(const wxString & option)305 void CompileOptionsBase::AddIncludeDir(const wxString& option)
306 {
307 wxString entry = UnixFilename(option);
308 if (m_IncludeDirs.Index(entry, s_case_sensitive) == wxNOT_FOUND)
309 {
310 m_IncludeDirs.Add(entry);
311 SetModified(true);
312 }
313 }
314
AddResourceIncludeDir(const wxString & option)315 void CompileOptionsBase::AddResourceIncludeDir(const wxString& option)
316 {
317 wxString entry = UnixFilename(option);
318 if (m_ResIncludeDirs.Index(entry, s_case_sensitive) == wxNOT_FOUND)
319 {
320 m_ResIncludeDirs.Add(entry);
321 SetModified(true);
322 }
323 }
324
AddLibDir(const wxString & option)325 void CompileOptionsBase::AddLibDir(const wxString& option)
326 {
327 wxString entry = UnixFilename(option);
328 if (m_LibDirs.Index(entry, s_case_sensitive) == wxNOT_FOUND)
329 {
330 m_LibDirs.Add(entry);
331 SetModified(true);
332 }
333 }
334
AddCommandsBeforeBuild(const wxString & command)335 void CompileOptionsBase::AddCommandsBeforeBuild(const wxString& command)
336 {
337 m_CmdsBefore.Add(command);
338 SetModified(true);
339 }
340
AddCommandsAfterBuild(const wxString & command)341 void CompileOptionsBase::AddCommandsAfterBuild(const wxString& command)
342 {
343 m_CmdsAfter.Add(command);
344 SetModified(true);
345 }
346
AddBuildScript(const wxString & script)347 void CompileOptionsBase::AddBuildScript(const wxString& script)
348 {
349 wxString envopt = UnixFilename(script);
350 if (m_Scripts.Index(envopt, s_case_sensitive) == wxNOT_FOUND)
351 {
352 m_Scripts.Add(envopt);
353 SetModified(true);
354 }
355 }
356
ReplaceLinkerOption(const wxString & option,const wxString & new_option)357 void CompileOptionsBase::ReplaceLinkerOption(const wxString& option, const wxString& new_option)
358 {
359 int idx = m_LinkerOptions.Index(option, s_case_sensitive);
360 if (idx != wxNOT_FOUND)
361 {
362 m_LinkerOptions.Item(idx) = new_option;
363 SetModified(true);
364 }
365 }
366
ReplaceLinkLib(const wxString & option,const wxString & new_option)367 void CompileOptionsBase::ReplaceLinkLib(const wxString& option, const wxString& new_option)
368 {
369 int idx = m_LinkLibs.Index(option, s_case_sensitive);
370 if (idx != wxNOT_FOUND)
371 {
372 m_LinkLibs.Item(idx) = new_option;
373 SetModified(true);
374 }
375 }
376
ReplaceCompilerOption(const wxString & option,const wxString & new_option)377 void CompileOptionsBase::ReplaceCompilerOption(const wxString& option, const wxString& new_option)
378 {
379 int idx = m_CompilerOptions.Index(option, s_case_sensitive);
380 if (idx != wxNOT_FOUND)
381 {
382 m_CompilerOptions.Item(idx) = new_option;
383 SetModified(true);
384 }
385 }
386
ReplaceResourceCompilerOption(const wxString & option,const wxString & new_option)387 void CompileOptionsBase::ReplaceResourceCompilerOption(const wxString& option, const wxString& new_option)
388 {
389 int idx = m_ResourceCompilerOptions.Index(option, s_case_sensitive);
390 if (idx != wxNOT_FOUND)
391 {
392 m_ResourceCompilerOptions.Item(idx) = new_option;
393 SetModified(true);
394 }
395 }
396
ReplaceIncludeDir(const wxString & option,const wxString & new_option)397 void CompileOptionsBase::ReplaceIncludeDir(const wxString& option, const wxString& new_option)
398 {
399 int idx = m_IncludeDirs.Index(option, s_case_sensitive);
400 if (idx != wxNOT_FOUND)
401 {
402 m_IncludeDirs.Item(idx) = new_option;
403 SetModified(true);
404 }
405 }
406
ReplaceResourceIncludeDir(const wxString & option,const wxString & new_option)407 void CompileOptionsBase::ReplaceResourceIncludeDir(const wxString& option, const wxString& new_option)
408 {
409 int idx = m_ResIncludeDirs.Index(option, s_case_sensitive);
410 if (idx != wxNOT_FOUND)
411 {
412 m_ResIncludeDirs.Item(idx) = new_option;
413 SetModified(true);
414 }
415 }
416
ReplaceLibDir(const wxString & option,const wxString & new_option)417 void CompileOptionsBase::ReplaceLibDir(const wxString& option, const wxString& new_option)
418 {
419 int idx = m_LibDirs.Index(option, s_case_sensitive);
420 if (idx != wxNOT_FOUND)
421 {
422 m_LibDirs.Item(idx) = new_option;
423 SetModified(true);
424 }
425 }
426
RemoveLinkerOption(const wxString & option)427 void CompileOptionsBase::RemoveLinkerOption(const wxString& option)
428 {
429 int idx = m_LinkerOptions.Index(option, s_case_sensitive);
430 if (idx != wxNOT_FOUND)
431 {
432 m_LinkerOptions.RemoveAt(idx);
433 SetModified(true);
434 }
435 }
436
RemoveLinkLib(const wxString & option)437 void CompileOptionsBase::RemoveLinkLib(const wxString& option)
438 {
439 int idx = m_LinkLibs.Index(option, s_case_sensitive);
440 if (idx != wxNOT_FOUND)
441 {
442 m_LinkLibs.RemoveAt(idx);
443 SetModified(true);
444 }
445 }
446
RemoveCompilerOption(const wxString & option)447 void CompileOptionsBase::RemoveCompilerOption(const wxString& option)
448 {
449 int idx = m_CompilerOptions.Index(option, s_case_sensitive);
450 if (idx != wxNOT_FOUND)
451 {
452 m_CompilerOptions.RemoveAt(idx);
453 SetModified(true);
454 }
455 }
456
RemoveResourceCompilerOption(const wxString & option)457 void CompileOptionsBase::RemoveResourceCompilerOption(const wxString& option)
458 {
459 int idx = m_ResourceCompilerOptions.Index(option, s_case_sensitive);
460 if (idx != wxNOT_FOUND)
461 {
462 m_ResourceCompilerOptions.RemoveAt(idx);
463 SetModified(true);
464 }
465 }
466
RemoveIncludeDir(const wxString & option)467 void CompileOptionsBase::RemoveIncludeDir(const wxString& option)
468 {
469 wxString entry = UnixFilename(option);
470 int idx = m_IncludeDirs.Index(entry, s_case_sensitive);
471 if (idx != wxNOT_FOUND)
472 {
473 m_IncludeDirs.RemoveAt(idx);
474 SetModified(true);
475 }
476 }
477
RemoveResourceIncludeDir(const wxString & option)478 void CompileOptionsBase::RemoveResourceIncludeDir(const wxString& option)
479 {
480 wxString entry = UnixFilename(option);
481 int idx = m_ResIncludeDirs.Index(entry, s_case_sensitive);
482 if (idx != wxNOT_FOUND)
483 {
484 m_ResIncludeDirs.RemoveAt(idx);
485 SetModified(true);
486 }
487 }
488
RemoveLibDir(const wxString & option)489 void CompileOptionsBase::RemoveLibDir(const wxString& option)
490 {
491 wxString entry = UnixFilename(option);
492 int idx = m_LibDirs.Index(entry, s_case_sensitive);
493 if (idx != wxNOT_FOUND)
494 {
495 m_LibDirs.RemoveAt(idx);
496 SetModified(true);
497 }
498 }
499
RemoveCommandsBeforeBuild(const wxString & command)500 void CompileOptionsBase::RemoveCommandsBeforeBuild(const wxString& command)
501 {
502 m_CmdsBefore.Remove(command);
503 SetModified(true);
504 }
505
RemoveCommandsAfterBuild(const wxString & command)506 void CompileOptionsBase::RemoveCommandsAfterBuild(const wxString& command)
507 {
508 m_CmdsAfter.Remove(command);
509 SetModified(true);
510 }
511
RemoveBuildScript(const wxString & script)512 void CompileOptionsBase::RemoveBuildScript(const wxString& script)
513 {
514 wxString envopt = UnixFilename(script);
515 int idx = m_Scripts.Index(envopt, s_case_sensitive);
516 if (idx != wxNOT_FOUND)
517 {
518 m_Scripts.RemoveAt(idx);
519 SetModified(true);
520 }
521 }
522
SetVar(const wxString & key,const wxString & value,bool onlyIfExists)523 bool CompileOptionsBase::SetVar(const wxString& key, const wxString& value, bool onlyIfExists)
524 {
525 if (onlyIfExists)
526 {
527 StringHash::iterator it = m_Vars.find(key);
528 if (it == m_Vars.end())
529 return false;
530 it->second = value;
531 return true;
532 }
533
534 m_Vars[key] = value;
535 SetModified(true);
536 return true;
537 }
538
UnsetVar(const wxString & key)539 bool CompileOptionsBase::UnsetVar(const wxString& key)
540 {
541 StringHash::iterator it = m_Vars.find(key);
542 if (it != m_Vars.end())
543 {
544 m_Vars.erase(it);
545 SetModified(true);
546 return true;
547 }
548 return false;
549 }
550
UnsetAllVars()551 void CompileOptionsBase::UnsetAllVars()
552 {
553 m_Vars.clear();
554 }
555
HasVar(const wxString & key) const556 bool CompileOptionsBase::HasVar(const wxString& key) const
557 {
558 StringHash::const_iterator it = m_Vars.find(key);
559 if (it != m_Vars.end())
560 return true;
561
562 return false;
563 }
564
GetVar(const wxString & key) const565 const wxString& CompileOptionsBase::GetVar(const wxString& key) const
566 {
567 StringHash::const_iterator it = m_Vars.find(key);
568 if (it != m_Vars.end())
569 return it->second;
570
571 static wxString emptystring = wxEmptyString;
572 return emptystring;
573 }
574
GetAllVars() const575 const StringHash& CompileOptionsBase::GetAllVars() const
576 {
577 return m_Vars;
578 }
579
SetLinkerExecutable(LinkerExecutableOption option)580 void CompileOptionsBase::SetLinkerExecutable(LinkerExecutableOption option)
581 {
582 if (m_LinkerExecutable == option)
583 return;
584
585 // We need to do this range check because this function could be called from scripting and there
586 // is no range checking done by the compiler.
587 if (option>= LinkerExecutableOption::First && option <= LinkerExecutableOption::Last)
588 {
589 m_LinkerExecutable = option;
590 SetModified(true);
591 }
592 else if (m_LinkerExecutable != LinkerExecutableOption::AutoDetect)
593 {
594 m_LinkerExecutable = LinkerExecutableOption::AutoDetect;
595 SetModified(true);
596 }
597 }
598
GetLinkerExecutable() const599 LinkerExecutableOption CompileOptionsBase::GetLinkerExecutable() const
600 {
601 return m_LinkerExecutable;
602 }
603