Code::Blocks  SVN r11506
projectloader.cpp
Go to the documentation of this file.
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: 11433 $
6  * $Id: projectloader.cpp 11433 2018-08-07 07:12:42Z fuscated $
7  * $HeadURL: https://svn.code.sf.net/p/codeblocks/code/trunk/src/sdk/projectloader.cpp $
8  */
9 
10 #include "sdk_precomp.h"
11 
12 #ifndef CB_PRECOMP
13  #include <wx/confbase.h>
14  #include <wx/fileconf.h>
15  #include <wx/intl.h>
16  #include <wx/filename.h>
17  #include <wx/msgdlg.h>
18  #include <wx/stopwatch.h>
19  #include "manager.h"
20  #include "configmanager.h"
21  #include "projectmanager.h"
22  #include "logmanager.h"
23  #include "macrosmanager.h"
24  #include "cbproject.h"
25  #include "compilerfactory.h"
26  #include "globals.h"
27 #endif
28 
29 #include <wx/dir.h>
30 #include <string>
31 
32 #include <algorithm>
33 #include "filefilters.h"
34 #include "projectloader.h"
35 #include "projectloader_hooks.h"
36 #include "annoyingdialog.h"
37 #include "configmanager.h"
38 #include "tinywxuni.h"
39 #include "filegroupsandmasks.h"
40 
42  : m_pProject(project),
43  m_Upgraded(false),
44  m_OpenDirty(false),
45  m_1_4_to_1_5_deftarget(-1),
46  m_IsPre_1_6(false)
47 {
48  //ctor
49 }
50 
52 {
53  //dtor
54 }
55 
56 bool ProjectLoader::Open(const wxString& filename)
57 {
58  return Open(filename, nullptr);
59 }
60 
61 bool ProjectLoader::Open(const wxString& filename, TiXmlElement** ppExtensions)
62 {
64  if (!pMsg)
65  return false;
66 
67  wxStopWatch sw;
68  pMsg->DebugLog(_T("Loading project file..."));
69  TiXmlDocument doc;
70  if (!TinyXML::LoadDocument(filename, &doc))
71  return false;
72 
73  pMsg->DebugLog(_T("Parsing project file..."));
74  TiXmlElement* root;
75  TiXmlElement* proj;
76 
77  root = doc.FirstChildElement("CodeBlocks_project_file");
78  if (!root)
79  {
80  // old tag
81  root = doc.FirstChildElement("Code::Blocks_project_file");
82  if (!root)
83  {
84  pMsg->DebugLog(_T("Not a valid Code::Blocks project file..."));
85  return false;
86  }
87  }
88  proj = root->FirstChildElement("Project");
89  if (!proj)
90  {
91  pMsg->DebugLog(_T("No 'Project' element in file..."));
92  return false;
93  }
94 
95  m_IsPre_1_2 = false; // flag for some changed defaults in version 1.2
96  TiXmlElement* version = root->FirstChildElement("FileVersion");
97  // don't show messages if we 're running a batch build (i.e. no gui)
98  if (!Manager::IsBatchBuild() && version)
99  {
100  int major = PROJECT_FILE_VERSION_MAJOR;
101  int minor = PROJECT_FILE_VERSION_MINOR;
102  version->QueryIntAttribute("major", &major);
103  version->QueryIntAttribute("minor", &minor);
104 
105  m_IsPre_1_6 = major < 1 || (major == 1 && minor < 6);
106 
107  if (major < 1 ||
108  (major == 1 && minor < 2))
109  {
110  // pre-1.2
111  pMsg->DebugLog(F(_T("Project version is %d.%d. Defaults have changed since then..."), major, minor));
112  m_IsPre_1_2 = true;
113  }
114  else if (major >= PROJECT_FILE_VERSION_MAJOR && minor > PROJECT_FILE_VERSION_MINOR)
115  {
116  pMsg->DebugLog(F(_T("Project version is > %d.%d. Trying to load..."), PROJECT_FILE_VERSION_MAJOR, PROJECT_FILE_VERSION_MINOR));
117  AnnoyingDialog dlg(_("Project file format is newer/unknown"),
118  _("This project file was saved with a newer version of Code::Blocks.\n"
119  "Will try to load, but you should make sure all the settings were loaded correctly..."),
122  dlg.ShowModal();
123  }
124  else
125  {
126  // use one message for all changes
127  wxString msg;
128  wxString warn_msg;
129 
130  // 1.5 -> 1.6: values matching defaults are not written to <Unit> sections
131  if (major == 1 && minor == 5)
132  {
133  msg << _("1.5 to 1.6:\n");
134  msg << _(" * only saves values that differ from defaults (i.e. project files are smaller now).\n");
135  msg << _(" * added object names generation mode setting (normal/extended).\n");
136  msg << _(" * added project notes.\n");
137  msg << _("\n");
138 
139  warn_msg << _("* Project file updated to version 1.6:\n");
140  warn_msg << _(" When a project file is saved as version 1.6, it will NO LONGER be read correctly\n");
141  warn_msg << _(" by earlier Code::Blocks versions!\n");
142  warn_msg << _(" So, if you plan on using this project with an earlier Code::Blocks version, you\n");
143  warn_msg << _(" should probably NOT save this project as version 1.6...\n");
144  warn_msg << _("\n");
145  }
146 
147  // 1.4 -> 1.5: updated custom build command per-project file
148  if (major == 1 && minor == 4)
149  {
150  msg << _("1.4 to 1.5:\n");
151  msg << _(" * added virtual build targets.\n");
152  msg << _("\n");
153  }
154 
155  // 1.3 -> 1.4: updated custom build command per-project file
156  if (major == 1 && minor == 3)
157  {
158  msg << _("1.3 to 1.4:\n");
159  msg << _(" * changed the way custom file build commands are stored (no auto-conversion).\n");
160  msg << _("\n");
161  }
162 
163  if (!msg.IsEmpty())
164  {
165  m_Upgraded = true;
166  msg.Prepend(wxString::Format(_("Project file format is older (%d.%d) than the current format (%d.%d).\n"
167  "The file will automatically be upgraded on save.\n"
168  "But please read the following list of changes, as some of them "
169  "might not automatically convert existing (old) settings.\n"
170  "If you don't understand what a change means, you probably don't "
171  "use that feature so you don't have to worry about it.\n\n"
172  "List of changes:\n"),
173  major,
174  minor,
177  AnnoyingDialog dlg(_("Project file format changed"),
178  msg,
181  dlg.ShowModal();
182  }
183 
184  if (!warn_msg.IsEmpty())
185  {
186  warn_msg.Prepend(_("!!! WARNING !!!\n\n"));
187  AnnoyingDialog dlg(_("Project file upgrade warning"),
188  warn_msg,
191  dlg.ShowModal();
192  }
193  }
194  }
195 
196  DoProjectOptions(proj);
197  DoBuild(proj);
198  DoCompilerOptions(proj);
200  DoLinkerOptions(proj);
201  DoIncludesOptions(proj);
202  DoLibsOptions(proj);
203  DoExtraCommands(proj);
204  DoUnits(proj);
205 
206  // if targets still use the "build with all" flag,
207  // it's time for conversion
208  if (!m_pProject->HasVirtualBuildTarget(_T("All")))
209  {
210  wxArrayString all;
211  for (int i = 0; i < m_pProject->GetBuildTargetsCount(); ++i)
212  {
214  if (bt && bt->GetIncludeInTargetAll())
215  all.Add(bt->GetTitle());
216  }
217  if (all.GetCount())
218  {
219  m_pProject->DefineVirtualBuildTarget(_T("All"), all);
220  m_Upgraded = true;
221  }
222  }
223 
224  // convert old deftarget int to string
225  if (m_1_4_to_1_5_deftarget != -1)
226  {
228  if (bt)
230  }
231 
232  if (ppExtensions)
233  *ppExtensions = nullptr;
234 
235  // as a last step, run all hooked callbacks
236  TiXmlElement* node = proj->FirstChildElement("Extensions");
237  if (node)
238  {
239  if (ppExtensions)
240  *ppExtensions = new TiXmlElement(*node);
242  }
243 
244  if (!version)
245  {
246  // pre 1.1 version
248  // format changed also:
249  // removed <IncludeDirs> and <LibDirs> elements and added them as child elements
250  // in <Compiler> and <Linker> elements respectively
251  // so set m_Upgraded to true, irrespectively of libs detection...
252  m_Upgraded = true;
253  }
254  else
255  {
256  // do something important based on version
257 // wxString major = version->Attribute("major");
258 // wxString minor = version->Attribute("minor");
259  }
260 
261  pMsg->DebugLog(wxString(_T("Done loading project in ")) << wxString::Format(_T("%d"), (int) sw.Time()) << _T("ms"));
262  return true;
263 }
264 
266 {
267  // ask to detect linker libraries and move them to the new
268  // CompileOptionsBase linker libs container
269  wxString msg;
270  msg.Printf(_("Project \"%s\" was saved with an earlier version of Code::Blocks.\n"
271  "In the current version, link libraries are treated separately from linker options.\n"
272  "Do you want to auto-detect the libraries \"%s\" is using and configure it accordingly?"),
274  m_pProject->GetTitle().c_str());
275  if (cbMessageBox(msg, _("Question"), wxICON_QUESTION | wxYES_NO) == wxID_YES)
276  {
277  // project first
279 
280  for (int i = 0; i < m_pProject->GetBuildTargetsCount(); ++i)
281  {
283  m_Upgraded = true;
284  }
285  }
286 }
287 
289 {
290  wxArrayString linkerOpts = object->GetLinkerOptions();
291  wxArrayString linkLibs = object->GetLinkLibs();
292 
293  wxString compilerId = object->GetCompilerID();
294  Compiler* compiler = CompilerFactory::GetCompiler(compilerId);
295  if (!compiler)
296  return;
297  wxString linkLib = compiler->GetSwitches().linkLibs;
298  wxString libExt = compiler->GetSwitches().libExtension;
299  size_t libExtLen = libExt.Length();
300 
301  size_t i = 0;
302  while (i < linkerOpts.GetCount())
303  {
304  wxString opt = linkerOpts[i];
305  if (!linkLib.IsEmpty() && opt.StartsWith(linkLib))
306  {
307  opt.Remove(0, 2);
308  wxString ext = compiler->GetSwitches().libExtension;
309  if (!ext.IsEmpty())
310  ext = _T(".") + ext;
311  linkLibs.Add(compiler->GetSwitches().libPrefix + opt + ext);
312  linkerOpts.RemoveAt(i, 1);
313  }
314  else if (opt.Length() > libExtLen && opt.Right(libExtLen) == libExt)
315  {
316  linkLibs.Add(opt);
317  linkerOpts.RemoveAt(i, 1);
318  }
319  else
320  ++i;
321  }
322 
323  object->SetLinkerOptions(linkerOpts);
324  object->SetLinkLibs(linkLibs);
325 }
326 
327 void ProjectLoader::DoMakeCommands(TiXmlElement* parentNode, CompileTargetBase* target)
328 {
329  if (!parentNode)
330  return; // no options
331 
332  TiXmlElement* node;
333 
334  node = parentNode->FirstChildElement("Build");
335  if (node && node->Attribute("command"))
336  target->SetMakeCommandFor(mcBuild, cbC2U(node->Attribute("command")));
337 
338  node = parentNode->FirstChildElement("CompileFile");
339  if (node && node->Attribute("command"))
340  target->SetMakeCommandFor(mcCompileFile, cbC2U(node->Attribute("command")));
341 
342  node = parentNode->FirstChildElement("Clean");
343  if (node && node->Attribute("command"))
344  target->SetMakeCommandFor(mcClean, cbC2U(node->Attribute("command")));
345 
346  node = parentNode->FirstChildElement("DistClean");
347  if (node && node->Attribute("command"))
348  target->SetMakeCommandFor(mcDistClean, cbC2U(node->Attribute("command")));
349 
350  node = parentNode->FirstChildElement("AskRebuildNeeded");
351  if (node && node->Attribute("command"))
352  target->SetMakeCommandFor(mcAskRebuildNeeded, cbC2U(node->Attribute("command")));
353 
354  node = parentNode->FirstChildElement("SilentBuild");
355  if (node && node->Attribute("command"))
356  target->SetMakeCommandFor(mcSilentBuild, cbC2U(node->Attribute("command")));
357 }
358 
359 void ProjectLoader::DoVirtualTargets(TiXmlElement* parentNode)
360 {
361  if (!parentNode)
362  return;
363 
364  TiXmlElement* node = parentNode->FirstChildElement("Add");
365  if (!node)
366  return; // no virtual targets
367 
368  while (node)
369  {
370  if (node->Attribute("alias") && node->Attribute("targets"))
371  {
372  wxString alias = cbC2U(node->Attribute("alias"));
373  wxString targets = cbC2U(node->Attribute("targets"));
374  wxArrayString arr = GetArrayFromString(targets, _T(";"), true);
375 
377  }
378 
379  node = node->NextSiblingElement("Add");
380  }
381 }
382 
383 void ProjectLoader::DoProjectOptions(TiXmlElement* parentNode)
384 {
385  TiXmlElement* node = parentNode->FirstChildElement("Option");
386  if (!node)
387  return; // no options
388 
389  wxString title;
390  wxString makefile;
391  bool makefile_custom = false;
392  wxString execution_dir;
393  wxString defaultTarget;
394  wxString compilerId = _T("gcc");
395  bool extendedObjectNames = false;
396  wxArrayString vfolders;
397  int platformsFinal = spAll;
399  bool showNotes = false;
400  bool checkFiles = true;
401  wxString notes;
402 
403  // loop through all options
404  while (node)
405  {
406  if (node->Attribute("title"))
407  {
408  title = cbC2U(node->Attribute("title"));
409  if (title.Trim().IsEmpty())
410  title = _T("untitled");
411  }
412 
413  else if (node->Attribute("platforms"))
414  platformsFinal = GetPlatformsFromString(cbC2U(node->Attribute("platforms")));
415 
416  else if (node->Attribute("makefile")) // there is only one attribute per option, so "else" is a safe optimisation
417  makefile = UnixFilename(cbC2U(node->Attribute("makefile")));
418 
419  else if (node->Attribute("makefile_is_custom"))
420  makefile_custom = strncmp(node->Attribute("makefile_is_custom"), "1", 1) == 0;
421 
422  else if (node->Attribute("execution_dir"))
423  execution_dir = UnixFilename(cbC2U(node->Attribute("execution_dir")));
424 
425  // old default_target (int) node
426  else if (node->QueryIntAttribute("default_target", &m_1_4_to_1_5_deftarget) == TIXML_SUCCESS)
427  {
428  // we read the value
429  }
430 
431  else if (node->Attribute("default_target"))
432  defaultTarget = cbC2U(node->Attribute("default_target"));
433 
434  else if (node->Attribute("compiler"))
435  compilerId = GetValidCompilerID(cbC2U(node->Attribute("compiler")), _T("the project"));
436 
437  else if (node->Attribute("extended_obj_names"))
438  extendedObjectNames = strncmp(node->Attribute("extended_obj_names"), "1", 1) == 0;
439 
440  else if (node->Attribute("pch_mode"))
441  pch_mode = (PCHMode)atoi(node->Attribute("pch_mode"));
442 
443  else if (node->Attribute("virtualFolders"))
444  vfolders = GetArrayFromString(cbC2U(node->Attribute("virtualFolders")), _T(";"));
445 
446  else if (node->Attribute("show_notes"))
447  {
448  TiXmlHandle parentHandle(node);
449  TiXmlText* t = (TiXmlText *) parentHandle.FirstChild("notes").FirstChild().Node();
450  if (t)
451  notes = cbC2U(t->Value());
452  showNotes = !notes.IsEmpty() && strncmp(node->Attribute("show_notes"), "1", 1) == 0;
453  }
454  else if (node->Attribute("check_files"))
455  checkFiles = strncmp(node->Attribute("check_files"), "0", 1) != 0;
456 
457  node = node->NextSiblingElement("Option");
458  }
459 
460  m_pProject->SetTitle(title);
461  m_pProject->SetPlatforms(platformsFinal);
462  m_pProject->SetMakefile(makefile);
463  m_pProject->SetMakefileCustom(makefile_custom);
464  m_pProject->SetMakefileExecutionDir(execution_dir);
465  m_pProject->SetDefaultExecuteTarget(defaultTarget);
466  m_pProject->SetCompilerID(compilerId);
467  m_pProject->SetExtendedObjectNamesGeneration(extendedObjectNames);
468  m_pProject->SetModeForPCH(pch_mode);
469  m_pProject->SetVirtualFolders(vfolders);
470  m_pProject->SetNotes(notes);
471  m_pProject->SetShowNotesOnLoad(showNotes);
473 
474  DoMakeCommands(parentNode->FirstChildElement("MakeCommands"), m_pProject);
475  DoVirtualTargets(parentNode->FirstChildElement("VirtualTargets"));
476 }
477 
478 void ProjectLoader::DoBuild(TiXmlElement* parentNode)
479 {
480  TiXmlElement* node = parentNode->FirstChildElement("Build");
481  while (node)
482  {
483  TiXmlElement* opt = node->FirstChildElement("Script");
484  while (opt)
485  {
486  if (opt->Attribute("file"))
487  m_pProject->AddBuildScript(cbC2U(opt->Attribute("file")));
488 
489  opt = opt->NextSiblingElement("Script");
490  }
491 
492  DoBuildTarget(node);
493  DoEnvironment(node, m_pProject);
494  node = node->NextSiblingElement("Build");
495  }
496 }
497 
498 void ProjectLoader::DoBuildTarget(TiXmlElement* parentNode)
499 {
500  TiXmlElement* node = parentNode->FirstChildElement("Target");
501  if (!node)
502  return; // no options
503 
504  while (node)
505  {
506  ProjectBuildTarget* target = nullptr;
507  wxString title = cbC2U(node->Attribute("title"));
508  if (!title.IsEmpty())
509  target = m_pProject->AddBuildTarget(title);
510 
511  if (target)
512  {
513  Manager::Get()->GetLogManager()->DebugLog(_T("Loading target ") + title);
514  DoBuildTargetOptions(node, target);
515  DoCompilerOptions(node, target);
516  DoResourceCompilerOptions(node, target);
517  DoLinkerOptions(node, target);
518  DoIncludesOptions(node, target);
519  DoLibsOptions(node, target);
520  DoExtraCommands(node, target);
521  DoEnvironment(node, target);
522  }
523 
524  node = node->NextSiblingElement("Target");
525  }
526 }
527 
528 void ProjectLoader::DoBuildTargetOptions(TiXmlElement* parentNode, ProjectBuildTarget* target)
529 {
530  TiXmlElement* node = parentNode->FirstChildElement("Option");
531  if (!node)
532  return; // no options
533 
534  bool use_console_runner = true;
535  wxString output;
536  wxString imp_lib;
537  wxString def_file;
538  wxString working_dir;
539  wxString obj_output;
540  wxString deps_output;
541  wxString deps;
542  wxString added;
543  int type = -1;
544  int platformsFinal = spAll;
545  wxString compilerId = m_pProject->GetCompilerID();
546  wxString parameters;
547  wxString hostApplication;
548  bool runHostApplicationInTerminal = false;
549  bool includeInTargetAll = m_IsPre_1_2 ? true : false;
550  bool createStaticLib = false;
551  bool createDefFile = false;
552  int projectCompilerOptionsRelation = 3;
553  int projectLinkerOptionsRelation = 3;
554  int projectIncludeDirsRelation = 3;
555  int projectLibDirsRelation = 3;
556  int projectResIncludeDirsRelation = 3;
557  TargetFilenameGenerationPolicy prefixPolicy = tgfpNone; // tgfpNone for compat. with older projects
558  TargetFilenameGenerationPolicy extensionPolicy = tgfpNone;
559 
560  while (node)
561  {
562  if (node->Attribute("platforms"))
563  platformsFinal = GetPlatformsFromString(cbC2U(node->Attribute("platforms")));
564 
565  if (node->Attribute("use_console_runner"))
566  use_console_runner = strncmp(node->Attribute("use_console_runner"), "0", 1) != 0;
567 
568  if (node->Attribute("output"))
569  output = UnixFilename(cbC2U(node->Attribute("output")));
570 
571  if (node->Attribute("imp_lib"))
572  imp_lib = UnixFilename(cbC2U(node->Attribute("imp_lib")));
573 
574  if (node->Attribute("def_file"))
575  def_file = UnixFilename(cbC2U(node->Attribute("def_file")));
576 
577  if (node->Attribute("prefix_auto"))
578  prefixPolicy = atoi(node->Attribute("prefix_auto")) == 1 ? tgfpPlatformDefault : tgfpNone;
579 
580  if (node->Attribute("extension_auto"))
581  extensionPolicy = atoi(node->Attribute("extension_auto")) == 1 ? tgfpPlatformDefault : tgfpNone;
582 
583  if (node->Attribute("working_dir"))
584  working_dir = UnixFilename(cbC2U(node->Attribute("working_dir")));
585 
586  if (node->Attribute("object_output"))
587  obj_output = UnixFilename(cbC2U(node->Attribute("object_output")));
588 
589  if (node->Attribute("deps_output"))
590  deps_output = UnixFilename(cbC2U(node->Attribute("deps_output")));
591 
592  if (node->Attribute("external_deps"))
593  deps = UnixFilename(cbC2U(node->Attribute("external_deps")));
594 
595  if (node->Attribute("additional_output"))
596  added = UnixFilename(cbC2U(node->Attribute("additional_output")));
597 
598  if (node->Attribute("type"))
599  type = atoi(node->Attribute("type"));
600 
601  if (node->Attribute("compiler"))
602  compilerId = GetValidCompilerID(cbC2U(node->Attribute("compiler")), target->GetTitle());
603 
604  if (node->Attribute("parameters"))
605  parameters = cbC2U(node->Attribute("parameters"));
606 
607  if (node->Attribute("host_application"))
608  hostApplication = UnixFilename(cbC2U(node->Attribute("host_application")));
609 
610  if (node->Attribute("run_host_application_in_terminal"))
611  {
612  wxString runInTerminal = cbC2U(node->Attribute("run_host_application_in_terminal"));
613  runHostApplicationInTerminal = (runInTerminal == wxT("1"));
614  }
615 
616  // used in versions prior to 1.5
617  if (node->Attribute("includeInTargetAll"))
618  includeInTargetAll = atoi(node->Attribute("includeInTargetAll")) != 0;
619 
620  if (node->Attribute("createDefFile"))
621  createDefFile = atoi(node->Attribute("createDefFile")) != 0;
622 
623  if (node->Attribute("createStaticLib"))
624  createStaticLib = atoi(node->Attribute("createStaticLib")) != 0;
625 
626  if (node->Attribute("projectCompilerOptionsRelation"))
627  projectCompilerOptionsRelation = atoi(node->Attribute("projectCompilerOptionsRelation"));
628 
629  if (node->Attribute("projectLinkerOptionsRelation"))
630  projectLinkerOptionsRelation = atoi(node->Attribute("projectLinkerOptionsRelation"));
631 
632  if (node->Attribute("projectIncludeDirsRelation"))
633  projectIncludeDirsRelation = atoi(node->Attribute("projectIncludeDirsRelation"));
634 
635  if (node->Attribute("projectLibDirsRelation"))
636  projectLibDirsRelation = atoi(node->Attribute("projectLibDirsRelation"));
637 
638  if (node->Attribute("projectResourceIncludeDirsRelation"))
639  {
640  projectResIncludeDirsRelation = atoi(node->Attribute("projectResourceIncludeDirsRelation"));
641  // there used to be a bug in this setting and it might have a negative or very big number
642  // detect this case and set as default
643  if (projectResIncludeDirsRelation < 0 || projectResIncludeDirsRelation >= ortLast)
644  projectResIncludeDirsRelation = 3;
645  }
646 
647  node = node->NextSiblingElement("Option");
648  }
649 
650  node = parentNode->FirstChildElement("Script");
651  while (node)
652  {
653  if (node->Attribute("file"))
654  target->AddBuildScript(cbC2U(node->Attribute("file")));
655 
656  node = node->NextSiblingElement("Script");
657  }
658 
659  if (type != -1)
660  {
661  target->SetPlatforms(platformsFinal);
662  target->SetCompilerID(compilerId);
663  target->SetTargetFilenameGenerationPolicy(prefixPolicy, extensionPolicy);
664  target->SetTargetType((TargetType)type); // type *must* come before output filename!
665  target->SetOutputFilename(output); // because if no filename defined, one will be suggested based on target type...
666  target->SetImportLibraryFilename(imp_lib);
667  target->SetDefinitionFileFilename(def_file);
668  target->SetUseConsoleRunner(use_console_runner);
669  if (!working_dir.IsEmpty())
670  target->SetWorkingDir(working_dir);
671  if (!obj_output.IsEmpty())
672  target->SetObjectOutput(obj_output);
673  if (!deps_output.IsEmpty())
674  target->SetDepsOutput(deps_output);
675  target->SetExternalDeps(deps);
676  target->SetAdditionalOutputFiles(added);
677  target->SetExecutionParameters(parameters);
678  target->SetHostApplication(hostApplication);
679  target->SetRunHostApplicationInTerminal(runHostApplicationInTerminal);
680  target->SetIncludeInTargetAll(includeInTargetAll); // used in versions prior to 1.5
681  target->SetCreateDefFile(createDefFile);
682  target->SetCreateStaticLib(createStaticLib);
683  target->SetOptionRelation(ortCompilerOptions, (OptionsRelation)projectCompilerOptionsRelation);
684  target->SetOptionRelation(ortLinkerOptions, (OptionsRelation)projectLinkerOptionsRelation);
685  target->SetOptionRelation(ortIncludeDirs, (OptionsRelation)projectIncludeDirsRelation);
686  target->SetOptionRelation(ortLibDirs, (OptionsRelation)projectLibDirsRelation);
687  target->SetOptionRelation(ortResDirs, (OptionsRelation)projectResIncludeDirsRelation);
688 
689  DoMakeCommands(parentNode->FirstChildElement("MakeCommands"), target);
690  }
691 }
692 
693 void ProjectLoader::DoCompilerOptions(TiXmlElement* parentNode, ProjectBuildTarget* target)
694 {
695  TiXmlElement* node = parentNode->FirstChildElement("Compiler");
696  if (!node)
697  return; // no options
698 
699  TiXmlElement* child = node->FirstChildElement("Add");
700  while (child)
701  {
702  wxString option = cbC2U(child->Attribute("option"));
703  wxString dir = UnixFilename(cbC2U(child->Attribute("directory")));
704  if (!option.IsEmpty())
705  {
706  if (target)
707  target->AddCompilerOption(option);
708  else
709  m_pProject->AddCompilerOption(option);
710  }
711  if (!dir.IsEmpty())
712  {
713  if (target)
714  target->AddIncludeDir(dir);
715  else
717  }
718 
719  child = child->NextSiblingElement("Add");
720  }
721 }
722 
723 void ProjectLoader::DoResourceCompilerOptions(TiXmlElement* parentNode, ProjectBuildTarget* target)
724 {
725  TiXmlElement* node = parentNode->FirstChildElement("ResourceCompiler");
726  if (!node)
727  return; // no options
728 
729  TiXmlElement* child = node->FirstChildElement("Add");
730  while (child)
731  {
732  wxString option = cbC2U(child->Attribute("option"));
733  wxString dir = UnixFilename(cbC2U(child->Attribute("directory")));
734  if (!option.IsEmpty())
735  {
736  if (target)
737  target->AddResourceCompilerOption(option);
738  else
740  }
741  if (!dir.IsEmpty())
742  {
743  if (target)
744  target->AddResourceIncludeDir(dir);
745  else
747  }
748 
749  child = child->NextSiblingElement("Add");
750  }
751 }
752 
753 void ProjectLoader::DoLinkerOptions(TiXmlElement* parentNode, ProjectBuildTarget* target)
754 {
755  TiXmlElement* node = parentNode->FirstChildElement("Linker");
756  if (!node)
757  return; // no options
758 
759  TiXmlElement* child = node->FirstChildElement("Add");
760  while (child)
761  {
762  wxString option = cbC2U(child->Attribute("option"));
763  wxString dir = UnixFilename(cbC2U(child->Attribute("directory")));
764  wxString lib = UnixFilename(cbC2U(child->Attribute("library")));
765  if (!option.IsEmpty())
766  {
767  if (target)
768  target->AddLinkerOption(option);
769  else
770  m_pProject->AddLinkerOption(option);
771  }
772  if (!lib.IsEmpty())
773  {
774  if (target)
775  target->AddLinkLib(lib);
776  else
777  m_pProject->AddLinkLib(lib);
778  }
779  if (!dir.IsEmpty())
780  {
781  if (target)
782  target->AddLibDir(dir);
783  else
784  m_pProject->AddLibDir(dir);
785  }
786 
787  child = child->NextSiblingElement("Add");
788  }
789 }
790 
791 void ProjectLoader::DoIncludesOptions(TiXmlElement* parentNode, ProjectBuildTarget* target)
792 {
793  TiXmlElement* node = parentNode->FirstChildElement("IncludeDirs");
794  if (!node)
795  return; // no options
796 
797  TiXmlElement* child = node->FirstChildElement("Add");
798  while (child)
799  {
800  wxString option = UnixFilename(cbC2U(child->Attribute("option")));
801  if (!option.IsEmpty())
802  {
803  if (target)
804  target->AddIncludeDir(option);
805  else
806  m_pProject->AddIncludeDir(option);
807  }
808 
809  child = child->NextSiblingElement("Add");
810  }
811 }
812 
813 void ProjectLoader::DoLibsOptions(TiXmlElement* parentNode, ProjectBuildTarget* target)
814 {
815  TiXmlElement* node = parentNode->FirstChildElement("LibDirs");
816  if (!node)
817  return; // no options
818 
819  TiXmlElement* child = node->FirstChildElement("Add");
820  while (child)
821  {
822  wxString option = UnixFilename(cbC2U(child->Attribute("option")));
823  if (!option.IsEmpty())
824  {
825  if (target)
826  target->AddLibDir(option);
827  else
828  m_pProject->AddLibDir(option);
829  }
830 
831  child = child->NextSiblingElement("Add");
832  }
833 }
834 
835 void ProjectLoader::DoExtraCommands(TiXmlElement* parentNode, ProjectBuildTarget* target)
836 {
837  TiXmlElement* node = parentNode->FirstChildElement("ExtraCommands");
838  while (node)
839  {
840  CompileOptionsBase* base = target ? target : (CompileOptionsBase*)m_pProject;
841  TiXmlElement* child = node->FirstChildElement("Mode");
842  while (child)
843  {
844  wxString mode = cbC2U(child->Attribute("after"));
845  if (mode == _T("always"))
846  base->SetAlwaysRunPostBuildSteps(true);
847 
848  child = child->NextSiblingElement("Mode");
849  }
850 
851  child = node->FirstChildElement("Add");
852  while (child)
853  {
854  wxString before;
855  wxString after;
856 
857  if (child->Attribute("before"))
858  before = cbC2U(child->Attribute("before"));
859  if (child->Attribute("after"))
860  after = cbC2U(child->Attribute("after"));
861 
862  if (!before.IsEmpty())
863  base->AddCommandsBeforeBuild(before);
864  if (!after.IsEmpty())
865  base->AddCommandsAfterBuild(after);
866 
867  child = child->NextSiblingElement("Add");
868  }
869  node = node->NextSiblingElement("ExtraCommands");
870  }
871 }
872 
873 void ProjectLoader::DoEnvironment(TiXmlElement* parentNode, CompileOptionsBase* base)
874 {
875  if (!base)
876  return;
877 
878  TiXmlElement* node = parentNode->FirstChildElement("Environment");
879  while (node)
880  {
881  TiXmlElement* child = node->FirstChildElement("Variable");
882  while (child)
883  {
884  wxString name = cbC2U(child->Attribute("name"));
885  wxString value = cbC2U(child->Attribute("value"));
886  if (!name.IsEmpty())
887  base->SetVar(name, UnixFilename(value));
888 
889  child = child->NextSiblingElement("Variable");
890  }
891  node = node->NextSiblingElement("Environment");
892  }
893 }
894 
895 namespace
896 {
897 wxString makePathAbsoluteIfNeeded(const wxString& path, const wxString& basePath)
898 {
899  wxString absolute = path;
900  wxFileName fname = path;
901  if (!fname.IsAbsolute())
902  {
903  fname.MakeAbsolute(basePath);
904  absolute = fname.GetFullPath();
905  }
906  return absolute;
907 }
908 
909 wxString makePathRelativeIfNeeded(const wxString& path, const wxString& basePath)
910 {
911  wxString relative = path;
912  wxFileName fname = path;
913  if (fname.IsAbsolute())
914  {
915  fname.MakeRelativeTo(basePath);
916  relative = fname.GetFullPath();
917  }
918  return relative;
919 }
920 
921 wxArrayString makePathsRelativeIfNeeded(const wxArrayString& paths, const wxString& basePath)
922 {
923  wxArrayString relatives = paths;
924  for(std::size_t index = 0U; index < paths.Count(); ++index)
925  {
926  wxString& path = relatives[index];
927  path = makePathRelativeIfNeeded(path, basePath);
928  }
929  return relatives;
930 }
931 
932 std::vector<wxString> filterOnWildcards(const wxArrayString& files, const wxString& wildCard)
933 {
934  wxString wild = wildCard;
935  if(wild.IsEmpty())
936  {
938  for (unsigned i = 0; i < fgm.GetGroupsCount(); ++i)
939  {
940  wild += fgm.GetFileMasks(i);
941  }
942  }
943 
944  const wxArrayString wilds = GetArrayFromString(wild, _T(";"));
945  std::vector<wxString> finalFiles;
946  for(std::size_t file = 0; file < files.Count(); ++file)
947  {
948  const wxString& fileName = files[file];
949  bool MatchesWildCard = false;
950  for (std::size_t x = 0; x < wilds.GetCount(); ++x)
951  {
952  if (fileName.Matches(wilds[x].Lower()))
953  {
954  MatchesWildCard = true;
955  break;
956  }
957  }
958  if(MatchesWildCard)
959  {
960  finalFiles.push_back(fileName);
961  }
962  }
963  return finalFiles;
964 }
965 
966 std::vector<wxString> filesInDir(const wxString& directory, const wxString& wildCard, bool recursive, const wxString& basePath)
967 {
968  const wxString directoryPath = makePathAbsoluteIfNeeded(directory, basePath);
969  std::vector<wxString> files;
970 
971  int flags = wxDIR_FILES;
972  if(recursive)
973  {
974  flags = flags | wxDIR_DIRS;
975  }
976  wxArrayString filesUnfiltered;
977  wxDir::GetAllFiles(directoryPath, &filesUnfiltered, wxEmptyString, flags);
978  filesUnfiltered = makePathsRelativeIfNeeded(filesUnfiltered, basePath);
979  return filterOnWildcards(filesUnfiltered, wildCard);
980 }
981 } // namespace
982 
983 void ProjectLoader::DoUnits(const TiXmlElement* parentNode)
984 {
985  Manager::Get()->GetLogManager()->DebugLog(_T("Loading project files..."));
987 
988  int count = 0;
989 
990  // TODO : we need to store all the globs, so that at save time we can filter files out, globs derived ones should not be stored as <Unit ... >
991  std::vector<cbProject::Glob> unitsGlobs;
992 
993  const std::string UnitsGlobLabel("UnitsGlob");
994  const TiXmlElement* unitsGlob = parentNode->FirstChildElement(UnitsGlobLabel.c_str());
995  while (unitsGlob)
996  {
997  const wxString directory = cbC2U(unitsGlob->Attribute("directory"));
998  const wxString wildCard = cbC2U(unitsGlob->Attribute("wildcard"));
999 
1000  int recursive = 1;
1001  unitsGlob->QueryIntAttribute("recursive", &recursive);
1002 
1003  if (!directory.IsEmpty())
1004  {
1005  const bool isRecursive = (recursive)?true:false;
1006  unitsGlobs.push_back(cbProject::Glob(directory, wildCard, isRecursive));
1007  std::vector<wxString> files = filesInDir(directory, wildCard, isRecursive, m_pProject->GetBasePath());
1008  for (std::size_t index = 0; index < files.size(); ++index)
1009  {
1010  const wxString filename = files[index];
1011  ProjectFile* file = m_pProject->AddFile(-1, UnixFilename(filename));
1012  if (!file)
1013  Manager::Get()->GetLogManager()->DebugLog(_T("Can't load file ") + filename);
1014  else
1015  {
1016  ++count;
1017  const TiXmlElement dummyUnitWithoutOptions("Unit");
1018  DoUnitOptions(&dummyUnitWithoutOptions, file);
1019  }
1020  }
1021  }
1022  unitsGlob = unitsGlob->NextSiblingElement(UnitsGlobLabel.c_str());
1023  }
1024  m_pProject->SetGlobs(unitsGlobs);
1025 
1026  const TiXmlElement* unit = parentNode->FirstChildElement("Unit");
1027  while (unit)
1028  {
1029  const wxString filename = cbC2U(unit->Attribute("filename"));
1030  if (!filename.IsEmpty())
1031  {
1032  ProjectFile* file = m_pProject->AddFile(-1, UnixFilename(filename));
1033  if (!file)
1034  Manager::Get()->GetLogManager()->DebugLog(_T("Can't load file ") + filename);
1035  else
1036  {
1037  ++count;
1038  DoUnitOptions(unit, file);
1039  }
1040  }
1041 
1042  unit = unit->NextSiblingElement("Unit");
1043  }
1045  Manager::Get()->GetLogManager()->DebugLog(F(_T("%d files loaded"), count));
1046 }
1047 
1048 void ProjectLoader::DoUnitOptions(const TiXmlElement* parentNode, ProjectFile* file)
1049 {
1050  int tempval = 0;
1051  bool foundCompile = false;
1052  bool foundLink = false;
1053  bool foundCompilerVar = false;
1054  bool foundTarget = false;
1055  bool noTarget = false;
1056 
1057 // Compiler* compiler = CompilerFactory::GetCompiler(m_pProject->GetCompilerID());
1058 
1059  const TiXmlElement* node = parentNode->FirstChildElement("Option");
1060  while (node)
1061  {
1062  if (node->Attribute("compilerVar"))
1063  {
1064  file->compilerVar = cbC2U(node->Attribute("compilerVar"));
1065  foundCompilerVar = true;
1066  }
1067  //
1068  if (node->QueryIntAttribute("compile", &tempval) == TIXML_SUCCESS)
1069  {
1070  file->compile = tempval != 0;
1071  foundCompile = true;
1072  }
1073  //
1074  if (node->QueryIntAttribute("link", &tempval) == TIXML_SUCCESS)
1075  {
1076  file->link = tempval != 0;
1077  foundLink = true;
1078  }
1079  //
1080  if (node->QueryIntAttribute("weight", &tempval) == TIXML_SUCCESS)
1081  file->weight = tempval;
1082  //
1083  if (node->Attribute("virtualFolder"))
1084  file->virtual_path = UnixFilename(cbC2U(node->Attribute("virtualFolder")));
1085  //
1086  if (node->Attribute("buildCommand") && node->Attribute("compiler"))
1087  {
1088  const wxString cmp = cbC2U(node->Attribute("compiler"));
1089  wxString tmp = cbC2U(node->Attribute("buildCommand"));
1090  if (!cmp.IsEmpty() && !tmp.IsEmpty())
1091  {
1092  tmp.Replace(_T("\\n"), _T("\n"));
1093  file->SetCustomBuildCommand(cmp, tmp);
1094  if (node->QueryIntAttribute("use", &tempval) == TIXML_SUCCESS)
1095  file->SetUseCustomBuildCommand(cmp, tempval != 0);
1096  }
1097  }
1098  //
1099  if (node->Attribute("target"))
1100  {
1101  wxString targetName = cbC2U(node->Attribute("target"));
1102  if (!targetName.IsSameAs(_T("<{~None~}>")))
1103  {
1104  file->AddBuildTarget(targetName);
1105  foundTarget = true;
1106  }
1107  else
1108  noTarget = true;
1109  }
1110 
1111  node = node->NextSiblingElement("Option");
1112  }
1113 
1114  // pre 1.6 versions upgrade
1115  if (m_IsPre_1_6)
1116  {
1117  // make sure the "compile" and "link" flags are honored
1118  if (!foundCompile)
1119  file->compile = true;
1120  if (!foundLink)
1121  file->link = true;
1122  if (!foundCompilerVar)
1123  file->compilerVar = _T("CPP");
1124  }
1125 
1126  if (!foundTarget && !noTarget)
1127  {
1128  // add to all targets
1129  for (int i = 0; i < m_pProject->GetBuildTargetsCount(); ++i)
1130  {
1132  }
1133 
1134  // use same targets for generated files
1135  for (size_t n = 0; n < file->generatedFiles.size(); ++n)
1136  {
1137  for (int i = 0; i < m_pProject->GetBuildTargetsCount(); ++i)
1138  {
1139  file->generatedFiles[n]->AddBuildTarget(m_pProject->GetBuildTarget(i)->GetTitle());
1140  }
1141  }
1142  }
1143 }
1144 
1145 // convenience function, used in Save()
1146 TiXmlElement* ProjectLoader::AddElement(TiXmlElement* parent, const char* name, const char* attr, const wxString& attribute)
1147 {
1148  TiXmlElement elem(name);
1149 
1150  if (attr)
1151  elem.SetAttribute(attr, cbU2C(attribute));
1152 
1153  return parent->InsertEndChild(elem)->ToElement();
1154 }
1155 
1156 // convenience function, used in Save()
1157 TiXmlElement* ProjectLoader::AddElement(TiXmlElement* parent, const char* name, const char* attr, int attribute)
1158 {
1159  TiXmlElement elem(name);
1160 
1161  if (attr)
1162  elem.SetAttribute(attr, attribute);
1163 
1164  return parent->InsertEndChild(elem)->ToElement();
1165 }
1166 
1167 // convenience function, used in Save()
1168 void ProjectLoader::AddArrayOfElements(TiXmlElement* parent, const char* name, const char* attr, const wxArrayString& array, bool isPath)
1169 {
1170  if (!array.GetCount())
1171  return;
1172 
1173  for (unsigned int i = 0; i < array.GetCount(); ++i)
1174  {
1175  if (array[i].IsEmpty())
1176  continue;
1177  AddElement(parent, name, attr, (isPath ? UnixFilename(array[i], wxPATH_UNIX) : array[i]));
1178  }
1179 }
1180 
1181 // convenience function, used in Save()
1182 void ProjectLoader::SaveEnvironment(TiXmlElement* parent, CompileOptionsBase* base)
1183 {
1184  if (!base)
1185  return;
1186  const StringHash& v = base->GetAllVars();
1187  if (v.empty())
1188  return;
1189 
1190  // explicitly sort the keys
1191  typedef std::map<wxString, wxString> SortedMap;
1192  SortedMap map;
1193  for (StringHash::const_iterator it = v.begin(); it != v.end(); ++it)
1194  map[it->first] = it->second;
1195 
1196  TiXmlElement* node = AddElement(parent, "Environment");
1197  for (SortedMap::const_iterator it = map.begin(); it != map.end(); ++it)
1198  {
1199  TiXmlElement* elem = AddElement(node, "Variable", "name", it->first);
1200  elem->SetAttribute("value", cbU2C(it->second));
1201  }
1202 }
1203 
1204 bool ProjectLoader::Save(const wxString& filename)
1205 {
1206  return Save(filename, nullptr);
1207 }
1208 
1209 bool ProjectLoader::Save(const wxString& filename, TiXmlElement* pExtensions)
1210 {
1211  if (ExportTargetAsProject(filename, wxEmptyString, pExtensions))
1212  {
1213  m_pProject->SetModified(false);
1214  return true;
1215  }
1216  return false;
1217 }
1218 
1219 bool ProjectLoader::ExportTargetAsProject(const wxString& filename, const wxString& onlyTarget, TiXmlElement* pExtensions)
1220 {
1221  const char* ROOT_TAG = "CodeBlocks_project_file";
1222 
1223  TiXmlDocument doc;
1224  doc.SetCondenseWhiteSpace(false);
1225  doc.InsertEndChild(TiXmlDeclaration("1.0", "UTF-8", "yes"));
1226  TiXmlElement* rootnode = static_cast<TiXmlElement*>(doc.InsertEndChild(TiXmlElement(ROOT_TAG)));
1227  if (!rootnode)
1228  return false;
1229 
1230 // Compiler* compiler = CompilerFactory::GetCompiler(m_pProject->GetCompilerID());
1231 
1232  rootnode->InsertEndChild(TiXmlElement("FileVersion"));
1233  rootnode->FirstChildElement("FileVersion")->SetAttribute("major", PROJECT_FILE_VERSION_MAJOR);
1234  rootnode->FirstChildElement("FileVersion")->SetAttribute("minor", PROJECT_FILE_VERSION_MINOR);
1235 
1236  rootnode->InsertEndChild(TiXmlElement("Project"));
1237  TiXmlElement* prjnode = rootnode->FirstChildElement("Project");
1238 
1239  AddElement(prjnode, "Option", "title", m_pProject->GetTitle());
1240  if (m_pProject->GetPlatforms() != spAll)
1241  {
1243  AddElement(prjnode, "Option", "platforms", platforms);
1244  }
1245  if (m_pProject->GetMakefile() != _T("Makefile"))
1246  AddElement(prjnode, "Option", "makefile", UnixFilename(m_pProject->GetMakefile(), wxPATH_UNIX));
1248  AddElement(prjnode, "Option", "makefile_is_custom", 1);
1250  AddElement(prjnode, "Option", "execution_dir", UnixFilename(m_pProject->GetMakefileExecutionDir(), wxPATH_UNIX));
1252  AddElement(prjnode, "Option", "pch_mode", (int)m_pProject->GetModeForPCH());
1254  AddElement(prjnode, "Option", "default_target", m_pProject->GetDefaultExecuteTarget());
1255  AddElement(prjnode, "Option", "compiler", m_pProject->GetCompilerID());
1256 
1257  wxArrayString virtualFolders = m_pProject->GetVirtualFolders();
1258  if (virtualFolders.GetCount() > 0)
1259  {
1260  wxString result; // the concatenated string
1261  for (size_t i = 0; i < virtualFolders.GetCount(); i++)
1262  {
1263  if (!result.IsEmpty())
1264  result << wxT(";"); // add the delimiter
1265 
1266  result << UnixFilename(virtualFolders[i], wxPATH_UNIX); // append Unix format folder name
1267  }
1268  AddElement(prjnode, "Option", "virtualFolders", result);
1269  }
1270 
1272  AddElement(prjnode, "Option", "extended_obj_names", 1);
1274  {
1275  TiXmlElement* notesBase = AddElement(prjnode, "Option", "show_notes", m_pProject->GetShowNotesOnLoad() ? 1 : 0);
1276  if (!m_pProject->GetNotes().IsEmpty())
1277  {
1278  TiXmlElement* notes = AddElement(notesBase, "notes");
1279  TiXmlText t(m_pProject->GetNotes().mb_str(wxConvUTF8));
1280  t.SetCDATA(true);
1281  notes->InsertEndChild(t);
1282  }
1283  }
1285  AddElement(prjnode, "Option", "check_files", 0);
1286 
1288  {
1289  TiXmlElement* makenode = AddElement(prjnode, "MakeCommands");
1290  AddElement(makenode, "Build", "command", m_pProject->GetMakeCommandFor(mcBuild));
1291  AddElement(makenode, "CompileFile", "command", m_pProject->GetMakeCommandFor(mcCompileFile));
1292  AddElement(makenode, "Clean", "command", m_pProject->GetMakeCommandFor(mcClean));
1293  AddElement(makenode, "DistClean", "command", m_pProject->GetMakeCommandFor(mcDistClean));
1294  AddElement(makenode, "AskRebuildNeeded", "command", m_pProject->GetMakeCommandFor(mcAskRebuildNeeded));
1295  AddElement(makenode, "SilentBuild", "command", m_pProject->GetMakeCommandFor(mcSilentBuild));
1296  }
1297 
1298  prjnode->InsertEndChild(TiXmlElement("Build"));
1299  TiXmlElement* buildnode = prjnode->FirstChildElement("Build");
1300 
1301  for (size_t x = 0; x < m_pProject->GetBuildScripts().GetCount(); ++x)
1302  AddElement(buildnode, "Script", "file", UnixFilename(m_pProject->GetBuildScripts().Item(x), wxPATH_UNIX));
1303 
1304  // now decide which target we're exporting.
1305  // remember that if onlyTarget is empty, we export all targets (i.e. normal save).
1306  ProjectBuildTarget* onlytgt = m_pProject->GetBuildTarget(onlyTarget);
1307 
1308  for (int i = 0; i < m_pProject->GetBuildTargetsCount(); ++i)
1309  {
1311  if (!target)
1312  break;
1313 
1314  // skip every target except the desired one
1315  if (onlytgt && onlytgt != target)
1316  continue;
1317 
1318  TiXmlElement* tgtnode = AddElement(buildnode, "Target", "title", target->GetTitle());
1319  if (target->GetPlatforms() != spAll)
1320  {
1321  wxString platforms = GetStringFromPlatforms(target->GetPlatforms());
1322  AddElement(tgtnode, "Option", "platforms", platforms);
1323  }
1324  if (target->GetTargetType() != ttCommandsOnly)
1325  {
1326  TargetFilenameGenerationPolicy prefixPolicy;
1327  TargetFilenameGenerationPolicy extensionPolicy;
1328  target->GetTargetFilenameGenerationPolicy(prefixPolicy, extensionPolicy);
1329 
1330  wxString outputFileName = target->GetOutputFilename();
1331  if (extensionPolicy == tgfpPlatformDefault)
1332  {
1333  wxFileName fname(outputFileName);
1334  fname.ClearExt();
1335  outputFileName = fname.GetFullPath();
1336  }
1337 
1338  if ( (prefixPolicy == tgfpPlatformDefault)
1339  && ( (!platform::windows && target->GetTargetType() == ttDynamicLib)
1340  || (target->GetTargetType() == ttStaticLib) ) )
1341  {
1342  wxString compilerId = target->GetCompilerID();
1343  Compiler* compiler = CompilerFactory::GetCompiler(compilerId);
1344  if (compiler)
1345  {
1346  wxFileName fname(outputFileName);
1347  wxString outputFileNameFile(fname.GetFullName());
1348 
1349  wxString compilerLibPrefix(compiler->GetSwitches().libPrefix);
1350  wxString outputFileNameWOPrefix;
1351  if (outputFileNameFile.StartsWith(compilerLibPrefix))
1352  {
1353  outputFileNameWOPrefix = outputFileNameFile.Mid(compilerLibPrefix.Len());
1354  if (!outputFileNameWOPrefix.IsEmpty())
1355  {
1356  fname.SetFullName(outputFileNameWOPrefix);
1357  outputFileName = fname.GetFullPath();
1358  }
1359  }
1360  }
1361  }
1362 
1363  TiXmlElement* outnode = AddElement(tgtnode, "Option", "output", UnixFilename(outputFileName, wxPATH_UNIX));
1364  if (target->GetTargetType() == ttDynamicLib)
1365  {
1366  if (target->GetDynamicLibImportFilename() != _T("$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME)"))
1367  outnode->SetAttribute("imp_lib", cbU2C(UnixFilename(target->GetDynamicLibImportFilename(), wxPATH_UNIX)));
1368  if (target->GetDynamicLibImportFilename() != _T("$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME)"))
1369  outnode->SetAttribute("def_file", cbU2C(UnixFilename(target->GetDynamicLibDefFilename(), wxPATH_UNIX)));
1370  }
1371  outnode->SetAttribute("prefix_auto", prefixPolicy == tgfpPlatformDefault ? "1" : "0");
1372  outnode->SetAttribute("extension_auto", extensionPolicy == tgfpPlatformDefault ? "1" : "0");
1373 
1374  if (target->GetWorkingDir() != _T("."))
1375  AddElement(tgtnode, "Option", "working_dir", UnixFilename(target->GetWorkingDir(), wxPATH_UNIX));
1376  if (target->GetObjectOutput() != _T(".objs"))
1377  AddElement(tgtnode, "Option", "object_output", UnixFilename(target->GetObjectOutput(), wxPATH_UNIX));
1378  if (target->GetDepsOutput() != _T(".deps"))
1379  AddElement(tgtnode, "Option", "deps_output", UnixFilename(target->GetDepsOutput(), wxPATH_UNIX));
1380  }
1381  if (!target->GetExternalDeps().IsEmpty())
1382  AddElement(tgtnode, "Option", "external_deps", UnixFilename(target->GetExternalDeps(), wxPATH_UNIX));
1383  if (!target->GetAdditionalOutputFiles().IsEmpty())
1384  AddElement(tgtnode, "Option", "additional_output", UnixFilename(target->GetAdditionalOutputFiles(), wxPATH_UNIX));
1385  AddElement(tgtnode, "Option", "type", target->GetTargetType());
1386  AddElement(tgtnode, "Option", "compiler", target->GetCompilerID());
1387  if (target->GetTargetType() == ttConsoleOnly && !target->GetUseConsoleRunner())
1388  AddElement(tgtnode, "Option", "use_console_runner", 0);
1389  if (!target->GetExecutionParameters().IsEmpty())
1390  AddElement(tgtnode, "Option", "parameters", target->GetExecutionParameters());
1391  if (!target->GetHostApplication().IsEmpty())
1392  {
1393  AddElement(tgtnode, "Option", "host_application", UnixFilename(target->GetHostApplication(), wxPATH_UNIX));
1394  if (target->GetRunHostApplicationInTerminal())
1395  AddElement(tgtnode, "Option", "run_host_application_in_terminal", 1);
1396  else
1397  AddElement(tgtnode, "Option", "run_host_application_in_terminal", 0);
1398  }
1399 
1400  // used in versions prior to 1.5
1401 // if (target->GetIncludeInTargetAll())
1402 // AddElement(tgtnode, "Option", "includeInTargetAll", 1);
1403  if ((target->GetTargetType() == ttStaticLib || target->GetTargetType() == ttDynamicLib) && target->GetCreateDefFile())
1404  AddElement(tgtnode, "Option", "createDefFile", 1);
1405  if (target->GetTargetType() == ttDynamicLib && target->GetCreateStaticLib())
1406  AddElement(tgtnode, "Option", "createStaticLib", 1);
1407  if (target->GetOptionRelation(ortCompilerOptions) != 3) // 3 is the default
1408  AddElement(tgtnode, "Option", "projectCompilerOptionsRelation", target->GetOptionRelation(ortCompilerOptions));
1409  if (target->GetOptionRelation(ortLinkerOptions) != 3) // 3 is the default
1410  AddElement(tgtnode, "Option", "projectLinkerOptionsRelation", target->GetOptionRelation(ortLinkerOptions));
1411  if (target->GetOptionRelation(ortIncludeDirs) != 3) // 3 is the default
1412  AddElement(tgtnode, "Option", "projectIncludeDirsRelation", target->GetOptionRelation(ortIncludeDirs));
1413  if (target->GetOptionRelation(ortResDirs) != 3) // 3 is the default
1414  AddElement(tgtnode, "Option", "projectResourceIncludeDirsRelation", target->GetOptionRelation(ortResDirs));
1415  if (target->GetOptionRelation(ortLibDirs) != 3) // 3 is the default
1416  AddElement(tgtnode, "Option", "projectLibDirsRelation", target->GetOptionRelation(ortLibDirs));
1417 
1418  for (size_t x = 0; x < target->GetBuildScripts().GetCount(); ++x)
1419  AddElement(tgtnode, "Script", "file", target->GetBuildScripts().Item(x));
1420 
1421  TiXmlElement* node = AddElement(tgtnode, "Compiler");
1422  AddArrayOfElements(node, "Add", "option", target->GetCompilerOptions());
1423  AddArrayOfElements(node, "Add", "directory", target->GetIncludeDirs(), true);
1424  if (node->NoChildren())
1425  tgtnode->RemoveChild(node);
1426 
1427  node = AddElement(tgtnode, "ResourceCompiler");
1428  AddArrayOfElements(node, "Add", "option", target->GetResourceCompilerOptions());
1429  AddArrayOfElements(node, "Add", "directory", target->GetResourceIncludeDirs(), true);
1430  if (node->NoChildren())
1431  tgtnode->RemoveChild(node);
1432 
1433  node = AddElement(tgtnode, "Linker");
1434  AddArrayOfElements(node, "Add", "option", target->GetLinkerOptions());
1435  AddArrayOfElements(node, "Add", "library", target->GetLinkLibs(), true);
1436  AddArrayOfElements(node, "Add", "directory", target->GetLibDirs(), true);
1437  if (node->NoChildren())
1438  tgtnode->RemoveChild(node);
1439 
1440  node = AddElement(tgtnode, "ExtraCommands");
1441  AddArrayOfElements(node, "Add", "before", target->GetCommandsBeforeBuild());
1442  AddArrayOfElements(node, "Add", "after", target->GetCommandsAfterBuild());
1443  if (node->NoChildren())
1444  tgtnode->RemoveChild(node);
1445  else
1446  {
1447  if (target->GetAlwaysRunPostBuildSteps())
1448  AddElement(node, "Mode", "after", wxString(_T("always")));
1449  }
1450 
1451  SaveEnvironment(tgtnode, target);
1452 
1453  if (target->MakeCommandsModified())
1454  {
1455  TiXmlElement* makenode = AddElement(tgtnode, "MakeCommands");
1456  AddElement(makenode, "Build", "command", target->GetMakeCommandFor(mcBuild));
1457  AddElement(makenode, "CompileFile", "command", target->GetMakeCommandFor(mcCompileFile));
1458  AddElement(makenode, "Clean", "command", target->GetMakeCommandFor(mcClean));
1459  AddElement(makenode, "DistClean", "command", target->GetMakeCommandFor(mcDistClean));
1460  AddElement(makenode, "AskRebuildNeeded", "command", target->GetMakeCommandFor(mcAskRebuildNeeded));
1461  AddElement(makenode, "SilentBuild", "command", target->GetMakeCommandFor(mcSilentBuild));
1462  }
1463  }
1464 
1465  // virtuals only for whole project
1466  if (onlyTarget.IsEmpty())
1467  {
1468  TiXmlElement* virtnode = AddElement(prjnode, "VirtualTargets");
1470  for (size_t i = 0; i < virtuals.GetCount(); ++i)
1471  {
1472  const wxArrayString& group = m_pProject->GetVirtualBuildTargetGroup(virtuals[i]);
1473  wxString groupStr = GetStringFromArray(group, _T(";"));
1474  if (!groupStr.IsEmpty())
1475  {
1476  TiXmlElement* elem = AddElement(virtnode, "Add", "alias", virtuals[i]);
1477  elem->SetAttribute("targets", cbU2C(groupStr));
1478  }
1479  }
1480  if (virtnode->NoChildren())
1481  prjnode->RemoveChild(virtnode);
1482  }
1483 
1484  SaveEnvironment(buildnode, m_pProject);
1485 
1486  TiXmlElement* node = AddElement(prjnode, "Compiler");
1487  AddArrayOfElements(node, "Add", "option", m_pProject->GetCompilerOptions());
1488  AddArrayOfElements(node, "Add", "directory", m_pProject->GetIncludeDirs(), true);
1489  if (node->NoChildren())
1490  prjnode->RemoveChild(node);
1491 
1492  node = AddElement(prjnode, "ResourceCompiler");
1493  AddArrayOfElements(node, "Add", "option", m_pProject->GetResourceCompilerOptions());
1494  AddArrayOfElements(node, "Add", "directory", m_pProject->GetResourceIncludeDirs(), true);
1495  if (node->NoChildren())
1496  prjnode->RemoveChild(node);
1497 
1498  node = AddElement(prjnode, "Linker");
1499  AddArrayOfElements(node, "Add", "option", m_pProject->GetLinkerOptions());
1500  AddArrayOfElements(node, "Add", "library", m_pProject->GetLinkLibs(), true);
1501  AddArrayOfElements(node, "Add", "directory", m_pProject->GetLibDirs(), true);
1502  if (node->NoChildren())
1503  prjnode->RemoveChild(node);
1504 
1505  node = AddElement(prjnode, "ExtraCommands");
1506  AddArrayOfElements(node, "Add", "before", m_pProject->GetCommandsBeforeBuild());
1507  AddArrayOfElements(node, "Add", "after", m_pProject->GetCommandsAfterBuild());
1508  if (node->NoChildren())
1509  prjnode->RemoveChild(node);
1510  else
1511  {
1513  AddElement(node, "Mode", "after", wxString(_T("always")));
1514  }
1515 
1516  std::vector<wxString> filesThrougGlobs;
1517  const std::vector<cbProject::Glob>& unitGlobs = m_pProject->GetGlobs();
1518  for (std::size_t index = 0; index < unitGlobs.size(); ++index)
1519  {
1520  const cbProject::Glob& glob = unitGlobs[index];
1521  if (TiXmlElement* unitsGlobNode = AddElement(prjnode, "UnitsGlob", "directory", glob.m_Path))
1522  {
1523  unitsGlobNode->SetAttribute("recursive", glob.m_Recursive ? "1" : "0");
1524  unitsGlobNode->SetAttribute("wildcard", cbU2C(glob.m_WildCard));
1525  }
1526  std::vector<wxString> files = filesInDir(glob.m_Path, glob.m_WildCard, glob.m_Recursive, m_pProject->GetBasePath());
1527  std::copy(files.begin(), files.end(), std::back_inserter(filesThrougGlobs));
1528  }
1529 
1530  ProjectFileArray pfa(ProjectFile::CompareProjectFiles);
1531 
1532  for (FilesList::iterator it = m_pProject->GetFilesList().begin(); it != m_pProject->GetFilesList().end(); ++it)
1533  {
1534  ProjectFile* f = *it;
1535 
1536  // do not save auto-generated files
1537  if (f->AutoGeneratedBy())
1538  continue;
1539 
1540  if (std::find(filesThrougGlobs.begin(), filesThrougGlobs.end(), f->relativeFilename) != filesThrougGlobs.end())
1541  continue;
1542 
1543  // do not save project files that do not belong in the target we 're exporting
1544  if (onlytgt && (onlytgt->GetFilesList().find(f) == onlytgt->GetFilesList().end()))
1545  continue;
1546 
1547  pfa.Add(f);
1548  }
1549  for (size_t i=0; i<pfa.GetCount(); ++i)
1550  {
1551  ProjectFile* f = pfa[i];
1553 
1554  TiXmlElement* unitnode = AddElement(prjnode, "Unit", "filename", UnixFilename(f->relativeFilename, wxPATH_UNIX));
1555  if (!f->compilerVar.IsEmpty())
1556  {
1557  const wxString ext = f->relativeFilename.AfterLast(_T('.')).Lower();
1558  if (f->compilerVar != _T("CC") && (ext.IsSameAs(FileFilters::C_EXT)))
1559  AddElement(unitnode, "Option", "compilerVar", f->compilerVar);
1560 #ifdef __WXMSW__
1561  else if (f->compilerVar != _T("WINDRES") && ext.IsSameAs(FileFilters::RESOURCE_EXT))
1562  AddElement(unitnode, "Option", "compilerVar", f->compilerVar);
1563 #endif
1564  else if (f->compilerVar != _T("CPP")) // default
1565  AddElement(unitnode, "Option", "compilerVar", f->compilerVar);
1566  }
1567 
1568  if (f->compile != (ft == ftSource || ft == ftResource))
1569  AddElement(unitnode, "Option", "compile", f->compile ? 1 : 0);
1570 
1571  if (f->link != ( ft == ftSource || ft == ftResource
1572  || ft == ftObject || ft == ftResourceBin
1573  || ft == ftStaticLib ) )
1574  {
1575  AddElement(unitnode, "Option", "link", f->link ? 1 : 0);
1576  }
1577  if (f->weight != 50)
1578  AddElement(unitnode, "Option", "weight", f->weight);
1579 
1580  if (!f->virtual_path.IsEmpty())
1581  AddElement(unitnode, "Option", "virtualFolder", UnixFilename(f->virtual_path, wxPATH_UNIX));
1582 
1583  // loop and save custom build commands
1584  for (pfCustomBuildMap::iterator it = f->customBuild.begin(); it != f->customBuild.end(); ++it)
1585  {
1586  pfCustomBuild& pfcb = it->second;
1587  if (!pfcb.buildCommand.IsEmpty())
1588  {
1589  wxString tmp = pfcb.buildCommand;
1590  tmp.Replace(_T("\n"), _T("\\n"));
1591  TiXmlElement* elem = AddElement(unitnode, "Option", "compiler", it->first);
1592  elem->SetAttribute("use", pfcb.useCustomBuildCommand ? "1" : "0");
1593  elem->SetAttribute("buildCommand", cbU2C(tmp));
1594  }
1595  }
1596 
1598  {
1599  for (unsigned int x = 0; x < f->buildTargets.GetCount(); ++x)
1600  AddElement(unitnode, "Option", "target", f->buildTargets[x]);
1601  }
1602 
1603  /* Add a target with a weird name if no targets are present. *
1604  * This will help us detecting a file with no targets. */
1605  if ((int)f->buildTargets.GetCount() == 0)
1606  AddElement(unitnode, "Option", "target", _T("<{~None~}>"));
1607  }
1608 
1609  // as a last step, run all hooked callbacks
1610  TiXmlElement* extnode = pExtensions
1611  ? prjnode->InsertEndChild(*pExtensions)->ToElement()
1612  : AddElement(prjnode, "Extensions");
1613  if (ProjectLoaderHooks::HasRegisteredHooks() && extnode)
1614  ProjectLoaderHooks::CallHooks(m_pProject, extnode, false);
1615 
1616  return cbSaveTinyXMLDocument(&doc, filename);
1617 }
1618 
1620 {
1621  if (CompilerFactory::GetCompiler(proposal))
1622  return proposal;
1623 
1624  // check the map; maybe we asked the user before
1625  CompilerSubstitutes::iterator it = m_CompilerSubstitutes.find(proposal);
1626  if (it != m_CompilerSubstitutes.end())
1627  return it->second;
1628 
1629  Compiler* compiler = nullptr;
1630 
1631  // if compiler is a number, then this is an older version of the project file
1632  // propose the same compiler by index
1633  if (!proposal.IsEmpty())
1634  {
1635  long int idx = -1;
1636  if (proposal.ToLong(&idx))
1637  compiler = CompilerFactory::GetCompiler(idx);
1638  }
1639 
1640  if (!compiler)
1641  {
1642  if(!(Manager::Get()->GetConfigManager(_T("app"))->ReadBool(_T("/environment/ignore_invalid_targets"), true)))
1643  {
1644  wxString msg;
1645  msg.Printf(_("The defined compiler for %s cannot be located (ID: %s).\n"
1646  "Please choose the compiler you want to use instead and click \"OK\".\n"
1647  "If you click \"Cancel\", the project/target will be excluded from the build."), scope.c_str(),
1648  proposal.c_str());
1649  compiler = CompilerFactory::SelectCompilerUI(msg);
1650  }
1651  }
1652 
1653  if (!compiler)
1654  {
1655  // allow for invalid compiler IDs to be preserved...
1656  m_CompilerSubstitutes[proposal] = proposal;
1657  return proposal;
1658  }
1659 
1660  m_OpenDirty = true;
1661 
1662  // finally, keep the user selection in the map so we don't ask him again
1663  m_CompilerSubstitutes[proposal] = compiler->GetID();
1664  return compiler->GetID();
1665 }
void DoUnits(const TiXmlElement *parentNode)
wxString AfterLast(wxUniChar ch) const
wxString F(const wxChar *msg,...)
sprintf-like function
Definition: logmanager.h:20
DLLIMPORT wxArrayString GetArrayFromString(const wxString &text, const wxString &separator=DEFAULT_ARRAY_SEP, bool trimSpaces=true)
Definition: globals.cpp:134
virtual void SetOptionRelation(OptionsRelationType type, OptionsRelation rel)
Set the target&#39;s options relation for type to rel.
virtual void GetTargetFilenameGenerationPolicy(TargetFilenameGenerationPolicy &prefixOut, TargetFilenameGenerationPolicy &extensionOut) const
#define PROJECT_FILE_VERSION_MAJOR
Definition: projectloader.h:12
void SetMakefileCustom(bool custom)
Mark if the project should use a custom Makefile for compilation.
Definition: cbproject.cpp:194
virtual void SetMakeCommandFor(MakeCommand cmd, const wxString &make)
Set the "make" command used for cmd.
bool Matches(const wxString &mask) const
unsigned short int weight
The weight.
Definition: projectfile.h:145
TargetFilenameGenerationPolicy
A target&#39;s filename can either be auto-generated based on the running platform, or completely specifi...
#define wxICON_QUESTION
void DoUnitOptions(const TiXmlElement *parentNode, ProjectFile *file)
void SetVirtualFolders(const wxArrayString &folders)
Set the virtual folders list.
Definition: cbproject.cpp:968
void SetModeForPCH(PCHMode mode)
Set the mode to handle precompiled headers.
Definition: cbproject.h:306
virtual bool GetCreateDefFile() const
Valid only for targets generating dynamic libraries (DLLs or SOs).
wxString relativeFilename
The relative (to the project) filename of this file.
Definition: projectfile.h:131
DLLIMPORT void CallHooks(cbProject *project, TiXmlElement *elem, bool isLoading)
Call all registered hooks using the supplied parameters.
bool Save(const wxString &filename) override
Save a file.
virtual bool GetUseConsoleRunner() const
Valid only for targets generating a console executable.
~ProjectLoader() override
Destructor.
void DoBuildTarget(TiXmlElement *parentNode)
virtual const wxString & GetAdditionalOutputFiles() const
virtual void SetObjectOutput(const wxString &dirname)
Set the target&#39;s objects output dir.
const int version
void SetDefaultExecuteTarget(const wxString &name)
Set the build target index which will be pre-selected when the "Select target" dialog appears when ru...
Definition: cbproject.cpp:1378
void SetFullName(const wxString &fullname)
CompilerSubstitutes m_CompilerSubstitutes
virtual wxString GetDepsOutput() const
Read the target&#39;s dependencies output dir.
static Manager * Get()
Use Manager::Get() to get a pointer to its instance Manager::Get() is guaranteed to never return an i...
Definition: manager.cpp:182
bool DefineVirtualBuildTarget(const wxString &alias, const wxArrayString &targets)
Define a new virtual build target.
Definition: cbproject.cpp:1449
virtual void AddCommandsAfterBuild(const wxString &command)
virtual const wxString & GetExecutionParameters() const
Read the target&#39;s execution parameters.
Linker include dir option.
virtual void SetCreateDefFile(bool createIt)
Set if the target creates a DEF imports file.
wxString Lower() const
virtual const wxString & GetHostApplication() const
Read the target&#39;s host application.
void SetShowNotesOnLoad(bool show)
Set show project notes on load automatically.
Definition: cbproject.cpp:1605
DLLIMPORT wxString GetStringFromPlatforms(int platforms, bool forceSeparate=false)
Return a string representation of a platform / multiple platforms.
Definition: globals.cpp:90
void DoExtraCommands(TiXmlElement *parentNode, ProjectBuildTarget *target=nullptr)
virtual FilesList & GetFilesList()
Provides an easy way to iterate all the files belonging in this target.
Definition: cbproject.h:685
virtual const wxString & GetExternalDeps() const
bool compile
Compile flag.
Definition: projectfile.h:138
void SaveEnvironment(TiXmlElement *parent, CompileOptionsBase *base)
void SetModified(bool modified=true) override
Mark the project as modified or not.
Definition: cbproject.cpp:179
unsigned int GetGroupsCount() const
Return total number of groups.
PCHMode GetModeForPCH() const
Definition: cbproject.h:301
void DoBuildTargetOptions(TiXmlElement *parentNode, ProjectBuildTarget *target)
bool GetCheckForExternallyModifiedFiles() const
Get check for externally modified files.
Definition: cbproject.cpp:1628
PCHMode
Precompiled headers mode.
Definition: cbproject.h:83
size_t Length() const
virtual void AddBuildScript(const wxString &script)
virtual const wxArrayString & GetCompilerOptions() const
wxCStrData c_str() const
long Time() const
static Compiler * GetCompiler(size_t index)
Generate filename based on running platform defaults.
#define _T(string)
virtual void AddIncludeDir(const wxString &option)
FileType
Known file types.
Definition: globals.h:49
bool LoadDocument(const wxString &filename, TiXmlDocument *doc)
Definition: tinywxuni.cpp:13
#define wxYES_NO
void AddArrayOfElements(TiXmlElement *parent, const char *name, const char *attr, const wxArrayString &array, bool isPath=false)
void EndAddFiles()
Notify that file(s) addition finished.
Definition: cbproject.cpp:600
wxString GetValidCompilerID(const wxString &proposal, const wxString &scope)
virtual void SetIncludeInTargetAll(bool buildIt)
Deprecated, do not use at all! Set if this target should be built when the virtual target "All" is se...
cbProject * m_pProject
const DLLIMPORT wxString C_EXT
const wxCharBuffer mb_str(const wxMBConv &conv=wxConvLibc) const
DLLIMPORT wxString GetStringFromArray(const wxArrayString &array, const wxString &separator=DEFAULT_ARRAY_SEP, bool SeparatorAtEnd=true)
Definition: globals.cpp:122
bool IsAbsolute(wxPathFormat format=wxPATH_NATIVE) const
virtual int GetPlatforms() const
DLLIMPORT FileType FileTypeOf(const wxString &filename)
Definition: globals.cpp:285
virtual void SetTargetFilenameGenerationPolicy(TargetFilenameGenerationPolicy prefix, TargetFilenameGenerationPolicy extension)
A target&#39;s filename can either be auto-generated based on the running platform, or completely specifi...
virtual void SetExecutionParameters(const wxString &params)
Set the target&#39;s execution parameters to params.
void ClearExt()
wxString & Remove(size_t pos)
static size_t GetAllFiles(const wxString &dirname, wxArrayString *files, const wxString &filespec=wxEmptyString, int flags=wxDIR_DEFAULT)
virtual void SetUseConsoleRunner(bool useIt)
Set if ConsoleRunner should be used.
#define wxT(string)
virtual void SetImportLibraryFilename(const wxString &filename)
Set the target&#39;s import library filename.
virtual const wxArrayString & GetBuildScripts() const
virtual bool MakeCommandsModified() const
True if any of the "make" commands is modified.
Represents a file in a Code::Blocks project.
Definition: projectfile.h:39
virtual void SetPlatforms(int platforms)
virtual wxString GetOutputFilename()
Read the target&#39;s output filename.
virtual bool GetCreateStaticLib()
Valid only for targets generating dynamic libraries (DLLs or SOs).
void BeginAddFiles()
Notify that file(s) will be added shortly.
Definition: cbproject.cpp:593
virtual void SetCompilerID(const wxString &id)
! Set the flag if the host app should be run in terminal
wxString m_WildCard
Definition: cbproject.h:427
virtual bool GetRunHostApplicationInTerminal() const
Get the flag if the host app should be run in terminal.
DLLIMPORT const wxWX2MBbuf cbU2C(const wxString &str)
Return multibyte (C string) representation of the string.
Definition: globals.cpp:743
virtual TargetType GetTargetType() const
Read the target&#39;s type.
virtual void SetDefinitionFileFilename(const wxString &filename)
Set the target&#39;s definition file filename.
static Compiler * SelectCompilerUI(const wxString &message=_("Select compiler"), const wxString &preselectedID=wxEmptyString)
bool ExportTargetAsProject(const wxString &filename, const wxString &onlyTarget, TiXmlElement *pExtensions)
Export a target as a new project.
const wxString & GetMakefile()
Definition: cbproject.cpp:988
wxString GetFileMasks(unsigned int group) const
Return a specific group file mask.
bool MakeRelativeTo(const wxString &pathBase=wxEmptyString, wxPathFormat format=wxPATH_NATIVE)
void DoCompilerOptions(TiXmlElement *parentNode, ProjectBuildTarget *target=nullptr)
virtual void AddResourceIncludeDir(const wxString &option)
void SetCompilerID(const wxString &id) override
! Set the flag if the host app should be run in terminal
Definition: cbproject.cpp:129
void DoVirtualTargets(TiXmlElement *parentNode)
virtual OptionsRelation GetOptionRelation(OptionsRelationType type) const
Read the target&#39;s options relation for type.
virtual void SetHostApplication(const wxString &app)
Set the target&#39;s host application to app.
DLLIMPORT wxString UnixFilename(const wxString &filename, wxPathFormat format=wxPATH_NATIVE)
Definition: globals.cpp:228
virtual const wxArrayString & GetResourceIncludeDirs() const
Represents a Code::Blocks project.
Definition: cbproject.h:96
virtual const wxArrayString & GetLinkerOptions() const
virtual void AddLinkLib(const wxString &option)
virtual void AddCommandsBeforeBuild(const wxString &command)
virtual const wxArrayString & GetLinkLibs() const
virtual void AddCompilerOption(const wxString &option)
virtual wxString GetDynamicLibImportFilename()
Read the target&#39;s dynamic library import filename (produced if target type is ttDynamicLib) ...
virtual void SetOutputFilename(const wxString &filename)
Set the target&#39;s output filename.
virtual wxString GetMakeCommandFor(MakeCommand cmd) const
Get the "make" command used for cmd.
wxString GetMakefileExecutionDir()
Definition: cbproject.cpp:1013
DLLIMPORT wxString cbC2U(const char *str)
Return str as a proper unicode-compatible string.
Definition: globals.cpp:733
virtual const wxString & GetTitle() const
Read the target&#39;s title.
void DoBuild(TiXmlElement *parentNode)
Resource compiler include dir option.
virtual void AddLibDir(const wxString &option)
virtual const wxArrayString & GetResourceCompilerOptions() const
Target produces a dynamic library.
size_t Replace(const wxString &strOld, const wxString &strNew, bool replaceAll=true)
OptionsRelation
Option&#39;s relation.
#define PROJECT_FILE_VERSION_MINOR
Definition: projectloader.h:13
bool Open(const wxString &filename) override
Open a file.
void SetCheckForExternallyModifiedFiles(bool check)
Set check for externally modified files.
Definition: cbproject.cpp:1619
bool IsSameAs(const wxString &s, bool caseSensitive=true) const
TiXmlElement * AddElement(TiXmlElement *parent, const char *name, const char *attr=nullptr, const wxString &attribute=wxEmptyString)
static bool IsBatchBuild()
Definition: manager.h:66
LogManager * GetLogManager() const
Definition: manager.cpp:439
wxString & Item(size_t nIndex)
pfCustomBuildMap customBuild
A map for custom builds.
Definition: projectfile.h:184
virtual wxString GetBasePath() const
Read the target&#39;s base path, e.g. if GetFilename() returns "/usr/local/bin/xxx", base path will retur...
wxString libExtension
Definition: compiler.h:224
wxString linkLibs
Definition: compiler.h:214
Compiler include dir option.
virtual const wxArrayString & GetCommandsAfterBuild() const
virtual wxString GetWorkingDir()
Read the target&#39;s working dir for execution (valid only for executable targets)
virtual void SetExternalDeps(const wxString &deps)
Set a list of all the external files this targets depends on.
This is a base class for all classes needing compilation parameters.
virtual void SetWorkingDir(const wxString &dirname)
Set the target&#39;s working dir on execution (valid only for executable targets)
virtual void AddResourceCompilerOption(const wxString &option)
const wxArrayString & GetVirtualBuildTargetGroup(const wxString &alias) const
Access a virtual build target&#39;s group of build targets.
Definition: cbproject.cpp:1496
wxString wxEmptyString
wxString Right(size_t count) const
virtual void SetAlwaysRunPostBuildSteps(bool always)
static int CompareProjectFiles(ProjectFile *item1, ProjectFile *item2)
Compare relative names of projectfiles.
const wxString & GetNotes() const
Get notes on the project.
Definition: cbproject.cpp:1600
ProjectFile * AddFile(const wxString &targetName, const wxString &filename, bool compile=true, bool link=true, unsigned short int weight=50)
Add a file to the project.
Definition: cbproject.cpp:621
virtual void SetCreateStaticLib(bool createIt)
Set if an import library should be created.
void SetCustomBuildCommand(const wxString &compilerId, const wxString &newBuildCommand)
Modify customBuild command for a compilerId.
No automatic generation; let the user specify the full filename.
const wxString & _(const wxString &string)
wxString & Trim(bool fromRight=true)
bool IsMakefileCustom()
Definition: cbproject.h:159
void DoLibsOptions(TiXmlElement *parentNode, ProjectBuildTarget *target=nullptr)
int GetBuildTargetsCount()
Definition: cbproject.h:200
virtual FilesList & GetFilesList()
Provides an easy way to iterate all the files belonging in this target.
void SetMakefile(const wxString &makefile)
Set the Makefile filename used when exporting a Makefile for the project, or when using a custom Make...
Definition: cbproject.h:148
wxString buildCommand
Definition: projectfile.h:28
virtual const wxArrayString & GetIncludeDirs() const
In a dir (named by the PCH) on the same level as the source header (default).
Definition: cbproject.h:86
ProjectFilesVector generatedFiles
Auto-generated files when compiling this file.
Definition: projectfile.h:207
bool useCustomBuildCommand
Definition: projectfile.h:29
wxString compilerVar
The compiler variable used for this file (e.g CPP, CC, etc).
Definition: projectfile.h:187
wxArtID wxART_WARNING
wxArrayString GetVirtualBuildTargets() const
Get a list of all defined virtual build targets.
Definition: cbproject.cpp:1487
Target produces a static library.
void SetGlobs(const std::vector< Glob > &globs)
Set the globs to the project, this are directory paths do retrieve files from to be added to the proj...
Definition: cbproject.cpp:1745
virtual void SetDepsOutput(const wxString &dirname)
Set the target&#39;s dependencies output dir.
ProjectBuildTarget * GetBuildTarget(int index)
Access a build target.
Definition: cbproject.cpp:1392
bool ToLong(long *val, int base=10) const
Abstract base class for compilers.
Definition: compiler.h:274
const wxString & GetDefaultExecuteTarget() const
Definition: cbproject.cpp:1387
const wxArrayString & GetVirtualFolders() const
Get a list of the virtual folders.
Definition: cbproject.cpp:908
bool GetExtendedObjectNamesGeneration() const
Gets object names generation mode (extended/normal).
Definition: cbproject.cpp:1586
void DoProjectOptions(TiXmlElement *parentNode)
wxString libPrefix
Definition: compiler.h:223
bool IsEmpty() const
virtual bool GetAlwaysRunPostBuildSteps() const
virtual const wxArrayString & GetLibDirs() const
virtual const wxString & GetCompilerID() const
Read the target&#39;s compiler.
Target produces a console executable (without GUI) (distinction between ttExecutable and ttConsoleOnl...
virtual bool SetVar(const wxString &key, const wxString &value, bool onlyIfExists=false)
bool GetShowNotesOnLoad() const
Get show project notes on load automatically.
Definition: cbproject.cpp:1614
wxString GetFullName() const
void DebugLog(const wxString &msg, Logger::level lv=Logger::info)
Definition: logmanager.h:146
virtual const CompilerSwitches & GetSwitches() const
Get the compiler&#39;s generic switches.
Definition: compiler.h:301
void DoEnvironment(TiXmlElement *parentNode, CompileOptionsBase *base)
wxString virtual_path
A string that represents the virtual folder this file will appear in.
Definition: projectfile.h:195
int ShowModal() override
void SetTargetType(TargetType pt) override
Set the target&#39;s type to pt.
wxString & Prepend(const wxString &str)
void ConvertVersion_Pre_1_1()
void DoIncludesOptions(TiXmlElement *parentNode, ProjectBuildTarget *target=nullptr)
size_t Add(const wxString &str, size_t copies=1)
bool HasVirtualBuildTarget(const wxString &alias) const
Does a virtual build target exist?
Definition: cbproject.cpp:1470
bool StartsWith(const wxString &prefix, wxString *rest=NULL) const
void SetTitle(const wxString &title) override
Changes project title.
Definition: cbproject.cpp:1650
void ConvertLibraries(CompileTargetBase *object)
void DoLinkerOptions(TiXmlElement *parentNode, ProjectBuildTarget *target=nullptr)
Represents a Code::Blocks project build target.
void SetExtendedObjectNamesGeneration(bool ext)
Sets object names generation to extended/normal mode.
Definition: cbproject.cpp:1565
Linker option.
size_t GetCount() const
ProjectFile * AutoGeneratedBy() const
If this is an auto-generated file, which file is generating it?
Definition: projectfile.h:201
void SetUseCustomBuildCommand(const wxString &compilerId, bool useCustomBuildCommand)
Modify &#39;Use custom command to build this file&#39; for a compilerId.
DLLIMPORT int GetPlatformsFromString(const wxString &platforms)
Return an integer representation of a platform string.
Definition: globals.cpp:73
void SetNotes(const wxString &notes)
Set notes on the project.
Definition: cbproject.cpp:1591
int m_1_4_to_1_5_deftarget
ProjectBuildTarget * AddBuildTarget(const wxString &targetName)
Add a new build target.
Definition: cbproject.cpp:1150
virtual void AddLinkerOption(const wxString &option)
void DoMakeCommands(TiXmlElement *parentNode, CompileTargetBase *target)
wxString m_Path
Definition: cbproject.h:426
bool MakeAbsolute(const wxString &cwd=wxEmptyString, wxPathFormat format=wxPATH_NATIVE)
void AddBuildTarget(const wxString &targetName)
Make this file belong to an additional build target.
Definition: projectfile.cpp:78
void RemoveAt(size_t nIndex, size_t count=1)
Compiler option.
int Printf(const wxString &pszFormat,...)
virtual wxString GetObjectOutput() const
Read the target&#39;s objects output dir.
void DoResourceCompilerOptions(TiXmlElement *parentNode, ProjectBuildTarget *target=nullptr)
wxString GetFullPath(wxPathFormat format=wxPATH_NATIVE) const
TargetType
Enum to define the type of output the target produces.
virtual const StringHash & GetAllVars() const
DLLIMPORT bool cbSaveTinyXMLDocument(TiXmlDocument *doc, const wxString &filename)
Saves a TinyXML document correctly, even if the path contains unicode characters. ...
Definition: globals.cpp:727
virtual wxString GetDynamicLibDefFilename()
Read the target&#39;s dynamic library definition file filename (produced if target type is ttDynamicLib) ...
virtual void SetRunHostApplicationInTerminal(bool in_terminal)
const DLLIMPORT wxString RESOURCE_EXT
wxArtID wxART_INFORMATION
static wxString Format(const wxString &format,...)
virtual bool GetIncludeInTargetAll() const
Deprecated, do not use at all!
wxString Mid(size_t first, size_t nCount=wxString::npos) const
virtual void SetAdditionalOutputFiles(const wxString &files)
Set a list of all additional output files this targets creates, besides its main output.
void SetMakefileExecutionDir(const wxString &dir)
Allow the specification of specific execution directory if the project use a custom Makefile...
Definition: cbproject.cpp:1004
Definition: globals.h:161
Dialog that contains a "Don&#39;t annoy me" checkbox.
DLLIMPORT int cbMessageBox(const wxString &message, const wxString &caption=wxEmptyString, int style=wxOK, wxWindow *parent=NULL, int x=-1, int y=-1)
wxMessageBox wrapper.
Definition: globals.cpp:1395
std::vector< Glob > GetGlobs() const
Retrieve the current globs from the project.
Definition: cbproject.cpp:1750
wxArrayString buildTargets
An array of strings, containing the names of all the build targets this file belongs to...
Definition: projectfile.h:190
wxString GetFirstValidBuildTargetName(bool virtuals_too=true) const
Definition: cbproject.cpp:1345
DLLIMPORT bool HasRegisteredHooks()
Are there any hooks registered?
Base class for build target classes Each Code::Blocks project consists of at least one target...
Target only runs commands in pre-build and/or post-build steps.
virtual const wxArrayString & GetCommandsBeforeBuild() const