Code::Blocks  SVN r11506
compilercommandgenerator.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: 10589 $
6  * $Id: compilercommandgenerator.cpp 10589 2015-11-15 19:21:12Z mortenmacfly $
7  * $HeadURL: https://svn.code.sf.net/p/codeblocks/code/trunk/src/sdk/compilercommandgenerator.cpp $
8  */
9 
10 #include "sdk_precomp.h"
12 
13 #include <wx/intl.h>
14 #include <wx/filename.h>
15 
16 #include "cbexception.h"
17 #include "cbproject.h"
18 #include "compilerfactory.h"
19 #include "compiler.h"
20 #include "manager.h"
21 #include "configmanager.h"
22 #include "logmanager.h"
23 #include "macrosmanager.h"
24 #include "scriptingmanager.h"
25 #include "filefilters.h"
26 
28 #include "scripting/sqplus/sqplus.h"
29 
30 // move this to globals if needed
32 {
33  wxString s = str;
34  if (!str.IsEmpty() && str.GetChar(0) == _T('"') && str.Last() == _T('"'))
35  s = str.Mid(1, str.Length() - 2);
36  return s;
37 }
38 
40 {
41  //ctor
42 }
43 
45 {
46  //dtor
47 }
48 
50 {
51  // clear old arrays
52  m_Output.clear();
53  m_StaticOutput.clear();
54  m_DefOutput.clear();
55  m_Inc.clear();
56  m_Lib.clear();
57  m_RC.clear();
58  m_CFlags.clear();
59  m_RCFlags.clear();
60  m_LDFlags.clear();
61  m_LDAdd.clear();
62 
63  // don't clear the backticks cache - it wouldn't be a cache then :)
64 // m_Backticks.clear();
65 
66  m_CompilerSearchDirs.clear();
67  m_LinkerSearchDirs.clear();
68 
69  // access the default compiler
71  if (!compiler)
72  cbThrow(_T("Default compiler is invalid!"));
73 
74  if (!project)
75  {
76  m_DefOutput[nullptr] = SetupOutputFilenames(compiler, nullptr);
77  m_Inc[nullptr] = SetupIncludeDirs(compiler, nullptr);
78  m_Lib[nullptr] = SetupLibrariesDirs(compiler, nullptr);
79  m_RC[nullptr] = SetupResourceIncludeDirs(compiler, nullptr);
80  m_CFlags[nullptr] = SetupCompilerOptions(compiler, nullptr);
81  m_RCFlags[nullptr] = SetupResourceCompilerOptions(compiler, nullptr);
82  m_LDFlags[nullptr] = SetupLinkerOptions(compiler, nullptr);
83  m_LDAdd[nullptr] = SetupLinkLibraries(compiler, nullptr);
84  return;
85  }
86  else
87  {
89  if (!m_PrjIncPath.IsEmpty())
90  {
91  if (m_PrjIncPath.Last() == _T('\\'))
94  }
95  }
96 
97  // reset failed-scripts arrays
100 
101  // change to the project's base dir so scripts can be found
102  // (they 're always stored relative to the base dir)
104 
105  // backup project settings
106  bool projectWasModified = project->GetModified();
107  CompileTargetBase backup = *(CompileTargetBase*)project;
108 
109  // Invoke plugins
110  {
112  Manager::Get()->ProcessEvent(evt);
113  }
114 
115  // project build scripts
116  DoBuildScripts(project, project, _T("SetBuildOptions"));
117 
118  // for each target
119  for (int i = 0; i < project->GetBuildTargetsCount(); ++i)
120  {
121  ProjectBuildTarget* target = project->GetBuildTarget(i);
122 
123  // access the compiler used for this target
124  compiler = CompilerFactory::GetCompiler(target->GetCompilerID());
125 
126  // for commands-only targets (or if invalid compiler), nothing to setup
127  // just add stub entries so that indices keep in sync
128  if (!compiler || target->GetTargetType() == ttCommandsOnly || !target->SupportsCurrentPlatform())
129  {
130  m_Output[target] = wxEmptyString;
131  m_StaticOutput[target] = wxEmptyString;
132  m_DefOutput[target] = wxEmptyString;
133  m_Inc[target] = wxEmptyString;
134  m_Lib[target] = wxEmptyString;
135  m_RC[target] = wxEmptyString;
136  m_CFlags[target] = wxEmptyString;
137  m_RCFlags[target] = wxEmptyString;
138  m_LDFlags[target] = wxEmptyString;
139  m_LDAdd[target] = wxEmptyString;
140  // continue with next target
141  continue;
142  }
143 
144  // backup target settings
145  CompileTargetBase backuptarget = *(CompileTargetBase*)target;
146 
147  // invoke plugins
148  {
150  evt.SetBuildTargetName(target->GetTitle());
151  Manager::Get()->ProcessEvent(evt);
152  }
153 
154  // target build scripts
155  DoBuildScripts(project, target, _T("SetBuildOptions"));
156 
157  m_DefOutput[target] = SetupOutputFilenames(compiler, target);
158  m_Inc[target] = SetupIncludeDirs(compiler, target);
159  m_Lib[target] = SetupLibrariesDirs(compiler, target);
160  m_RC[target] = SetupResourceIncludeDirs(compiler, target);
161  m_CFlags[target] = SetupCompilerOptions(compiler, target);
162  m_RCFlags[target] = SetupResourceCompilerOptions(compiler, target);
163  m_LDFlags[target] = SetupLinkerOptions(compiler, target);
164  m_LDAdd[target] = SetupLinkLibraries(compiler, target);
165 
166  // restore target settings
167  *(CompileTargetBase*)target = backuptarget;
168  }
169 
170  // restore project settings
171  *(CompileTargetBase*)project = backup;
172  project->SetModified(projectWasModified);
173 
174  // let's display all script errors now in a batch
176  {
177  wxString msg;
178 
180  {
181  msg << _("Scripts that failed to load either because they don't exist\n"
182  "or because they contain syntax errors:\n\n");
183  for (size_t i = 0; i < m_NotLoadedScripts.GetCount(); ++i)
184  {
185  msg << m_NotLoadedScripts[i] << _T("\n");
186  }
187  msg << _T("\n");
188  }
190  {
191  msg << _("Scripts that failed to load because the mandatory function\n"
192  "SetBuildOptions() is missing:\n\n");
193  for (size_t i = 0; i < m_ScriptsWithErrors.GetCount(); ++i)
194  {
195  msg << m_ScriptsWithErrors[i] << _T("\n");
196  }
197  msg << _T("\n");
198  }
199 
200  if (Manager::IsBatchBuild()) // no dialog if batch building...
202  else
203  cbMessageBox(msg, _("Error"), wxICON_ERROR);
204  }
205 }
206 
208  ProjectBuildTarget* target,
209  ProjectFile* pf,
210  const wxString& file,
211  const wxString& object,
212  const wxString& flat_object,
213  const wxString& deps)
214 {
215 #ifdef command_line_generation
216  Manager::Get()->GetLogManager()->DebugLog(F(_T("GenerateCommandLine[0]: macro='%s', file='%s', object='%s', flat_object='%s', deps='%s'."),
217  macro.wx_str(), file.wx_str(), object.wx_str(), flat_object.wx_str(), deps.wx_str()));
218 #endif
219 
220  if (target && !target->SupportsCurrentPlatform())
221  {
222  macro.Clear();
223  return;
224  }
225 
226  Compiler* compiler = target
229  if (!compiler)
230  {
231  macro.Clear();
232  return;
233  }
234 
235  enum CompilerExe
236  {
237  ceUnknown,
238  ceC,
239  ceCPP
240  };
241  CompilerExe compExec = ceUnknown;
242  wxString compilerStr;
243  if (pf)
244  {
245  if (pf->compilerVar.Matches(_T("CPP")))
246  {
247  compilerStr = compiler->GetPrograms().CPP;
248  compExec = ceCPP;
249  }
250  else if (pf->compilerVar.Matches(_T("CC")))
251  {
252  compilerStr = compiler->GetPrograms().C;
253  compExec = ceC;
254  }
255  else if (pf->compilerVar.Matches(_T("WINDRES")))
256  compilerStr = compiler->GetPrograms().WINDRES;
257  }
258  else
259  {
260  // filename might be quoted, so unquote it if needed or extension can be 'c"'
261  wxFileName fname( UnquoteStringIfNeeded(file) );
262  if (fname.GetExt().Lower().Matches(_T("c")))
263  {
264  compilerStr = compiler->GetPrograms().C;
265  compExec = ceC;
266  }
267  else
268  {
269  compilerStr = compiler->GetPrograms().CPP;
270  compExec = ceCPP;
271  }
272  }
273 
274  // check that we have valid compiler/linker program names (and are indeed needed by the macro)
275  if ( (compilerStr.IsEmpty() && macro.Contains(_T("$compiler")))
276  || (compiler->GetPrograms().LD.IsEmpty() && macro.Contains(_T("$linker")))
277  || (compiler->GetPrograms().LIB.IsEmpty() && macro.Contains(_T("$lib_linker")))
278  || (compiler->GetPrograms().WINDRES.IsEmpty() && macro.Contains(_T("$rescomp"))) )
279  {
280  Manager::Get()->GetLogManager()->DebugLog(F(_T("GenerateCommandLine: Required compiler executable (%s) not found! Check the toolchain settings."), file.wx_str()));
281  macro.Clear();
282  return;
283  }
284 
285  FixPathSeparators(compiler, compilerStr);
286 
287  wxString tmpIncludes(m_Inc[target]);
288  wxString tmpResIncludes(m_RC[target]);
289  if (Manager::Get()->GetConfigManager(_T("compiler"))->ReadBool(_T("/include_file_cwd"), false))
290  {
291  // Because C::B doesn't compile each file by running in the same directory with it,
292  // it can cause some problems when the file #includes other files relative,
293  // e.g. #include "../a_lib/include/a.h"
294  //
295  // So here we add the currently compiling file's directory to the includes
296  // search dir so it works.
297  wxFileName fileCwd( UnquoteStringIfNeeded(file) );
298  wxString fileInc = fileCwd.GetPath();
299  FixPathSeparators(compiler, fileInc);
300  if (!fileInc.IsEmpty()) // only if non-empty! (remember r1813 errors)
301  {
302  QuoteStringIfNeeded(fileInc);
303  if (compiler->GetSwitches().includeDirs.EndsWith(_T("(")))
304  {
305  // special handling for "INCDIR(path1;path2)" style includes
306  tmpIncludes.RemoveLast();
307  tmpResIncludes.RemoveLast();
308  tmpIncludes += compiler->GetSwitches().includeDirSeparator + fileInc + _T(")");
309  tmpResIncludes += compiler->GetSwitches().includeDirSeparator + fileInc + _T(")");
310  }
311  else
312  {
313  tmpIncludes += compiler->GetSwitches().includeDirSeparator +
314  compiler->GetSwitches().includeDirs + fileInc;
315  tmpResIncludes += compiler->GetSwitches().includeDirSeparator +
316  compiler->GetSwitches().includeDirs + fileInc;
317  }
318  }
319  }
320 
321  if (Manager::Get()->GetConfigManager(_T("compiler"))->ReadBool(_T("/include_prj_cwd"), false))
322  {
323  // Because C::B doesn't compile each file by running in the same directory with it,
324  // it can cause some problems when the file #includes other files relative,
325  // e.g. #include "../a_lib/include/a.h"
326  //
327  // So here we add the project's top-level directory (common toplevel path) to the includes
328  // search dir so it works.
329  wxString fileInc = m_PrjIncPath;
330  FixPathSeparators(compiler, fileInc);
331  if (compiler->GetSwitches().includeDirs.EndsWith(_T("(")))
332  {
333  // special handling for "INCDIR(path1;path2)" style includes
334  tmpIncludes.RemoveLast();
335  tmpResIncludes.RemoveLast();
336  tmpIncludes += compiler->GetSwitches().includeDirSeparator + fileInc + _T(")");
337  tmpResIncludes += compiler->GetSwitches().includeDirSeparator + fileInc + _T(")");
338  }
339  else
340  {
341  tmpIncludes += compiler->GetSwitches().includeDirSeparator +
342  compiler->GetSwitches().includeDirs + fileInc;
343  tmpResIncludes += compiler->GetSwitches().includeDirSeparator +
344  compiler->GetSwitches().includeDirs + fileInc;
345  }
346  }
347 
348 #ifdef command_line_generation
349  Manager::Get()->GetLogManager()->DebugLog(F(_T("GenerateCommandLine[1]: tmpIncludes='%s', tmpResIncludes='%s'."),
350  tmpIncludes.wx_str(), tmpResIncludes.wx_str()));
351 #endif
352 
353  wxString tmp;
354  wxString tmpFile = file;
355  wxString tmpDeps = deps;
356  wxString tmpObject = object;
357  wxString tmpFlatObject = flat_object;
358 
359  wxFileName tmpFname( UnquoteStringIfNeeded(tmpFile) );
360  wxFileName tmpOutFname;
361 
362 #ifdef command_line_generation
363  Manager::Get()->GetLogManager()->DebugLog(F(_T("GenerateCommandLine[2]: tmpFile='%s', tmpDeps='%s', tmpObject='%s', tmpFlatObject='%s',\ntmpFname.GetName='%s', tmpFname.GetPath='%s', tmpFname.GetExt='%s'."),
364  tmpFile.wx_str(), tmpDeps.wx_str(), tmpObject.wx_str(), tmpFlatObject.wx_str(), tmpFname.GetName().wx_str(), tmpFname.GetPath().wx_str(), tmpFname.GetExt().wx_str()));
365 #endif
366 
367  FixPathSeparators(compiler, tmpFile);
368  FixPathSeparators(compiler, tmpDeps);
369  FixPathSeparators(compiler, tmpObject);
370  FixPathSeparators(compiler, tmpFlatObject);
371 
372 #ifdef command_line_generation
373  Manager::Get()->GetLogManager()->DebugLog(F(_T("GenerateCommandLine[3]: tmpFile='%s', tmpDeps='%s', tmpObject='%s', tmpFlatObject='%s'."),
374  tmpFile.wx_str(), tmpDeps.wx_str(), tmpObject.wx_str(), tmpFlatObject.wx_str()));
375  Manager::Get()->GetLogManager()->DebugLog(F(_T("GenerateCommandLine[4]: macro='%s'."),
376  macro.wx_str()));
377 #endif
378  // Special handling for compiler options to filter between C and C++ compilers
379  wxString cFlags = m_CFlags[target];
380  wxArrayString remFlags;
381  if (compExec == ceC)
382  remFlags = GetArrayFromString(compiler->GetCPPOnlyFlags(), wxT(" "));
383  else if (compExec == ceCPP)
384  remFlags = GetArrayFromString(compiler->GetCOnlyFlags(), wxT(" "));
385  if (!remFlags.IsEmpty())
386  {
387  wxArrayString aCflags = GetArrayFromString(cFlags, wxT(" "));
388  for (size_t i = 0; i < remFlags.GetCount(); ++i)
389  {
390  int index = aCflags.Index(remFlags[i]);
391  if (index != wxNOT_FOUND)
392  aCflags.RemoveAt(index);
393  }
394  cFlags = GetStringFromArray(aCflags, wxT(" "), false);
395  }
396 
397  wxString allObjectsQuoted(tmpObject);
398  if (!(allObjectsQuoted.IsEmpty() || m_LDAdd[target].IsEmpty()))
399  allObjectsQuoted += compiler->GetSwitches().objectSeparator;
400  allObjectsQuoted += m_LDAdd[target];
401  if (allObjectsQuoted.Find(_T('"')) != -1)
402  {
403  allObjectsQuoted.Replace(_T("\""), _T("\\\""));
404  allObjectsQuoted = _T("\"") + allObjectsQuoted + _T("\"");
405  }
406 
407  macro.Replace(_T("$compiler"), compilerStr);
408  macro.Replace(_T("$linker"), compiler->GetPrograms().LD);
409  macro.Replace(_T("$lib_linker"), compiler->GetPrograms().LIB);
410  macro.Replace(_T("$rescomp"), compiler->GetPrograms().WINDRES);
411  macro.Replace(_T("$options"), cFlags);
412  macro.Replace(_T("$res_options"), m_RCFlags[target]);
413  macro.Replace(_T("$link_options"), m_LDFlags[target]);
414  macro.Replace(_T("$includes"), tmpIncludes);
415  macro.Replace(_T("$res_includes"), tmpResIncludes);
416  macro.Replace(_T("$libdirs"), m_Lib[target]);
417  macro.Replace(_T("$libs"), m_LDAdd[target]);
418  macro.Replace(_T("$file_basename"), tmpFname.GetName()); // old way - remove later
419  macro.Replace(_T("$file_name"), tmpFname.GetName());
420  macro.Replace(_T("$file_dir"), tmpFname.GetPath());
421  macro.Replace(_T("$file_ext"), tmpFname.GetExt());
422  macro.Replace(_T("$file"), tmpFile);
423  macro.Replace(_T("$dep_object"), tmpDeps);
424 
425 #ifdef command_line_generation
426  Manager::Get()->GetLogManager()->DebugLog(F(_T("GenerateCommandLine[5]: macro='%s'."), macro.wx_str()));
427 #endif
428 
429  if (target)
430  { // this one has to come before $object, otherwise $object would go first
431  // leaving nothing to replace for this $objects_output_dir,
432  // and after $options because $objects_output_dir may be in compiler flags ($options).
433  tmp = target->GetObjectOutput();
434  FixPathSeparators(compiler, tmp);
435  macro.Replace(_T("$objects_output_dir"), tmp);
436  }
437  macro.Replace(_T("$object"), tmpObject);
438  macro.Replace(_T("$resource_output"), tmpObject);
439  if (!target)
440  {
441  // single file compilation, probably
442  wxFileName fname( UnquoteStringIfNeeded(object) );
444  wxString output = fname.GetFullPath();
445  QuoteStringIfNeeded(output);
446  FixPathSeparators(compiler, output);
447  macro.Replace(_T("$exe_output"), output);
448  tmpOutFname.Assign(output);
449  }
450  else
451  {
452  macro.Replace(_T("$exe_output"), m_Output[target]);
453  tmpOutFname.Assign(m_Output[target]);
454  }
455  macro.Replace(_T("$exe_name"), tmpOutFname.GetName());
456  macro.Replace(_T("$exe_dir"), tmpOutFname.GetPath());
457  macro.Replace(_T("$exe_ext"), tmpOutFname.GetExt());
458 
459  macro.Replace(_T("$link_resobjects"), tmpDeps);
460  macro.Replace(_T("$link_objects"), tmpObject);
461  macro.Replace(_T("$link_flat_objects"), tmpFlatObject);
462  // the following were added to support the QUICK HACK in compiler plugin:
463  // DirectCommands::GetTargetLinkCommands()
464  macro.Replace(_T("$+link_objects"), tmpObject);
465  macro.Replace(_T("$-link_objects"), tmpObject);
466  macro.Replace(_T("$-+link_objects"), tmpObject);
467  macro.Replace(_T("$+-link_objects"), tmpObject);
468  macro.Replace(_T("$all_link_objects_quoted"), allObjectsQuoted);
469 
470 #ifdef command_line_generation
471  Manager::Get()->GetLogManager()->DebugLog(F(_T("GenerateCommandLine[6]: macro='%s', file='%s', object='%s', flat_object='%s', deps='%s'."),
472  macro.wx_str(), file.wx_str(), object.wx_str(), flat_object.wx_str(), deps.wx_str()));
473 
474  Manager::Get()->GetLogManager()->DebugLog(F(_T("GenerateCommandLine[7]: m_Output[target]='%s, m_StaticOutput[target]='%s', m_DefOutput[target]='%s'."),
475  m_Output[target].wx_str(), m_StaticOutput[target].wx_str(), m_DefOutput[target].wx_str()));
476 #endif
477 
478  if ( target
479  && ( (target->GetTargetType() == ttStaticLib)
480  || (target->GetTargetType() == ttDynamicLib) ) )
481  {
482  if ( (target->GetTargetType() == ttStaticLib)
483  || (target->GetCreateStaticLib()) )
484  macro.Replace(_T("$static_output"), m_StaticOutput[target]);
485  else
486  {
487  macro.Replace(_T("-Wl,--out-implib=$static_output"), _T("")); // special gcc case
488  macro.Replace(_T("$static_output"), _T(""));
489  }
490 
491  if (target->GetCreateDefFile())
492  macro.Replace(_T("$def_output"), m_DefOutput[target]);
493  else
494  {
495  macro.Replace(_T("-Wl,--output-def=$def_output"), _T("")); // special gcc case
496  macro.Replace(_T("$def_output"), _T(""));
497  }
498  }
499 
500 #ifdef command_line_generation
501  Manager::Get()->GetLogManager()->DebugLog(F(_T("GenerateCommandLine[8]: macro='%s', file='%s', object='%s', flat_object='%s', deps='%s'."),
502  macro.wx_str(), file.wx_str(), object.wx_str(), flat_object.wx_str(), deps.wx_str()));
503 #endif
504 
505  // finally, replace all macros in one go
506  Manager::Get()->GetMacrosManager()->ReplaceMacros(macro, target);
507 
508 #ifdef command_line_generation
509  Manager::Get()->GetLogManager()->DebugLog(F(_T("GenerateCommandLine[9]: macro='%s'."), macro.wx_str()));
510 #endif
511 }
512 
515 {
516  ProjectBuildTarget* bt = dynamic_cast<ProjectBuildTarget*>(target);
517  static const wxString clearout_buildscripts = _T("SetBuildOptions <- null;");
518  const wxArrayString& scripts = target->GetBuildScripts();
519  for (size_t i = 0; i < scripts.GetCount(); ++i)
520  {
521  wxString script_nomacro = scripts[i];
522  Manager::Get()->GetMacrosManager()->ReplaceMacros(script_nomacro, bt);
523  script_nomacro = wxFileName(script_nomacro).IsAbsolute() ? script_nomacro : project->GetBasePath() + wxFILE_SEP_PATH + script_nomacro;
524 
525  // if the script has failed before, skip it
526  if (m_NotLoadedScripts.Index(script_nomacro) != wxNOT_FOUND ||
527  m_ScriptsWithErrors.Index(script_nomacro) != wxNOT_FOUND)
528  {
529  continue;
530  }
531 
532  // clear previous script's context
533  Manager::Get()->GetScriptingManager()->LoadBuffer(clearout_buildscripts);
534 
535  // if the script doesn't exist, just return
536  if (!Manager::Get()->GetScriptingManager()->LoadScript(script_nomacro))
537  {
538  m_NotLoadedScripts.Add(script_nomacro);
539  continue;
540  }
541 
542  try
543  {
544  SqPlus::SquirrelFunction<void> f(cbU2C(funcName));
545  f(target);
546  }
547  catch (SquirrelError& e)
548  {
550  m_ScriptsWithErrors.Add(script_nomacro);
551  }
552  }
553 }
554 
556 {
557  // replace path separators with forward slashes if needed by this compiler
558  if (!compiler || !compiler->GetSwitches().forceFwdSlashes)
559  return;
560 
561  size_t i = 0;
562  while (i < inAndOut.Length())
563  {
564  if (inAndOut.GetChar(i) == _T('\\') &&
565  (i == inAndOut.Length() - 1 || inAndOut.GetChar(i + 1) != _T(' ')))
566  {
567  inAndOut.SetChar(i, _T('/'));
568  }
569  ++i;
570  }
571 }
572 
575 {
576  if (!target)
577  return wxEmptyString;
578 
579  // exe file
580  wxString result = target->GetOutputFilename();
581  QuoteStringIfNeeded(result);
582  FixPathSeparators(compiler, result);
583  m_Output[target] = result;
584 
585 #ifdef command_line_generation
586  Manager::Get()->GetLogManager()->DebugLog(F(_T("SetupOutputFilenames[0]: m_Output[target]='%s'."), m_Output[target].wx_str()));
587 #endif
588 
589  // static/import library name
590  switch (target->GetTargetType())
591  {
592  case ttDynamicLib:
593  {
594  TargetFilenameGenerationPolicy PrefixPolicy;
595  TargetFilenameGenerationPolicy ExtensionPolicy;
596  target->GetTargetFilenameGenerationPolicy(PrefixPolicy, ExtensionPolicy);
597 
598  wxString importLibraryFileNameString(target->GetDynamicLibImportFilename());
599  Manager::Get()->GetMacrosManager()->ReplaceMacros(importLibraryFileNameString, target);
600  wxFileName importLibraryFileName( UnquoteStringIfNeeded(importLibraryFileNameString) );
601 
602  // apply prefix if needed
603  if ( (PrefixPolicy == tgfpPlatformDefault)
604  && !importLibraryFileName.GetName().StartsWith(compiler->GetSwitches().libPrefix) )
605  importLibraryFileName.SetName(compiler->GetSwitches().libPrefix + importLibraryFileName.GetName());
606 
607  // apply extension if needed
608  if (ExtensionPolicy == tgfpPlatformDefault)
609  {
610  wxString current_ext = importLibraryFileName.GetExt();
611  wxString requested_ext = compiler->GetSwitches().libExtension;
612 
613  if (!current_ext.IsSameAs(requested_ext, false))
614  importLibraryFileName.SetFullName(importLibraryFileName.GetFullName() + wxFILE_SEP_EXT + requested_ext);
615  }
616  result = UnixFilename(importLibraryFileName.GetFullPath());
617  QuoteStringIfNeeded(result);
618  FixPathSeparators(compiler, result);
619  m_StaticOutput[target] = result;
620 
621 #ifdef command_line_generation
622  Manager::Get()->GetLogManager()->DebugLog(F(_T("SetupOutputFilenames[1]: m_StaticOutput[target]='%s'."), m_StaticOutput[target].wx_str()));
623 #endif
624 
625  wxString definitionFileFileNameString(target->GetDynamicLibDefFilename());
626  Manager::Get()->GetMacrosManager()->ReplaceMacros(definitionFileFileNameString, target);
627  wxFileName definitionFileFileName( UnquoteStringIfNeeded(definitionFileFileNameString) );
628 
629  // apply prefix if needed
630  if ( (PrefixPolicy == tgfpPlatformDefault)
631  && !definitionFileFileName.GetName().StartsWith(compiler->GetSwitches().libPrefix) )
632  definitionFileFileName.SetName(compiler->GetSwitches().libPrefix + definitionFileFileName.GetName());
633 
634  // apply extension if needed
635  if (ExtensionPolicy == tgfpPlatformDefault)
636  {
637  wxString current_ext = definitionFileFileName.GetExt();
638  wxString requested_ext = _T("def");
639 
640  if (!current_ext.IsSameAs(requested_ext, false))
641  definitionFileFileName.SetFullName(definitionFileFileName.GetFullName() + wxFILE_SEP_EXT + requested_ext);
642  }
643  result = UnixFilename(definitionFileFileName.GetFullPath());
644  QuoteStringIfNeeded(result);
645  FixPathSeparators(compiler, result);
646 
647 #ifdef command_line_generation
648  Manager::Get()->GetLogManager()->DebugLog(F(_T("SetupOutputFilenames[2]: result='%s'."), result.wx_str()));
649 #endif
650  }
651  break;
652 
653  case ttExecutable:
654  case ttConsoleOnly:
655  case ttStaticLib:
656  case ttCommandsOnly:
657  case ttNative:
658  default:
659  {
660  // Replace Variables FIRST to address the $(VARIABLE)libfoo.a problem
661  // if $(VARIABLE) expands to /bar/ then wxFileName will still consider $(VARIABLE)libfoo.a a filename,
662  // not a fully qualified path, so we will prepend lib to /bar/libfoo.a incorrectly
663  // NOTE (thomas#1#): A better solution might be to use a regex, but finding an universal regex might not be easy...
664  wxString fnameString(target->GetOutputFilename());
665  Manager::Get()->GetMacrosManager()->ReplaceMacros(fnameString, target);
666  wxFileName fname( UnquoteStringIfNeeded(fnameString) );
667 
668  TargetFilenameGenerationPolicy PrefixPolicy;
669  TargetFilenameGenerationPolicy ExtensionPolicy;
670  target->GetTargetFilenameGenerationPolicy(PrefixPolicy, ExtensionPolicy);
671  if ( (PrefixPolicy == tgfpPlatformDefault)
672  || (target->GetTargetType() == ttDynamicLib) )
673  {
674  if (!fname.GetName().StartsWith(compiler->GetSwitches().libPrefix))
675  fname.SetName(compiler->GetSwitches().libPrefix + fname.GetName());
676  }
677  if ( (ExtensionPolicy == tgfpPlatformDefault)
678  || (target->GetTargetType() == ttDynamicLib) )
679  {
680  wxString current_ext = fname.GetExt();
681  wxString requested_ext = compiler->GetSwitches().libExtension;
682  if ( (platform::windows && !current_ext.IsSameAs(requested_ext, false))
683  || (!current_ext.IsSameAs(requested_ext)) )
684  {
685  // Note: Do not use SetExt here to handle libs like e.g. System.Core correctly.
686  // Otherwise SetExt would result in System.dll instead of System.Core.dll
687  fname.SetFullName(fname.GetFullName() + wxFILE_SEP_EXT + requested_ext);
688  }
689  }
690  result = UnixFilename(fname.GetFullPath());
691  QuoteStringIfNeeded(result);
692  FixPathSeparators(compiler, result);
693  m_StaticOutput[target] = result;
694 
695 #ifdef command_line_generation
696  Manager::Get()->GetLogManager()->DebugLog(F(_T("SetupOutputFilenames[3]: m_StaticOutput[target]='%s'."), m_StaticOutput[target].wx_str()));
697 #endif
698 
699  // def
700  fname.SetExt(_T("def"));
701  result = UnixFilename(fname.GetFullPath());
702  QuoteStringIfNeeded(result); // NOTE (thomas#1#): Do we really need to call QuoteStringIfNeeded that often? ReplaceMacros already does it, and we do it twice again without ever possibly adding whitespace
703  FixPathSeparators(compiler, result);
704 
705 #ifdef command_line_generation
706  Manager::Get()->GetLogManager()->DebugLog(F(_T("SetupOutputFilenames[4]: result='%s'."), result.wx_str()));
707 #endif
708  }
709  break;
710  }
711 
712 #ifdef command_line_generation
713  Manager::Get()->GetLogManager()->DebugLog(F(_T("SetupOutputFilenames[5]: result='%s'."), result.wx_str()));
714 #endif
715  return result;
716 }
717 
719 {
720  wxArrayString result;
721 
722  if (target)
723  {
724  // currently, we ignore compiler search dirs (despite the var's name)
725  // we only care about project/target search dirs
726  wxArrayString prjSearchDirs = target->GetParentProject()->GetIncludeDirs();
727  wxArrayString tgtSearchDirs = target->GetIncludeDirs();
728  wxArrayString searchDirs;
729  searchDirs = GetOrderedOptions(target, ortIncludeDirs, prjSearchDirs, tgtSearchDirs);
730  // replace vars
731  for (unsigned int x = 0; x < searchDirs.GetCount(); ++x)
732  Manager::Get()->GetMacrosManager()->ReplaceMacros(searchDirs[x], target);
733  // respect include dirs set by specific options (helps dependency tracking)
734  if ( Manager::Get()->GetConfigManager(_T("compiler"))->ReadBool(_T("/include_prj_cwd"), false) )
735  searchDirs.Add(target->GetParentProject()->GetBasePath());
736  if ( Manager::Get()->GetConfigManager(_T("compiler"))->ReadBool(_T("/include_file_cwd"), false) )
737  searchDirs.Add(_T("."));
738  m_CompilerSearchDirs.insert(m_CompilerSearchDirs.end(), std::make_pair(target, searchDirs));
739 
740  // decide order
741  result = GetOrderedOptions(target, ortIncludeDirs, target->GetParentProject()->GetIncludeDirs(), target->GetIncludeDirs());
742  }
743 
744  // compiler dirs
745  const wxArrayString& carr = compiler->GetIncludeDirs();
746  for (unsigned int x = 0; x < carr.GetCount(); ++x)
747  result.Add(carr[x]);
748 
749  for (unsigned int x = 0; x < result.GetCount(); ++x)
750  {
751  wxString& tmp(result[x]);
752  Manager::Get()->GetMacrosManager()->ReplaceMacros(tmp, target);
753  if (platform::windows && compiler->GetSwitches().Use83Paths)
754  {
755  wxFileName fn(UnquoteStringIfNeeded(tmp), wxEmptyString); // explicitly assign as path
756  if (fn.DirExists())
757  tmp = fn.GetShortPath();
758  }
759  FixPathSeparators(compiler, tmp);
760  if ( tmp.Trim().IsEmpty() )
761  Manager::Get()->GetLogManager()->DebugLogError(_T("Warning: Compiler include folder evaluates to empty value."));
762  }
763 
764  return result;
765 }
766 
768 {
769  wxArrayString result;
770 
771  if (target)
772  {
773  // currently, we ignore compiler search dirs (despite the var's name)
774  // we only care about project/target search dirs
775  wxArrayString prjSearchDirs = target->GetParentProject()->GetLibDirs();
776  wxArrayString tgtSearchDirs = target->GetLibDirs();
777  wxArrayString searchDirs;
778  searchDirs = GetOrderedOptions(target, ortLibDirs, prjSearchDirs, tgtSearchDirs);
779  // replace vars
780  for (unsigned int x = 0; x < searchDirs.GetCount(); ++x)
781  {
782  Manager::Get()->GetMacrosManager()->ReplaceMacros(searchDirs[x], target);
783 
784  // also, normalize path (make absolute)
785  wxFileName fn( UnquoteStringIfNeeded(searchDirs[x]) );
786  if (fn.IsRelative())
787  {
788  fn.MakeAbsolute(target->GetParentProject()->GetBasePath());
789  searchDirs[x] = fn.GetFullPath();
790  }
791  }
792  m_LinkerSearchDirs.insert(m_LinkerSearchDirs.end(), std::make_pair(target, searchDirs));
793 
794  // decide order
795  result = GetOrderedOptions(target, ortLibDirs, target->GetParentProject()->GetLibDirs(), target->GetLibDirs());
796  }
797  // compiler dirs
798  const wxArrayString& carr = compiler->GetLibDirs();
799  for (unsigned int x = 0; x < carr.GetCount(); ++x)
800  result.Add(carr[x]);
801 
802  for (unsigned int x = 0; x < result.GetCount(); ++x)
803  {
804  wxString& tmp(result[x]);
805  Manager::Get()->GetMacrosManager()->ReplaceMacros(tmp, target);
806  if (platform::windows && compiler->GetSwitches().Use83Paths)
807  {
808  wxFileName fn(UnquoteStringIfNeeded(tmp), wxEmptyString); // explicitly assign as path
809  if (fn.DirExists())
810  tmp = fn.GetShortPath();
811  }
812  FixPathSeparators(compiler, tmp);
813  if ( tmp.Trim().IsEmpty() )
814  Manager::Get()->GetLogManager()->DebugLogError(_T("Warning: Linker include folder evaluates to empty value."));
815  }
816 
817  return result;
818 }
819 
821 {
822  wxArrayString result;
823 
824  if (target) // decide order
826 
827  // compiler dirs
828  const wxArrayString& carr = compiler->GetResourceIncludeDirs();
829  for (unsigned int x = 0; x < carr.GetCount(); ++x)
830  result.Add(carr[x]);
831 
832  for (unsigned int x = 0; x < result.GetCount(); ++x)
833  {
834  wxString& tmp(result[x]);
835  Manager::Get()->GetMacrosManager()->ReplaceMacros(tmp, target);
836  if (platform::windows && compiler->GetSwitches().Use83Paths)
837  {
838  wxFileName fn(UnquoteStringIfNeeded(tmp), wxEmptyString); // explicitly assign as path
839  if (fn.DirExists())
840  tmp = fn.GetShortPath();
841  }
842  FixPathSeparators(compiler, tmp);
843  if ( tmp.Trim().IsEmpty() )
844  Manager::Get()->GetLogManager()->DebugLogError(_T("Warning: Resource compiler include folder evaluates to empty value."));
845  }
846 
847  return result;
848 }
849 
851 {
852  wxString result;
853  bool subseq(false);
854 
855  if (opt.EndsWith(_T("(")))
856  {
857  // special handling for "INCDIR(path1;path2)" style includes
858  result << opt;
859  for (unsigned int x = 0; x < arr.GetCount(); ++x)
860  {
861  if (subseq)
862  result << separator;
863  subseq = true;
864  wxString tmp(arr[x]);
865  QuoteStringIfNeeded(tmp);
866  result << tmp;
867  }
868  result << _T(')');
869  return result;
870  }
871  for (unsigned int x = 0; x < arr.GetCount(); ++x)
872  {
873  if (subseq)
874  result << separator;
875  subseq = true;
876  wxString tmp(arr[x]);
877  QuoteStringIfNeeded(tmp);
878  result << opt << tmp;
879  }
880  return result;
881 }
882 
884 {
885  Manager::Get()->GetLogManager()->Log(_T("PathSearch: ") + filename);
886  if (wxFileExists(filename))
887  return filename;
888  for (unsigned int x = 0; x < arr.GetCount(); ++x)
889  {
890  wxString fn(arr[x] + wxFILE_SEP_PATH + filename);
891  Manager::Get()->GetLogManager()->Log(_T("PathSearch: trying: ") + fn);
892  if (wxFileExists(fn))
893  return fn;
894  }
895  Manager::Get()->GetLogManager()->Log(_T("PathSearch: end: ") + filename);
896  return filename;
897 }
898 
901 {
902  return MakeOptString(GetOrderedIncludeDirs(compiler, target),
903  compiler->GetSwitches().includeDirs,
904  compiler->GetSwitches().includeDirSeparator);
905 }
906 
909 {
910  if (compiler->GetSwitches().linkerNeedsPathResolved)
911  return wxString();
912  return MakeOptString(GetOrderedLibrariesDirs(compiler, target),
913  compiler->GetSwitches().libDirs,
914  compiler->GetSwitches().libDirSeparator);
915 }
916 
919 {
920  return MakeOptString(GetOrderedResourceIncludeDirs(compiler, target),
921  compiler->GetSwitches().includeDirs,
922  compiler->GetSwitches().includeDirSeparator);
923 }
924 
927 {
928  wxString result;
929 
930  if (target)
931  {
932  // target options
933  wxString tstr = GetStringFromArray(target->GetCompilerOptions(), _T(' ')) << _T(" ");
934 
935  // project options
936  wxString pstr = GetStringFromArray(target->GetParentProject()->GetCompilerOptions(), _T(' ')) << _T(" ");
937 
938  // decide order
939  result = GetOrderedOptions(target, ortCompilerOptions, pstr, tstr);
940  }
941 
942  // compiler options
943  result << GetStringFromArray(compiler->GetCompilerOptions(), _T(' ')) << _T(" ");
944 
945  Manager::Get()->GetMacrosManager()->ReplaceMacros(result, target);
946 
947  wxString bt = ExpandBackticks(result);
948  SearchDirsFromBackticks(compiler, target, bt);
949 
950  // add in array
951  return result;
952 }
953 
956 {
957  wxString result;
958 
959  if (target)
960  {
961  // target options
962  wxString tstr = GetStringFromArray(target->GetLinkerOptions(), _T(' '));
963 
964  // project options
966 
967  // decide order
968  result = GetOrderedOptions(target, ortLinkerOptions, pstr, tstr);
969  }
970 
971  // linker options
972  result << GetStringFromArray(compiler->GetLinkerOptions(), _T(' '));
973 
974  Manager::Get()->GetMacrosManager()->ReplaceMacros(result, target);
975 
976  wxString bt = ExpandBackticks(result);
977  SearchDirsFromBackticks(compiler, target, bt);
978 
979  // add in array
980  return result;
981 }
982 
985 {
986  if (lib.IsEmpty())
987  return wxEmptyString;
988 
989  wxString result = lib;
990 
991  // construct linker option for each result, based on compiler's settings
992  wxString libPrefix = compiler->GetSwitches().libPrefix;
993  wxString libExt = compiler->GetSwitches().libExtension;
994  QuoteStringIfNeeded(result);
995  FixPathSeparators(compiler, result);
996  // run replacements on libs only if no slashes in name (which means it's a relative or absolute path)
997  if (result.Find('/') == -1 && result.Find('\\') == -1)
998  {
999  // 'result' prefix
1000  bool hadLibPrefix = false;
1001  if (!compiler->GetSwitches().linkerNeedsLibPrefix &&
1002  !libPrefix.IsEmpty() &&
1003  result.StartsWith(libPrefix))
1004  {
1005  result.Remove(0, libPrefix.Length());
1006  hadLibPrefix = true;
1007  }
1008  // extension
1009  if (!compiler->GetSwitches().linkerNeedsLibExtension &&
1010  result.Length() > libExt.Length() &&
1011  result.Right(libExt.Length() + 1) == _T(".") + libExt)
1012  {
1013  // remove the extension only if we had a result prefix
1014  if (hadLibPrefix)
1015  result.RemoveLast(libExt.Length() + 1);
1016  }
1017  else if (compiler->GetSwitches().linkerNeedsLibExtension &&
1018  !libExt.IsEmpty())
1019  {
1020  if (result.Length() <= libExt.Length() ||
1021  result.Right(libExt.Length() + 1) != _T(".") + libExt)
1022  {
1023  result << _T(".") << libExt;
1024  }
1025  }
1026  result = compiler->GetSwitches().linkLibs + result;
1027  }
1028  return result;
1029 }
1030 
1033 {
1034  wxArrayString libs;
1035 
1036  if (target) // decide order
1037  libs = GetOrderedOptions(target, ortLinkerOptions, target->GetParentProject()->GetLinkLibs(), target->GetLinkLibs());
1038 
1039  // compiler link libraries
1040  const wxArrayString& carr = compiler->GetLinkLibs();
1041  for (unsigned int x = 0; x < carr.GetCount(); ++x)
1042  libs.Add(carr[x]);
1043 
1044  for (unsigned int x = 0; x < libs.GetCount(); ++x)
1045  libs[x] = FixupLinkLibraries(compiler, libs[x]);
1046 
1047  if (compiler->GetSwitches().linkerNeedsPathResolved)
1048  {
1049  wxArrayString path(GetOrderedLibrariesDirs(compiler, target));
1050  for (unsigned int x = 0; x < libs.GetCount(); ++x)
1051  {
1052  libs[x] = PathSearch(path, libs[x]);
1053  }
1054  }
1055  wxString result;
1056  bool subseq(false);
1057  for (unsigned int x = 0; x < libs.GetCount(); ++x)
1058  {
1059  if (subseq)
1060  result << compiler->GetSwitches().objectSeparator;
1061  subseq = true;
1062  wxString tmp(libs[x]);
1063  QuoteStringIfNeeded(tmp);
1064  result << tmp;
1065  }
1066  return result;
1067 } // end of SetupLinkLibraries
1068 
1071 {
1072  wxString result;
1073 
1074  if (target)
1075  {
1076  // target options
1077  wxString tstr = GetStringFromArray(target->GetResourceCompilerOptions(), _T(' '));
1078 
1079  // project options
1080  wxString pstr = GetStringFromArray(target->GetParentProject()->GetResourceCompilerOptions(), _T(' '));
1081 
1082  // decide order
1083  result = GetOrderedOptions(target, ortCompilerOptions, pstr, tstr);
1084  }
1085 
1086  // resource compiler options
1087  result << GetStringFromArray(compiler->GetResourceCompilerOptions(), _T(' '));
1088 
1089  Manager::Get()->GetMacrosManager()->ReplaceMacros(result, target);
1090 
1091  wxString bt = ExpandBackticks(result);
1092  SearchDirsFromBackticks(compiler, target, bt);
1093 
1094  // add in array
1095  return result;
1096 }
1097 
1099 {
1100  static wxArrayString retIfError;
1101  retIfError.Clear();
1102 
1103  SearchDirsMap::iterator it = m_CompilerSearchDirs.find(target);
1104  if (it == m_CompilerSearchDirs.end())
1105  return retIfError;
1106 
1107  return it->second;
1108 }
1109 
1111 {
1112  static wxArrayString retIfError;
1113  retIfError.Clear();
1114 
1115  SearchDirsMap::iterator it = m_LinkerSearchDirs.find(target);
1116  if (it == m_LinkerSearchDirs.end())
1117  return retIfError;
1118 
1119  return it->second;
1120 }
1121 
1126 wxString CompilerCommandGenerator::GetOrderedOptions(const ProjectBuildTarget* target, OptionsRelationType rel, const wxString& project_options, const wxString& target_options)
1127 {
1128  wxString result;
1129  OptionsRelation relation = target->GetOptionRelation(rel);
1130  switch (relation)
1131  {
1133  result << project_options;
1134  break;
1136  result << target_options;
1137  break;
1139  result << target_options << project_options;
1140  break;
1142  result << project_options << target_options;
1143  break;
1144  default:
1145  break;
1146  }
1147  return result;
1148 }
1149 
1155 {
1156  wxArrayString result;
1157  OptionsRelation relation = target->GetOptionRelation(rel);
1158  switch (relation)
1159  {
1161  for (size_t i = 0; i < project_options.GetCount(); ++i)
1162  result.Add(project_options[i]);
1163  break;
1165  for (size_t i = 0; i < target_options.GetCount(); ++i)
1166  result.Add(target_options[i]);
1167  break;
1169  for (size_t i = 0; i < target_options.GetCount(); ++i)
1170  result.Add(target_options[i]);
1171  for (size_t i = 0; i < project_options.GetCount(); ++i)
1172  result.Add(project_options[i]);
1173  break;
1175  for (size_t i = 0; i < project_options.GetCount(); ++i)
1176  result.Add(project_options[i]);
1177  for (size_t i = 0; i < target_options.GetCount(); ++i)
1178  result.Add(target_options[i]);
1179  break;
1180  default:
1181  break;
1182  }
1183  return result;
1184 }
1185 
1188  const wxArrayString& inc_dirs, const wxString& inc_switch)
1189 {
1190  wxString inc_string;
1191  for (size_t x = 0; x < inc_dirs.GetCount(); ++x)
1192  {
1193  wxString inc_dir = inc_dirs[x];
1194  Manager::Get()->GetMacrosManager()->ReplaceMacros(inc_dir, target);
1195  // probably change to 8.3 notation (on Windows)
1196  if (platform::windows && compiler->GetSwitches().Use83Paths)
1197  {
1198  wxFileName fn(UnquoteStringIfNeeded(inc_dir), wxEmptyString); // explicitly assign as path
1199  if (fn.DirExists())
1200  inc_dir = fn.GetShortPath();
1201  }
1202  QuoteStringIfNeeded(inc_dir);
1203  FixPathSeparators(compiler, inc_dir);
1204  inc_string << inc_switch << inc_dir << _T(' ');
1205  }
1206  return inc_string;
1207 }
1208 
1209 
1210 
1211 // parse the result of a backticked expression for compiler/linker search dirs
1213 {
1214  if (btOutput.IsEmpty())
1215  return;
1216 
1217  // NOTE: this ignores spaces in search dirs
1218  // but usually backticks are only used under non-windows platforms by
1219  // large libs and they never use spaces in paths.
1220  // so, nobody should notice this :)
1221 
1222  // compiler search dirs
1223  size_t pos = 0;
1224  while (true)
1225  {
1226  pos = btOutput.find(compiler->GetSwitches().includeDirs, pos);
1227  if (pos == wxString::npos)
1228  break;
1229 
1230  pos += compiler->GetSwitches().includeDirs.Length();
1231  size_t pos2 = btOutput.find(_T(' '), pos);
1232  if (pos2 != pos)
1233  {
1234  if (pos2 == wxString::npos) // whole remaining string
1235  m_CompilerSearchDirs[target].Add(btOutput.Mid(pos, btOutput.Length() - pos));
1236  else
1237  m_CompilerSearchDirs[target].Add(btOutput.Mid(pos, pos2 - pos));
1238  }
1239  ++pos;
1240  }
1241 
1242  // linker search dirs
1243  pos = 0;
1244  while (true)
1245  {
1246  pos = btOutput.find(compiler->GetSwitches().libDirs, pos);
1247  if (pos == wxString::npos)
1248  break;
1249 
1250  pos += compiler->GetSwitches().libDirs.Length();
1251  size_t pos2 = btOutput.find(_T(' '), pos);
1252  if (pos2 != pos)
1253  {
1254  // note that backtick'd expressions always return full paths so no need to
1255  // re-normalize it here
1256  if (pos2 == wxString::npos) // whole remaining string
1257  m_LinkerSearchDirs[target].Add(btOutput.Mid(pos, btOutput.Length() - pos));
1258  else
1259  m_LinkerSearchDirs[target].Add(btOutput.Mid(pos, pos2 - pos));
1260  }
1261  ++pos;
1262  }
1263 }
bool linkerNeedsLibExtension
Definition: compiler.h:226
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 GetTargetFilenameGenerationPolicy(TargetFilenameGenerationPolicy &prefixOut, TargetFilenameGenerationPolicy &extensionOut) const
bool Matches(const wxString &mask) const
virtual wxArrayString GetOrderedResourceIncludeDirs(Compiler *compiler, ProjectBuildTarget *target)
TargetFilenameGenerationPolicy
A target&#39;s filename can either be auto-generated based on the running platform, or completely specifi...
wxString UnquoteStringIfNeeded(const wxString &str)
OptionsMap m_DefOutput
def output filenames, per-target
void Assign(const wxFileName &filepath)
void SetFullName(const wxString &fullname)
ConfigManager * GetConfigManager(const wxString &name_space) const
Definition: manager.cpp:474
void DebugLogError(const wxString &msg)
Definition: logmanager.h:147
OptionsMap m_Inc
compiler &#39;include&#39; dirs, per-target
virtual bool SupportsCurrentPlatform() const
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
void SetBuildTargetName(const wxString &target)
Definition: sdk_events.h:60
virtual void FixPathSeparators(Compiler *compiler, wxString &inAndOut)
wxString libDirs
Definition: compiler.h:213
SearchDirsMap m_LinkerSearchDirs
array of final linker search dirs, per-target
Linker include dir option.
wxString WINDRES
Definition: compiler.h:203
virtual wxString SetupLinkLibraries(Compiler *compiler, ProjectBuildTarget *target)
Setup link libraries for build target.
wxString Lower() const
The option uses parent options only.
#define wxICON_ERROR
The option uses target options appended to parent options.
bool wxFileExists(const wxString &filename)
static Compiler * GetDefaultCompiler()
wxString GetShortPath() const
virtual wxString FixupLinkLibraries(Compiler *compiler, const wxString &lib)
Fix library name based on advanced compiler settings.
bool ReadBool(const wxString &name, bool defaultVal=false)
int Index(const wxString &sz, bool bCase=true, bool bFromEnd=false) const
void SetModified(bool modified=true) override
Mark the project as modified or not.
Definition: cbproject.cpp:179
virtual wxString SetupLibrariesDirs(Compiler *compiler, ProjectBuildTarget *target)
Setup linker include dirs for build target.
void LogToStdOut(const wxString &msg, Logger::level lv=Logger::info)
Definition: logmanager.h:149
Target produces an executable.
size_t Length() const
wxString CPP
Definition: compiler.h:200
virtual const wxArrayString & GetCompilerOptions() const
virtual const wxArrayString & GetCompilerSearchDirs(ProjectBuildTarget *target)
Get the full include dirs used in the actual command line.
static Compiler * GetCompiler(size_t index)
Generate filename based on running platform defaults.
#define _T(string)
OptionsMap m_RC
resource compiler &#39;include&#39; dirs, per-target
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
wxString GetProcessedIncludeDir(Compiler *compiler, ProjectBuildTarget *target, const wxArrayString &inc_dirs, const wxString &inc_switch)
Processes include dirs by default.
virtual wxArrayString GetOrderedLibrariesDirs(Compiler *compiler, ProjectBuildTarget *target)
const wxString & GetCPPOnlyFlags()
Definition: compiler.h:376
wxString & Remove(size_t pos)
wxString GetName() const
virtual wxString SetupOutputFilenames(Compiler *compiler, ProjectBuildTarget *target)
Setup output filename for build target.
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.
virtual wxString GetOrderedOptions(const ProjectBuildTarget *target, OptionsRelationType rel, const wxString &project_options, const wxString &target_options)
Arrange order of options.
#define wxT(string)
OptionsMap m_Lib
linker &#39;include&#39; dirs, per-target
virtual const wxArrayString & GetBuildScripts() const
#define wxNOT_FOUND
wxString m_PrjIncPath
directive to add the project&#39;s top-level path in compiler search dirs (ready for the command line) ...
EVTIMPORT const wxEventType cbEVT_COMPILER_SET_BUILD_OPTIONS
Definition: sdk_events.cpp:150
Represents a file in a Code::Blocks project.
Definition: projectfile.h:39
size_t find(const wxString &str, size_t nStart=0) const
A generic Code::Blocks event.
Definition: sdk_events.h:20
virtual wxString GetOutputFilename()
Read the target&#39;s output filename.
virtual cbProject * GetParentProject()
wxString LD
Definition: compiler.h:201
bool forceFwdSlashes
Definition: compiler.h:218
virtual wxArrayString GetOrderedIncludeDirs(Compiler *compiler, ProjectBuildTarget *target)
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 Init(cbProject *project)
Initialize for use with the specified project.
wxUSE_UNICODE_dependent wxChar
bool Contains(const wxString &str) const
virtual OptionsRelation GetOptionRelation(OptionsRelationType type) const
Read the target&#39;s options relation for type.
DLLIMPORT wxString UnixFilename(const wxString &filename, wxPathFormat format=wxPATH_NATIVE)
Definition: globals.cpp:228
wxString GetExt() const
virtual const wxArrayString & GetResourceIncludeDirs() const
Represents a Code::Blocks project.
Definition: cbproject.h:96
virtual const wxArrayString & GetLinkerOptions() const
const wxString & GetCOnlyFlags()
Definition: compiler.h:375
bool wxSetWorkingDirectory(const wxString &dir)
wxString & RemoveLast(size_t n=1)
virtual const wxArrayString & GetLinkLibs() const
virtual wxString GetDynamicLibImportFilename()
Read the target&#39;s dynamic library import filename (produced if target type is ttDynamicLib) ...
virtual const wxString & GetTitle() const
Read the target&#39;s title.
Resource compiler include dir option.
Target produces a dynamic library.
size_t Replace(const wxString &strOld, const wxString &strNew, bool replaceAll=true)
OptionsRelation
Option&#39;s relation.
The option uses parent options appended to target options.
wxChar includeDirSeparator
Definition: compiler.h:240
bool IsSameAs(const wxString &s, bool caseSensitive=true) const
static bool IsBatchBuild()
Definition: manager.h:66
virtual const CompilerPrograms & GetPrograms() const
Get the compiler&#39;s programs.
Definition: compiler.h:299
Target produces a native binary.
LogManager * GetLogManager() const
Definition: manager.cpp:439
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
wxString linkLibs
Definition: compiler.h:214
OptionsMap m_LDAdd
link libraries, per-target
Compiler include dir option.
void DisplayErrors(SquirrelError *exception=nullptr, bool clearErrors=true)
Display error dialog.
void SetChar(size_t n, wxUniChar ch)
OptionsMap m_CFlags
compiler flags, per-target
const wxStringCharType * wx_str() const
wxString includeDirs
Definition: compiler.h:212
wxString wxEmptyString
virtual wxString SetupResourceIncludeDirs(Compiler *compiler, ProjectBuildTarget *target)
Setup resource compiler include dirs for build target.
wxString Right(size_t count) const
MacrosManager * GetMacrosManager() const
Definition: manager.cpp:454
const wxString & _(const wxString &string)
virtual wxString SetupLinkerOptions(Compiler *compiler, ProjectBuildTarget *target)
Setup linker flags for build target.
DLLIMPORT void QuoteStringIfNeeded(wxString &str)
Definition: globals.cpp:260
wxString & Trim(bool fromRight=true)
void ReplaceMacros(wxString &buffer, ProjectBuildTarget *target=nullptr, bool subrequest=false)
virtual wxString SetupIncludeDirs(Compiler *compiler, ProjectBuildTarget *target)
Setup compiler include dirs for build target.
int GetBuildTargetsCount()
Definition: cbproject.h:200
#define cbThrow(message)
Definition: cbexception.h:42
virtual const wxArrayString & GetIncludeDirs() const
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
Abstract base class for compilers.
Definition: compiler.h:274
virtual const wxArrayString & GetLinkerSearchDirs(ProjectBuildTarget *target)
Get the full linker dirs used in the actual command line.
wxString libPrefix
Definition: compiler.h:223
bool IsEmpty() const
virtual const wxArrayString & GetLibDirs() const
void Clear()
wxString GetPath(int flags=wxPATH_GET_VOLUME, wxPathFormat format=wxPATH_NATIVE) const
virtual const wxString & GetCompilerID() const
Read the target&#39;s compiler.
static const size_t npos
Target produces a console executable (without GUI) (distinction between ttExecutable and ttConsoleOnl...
bool IsRelative(wxPathFormat format=wxPATH_NATIVE) const
wxString C
Definition: compiler.h:199
void Log(const wxString &msg, int i=app_log, Logger::level lv=Logger::info)
Definition: logmanager.h:140
wxString GetFullName() const
SearchDirsMap m_CompilerSearchDirs
array of final compiler search dirs, per-target
static wxString PathSearch(const wxArrayString &arr, const wxString &filename)
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 ProcessEvent(CodeBlocksEvent &event)
Definition: manager.cpp:246
bool EndsWith(const wxString &suffix, wxString *rest=NULL) const
OptionsMap m_RCFlags
resource compiler flags, per-target
wxString GetCommonTopLevelPath() const
Definition: cbproject.cpp:423
bool GetModified() const override
Definition: cbproject.cpp:162
wxChar libDirSeparator
Definition: compiler.h:241
void SetExt(const wxString &ext)
size_t Add(const wxString &str, size_t copies=1)
bool StartsWith(const wxString &prefix, wxString *rest=NULL) const
OptionsMap m_StaticOutput
static output filenames, per-target
bool linkerNeedsLibPrefix
Definition: compiler.h:225
Represents a Code::Blocks project build target.
Linker option.
wxString LIB
Definition: compiler.h:202
size_t GetCount() const
int Find(wxUniChar ch, bool fromEnd=false) const
wxUniChar GetChar(size_t n) const
wxUniChar Last() const
OptionsMap m_LDFlags
linker flags, per-target
DLLIMPORT wxString ExpandBackticks(wxString &str)
Definition: globals.cpp:861
ScriptingManager * GetScriptingManager() const
Definition: manager.cpp:469
bool MakeAbsolute(const wxString &cwd=wxEmptyString, wxPathFormat format=wxPATH_NATIVE)
bool DirExists() const
void RemoveAt(size_t nIndex, size_t count=1)
void SearchDirsFromBackticks(Compiler *compiler, ProjectBuildTarget *target, const wxString &btOutput)
Compiler option.
void SetName(const wxString &name)
The option uses target options only.
wxString GetFullPath(wxPathFormat format=wxPATH_NATIVE) const
bool LoadBuffer(const wxString &buffer, const wxString &debugName=_T("CommandLine"))
Loads a string buffer.
static wxString MakeOptString(const wxArrayString &arr, const wxString &opt, wxChar separator=_T(' '))
virtual wxString GetDynamicLibDefFilename()
Read the target&#39;s dynamic library definition file filename (produced if target type is ttDynamicLib) ...
OptionsRelationType
Enum that defines the option&#39;s relation types.
wxString Mid(size_t first, size_t nCount=wxString::npos) const
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
virtual void DoBuildScripts(cbProject *project, CompileTargetBase *target, const wxString &funcName)
Apply pre-build scripts for base.
virtual wxString SetupResourceCompilerOptions(Compiler *compiler, ProjectBuildTarget *target)
Setup resource compiler flags for build target.
virtual wxString SetupCompilerOptions(Compiler *compiler, ProjectBuildTarget *target)
Setup compiler flags for build target.
bool linkerNeedsPathResolved
Definition: compiler.h:227
OptionsMap m_Output
output filenames, per-target
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.