Code::Blocks  SVN r11506
directcommands.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of the Code::Blocks IDE and licensed under the GNU General Public License, version 3
3  * http://www.gnu.org/licenses/gpl-3.0.html
4  *
5  * $Revision: 11343 $
6  * $Id: directcommands.cpp 11343 2018-03-21 18:19:51Z pecanh $
7  * $HeadURL: https://svn.code.sf.net/p/codeblocks/code/trunk/src/plugins/compilergcc/directcommands.cpp $
8  */
9 
10 #include <sdk.h>
11 #include <wx/intl.h>
12 #include <wx/filename.h>
13 #include <wx/msgdlg.h>
14 #include <wx/stream.h>
15 #include <wx/wfstream.h>
16 #include <wx/txtstrm.h>
17 #include <wx/regex.h> // used in QUICK hack at line 574
18 #include <compiler.h>
19 #include <cbproject.h>
20 #include <projectbuildtarget.h>
21 #include <globals.h>
22 #include <manager.h>
23 #include <logmanager.h>
24 #include <configmanager.h>
25 #include <macrosmanager.h>
26 #include "directcommands.h"
28 #include "compilergcc.h"
29 #include "cbexception.h"
30 #include "filefilters.h"
31 #include <depslib.h>
32 
33 const wxString COMPILER_SIMPLE_LOG(_T("SLOG:"));
34 const wxString COMPILER_NOTE_LOG(_T("SLOG:NLOG:"));
35 const wxString COMPILER_WARNING_LOG(_T("SLOG:WLOG:"));
36 const wxString COMPILER_ERROR_LOG(_T("SLOG:ELOG:"));
37 const wxString COMPILER_TARGET_CHANGE(_T("TGT:"));
38 const wxString COMPILER_WAIT(_T("WAIT"));
39 const wxString COMPILER_WAIT_LINK(_T("LINK"));
40 
41 const wxString COMPILER_NOTE_ID_LOG = COMPILER_NOTE_LOG.AfterFirst(wxT(':'));
42 const wxString COMPILER_WARNING_ID_LOG = COMPILER_WARNING_LOG.AfterFirst(wxT(':'));
43 const wxString COMPILER_ERROR_ID_LOG = COMPILER_ERROR_LOG.AfterFirst(wxT(':'));
44 
46  Compiler* compiler,
47  cbProject* project,
48  int logPageIndex) :
49  m_doYield(false),
50  m_PageIndex(logPageIndex),
51  m_pCompilerPlugin(compilerPlugin),
52  m_pCompiler(compiler),
53  m_pProject(project),
54  m_pGenerator(0)
55 {
56  // even if there is no project, the command generator need to be
57  // initialised for single file compilation to work.
58  // it can handle a NULL pointer argument... ;-)
60 
61  // ctor
62  if (!m_pProject)
63  return; // probably a compile file cmd without a project
64 
65  depsStart();
66  wxFileName cwd;
68  // depslib does special handling on Windows in case the CWD is a root
69  // folder like "R:". But this ONLY works, if its just "R:", NOT e.g. "R:/"
70  wxString depsCWD = cwd.GetPath(wxPATH_GET_VOLUME);
71  Manager::Get()->GetLogManager()->DebugLog(F(_("CWD for depslib was: %s."), depsCWD.wx_str()));
72  if ( (depsCWD.Len()==3) && (depsCWD.GetChar(1)==':')
73  && ( (depsCWD.GetChar(2)=='\\') || (depsCWD.GetChar(2)=='/') ) )
74  {
75  depsCWD.RemoveLast();
76  }
77  Manager::Get()->GetLogManager()->DebugLog(F(_("CWD for depslib is: %s."), depsCWD.wx_str()));
78  depsSetCWD(depsCWD.mb_str());
79 
81  fname.SetExt(_T("depend"));
82  depsCacheRead(fname.GetFullPath().mb_str());
83 }
84 
86 {
87  if (!m_pProject)
88  return; // probably a compile file cmd without a project
89 
90  struct depsStats stats;
91  depsGetStats(&stats);
92  if (stats.cache_updated)
93  {
95  fname.SetExt(_T("depend"));
96  depsCacheWrite(fname.GetFullPath().mb_str());
97  }
98 
100  F(_("Scanned %ld files for #includes, cache used %ld, cache updated %ld"),
101  stats.scanned, stats.cache_used, stats.cache_updated));
102 
103  depsDone();
104 
105  delete m_pGenerator;
106 }
107 
108 void DirectCommands::AddCommandsToArray(const wxString& cmds, wxArrayString& array, bool isWaitCmd, bool isLinkCmd) const
109 {
110  wxString cmd = cmds;
111  while (!cmd.IsEmpty())
112  {
113  int idx = cmd.Find(_T("\n"));
114  wxString cmdpart = idx != -1 ? cmd.Left(idx) : cmd;
115  cmdpart.Trim(false);
116  cmdpart.Trim(true);
117  if (!cmdpart.IsEmpty())
118  {
119  if (isWaitCmd)
120  array.Add(COMPILER_WAIT);
121  if (isLinkCmd)
122  array.Add(COMPILER_WAIT_LINK);
123  array.Add(cmdpart);
124  }
125  if (idx == -1)
126  break;
127  cmd.Remove(0, idx + 1);
128  }
129 }
130 
132 {
133  int diff = (*one)->weight - (*two)->weight;
134  diff = (diff == 0 ? (*one)->relativeFilename.CmpNoCase((*two)->relativeFilename) : diff);
135  return (diff == 0 ? (*one)->relativeFilename.Cmp((*two)->relativeFilename) : diff);
136 }
137 
138 MyFilesArray DirectCommands::GetProjectFilesSortedByWeight(ProjectBuildTarget* target, bool compile, bool link) const
139 {
140  MyFilesArray files;
141  for (FilesList::iterator it = m_pProject->GetFilesList().begin(); it != m_pProject->GetFilesList().end(); ++it)
142  {
143  ProjectFile* pf = *it;
144  // require compile
145  if (compile && !pf->compile)
146  continue;
147  // require link
148  if (link && !pf->link)
149  continue;
150  // if the file does not belong in this target (if we have a target), skip it
151  if (target && (pf->buildTargets.Index(target->GetTitle()) == wxNOT_FOUND))
152  continue;
153  files.Add(pf);
154  }
155  files.Sort(MySortProjectFilesByWeight);
156  return files;
157 }
158 
160 {
161  wxArrayString ret;
162 
163  // is it compilable?
164  if (!pf || !pf->compile || pf->compilerVar.IsEmpty())
165  return ret;
166 
167  // might happen for single file compilation if user chose a target the file does NOT belong to:
168  if (target && pf->GetBuildTargets().Index(target->GetTitle()) == wxNOT_FOUND)
169  {
170  Manager::Get()->GetLogManager()->DebugLog(_("Invalid target selected to compile project file for: File does not belong to this target."));
171  return ret;
172  }
173 
174  if (!force)
175  {
176  DepsSearchStart(target);
177 
178  const pfDetails& pfd = pf->GetFileDetails(target);
179  wxString err;
180  if ( !IsObjectOutdated(target, pfd, &err) )
181  {
182  if ( !err.IsEmpty() )
183  ret.Add(COMPILER_WARNING_LOG + err);
184  return ret;
185  }
186  }
187 
188  if (target)
189  ret.Add(COMPILER_TARGET_CHANGE + target->GetTitle());
190  AppendArray(GetCompileFileCommand(target, pf), ret);
191  return ret;
192 }
193 
195 {
196  wxArrayString ret;
197  wxArrayString ret_generated;
198 
199  // is it compilable?
200  if (!pf || !pf->compile)
201  return ret;
202 
203  if (pf->compilerVar.IsEmpty())
204  {
205  Manager::Get()->GetLogManager()->DebugLog(_("Cannot resolve compiler var for project file."));
206  return ret;
207  }
208 
209  Compiler* compiler = target
211  : m_pCompiler;
212  if (!compiler)
213  {
214  Manager::Get()->GetLogManager()->DebugLog(_("Can't access compiler for file."));
215  return ret;
216  }
217 
218  const pfDetails& pfd = pf->GetFileDetails(target);
219  wxString object = (compiler->GetSwitches().UseFlatObjects)
220  ? pfd.object_file_flat : pfd.object_file;
221  wxString object_dir = (compiler->GetSwitches().UseFlatObjects)
223  // create output dir
224  if (!object_dir.IsEmpty() && !CreateDirRecursively(object_dir, 0755))
225  Manager::Get()->GetLogManager()->DebugLog(_("Can't create object output directory:\n") + object_dir);
226 
227  // lookup file's type
228  const FileType ft = FileTypeOf(pf->relativeFilename);
229 
230  bool is_resource = ft == ftResource;
231  bool is_header = ft == ftHeader;
232 
233  // allowed resources under all platforms: makes sense when cross-compiling for
234  // windows under linux.
235  // and anyway, if the user is dumb enough to try to compile resources without
236  // having a resource compiler, (s)he deserves the upcoming build error ;)
237 
238  wxString compiler_cmd;
239  if (!is_header || compiler->GetSwitches().supportsPCH)
240  {
241  const CompilerTool* tool = compiler->GetCompilerTool(is_resource ? ctCompileResourceCmd : ctCompileObjectCmd, pf->file.GetExt());
242 
243  // does it generate other files to compile?
244  for (size_t i = 0; i < pf->generatedFiles.size(); ++i)
245  AppendArray(GetCompileFileCommand(target, pf->generatedFiles[i]), ret_generated); // recurse
246 
247  pfCustomBuild& pcfb = pf->customBuild[compiler->GetID()];
248  if (pcfb.useCustomBuildCommand)
249  compiler_cmd = pcfb.buildCommand;
250  else if (tool)
251  compiler_cmd = tool->command;
252  else
253  compiler_cmd = wxEmptyString;
254 
255  wxString source_file;
256  if (compiler->GetSwitches().UseFullSourcePaths)
257  source_file = UnixFilename(pfd.source_file_absolute_native);
258  else
259  source_file = pfd.source_file;
260 
261 #ifdef command_line_generation
262  Manager::Get()->GetLogManager()->DebugLog(F(_T("GetCompileFileCommand[1]: compiler_cmd='%s', source_file='%s', object='%s', object_dir='%s'."),
263  compiler_cmd.wx_str(), source_file.wx_str(), object.wx_str(), object_dir.wx_str()));
264 #endif
265 
266  // for resource files, use short from if path because if windres bug with spaces-in-paths
267  if (is_resource && compiler->GetSwitches().UseFullSourcePaths)
268  source_file = pf->file.GetShortPath();
269 
270  QuoteStringIfNeeded(source_file);
271 
272 #ifdef command_line_generation
273  Manager::Get()->GetLogManager()->DebugLog(F(_T("GetCompileFileCommand[2]: source_file='%s'."),
274  source_file.wx_str()));
275 #endif
276 
277  m_pGenerator->GenerateCommandLine(compiler_cmd,
278  target,
279  pf,
280  source_file,
281  object,
282  pfd.object_file_flat,
283  pfd.dep_file);
284  }
285 
286  if (!is_header && compiler_cmd.IsEmpty())
287  {
288  ret.Add(COMPILER_SIMPLE_LOG + _("Skipping file (no compiler program set): ") + pfd.source_file_native );
289  return ret;
290  }
291 
292  switch (compiler->GetSwitches().logging)
293  {
294  case clogFull:
295  ret.Add(COMPILER_SIMPLE_LOG + compiler_cmd);
296  break;
297 
298  case clogSimple:
299  if (is_header)
300  ret.Add(COMPILER_SIMPLE_LOG + _("Pre-compiling header: ") + pfd.source_file_native );
301  else
302  ret.Add(COMPILER_SIMPLE_LOG + _("Compiling: ") + pfd.source_file_native );
303  break;
304 
305  case clogNone: // fall-through
306  default:
307  break;
308  }
309 
310  AddCommandsToArray(compiler_cmd, ret);
311 
312  if (is_header)
313  ret.Add(COMPILER_WAIT);
314 
315  if (ret_generated.GetCount())
316  {
317  // not only append commands for (any) generated files to be compiled
318  // but also insert a "pause" to allow this file to generate its files first
319  if (!is_header) // if is_header, the "pause" has already been added
320  ret.Add(COMPILER_WAIT);
321  AppendArray(ret_generated, ret);
322  }
323 
324  // if it's a PCH, delete the previously generated PCH to avoid problems
325  // (it 'll be recreated anyway)
326  if ( (ft == ftHeader) && pf->compile )
327  {
328  wxString object_abs = (compiler->GetSwitches().UseFlatObjects)
331 
332  if ( !wxRemoveFile(object_abs) )
333  Manager::Get()->GetLogManager()->DebugLog(_("Cannot remove old PCH file:\n") + object_abs);
334  }
335 
336  return ret;
337 }
338 
341 {
342  wxArrayString ret;
343 
344  // lookup file's type
345  FileType ft = FileTypeOf(filename);
346 
347  // is it compilable?
348  if (ft != ftSource)
349  return ret;
350 
351  wxFileName fname(filename);
353  wxString o_filename = fname.GetFullPath();
354  wxString srcExt = fname.GetExt();
356  wxString exe_filename = fname.GetFullPath();
357 
358  wxString s_filename = filename;
359  QuoteStringIfNeeded(s_filename);
360  QuoteStringIfNeeded(o_filename);
361 
363  if (!compiler)
364  return ret;
365 
366  // please leave this check here for convenience: single file compilation is "special"
367  if (!m_pGenerator) cbThrow(_T("Command generator not initialised through ctor!"));
368 
369  wxString compilerCmd = compiler->GetCommand(ctCompileObjectCmd, srcExt);
370  m_pGenerator->GenerateCommandLine(compilerCmd,
371  0,
372  0,
373  s_filename,
374  o_filename,
375  o_filename,
376  wxEmptyString);
377  wxString linkerCmd = compiler->GetCommand(ctLinkConsoleExeCmd, fname.GetExt());
379  0,
380  0,
382  o_filename,
383  o_filename,
384  wxEmptyString);
385 
386  if (!compilerCmd.IsEmpty())
387  {
388  switch (m_pCompiler->GetSwitches().logging)
389  {
390  case clogFull:
391  ret.Add(COMPILER_SIMPLE_LOG + compilerCmd);
392  break;
393 
394  case clogSimple:
395  ret.Add(COMPILER_SIMPLE_LOG + _("Compiling: ") + filename);
396  break;
397 
398  case clogNone: // fall-through
399  default:
400  break;
401  }
402  AddCommandsToArray(compilerCmd, ret);
403  }
404  else
405  ret.Add(COMPILER_SIMPLE_LOG + _("Skipping file (no compiler program set): ") + filename);
406 
407  if (!linkerCmd.IsEmpty())
408  {
409  switch (m_pCompiler->GetSwitches().logging)
410  {
411  case clogFull:
412  ret.Add(COMPILER_SIMPLE_LOG + linkerCmd);
413  break;
414 
415  case clogSimple: // fall-through
416  case clogNone: // fall-through
417  default: // linker always simple log (if not full)
418  ret.Add(COMPILER_SIMPLE_LOG + _("Linking console executable: ") + exe_filename);
419  break;
420  }
421  AddCommandsToArray(linkerCmd, ret, true);
422  }
423  else
424  ret.Add(COMPILER_SIMPLE_LOG + _("Skipping linking (no linker program set): ") + exe_filename);
425  return ret;
426 }
427 
430 {
431  wxArrayString ret;
432 
433  // lookup file's type
434  FileType ft = FileTypeOf(filename);
435 
436  // is it compilable?
437  if (ft != ftSource)
438  return ret;
439 
440  wxFileName fname(filename);
442  wxString o_filename = fname.GetFullPath();
444  wxString exe_filename = fname.GetFullPath();
445 
446  ret.Add(o_filename);
447  ret.Add(exe_filename);
448 
449  return ret;
450 }
451 
453 {
454  wxArrayString ret;
455 
456  if (target)
457  ret = GetTargetCompileCommands(target, force);
458  else
459  {
460  for (int x = 0; x < m_pProject->GetBuildTargetsCount(); ++x)
461  {
463  if (bt->GetIncludeInTargetAll()) // only if target gets build with "all"
464  {
465  wxArrayString targetcompile = GetTargetCompileCommands(bt, force);
466  AppendArray(targetcompile, ret);
467  }
468  }
469  }
470  return ret;
471 }
472 
474 {
475  wxArrayString ret;
476 
477  // set list of #include directories
478  DepsSearchStart(target);
479 
480  // iterate all files of the project/target and add them to the build process
481  size_t counter = ret.GetCount();
482  MyFilesArray files = GetProjectFilesSortedByWeight(target, true, false);
483  size_t fcount = files.GetCount();
484  bool hasWeight = false;
485  unsigned short int lastWeight = 0;
486  for (unsigned int i = 0; i < fcount; ++i)
487  {
488  ProjectFile* pf = files[i];
489  // auto-generated files are handled automatically in GetCompileFileCommand()
490  if (pf->AutoGeneratedBy())
491  continue;
492 
493  const pfDetails& pfd = pf->GetFileDetails(target);
494  wxString err;
495  if (force || IsObjectOutdated(target, pfd, &err))
496  {
497  // Add a wait command if the weight of the current file is different from the previous one
498  // Because GetCompileFileCommand() already adds a wait command if it compiled a PCH we
499  // check the last command to prevent two consecutive wait commands
500  if (hasWeight && lastWeight != pf->weight && (ret.IsEmpty() || ret.Last() != COMPILER_WAIT))
501  ret.Add(COMPILER_WAIT);
502 
503  // compile file
504  wxArrayString filecmd = GetCompileFileCommand(target, pf);
505  AppendArray(filecmd, ret);
506 
507  // Update the weight
508  if (!hasWeight)
509  hasWeight = true;
510  lastWeight = pf->weight;
511  }
512  else
513  {
514  if (!err.IsEmpty())
515  ret.Add(COMPILER_WARNING_LOG + err);
516  }
517  if (m_doYield)
518  Manager::Yield();
519  }
520 
521  // add link command
522  wxArrayString link = GetLinkCommands(target, ret.GetCount() != counter);
523  AppendArray(link, ret);
524 
525  return ret;
526 }
527 
529 {
530  Compiler* compiler = target ? CompilerFactory::GetCompiler(target->GetCompilerID()) : m_pCompiler;
531  wxArrayString buildcmds = target ? target->GetCommandsBeforeBuild() : m_pProject->GetCommandsBeforeBuild();
532  if (!buildcmds.IsEmpty())
533  {
534  wxString title = target ? target->GetTitle() : m_pProject->GetTitle();
535  wxArrayString tmp;
536  for (size_t i = 0; i < buildcmds.GetCount(); ++i)
537  {
538  if (compiler)
539  {
540  if (target)
542  else
543  m_pGenerator->GenerateCommandLine(buildcmds[i], m_pProject->GetCurrentlyCompilingTarget(), 0, wxEmptyString, wxEmptyString, wxEmptyString, wxEmptyString);
544  }
545 
546  tmp.Add(COMPILER_WAIT); // all commands should wait for queue to empty first
547  tmp.Add(COMPILER_SIMPLE_LOG + buildcmds[i]);
548  tmp.Add(buildcmds[i]);
549  }
550  buildcmds = tmp;
551  if (target)
552  buildcmds.Insert(COMPILER_SIMPLE_LOG + _("Running target pre-build steps"), 0);
553  else
554  buildcmds.Insert(COMPILER_SIMPLE_LOG + _("Running project pre-build steps"), 0);
555  if (m_doYield)
556  Manager::Yield();
557  }
558  return buildcmds;
559 }
560 
562 {
563  Compiler* compiler = target ? CompilerFactory::GetCompiler(target->GetCompilerID()) : m_pCompiler;
564  wxArrayString buildcmds = target ? target->GetCommandsAfterBuild() : m_pProject->GetCommandsAfterBuild();
565  if (!buildcmds.IsEmpty())
566  {
567  wxString title = target ? target->GetTitle() : m_pProject->GetTitle();
568  wxArrayString tmp;
569  for (size_t i = 0; i < buildcmds.GetCount(); ++i)
570  {
571  if (compiler)
572  {
573  if (target)
574  {
575  m_pGenerator->GenerateCommandLine(buildcmds[i], target, 0, wxEmptyString,
577  }
578  else
579  {
581  0, wxEmptyString, wxEmptyString, wxEmptyString, wxEmptyString);
582  }
583  }
584 
585  tmp.Add(COMPILER_WAIT); // all commands should wait for queue to empty first
586  tmp.Add(COMPILER_SIMPLE_LOG + buildcmds[i]);
587  tmp.Add(buildcmds[i]);
588  }
589  buildcmds = tmp;
590  if (target)
591  buildcmds.Insert(COMPILER_SIMPLE_LOG + _("Running target post-build steps"), 0);
592  else
593  buildcmds.Insert(COMPILER_SIMPLE_LOG + _("Running project post-build steps"), 0);
594  if (m_doYield)
595  Manager::Yield();
596  }
597  return buildcmds;
598 }
599 
601 {
602  wxArrayString ret;
603 
604  if (target)
605  ret = GetTargetLinkCommands(target, force);
606  else
607  {
608  for (int x = 0; x < m_pProject->GetBuildTargetsCount(); ++x)
609  {
611  if (bt->GetIncludeInTargetAll()) // only if target gets build with "all"
612  {
613  wxArrayString targetlink = GetTargetLinkCommands(bt, force);
614  AppendArray(targetlink, ret);
615  }
616  }
617  }
618  return ret;
619 }
620 
622 {
623  wxArrayString ret;
624 
625  wxString output = target->GetOutputFilename();
626  Manager::Get()->GetMacrosManager()->ReplaceMacros(output, target);
627 
628  wxFileName out = UnixFilename(output);
629  wxString linkfiles;
630  wxString FlatLinkFiles;
631  wxString resfiles;
632  bool IsOpenWatcom = target->GetCompilerID().IsSameAs(_T("ow"));
633 
634  time_t outputtime;
635  depsTimeStamp(output.mb_str(), &outputtime);
636  if (!outputtime)
637  force = true;
638  wxArrayString fileMissing;
639  if ( AreExternalDepsOutdated(target, out.GetFullPath(), &fileMissing) )
640  force = true;
641 
642  if (!fileMissing.IsEmpty())
643  {
644  wxString warn;
645 #ifdef NO_TRANSLATION
646  warn.Printf(wxT("WARNING: Target '%s': Unable to resolve %lu external dependenc%s:"),
647  target->GetFullTitle().wx_str(), static_cast<unsigned long>(fileMissing.Count()), wxString(fileMissing.Count() == 1 ? wxT("y") : wxT("ies")).wx_str());
648 #else
649  warn.Printf(_("WARNING: Target '%s': Unable to resolve %lu external dependency/ies:"),
650  target->GetFullTitle().wx_str(), static_cast<unsigned long>(fileMissing.Count()));
651 #endif // NO_TRANSLATION
652  ret.Add(COMPILER_WARNING_LOG + warn);
653  for (size_t i = 0; i < fileMissing.Count(); ++i)
654  ret.Add(COMPILER_NOTE_LOG + wxString(wxT(' '), 8) + fileMissing[i]);
655  }
656 
657  Compiler* compiler = target ? CompilerFactory::GetCompiler(target->GetCompilerID()) : m_pCompiler;
658 
659  wxString prependHack; // part of the following hack
660  if (target->GetTargetType() == ttStaticLib)
661  {
662  // QUICK HACK: some linkers (e.g. bcc, dmc) require a - or + in front of
663  // object files for static library. What we 'll do here until we redesign
664  // the thing, is to accept this symbol as part of the $link_objects macro
665  // like this:
666  // $+link_objects
667  // $-link_objects
668  // $-+link_objects
669  // $+-link_objects
670  //
671  // So, we first scan the command for this special case and, if found,
672  // set a flag so that the linkfiles array is filled with the correct options
673  wxString compilerCmd = compiler ? compiler->GetCommand(ctLinkStaticCmd) : wxString(wxEmptyString);
674  wxRegEx re(_T("\\$([-+]+)link_objects"));
675  if (re.Matches(compilerCmd))
676  prependHack = re.GetMatch(compilerCmd, 1);
677  }
678 
679  // get all the linkable objects for the target
680  MyFilesArray files = GetProjectFilesSortedByWeight(target, false, true);
681  if (files.GetCount() == 0)
682  {
683  if (target->GetTargetType() != ttCommandsOnly)
684  ret.Add(COMPILER_SIMPLE_LOG + _("Linking stage skipped (build target has no object files to link)"));
685  return ret;
686  }
687  if (IsOpenWatcom && target->GetTargetType() != ttStaticLib)
688  linkfiles << _T("file ");
689  bool subseq(false);
690  for (unsigned int i = 0; i < files.GetCount(); ++i)
691  {
692  ProjectFile* pf = files[i];
693 
694  // we have to test again for each file if it is to be compiled
695  // and we can't check the file for existence because we 're still
696  // generating the command lines that will create the files...
697  wxString macro = _T("$compiler");
699  if (macro.IsEmpty())
700  continue;
701 
702  const pfDetails& pfd = pf->GetFileDetails(target);
703  wxString Object = (compiler->GetSwitches().UseFlatObjects) ? pfd.object_file_flat
704  : pfd.object_file;
705 
707  {
708  if (subseq)
709  resfiles << _T(" ");
710  // -----------------------------------------
711  // Following lines have been modified for OpenWatcom
712  if (IsOpenWatcom)
713  resfiles << _T("option resource=") << Object;
714  else
715  resfiles << Object;
716  // ------------------------------------------
717  }
718  else
719  {
720  // -----------------------------------------
721  // Following lines have been modified for OpenWatcom
722  if (IsOpenWatcom && target->GetTargetType() == ttStaticLib)
723  {
724  if (subseq)
725  {
726  linkfiles << _T(" ");
727  FlatLinkFiles << _T(" ");
728  }
729  linkfiles << prependHack << Object; // see QUICK HACK above (prependHack)
730  FlatLinkFiles << prependHack << pfd.object_file_flat; // see QUICK HACK above (prependHack)
731  }
732  else
733  {
734  if (subseq)
735  {
736  linkfiles << compiler->GetSwitches().objectSeparator;
737  FlatLinkFiles << compiler->GetSwitches().objectSeparator;
738  }
739  linkfiles << prependHack << Object; // see QUICK HACK above (prependHack)
740  FlatLinkFiles << prependHack << pfd.object_file_flat; // see QUICK HACK above (prependHack)
741  }
742  // -----------------------------------------
743  }
744  subseq = true;
745 
746  // timestamp check
747  if (!force)
748  {
749  time_t objtime;
750  depsTimeStamp(pfd.object_file_native.mb_str(), &objtime);
751  // Honor compiler request to Use Flat Objects
752  // (Settings/compiler/otherSettings/advancedOptions/Others/UseFlatObjects)
753  if (compiler->GetSwitches().UseFlatObjects)
754  depsTimeStamp(pfd.object_file_flat.mb_str(), &objtime);
755 
756  if (!objtime)
757  force = true;
758  if (objtime > outputtime)
759  force = true;
760  }
761  }
762  if (IsOpenWatcom)
763  {
764  linkfiles.Trim();
765  }
766 
767  if (!force)
768  return ret;
769 
770  // create output dir
772  wxString dstname = out.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR);
773  Manager::Get()->GetMacrosManager()->ReplaceMacros(dstname, target);
774  if (!dstname.IsEmpty() && !CreateDirRecursively(dstname, 0755))
775  {
776  cbMessageBox(_("Can't create output directory ") + dstname);
777  }
778 
779  // add actual link command
780  wxString kind_of_output;
781  CommandType ct = ctCount; // get rid of compiler warning
782  switch (target->GetTargetType())
783  {
784  case ttConsoleOnly:
785  ct = ctLinkConsoleExeCmd;
786  kind_of_output = _("console executable");
787  break;
788 
789  case ttExecutable:
790  ct = ctLinkExeCmd;
791  kind_of_output = _("executable");
792  break;
793 
794  case ttDynamicLib:
795  ct = ctLinkDynamicCmd;
796  kind_of_output = _("dynamic library");
797  break;
798 
799  case ttStaticLib:
800  ct = ctLinkStaticCmd;
801  kind_of_output = _("static library");
802  break;
803 
804  case ttNative:
805  ct = ctLinkNativeCmd;
806  kind_of_output = _("native");
807  break;
808 
809  case ttCommandsOnly:
810  // add target post-build commands
811  ret.Clear();
812  AppendArray(GetPostBuildCommands(target), ret);
813  return ret;
814  break;
815  default:
816  wxString ex;
817  ex.Printf(_T("Encountered invalid TargetType (value = %d)"), target->GetTargetType());
818  cbThrow(ex);
819  break;
820  }
821  wxString compilerCmd = compiler->GetCommand(ct);
822  m_pGenerator->GenerateCommandLine(compilerCmd,
823  target,
824  0,
825  _T(""),
826  linkfiles,
827  FlatLinkFiles,
828  resfiles);
829  if (!compilerCmd.IsEmpty())
830  {
831  switch (compiler->GetSwitches().logging)
832  {
833  case clogFull:
834  ret.Add(COMPILER_SIMPLE_LOG + compilerCmd);
835  break;
836 
837  case clogSimple: // fall-through
838  case clogNone: // fall-through
839  default: // linker always simple log (if not full)
840  ret.Add(COMPILER_SIMPLE_LOG + _("Linking ") + kind_of_output + _T(": ") + output);
841  break;
842  }
843 
844  // for an explanation of the following, see GetTargetCompileCommands()
845  if (target && ret.GetCount() != 0)
846  ret.Add(COMPILER_TARGET_CHANGE + target->GetTitle());
847 
848  // the 'true' will make sure all commands will be prepended by
849  // COMPILER_WAIT signal
850  AddCommandsToArray(compilerCmd, ret, true, true);
851  }
852  else
853  ret.Add(COMPILER_SIMPLE_LOG + _("Skipping linking (no linker program set): ") + output);
854 
855  return ret;
856 }
857 
859 {
860  wxArrayString ret;
861 
862  if (target)
863  ret = GetTargetCleanCommands(target);
864  else
865  {
866  for (int x = 0; x < m_pProject->GetBuildTargetsCount(); ++x)
867  {
869  wxArrayString targetclear = GetTargetCleanCommands(bt, distclean);
870  AppendArray(targetclear, ret);
871  }
872  }
873  return ret;
874 }
875 
877 {
878  wxArrayString ret;
879 
880  // add object files
881  MyFilesArray files = GetProjectFilesSortedByWeight(target, true, false);
882  for (unsigned int i = 0; i < files.GetCount(); ++i)
883  {
884  ProjectFile* pf = files[i];
885  const pfDetails& pfd = pf->GetFileDetails(target);
886  Compiler* compiler = target ? CompilerFactory::GetCompiler(target->GetCompilerID()) : m_pCompiler;
887  if (compiler)
888  {
889  wxString ObjectAbs = (compiler->GetSwitches().UseFlatObjects)
892  ret.Add(ObjectAbs);
893  // if this is an auto-generated file, delete it
894  if (pf->AutoGeneratedBy())
895  ret.Add(pf->file.GetFullPath());
896 
897  if (distclean)
898  ret.Add(pfd.dep_file_absolute_native);
899  }
900  }
901 
902  // add target output
903  wxString outputfilename = target->GetOutputFilename();
904 
905  if (target->GetTargetType() != ttCommandsOnly)
906  {
907  Manager::Get()->GetMacrosManager()->ReplaceMacros(outputfilename, target);
908  ret.Add(outputfilename);
909  }
910 
911  if (target->GetTargetType() == ttDynamicLib)
912  {
913  // for dynamic libs, delete static lib
914  outputfilename = target->GetStaticLibFilename();
915  Manager::Get()->GetMacrosManager()->ReplaceMacros(outputfilename, target);
916  ret.Add(outputfilename);
917  // .def exports file is not deleted, because it may be user-supplied
918 // ret.Add(target->GetDynamicLibDefFilename());
919  }
920 
921  return ret;
922 }
923 
929  const wxString& buildOutput,
930  wxArrayString* filesMissing) const
931 {
932  Compiler* compiler = CompilerFactory::GetCompiler(target->GetCompilerID());
933 
934  // if no output, probably a commands-only target; nothing to relink
935  // but we have to check other dependencies
936  time_t timeOutput = 0;
937  if (!buildOutput.IsEmpty())
938  {
939  wxString output = buildOutput;
941  depsTimeStamp(output.mb_str(), &timeOutput);
942  // if build output exists, check for updated static libraries
943  if (timeOutput)
944  {
945  // look for static libraries in target/project library dirs
946  wxArrayString libs = target->GetLinkLibs();
947  const wxArrayString& prjLibs = target->GetParentProject()->GetLinkLibs();
948  const wxArrayString& cmpLibs = compiler->GetLinkLibs();
949  AppendArray(prjLibs, libs);
950  AppendArray(cmpLibs, libs);
951 
952  const wxArrayString& prjLibDirs = target->GetParentProject()->GetLibDirs();
953  const wxArrayString& cmpLibDirs = compiler->GetLibDirs();
954  wxArrayString libDirs = target->GetLibDirs();
955  AppendArray(prjLibDirs, libDirs);
956  AppendArray(cmpLibDirs, libDirs);
957 
958  for (size_t i = 0; i < libs.GetCount(); ++i)
959  {
960  wxString lib = libs[i];
961 
962  // if user manually pointed to a library, without using the lib dirs,
963  // then just check the file directly w/out involving the search dirs...
964  if (lib.Contains(_T("/")) || lib.Contains(_T("\\")))
965  {
966  Manager::Get()->GetMacrosManager()->ReplaceMacros(lib, target);
967  lib = UnixFilename(lib);
968  time_t timeExtDep;
969  depsTimeStamp(lib.mb_str(), &timeExtDep);
970  if (timeExtDep > timeOutput)
971  {
972  // force re-link
973  Manager::Get()->GetLogManager()->DebugLog(F(_T("Forcing re-link of '%s/%s' because '%s' is newer"),
974  target->GetParentProject()->GetTitle().wx_str(),
975  target->GetTitle().wx_str(),
976  lib.wx_str()));
977  return true;
978  }
979  continue;
980  }
981 
982  if (!lib.StartsWith(compiler->GetSwitches().libPrefix))
983  lib = compiler->GetSwitches().libPrefix + lib;
984  if (!lib.EndsWith(_T(".") + compiler->GetSwitches().libExtension))
985  lib += _T(".") + compiler->GetSwitches().libExtension;
986 
987  for (size_t l = 0; l < libDirs.GetCount(); ++l)
988  {
989  wxString dir = libDirs[l] + wxFILE_SEP_PATH + lib;
990  Manager::Get()->GetMacrosManager()->ReplaceMacros(dir, target);
991  dir = UnixFilename(dir);
992  time_t timeExtDep;
993  depsTimeStamp(dir.mb_str(), &timeExtDep);
994  if (timeExtDep > timeOutput)
995  {
996  // force re-link
997  Manager::Get()->GetLogManager()->DebugLog(F(_T("Forcing re-link of '%s/%s' because '%s' is newer"),
998  target->GetParentProject()->GetTitle().wx_str(),
999  target->GetTitle().wx_str(),
1000  dir.wx_str()));
1001  return true;
1002  }
1003  }
1004  }
1005  }
1006  }
1007 
1008  // array is separated by ;
1009  wxArrayString extDeps = GetArrayFromString(target->GetExternalDeps(), _T(";"));
1010  wxArrayString addFiles = GetArrayFromString(target->GetAdditionalOutputFiles(), _T(";"));
1011  for (size_t i = 0; i < extDeps.GetCount(); ++i)
1012  {
1013  if (extDeps[i].IsEmpty())
1014  continue;
1015 
1016  Manager::Get()->GetMacrosManager()->ReplaceMacros(extDeps[i]);
1017  time_t timeExtDep;
1018  depsTimeStamp(extDeps[i].mb_str(), &timeExtDep);
1019  // if external dep doesn't exist, no need to relink
1020  // but we have to check other dependencies
1021  if (!timeExtDep)
1022  {
1023  if (filesMissing) filesMissing->Add(extDeps[i]);
1024  continue;
1025  }
1026 
1027  // let's check the additional output files
1028  for (size_t j = 0; j < addFiles.GetCount(); ++j)
1029  {
1030  if (addFiles[j].IsEmpty())
1031  continue;
1032 
1033  Manager::Get()->GetMacrosManager()->ReplaceMacros(addFiles[j]);
1034  time_t timeAddFile;
1035  depsTimeStamp(addFiles[j].mb_str(), &timeAddFile);
1036  // if additional file doesn't exist, we can skip it
1037  if (!timeAddFile)
1038  {
1039  if (filesMissing) filesMissing->Add(addFiles[j]);
1040  continue;
1041  }
1042 
1043  // if external dep is newer than additional file, relink
1044  if (timeExtDep > timeAddFile)
1045  return true;
1046  }
1047 
1048  // if no output, probably a commands-only target; nothing to relink
1049  // but we have to check other dependencies
1050  if (buildOutput.IsEmpty())
1051  continue;
1052 
1053  // now check the target's output
1054  // this is moved last because, for "commands only" targets,
1055  // it would return before we had a chance to check the
1056  // additional output files (above)
1057 
1058  // if build output doesn't exist, relink
1059  if (!timeOutput)
1060  return true;
1061 
1062  // if external dep is newer than build output, relink
1063  if (timeExtDep > timeOutput)
1064  return true;
1065  }
1066  return false; // no force relink
1067 }
1068 
1069 bool DirectCommands::IsObjectOutdated(ProjectBuildTarget* target, const pfDetails& pfd, wxString* errorStr) const
1070 {
1071  // If the source file does not exist, then do not compile.
1072  time_t timeSrc;
1073  depsTimeStamp(pfd.source_file_absolute_native.mb_str(), &timeSrc);
1074  if (!timeSrc)
1075  {
1076  if (errorStr)
1077  *errorStr = _("WARNING: Can't read file's timestamp: ") + pfd.source_file_absolute_native;
1078 
1080  return true; // fall-back: Its better to compile in that case
1081 
1082  return false;
1083  }
1084 
1085  // If the object file does not exist, then it must be built. In this case
1086  // there is no need to scan the source file for headers.
1087  time_t timeObj;
1088  Compiler* compiler = target ? CompilerFactory::GetCompiler(target->GetCompilerID()) : m_pCompiler;
1089  if (!compiler)
1090  return false;
1091 
1092  wxString ObjectAbs = (compiler->GetSwitches().UseFlatObjects)
1095  depsTimeStamp(ObjectAbs.mb_str(), &timeObj);
1096  if (!timeObj)
1097  return true; // fall-back: Its better to compile in that case
1098 
1099  // If the source file is newer than the object file, then the object file
1100  // must be built. In this case there is no need to scan the source file
1101  // for headers.
1102  if (timeSrc > timeObj)
1103  return true;
1104 
1105  // Do the check for includes only, if not disabled by the user, e.g. in case of non C/C++ compilers
1106  if ( Manager::Get()->GetConfigManager(_T("compiler"))->ReadBool(_T("/skip_include_deps"), false) )
1107  return false;
1108 
1109  // Scan the source file for headers. Result is NULL if the file does
1110  // not exist. If one of the descendent header files is newer than the
1111  // object file, then the object file must be built.
1112  depsRef ref = depsScanForHeaders(pfd.source_file_absolute_native.mb_str());
1113  if (ref)
1114  {
1115  time_t timeNewest;
1116  (void) depsGetNewest(ref, &timeNewest);
1117  return (timeNewest > timeObj);
1118  }
1119 
1120  // object file is up to date with source file and does not depend on #includes
1121  return false;
1122 }
1123 
1125 {
1126  depsSearchStart();
1127 
1130 
1131  for (unsigned int i = 0; i < incs.GetCount(); ++i)
1132  {
1133  // replace custom vars in include dirs
1134  mm->ReplaceMacros(incs[i], target);
1135  // actually add search dirs for deps
1136  depsAddSearchDir(incs[i].mb_str());
1137  }
1138 
1139  // We could add the "global" compiler directories too, but we normally
1140  // don't care about the modification times of system include files.
1141 }
const wxString COMPILER_SIMPLE_LOG(_T("SLOG:"))
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
CompilerLoggingType logging
Definition: compiler.h:222
wxString dep_file
Definition: projectfile.h:249
unsigned short int weight
The weight.
Definition: projectfile.h:145
bool wxRemoveFile(const wxString &file)
wxString relativeFilename
The relative (to the project) filename of this file.
Definition: projectfile.h:131
virtual const wxString & GetAdditionalOutputFiles() const
void Assign(const wxFileName &filepath)
ConfigManager * GetConfigManager(const wxString &name_space) const
Definition: manager.cpp:474
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
wxString source_file_absolute_native
Definition: projectfile.h:261
virtual FilesList & GetFilesList()
Provides an easy way to iterate all the files belonging in this target.
Definition: cbproject.h:685
wxString object_file
Definition: projectfile.h:248
bool wxFileExists(const wxString &filename)
virtual const CompilerTool * GetCompilerTool(CommandType ct, const wxString &fileExtension=wxEmptyString) const
Get a compiler tool based on CommandType.
Definition: compiler.cpp:334
wxFileName file
The full filename of this file.
Definition: projectfile.h:126
static Compiler * GetDefaultCompiler()
wxString GetShortPath() const
Link console executable command, e.g. "$linker $libdirs -o $exe_output $link_objects $libs"...
Definition: compiler.h:172
virtual const wxString & GetExternalDeps() const
bool compile
Compile flag.
Definition: projectfile.h:138
bool ReadBool(const wxString &name, bool defaultVal=false)
int Index(const wxString &sz, bool bCase=true, bool bFromEnd=false) const
Target produces an executable.
virtual const wxArrayString & GetCompilerSearchDirs(ProjectBuildTarget *target)
Get the full include dirs used in the actual command line.
wxString object_file_native
Definition: projectfile.h:256
static Compiler * GetCompiler(size_t index)
void AddCommandsToArray(const wxString &cmds, wxArrayString &array, bool isWaitCmd=false, bool isLinkCmd=false) const
bool Matches(const wxString &text, int flags=0) const
#define _T(string)
FileType
Known file types.
Definition: globals.h:49
const wxCharBuffer mb_str(const wxMBConv &conv=wxConvLibc) const
DLLIMPORT FileType FileTypeOf(const wxString &filename)
Definition: globals.cpp:285
wxString object_file_flat_absolute_native
Definition: projectfile.h:263
Compile object command, e.g. "$compiler $options $includes -c $file -o $object".
Definition: compiler.h:168
wxString & Remove(size_t pos)
bool UseFullSourcePaths
Definition: compiler.h:231
const wxString COMPILER_WARNING_LOG(_T("SLOG:WLOG:"))
virtual void GenerateCommandLine(wxString &macro, ProjectBuildTarget *target, ProjectFile *pf, const wxString &file, const wxString &object, const wxString &flat_object, const wxString &deps)
Get the command line to compile/link the specific file.
wxString AfterFirst(wxUniChar ch) const
#define wxT(string)
wxString object_dir_native
Definition: projectfile.h:258
wxArrayString GetTargetLinkCommands(ProjectBuildTarget *target, bool force=false) const
#define wxNOT_FOUND
Represents a file in a Code::Blocks project.
Definition: projectfile.h:39
const wxString COMPILER_TARGET_CHANGE(_T("TGT:"))
ProjectBuildTarget * GetCurrentlyCompilingTarget()
Get a pointer to the currently compiling target.
Definition: cbproject.h:478
virtual wxString GetOutputFilename()
Read the target&#39;s output filename.
wxArrayString GetTargetCompileCommands(ProjectBuildTarget *target, bool force=false) const
virtual cbProject * GetParentProject()
virtual wxString GetStaticLibFilename()
Read the target&#39;s static library filename (produced if target type is ttStaticLib) ...
virtual const wxString & GetCommand(CommandType ct, const wxString &fileExtension=wxEmptyString) const
Get a command based on CommandType.
Definition: compiler.cpp:305
virtual wxString GetFullTitle() const
wxArrayString GetCompileSingleFileCommand(const wxString &filename) const
This is to be used only for files not belonging to a project!!!
wxString source_file
Definition: projectfile.h:247
virtual TargetType GetTargetType() const
Read the target&#39;s type.
wxString dep_file_absolute_native
Definition: projectfile.h:264
wxString object_dir_flat_native
Definition: projectfile.h:259
const wxString COMPILER_WAIT(_T("WAIT"))
const wxString & GetID() const
Get this compiler&#39;s unique ID.
Definition: compiler.h:351
const wxString COMPILER_ERROR_LOG(_T("SLOG:ELOG:"))
wxArrayString GetPreBuildCommands(ProjectBuildTarget *target) const
bool Contains(const wxString &str) const
DLLIMPORT wxString UnixFilename(const wxString &filename, wxPathFormat format=wxPATH_NATIVE)
Definition: globals.cpp:228
wxString GetExt() const
void Insert(wxString lItem, size_t nIndex, size_t copies=1)
Represents a Code::Blocks project.
Definition: cbproject.h:96
virtual const wxString & GetFilename() const
Link dynamic (dll) lib command, e.g. "$linker -shared -Wl,--output-def=$def_output -Wl...
Definition: compiler.h:173
wxString & RemoveLast(size_t n=1)
virtual const wxArrayString & GetLinkLibs() const
Struct for compiler/linker commands.
Definition: compiler.h:249
bool AreExternalDepsOutdated(ProjectBuildTarget *target, const wxString &buildOutput, wxArrayString *filesMissing) const
external deps are manually set by the user e.g.
wxString objectExtension
Definition: compiler.h:217
virtual const wxString & GetTitle() const
Read the target&#39;s title.
wxString Left(size_t count) const
wxArrayString GetTargetCleanCommands(ProjectBuildTarget *target, bool distclean=false) const
wxArrayString GetCompileCommands(ProjectBuildTarget *target, bool force=false) const
wxArrayString GetCleanCommands(ProjectBuildTarget *target, bool distclean=false) const
Target produces a dynamic library.
wxString & Last()
bool IsSameAs(const wxString &s, bool caseSensitive=true) const
bool GetMatch(size_t *start, size_t *len, size_t index=0) const
Target produces a native binary.
LogManager * GetLogManager() const
Definition: manager.cpp:439
pfCustomBuildMap customBuild
A map for custom builds.
Definition: projectfile.h:184
bool IsObjectOutdated(ProjectBuildTarget *target, const pfDetails &pfd, wxString *errorStr=0) const
This is a helper class that caches various filenames for one ProjectFile.
Definition: projectfile.h:241
const pfDetails & GetFileDetails(ProjectBuildTarget *target)
Access the file details for this project file for the specified target.
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
bool IsEmpty() const
wxChar objectSeparator
Definition: compiler.h:242
const wxString ref(_T("&"))
void DepsSearchStart(ProjectBuildTarget *target) const
virtual const wxArrayString & GetCommandsAfterBuild() const
wxArrayString CompileFile(ProjectBuildTarget *target, ProjectFile *pf, bool force=false) const
const wxStringCharType * wx_str() const
Link executable command, e.g. "$linker $libdirs -o $exe_output $link_objects $libs -mwindows"...
Definition: compiler.h:171
wxString wxEmptyString
wxString command
command to execute
Definition: compiler.h:262
MacrosManager * GetMacrosManager() const
Definition: manager.cpp:454
const wxString & _(const wxString &string)
DLLIMPORT void QuoteStringIfNeeded(wxString &str)
Definition: globals.cpp:260
wxString & Trim(bool fromRight=true)
void ReplaceMacros(wxString &buffer, ProjectBuildTarget *target=nullptr, bool subrequest=false)
int GetBuildTargetsCount()
Definition: cbproject.h:200
const wxString COMPILER_NOTE_LOG(_T("SLOG:NLOG:"))
wxString buildCommand
Definition: projectfile.h:28
static void Yield()
Whenever you need to call wxYield(), call Manager::Yield(). It&#39;s safer.
Definition: manager.cpp:221
#define cbThrow(message)
Definition: cbexception.h:42
CommandType
Helper enum to retrieve compiler commands.
Definition: compiler.h:166
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
Target produces a static library.
ProjectBuildTarget * GetBuildTarget(int index)
Access a build target.
Definition: cbproject.cpp:1392
const DLLIMPORT wxString EXECUTABLE_EXT
wxArrayString GetPostBuildCommands(ProjectBuildTarget *target) const
Compile Win32 resources command, e.g. "$rescomp -i $file -J rc -o $resource_output -O coff $includes"...
Definition: compiler.h:170
Abstract base class for compilers.
Definition: compiler.h:274
wxArrayString GetCompileFileCommand(ProjectBuildTarget *target, ProjectFile *pf) const
cbProject * m_pProject
wxString object_file_absolute_native
Definition: projectfile.h:262
wxString libPrefix
Definition: compiler.h:223
bool IsEmpty() const
virtual const wxArrayString & GetLibDirs() const
Compiler * m_pCompiler
wxString GetPath(int flags=wxPATH_GET_VOLUME, wxPathFormat format=wxPATH_NATIVE) const
virtual const wxString & GetCompilerID() const
Read the target&#39;s compiler.
size_t Len() const
DLLIMPORT void AppendArray(const wxArrayString &from, wxArrayString &to)
Definition: globals.cpp:222
Target produces a console executable (without GUI) (distinction between ttExecutable and ttConsoleOnl...
static int MySortProjectFilesByWeight(ProjectFile **one, ProjectFile **two)
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
bool EndsWith(const wxString &suffix, wxString *rest=NULL) const
void SetExt(const wxString &ext)
CompilerCommandGenerator * m_pGenerator
MyFilesArray GetProjectFilesSortedByWeight(ProjectBuildTarget *target, bool compile, bool link) const
size_t Add(const wxString &str, size_t copies=1)
bool StartsWith(const wxString &prefix, wxString *rest=NULL) const
Represents a Code::Blocks project build target.
DirectCommands(DirectCommands &)
size_t GetCount() const
ProjectFile * AutoGeneratedBy() const
If this is an auto-generated file, which file is generating it?
Definition: projectfile.h:201
int Find(wxUniChar ch, bool fromEnd=false) const
Link native binary command.
Definition: compiler.h:175
wxUniChar GetChar(size_t n) const
DLLIMPORT bool CreateDirRecursively(const wxString &full_path, int perms=0755)
Definition: globals.cpp:610
Link static lib command, e.g. "ar -r $output $link_objects\n\tranlib $static_output".
Definition: compiler.h:174
const wxArrayString & GetBuildTargets() const
wxString source_file_native
Definition: projectfile.h:255
bool MakeAbsolute(const wxString &cwd=wxEmptyString, wxPathFormat format=wxPATH_NATIVE)
int Printf(const wxString &pszFormat,...)
wxArrayString GetLinkCommands(ProjectBuildTarget *target, bool force=false) const
wxString GetFullPath(wxPathFormat format=wxPATH_NATIVE) const
Do NOT use.
Definition: compiler.h:177
wxArrayString GetCleanSingleFileCommand(const wxString &filename) const
This is to be used only for files not belonging to a project!!!
virtual bool GetIncludeInTargetAll() const
Deprecated, do not use at all!
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
wxArrayString buildTargets
An array of strings, containing the names of all the build targets this file belongs to...
Definition: projectfile.h:190
Target only runs commands in pre-build and/or post-build steps.
wxString object_file_flat
Definition: projectfile.h:253
virtual CompilerCommandGenerator * GetCommandGenerator(cbProject *project)
This is to be overridden, if compiler needs to alter the default command line generation.
Definition: compiler.cpp:298
bool UseFlatObjects
Definition: compiler.h:230
virtual const wxArrayString & GetCommandsBeforeBuild() const