NCBI C++ ToolKit
proj_tree_builder.cpp
Go to the documentation of this file.

Go to the SVN repository for this file.

1 /* $Id: proj_tree_builder.cpp 100743 2023-09-06 17:30:04Z gouriano $
2  * ===========================================================================
3  *
4  * PUBLIC DOMAIN NOTICE
5  * National Center for Biotechnology Information
6  *
7  * This software/database is a "United States Government Work" under the
8  * terms of the United States Copyright Act. It was written as part of
9  * the author's official duties as a United States Government employee and
10  * thus cannot be copyrighted. This software/database is freely available
11  * to the public for use. The National Library of Medicine and the U.S.
12  * Government have not placed any restriction on its use or reproduction.
13  *
14  * Although all reasonable efforts have been taken to ensure the accuracy
15  * and reliability of the software and data, the NLM and the U.S.
16  * Government do not and cannot warrant the performance or results that
17  * may be obtained by using this software or data. The NLM and the U.S.
18  * Government disclaim all warranties, express or implied, including
19  * warranties of performance, merchantability or fitness for any particular
20  * purpose.
21  *
22  * Please cite the author in any work or product based on this material.
23  *
24  * ===========================================================================
25  *
26  * Author: Viatcheslav Gorelenkov
27  *
28  */
29 
30 #include <ncbi_pch.hpp>
31 #include "proj_tree_builder.hpp"
32 #include "proj_builder_app.hpp"
33 #include "proj_src_resolver.hpp"
34 #include "msvc_prj_defines.hpp"
35 
36 #include "proj_projects.hpp"
37 #include <algorithm>
38 
39 #include "ptb_err_codes.hpp"
40 
42 
43 const char* s_check_separator = " ____ ";
45 static size_t s_BuildOrder=0;
46 
47 void s_WriteBuildOrder(const string& dir_name, const string& mkname)
48 {
49  string name( CDirEntry::ConcatPath(dir_name,mkname));
51 }
52 
54  const CProjItem& item, list<string> dependencies, const CProjectItemsTree& tree)
55 {
56  bool res = true;
57  if (item.m_MkName.empty()) {
58 // error?
59  return res;
60  }
61  ITERATE(list<string>, d, dependencies) {
63  tree.m_Projects.find(CreateProjKey(*d));
64  if (n != tree.m_Projects.end()) {
65  const CProjItem& dep_item = n->second;
66  if (dep_item.m_MkName.empty()) {
67  //error?
68  } else if (s_buildOrder_byname[dep_item.m_MkName] >
72  "should be built after: " << dep_item.m_MkName);
73  res = false;
74  }
75  }
76 
77  }
78  return res;
79 }
80 
81 
83 {
84  PLibExclude(const string& prj_name, const list<string>& excluded_lib_ids)
85  : m_Prj(prj_name)
86  {
87  copy(excluded_lib_ids.begin(), excluded_lib_ids.end(),
88  inserter(m_ExcludedLib, m_ExcludedLib.end()) );
89  }
90 
91  bool operator() (const string& lib_id) const
92  {
93  if (m_ExcludedLib.find(lib_id) != m_ExcludedLib.end()) {
94  PTB_WARNING_EX(kEmptyStr,ePTB_ProjectExcluded,"Project " << m_Prj << ": library excluded by request: " << lib_id);
95  return true;
96  }
97  return false;
98  }
99 
100 private:
101  string m_Prj;
103 };
104 
105 
106 //-----------------------------------------------------------------------------
108  const string& projname,
110 {
111  string fname = "Makefile." + projname;
112 
113  string fname_base = CDirEntry::ConcatPath(base_dir, fname);
114  string fname_app = CDirEntry::ConcatPath(base_dir, fname + ".app");
115  string fname_lib = CDirEntry::ConcatPath(base_dir, fname + ".lib");
116  string fname_dll = CDirEntry::ConcatPath(base_dir, fname + ".dll");
117  string fname_msvc= CDirEntry::ConcatPath(base_dir, fname);
118  string fname_msvc2(fname_msvc);
119 
122  fname_msvc += ".msvcproj";
123  } else {
124  fname_msvc2 += ".in";
125  }
126 
127  switch (type) {
128  case SMakeInInfo::eApp:
129  if ( CDirEntry(fname_app).Exists()) {
130  return CProjKey::eApp;
131  }
132  break;
133  case SMakeInInfo::eLib:
134  if ( CDirEntry(fname_lib).Exists()) {
135  return CProjKey::eLib;
136  }
137  break;
138  case SMakeInInfo::eDll:
139  if ( CDirEntry(fname_dll).Exists()) {
140  return CProjKey::eDll;
141  }
142  break;
143  case SMakeInInfo::eMsvc:
144  if ( CDirEntry(fname_msvc).Exists() || CDirEntry(fname_msvc2).Exists()) {
145  return CProjKey::eMsvc;
146  }
147  break;
148 
149  default:
150  break;
151  }
152 
153  if ( CDirEntry(fname_lib).Exists() )
154  return CProjKey::eLib;
155  else if (CDirEntry(fname_dll).Exists() )
156  return CProjKey::eDll;
157  else if (CDirEntry(fname_app).Exists() )
158  return CProjKey::eApp;
159  else if (CDirEntry(fname_msvc).Exists() || CDirEntry(fname_msvc2).Exists() )
160  return CProjKey::eMsvc;
161  else if (CDirEntry(CDirEntry::ConcatPath(base_dir, fname + ".metal")).Exists() )
162  return CProjKey::eLib;
163 
164  switch (type) {
165  case SMakeInInfo::eApp:
167  "Makefile not found");
168  break;
169 
170  case SMakeInInfo::eLib:
172  "Makefile not found");
173  break;
174 
175  case SMakeInInfo::eDll:
177  "Makefile not found");
178  break;
179 
180  case SMakeInInfo::eMsvc:
182  "Makefile not found");
183  break;
184 
185  default:
187  "Makefile not found");
188  break;
189  }
190  return CProjKey::eNoProj;
191 }
192 
193 
194 bool SMakeProjectT::IsMakeInFile(const string& name)
195 {
196  return name == "Makefile.in";
197 }
198 
199 
200 bool SMakeProjectT::IsMakeLibFile(const string& name)
201 {
202  return NStr::StartsWith(name, "Makefile") &&
203  NStr::EndsWith(name, ".lib");
204 }
205 
206 bool SMakeProjectT::IsMakeDllFile(const string& name)
207 {
208  return NStr::StartsWith(name, "Makefile") &&
209  NStr::EndsWith(name, ".dll");
210 }
211 
212 
213 bool SMakeProjectT::IsMakeAppFile(const string& name)
214 {
215  return NStr::StartsWith(name, "Makefile") &&
216  NStr::EndsWith(name, ".app");
217 }
218 
219 
220 /*
221 bool SMakeProjectT::IsUserProjFile(const string& name)
222 {
223  return NStr::StartsWith(name, "Makefile") &&
224  NStr::EndsWith(name, ".msvcproj");
225 }
226 */
227 
228 
230  TFiles& files,
231  const set<string>& keys)
232 {
233  const CMsvcSite& site = GetApp().GetSite();
234  set<string> defs_unresolved;
235  map<string,string> defs_resolved;
237 
238  CMsvcProjectMakefile msvc_prj(p->first + "." + GetApp().GetRegSettings().m_MakefilesExt);
239  bool msvc_empty = msvc_prj.IsEmpty();
240 
242  n,
243  p->second.m_Contents) {
244 
245  const string& key = n->first;
246  list<string>& values = n->second;
247  bool cppflags = key == "CPPFLAGS";
248 
249 // if (keys.find(key) != keys.end())
250  {
251  bool modified = false;
252  list<string> new_vals;
253  list<string> redef_values;
254  modified = msvc_prj.Redefine(values,redef_values);
255  NON_CONST_ITERATE(list<string>, k, redef_values) {
256 // NON_CONST_ITERATE(list<string>, k, values) {
257  //iterate all values and try to resolve
258  const string& val = *k;
259  if (cppflags && site.IsCppflagDescribed(val)) {
260  if (msvc_empty) {
261  new_vals.push_back(val);
262  } else {
263  msvc_prj.Append(new_vals,val);
264  }
265  } else if( !CSymResolver::HasDefine(val) ) {
266  if (msvc_empty) {
267  new_vals.push_back(val);
268  } else {
269  msvc_prj.Append(new_vals,val);
270  }
271  } else {
272  list<string> resolved_def;
273  string val_define = FilterDefine(val);
274  resolver.Resolve(val, &resolved_def, p->second);
275  if ( resolved_def.empty() ) {
276  defs_unresolved.insert(val);
277  new_vals.push_back(val_define); //not resolved - keep old val
278  } else {
279  defs_resolved[val] = NStr::Join( resolved_def, " ");
280  //was resolved
281  ITERATE(list<string>, l, resolved_def) {
282  const string& define = *l;
283  if ( IsConfigurableDefine(define) ) {
284  string stripped = StripConfigurableDefine(define);
285  string resolved_def_str;
286  list<string> libchoices_includes ;
287  site.GetLibChoiceIncludes(stripped, &libchoices_includes);
288  if (!libchoices_includes.empty()) {
289  resolved_def_str = NStr::Join( libchoices_includes, " ");
290  } else {
291  resolved_def_str = site.GetDefinesEntry(stripped);
292  }
293  if ( !resolved_def_str.empty() ) {
294  defs_resolved[define] = resolved_def_str;
295  list<string> resolved_defs;
296  NStr::Split(resolved_def_str,
299  if (msvc_empty) {
300  copy(resolved_defs.begin(),
301  resolved_defs.end(),
302  back_inserter(new_vals));
303  } else {
304  msvc_prj.Append(new_vals,resolved_defs);
305  }
306  } else {
307 // configurable definitions could be described in terms of components
308  list<string> components;
309  site.GetComponents(stripped, &components);
310  if (!components.empty()) {
311  defs_resolved[define] = "Component= " + NStr::Join( components, ", ");
312  } else {
313  defs_unresolved.insert(define);
314  }
315  if (msvc_empty) {
316  new_vals.push_back(define);
317  } else {
318  msvc_prj.Append(new_vals,define);
319  }
320  }
321 
322  } else if (HasConfigurableDefine(define)) {
323  string def(define);
324  while (HasConfigurableDefine(def)) {
325  string raw = ExtractConfigurableDefine(def);
326  string stripped = StripConfigurableDefine(raw);
327  string resolved_def_str = site.GetDefinesEntry(stripped);
328  if (resolved_def_str == " ") {
329  resolved_def_str.erase();
330  }
331  NStr::ReplaceInPlace(def, raw, resolved_def_str);
332  }
333  if (msvc_empty) {
334  new_vals.push_back( def);
335  } else {
336  msvc_prj.Append(new_vals,def);
337  }
338  } else {
339  if (msvc_empty) {
340  new_vals.push_back(define);
341  } else {
342  msvc_prj.Append(new_vals,define);
343  }
344  }
345  }
346  modified = true;
347  }
348  }
349  }
350  if (modified) {
351  msvc_prj.Redefine(new_vals,redef_values);
352  values = redef_values; // by ref!
353  }
354  }
355  }
356  }
357 
358  if (!defs_resolved.empty()) {
359  string s;
360  for (map<string,string>::const_iterator r = defs_resolved.begin();
361  r != defs_resolved.end(); ++r) {
362  s += ' ';
363  s += r->first;
364  s += " = ";
365  s += r->second;
366  s += ";";
367  }
368  PTB_INFO("Resolved macro definitions: " << s);
369  }
370  if (!defs_unresolved.empty()) {
371  string s;
372  for (set<string>::const_iterator u = defs_unresolved.begin();
373  u != defs_unresolved.end(); ++u) {
374  s += ' ';
375  s += *u;
376  }
378  "Unresolved macro definitions:" << s);
379  }
380 }
381 
382 
383 string SMakeProjectT::GetOneIncludeDir(const string& flag, const string& token)
384 {
385  size_t token_pos = flag.find(token);
386  if (token_pos != NPOS &&
387  token_pos + token.length() < flag.length()) {
388  return flag.substr(token_pos + token.length());
389  }
390  return "";
391 }
392 
393 
394 void SMakeProjectT::CreateIncludeDirs(const list<string>& cpp_flags,
395  const string& source_base_dir,
396  list<string>* include_dirs)
397 {
398  include_dirs->clear();
399  ITERATE(list<string>, p, cpp_flags) {
400  const string& flag = *p;
401 // string token("-I$(includedir)");
402 
403  // process -I$(includedir)
404  string token_val;
405  token_val = SMakeProjectT::GetOneIncludeDir(flag, "-I$(includedir)");
406  if ( !token_val.empty() ) {
407  string dir =
408  CDirEntry::ConcatPath(GetApp().GetProjectTreeInfo().m_Include,
409  token_val);
410  dir = CDirEntry::NormalizePath(dir);
412 
413  include_dirs->push_back(dir);
414  }
415  token_val = SMakeProjectT::GetOneIncludeDir(flag, "-I$(incdir)");
416  if ( !token_val.empty() ) {
417  string dir = CDirEntry::ConcatPath(GetApp().m_IncDir,token_val);
418  dir = CDirEntry::NormalizePath(dir);
420 
421  include_dirs->push_back(dir);
422  }
423 
424  // process -I$(srcdir)
425  token_val = SMakeProjectT::GetOneIncludeDir(flag, "-I$(srcdir)");
426  if ( !token_val.empty() || flag == "-I$(srcdir)" ) {
427  string dir =
428  CDirEntry::ConcatPath(source_base_dir,
429  token_val);
430  dir = CDirEntry::NormalizePath(dir);
432 
433  include_dirs->push_back(dir);
434  }
435 
436  // process -Ipath
437  token_val = SMakeProjectT::GetOneIncludeDir(flag, "-I");
438  if ( !token_val.empty() && token_val[0] != '$' && token_val[0] != '@' && token_val[0] != ':' ) {
439  string dir = CDirEntry::NormalizePath(token_val);
441  include_dirs->push_back(dir);
442  }
443 
444  // process defines like NCBI_C_INCLUDE
445  if(CSymResolver::IsDefine(flag)) {
446  string dir_all;
448  if ( !dir_all.empty() ) {
449  list<string> dir_list;
451  ITERATE(list<string>, dir_item, dir_list) {
452  const string& dir = *dir_item;
453  if ( CDirEntry(dir).IsDir() ) {
454  include_dirs->push_back(dir);
455  } else if (CDirEntry::IsAbsolutePath(dir)) {
456  PTB_WARNING_EX(kEmptyStr, ePTB_FileNotFound, "In " << source_base_dir << ": "
457  << flag << " = " << dir << ": "
458  << dir << " not found");
459  include_dirs->push_back(dir);
460  } else {
461  string d =
462  CDirEntry::ConcatPath(GetApp().GetProjectTreeInfo().m_Include, dir);
465  if ( CDirEntry(d).IsDir() ) {
466  include_dirs->push_back(d);
467  }
468 /*
469  else {
470  LOG_POST(Warning << flag << " = " << dir << ": "
471  << dir << " not found");
472  }
473 */
474  }
475  }
476  }
477  }
478 
479  // process additional include dirs for LibChoices
480  if(CSymResolver::IsDefine(flag)) {
481  string sflag = CSymResolver::StripDefine(flag);
482  list<string> libchoices_abs_includes ;
484  &libchoices_abs_includes);
485  ITERATE(list<string>, n, libchoices_abs_includes) {
486  const string& dir = *n;
487  if ( !dir.empty() ) {
488  include_dirs->push_back(dir);
489  }
490  }
491  }
492  }
493  include_dirs->sort();
494  include_dirs->unique();
495 }
496 
497 
498 void SMakeProjectT::CreateDefines(const list<string>& cpp_flags,
499  list<string>* defines)
500 {
501  defines->clear();
502 
503  ITERATE(list<string>, p, cpp_flags) {
504  const string& flag = *p;
505  if ( NStr::StartsWith(flag, "-D") ) {
506  defines->push_back(flag.substr(2));
507  }
508  }
509 }
510 
511 
513  const list<string>& libs_flags, const list<string>& expected_flags,
514  list<string>* libs_list, const string* mkname)
515 {
516  bool liborder_found = mkname != NULL && GetApp().m_LibraryOrder.find(*mkname) != GetApp().m_LibraryOrder.end();
518  list<string> unkflags;
519  list<CProjKey> libs3;
520  ITERATE(list<string>, p, libs_flags) {
521  string flag = *p;
522  if (flag == "#") {
523  break;
524  } else if ( IsConfigurableDefine(flag) ) {
525  libs_list->push_back(StripConfigurableDefine(flag));
526  done.insert(flag);
527  } else if (NStr::StartsWith(flag, "-l")) {
528  string suffix;
530  if (liborder_found && find(
531  GetApp().m_LibraryOrder[*mkname].begin(),
532  GetApp().m_LibraryOrder[*mkname].end(), flag.substr(2)) !=
533  GetApp().m_LibraryOrder[*mkname].end()) {
534  continue;
535  }
536  libs3.push_back( CProjKey(CProjKey::eLib, flag.substr(2), suffix));
537 // user cannot be trusted
538 // GetApp().m_3PartyLibs.insert(flag.substr(2));
539  done.insert(flag.substr(2));
540  } else if ( NStr::CompareCase(flag, "-framework") == 0 ) {
541  if (p != libs_flags.end()) {
542  GetApp().m_3PartyLibs.insert(*(++p));
543  GetApp().m_Frameworks.insert(*p);
544  done.insert(flag);
545  }
546  } else {
547  unkflags.push_back(flag);
548  }
549  }
550  bool added = false;
551  if (GetApp().m_AddMissingDep) {
552  ITERATE(list<string>, p, expected_flags) {
553  const string& flag = *p;
554  if (NStr::StartsWith(flag, "-l")) {
555  if (done.find(flag.substr(2)) == done.end()) {
556  libs3.push_back( CProjKey(CProjKey::eLib, flag.substr(2)));
557  done.insert(flag.substr(2));
558  added = true;
559  }
560  } else if (IsConfigurableDefine(flag)) {
561  if (done.find(flag) == done.end()) {
562  libs3.push_back( CProjKey(CProjKey::eLib, flag));
563  done.insert(flag);
564  added = true;
565  }
566  } else {
567  if (find(unkflags.begin(), unkflags.end(), flag) == unkflags.end()) {
568  unkflags.push_back(flag);
569  added = true;
570  }
571  }
572  }
573  }
574  if (mkname != NULL && !GetApp().IsScanningWholeTree() && !libs3.empty()) {
575  list<string> liborder;
576  if (added) {
577  liborder.push_back("");
578  }
579  VerifyLibDepends(libs3, *mkname, liborder);
580  if (!liborder.empty()) {
581  GetApp().m_3PartyLibraryOrder[*mkname] = unkflags;
582  ITERATE( list<string>, s, liborder) {
583  if (!s->empty()) {
584  GetApp().m_3PartyLibraryOrder[*mkname].push_back(*s);
585  if (libs_list && find(libs_list->begin(), libs_list->end(), *s) == libs_list->end()) {
586  if ( IsConfigurableDefine(*s) ) {
587  libs_list->push_back(StripConfigurableDefine(*s));
588  } else {
589  libs_list->push_back(*s);
590  }
591  }
592  }
593  }
594  }
595  }
596 }
597 
598 
600  (const CSimpleMakeFileContents& makein_contents,
602 {
603  info->clear();
605 
606  p = makein_contents.m_Contents.find("LIB_PROJ");
607  if (p != makein_contents.m_Contents.end()) {
608 
609  info->push_back(SMakeInInfo(SMakeInInfo::eLib, p->second,
610  makein_contents.GetMakeType()));
611  }
612  p = makein_contents.m_Contents.find("EXPENDABLE_LIB_PROJ");
613  if (p != makein_contents.m_Contents.end()) {
614 
615  info->push_back(SMakeInInfo(SMakeInInfo::eLib, p->second,
616  max(makein_contents.GetMakeType(),eMakeType_Expendable)));
617  }
618  p = makein_contents.m_Contents.find("POTENTIAL_LIB_PROJ");
619  if (p != makein_contents.m_Contents.end()) {
620 
621  info->push_back(SMakeInInfo(SMakeInInfo::eLib, p->second,
622  max(makein_contents.GetMakeType(),eMakeType_Potential)));
623  }
624 
625  p = makein_contents.m_Contents.find("DLL_PROJ");
626  if (p != makein_contents.m_Contents.end()) {
627 
628  info->push_back(SMakeInInfo(SMakeInInfo::eDll, p->second,
629  makein_contents.GetMakeType()));
630  }
631  p = makein_contents.m_Contents.find("EXPENDABLE_DLL_PROJ");
632  if (p != makein_contents.m_Contents.end()) {
633 
634  info->push_back(SMakeInInfo(SMakeInInfo::eDll, p->second,
635  max(makein_contents.GetMakeType(),eMakeType_Expendable)));
636  }
637  p = makein_contents.m_Contents.find("POTENTIAL_DLL_PROJ");
638  if (p != makein_contents.m_Contents.end()) {
639 
640  info->push_back(SMakeInInfo(SMakeInInfo::eDll, p->second,
641  max(makein_contents.GetMakeType(),eMakeType_Potential)));
642  }
643 
644  p = makein_contents.m_Contents.find("APP_PROJ");
645  if (p != makein_contents.m_Contents.end()) {
646 
647  info->push_back(SMakeInInfo(SMakeInInfo::eApp, p->second,
648  makein_contents.GetMakeType()));
649  }
650  p = makein_contents.m_Contents.find("EXPENDABLE_APP_PROJ");
651  if (p != makein_contents.m_Contents.end()) {
652 
653  info->push_back(SMakeInInfo(SMakeInInfo::eApp, p->second,
654  max(makein_contents.GetMakeType(),eMakeType_Expendable)));
655  }
656  p = makein_contents.m_Contents.find("POTENTIAL_APP_PROJ");
657  if (p != makein_contents.m_Contents.end()) {
658 
659  info->push_back(SMakeInInfo(SMakeInInfo::eApp, p->second,
660  max(makein_contents.GetMakeType(),eMakeType_Potential)));
661  }
662 
663  p = makein_contents.m_Contents.find("ASN_PROJ");
664  if (p != makein_contents.m_Contents.end()) {
665 
666  info->push_back(SMakeInInfo(SMakeInInfo::eASN, p->second,
667  makein_contents.GetMakeType()));
668  }
669  p = makein_contents.m_Contents.find("DTD_PROJ");
670  if (p != makein_contents.m_Contents.end()) {
671 
672  info->push_back(SMakeInInfo(SMakeInInfo::eDTD, p->second,
673  makein_contents.GetMakeType()));
674  }
675  p = makein_contents.m_Contents.find("XSD_PROJ");
676  if (p != makein_contents.m_Contents.end()) {
677 
678  info->push_back(SMakeInInfo(SMakeInInfo::eXSD, p->second,
679  makein_contents.GetMakeType()));
680  }
681  p = makein_contents.m_Contents.find("WSDL_PROJ");
682  if (p != makein_contents.m_Contents.end()) {
683 
684  info->push_back(SMakeInInfo(SMakeInInfo::eWSDL, p->second,
685  makein_contents.GetMakeType()));
686  }
687  p = makein_contents.m_Contents.find("JSD_PROJ");
688  if (p != makein_contents.m_Contents.end()) {
689 
690  info->push_back(SMakeInInfo(SMakeInInfo::eJSD, p->second,
691  makein_contents.GetMakeType()));
692  }
693  p = makein_contents.m_Contents.find("PROTOBUF_PROJ");
694  if (p != makein_contents.m_Contents.end()) {
695 
696  info->push_back(SMakeInInfo(SMakeInInfo::eProtobuf, p->second,
697  makein_contents.GetMakeType()));
698  }
699 
701  p = makein_contents.m_Contents.find("UNIX_PROJ");
703  p = makein_contents.m_Contents.find("XCODE_PROJ");
704  } else {
705  p = makein_contents.m_Contents.find("MSVC_PROJ");
706  }
707  if (p != makein_contents.m_Contents.end()) {
708 
709  info->push_back(SMakeInInfo(SMakeInInfo::eMsvc, p->second,
710  makein_contents.GetMakeType()));
711  }
712 
714  p = makein_contents.m_Contents.find("EXPENDABLE_UNIX_PROJ");
715  if (p != makein_contents.m_Contents.end()) {
716 
717  info->push_back(SMakeInInfo(SMakeInInfo::eMsvc, p->second,
718  max(makein_contents.GetMakeType(),eMakeType_Expendable)));
719  }
720  }
721  p = makein_contents.m_Contents.find("METAL_PROJ");
722  if (p != makein_contents.m_Contents.end()) {
723 
724  info->push_back(SMakeInInfo(SMakeInInfo::eMetal, p->second,
725  makein_contents.GetMakeType()));
726  }
727 }
728 
729 
731  (const string& base_dir,
732  const string& projname,
734 {
735  CProjItem::TProjType proj_type =
736  SMakeProjectT::GetProjType(base_dir, projname, type);
737 
738  string fname = "Makefile." + projname;
739  switch (proj_type) {
740  case CProjKey::eLib: fname += type == SMakeInInfo::eMetal ? ".metal" : ".lib"; break;
741  case CProjKey::eDll: fname += ".dll"; break;
742  case CProjKey::eApp: fname += ".app"; break;
743  case CProjKey::eMsvc:
745  if (!CDirEntry( CDirEntry::ConcatPath(base_dir,fname)).Exists()) {
746  fname += ".in";
747  }
749  fname += ".msvcproj";
750  }
751  break;
752  default: break;
753  }
754  return CDirEntry::ConcatPath(base_dir, fname);
755 }
756 
757 
758 void SMakeProjectT::CreateFullPathes(const string& dir,
759  const list<string> files,
760  list<string>* full_pathes)
761 {
762  ITERATE(list<string>, p, files) {
763  string full_path = CDirEntry::ConcatPath(dir, *p);
764  full_pathes->push_back(full_path);
765  }
766 }
767 
768 static
769 void s_CollectAllLeaves(const map<string, set<string> >& source_dep,
770  const map<string, set<string> >& source_flags,
771  const string& branch,
772  set<string>& all_dep,
773  set<string>& all_flags)
774 {
775  if (all_dep.find(branch) != all_dep.end()) {
776  return;
777  }
778  all_dep.insert(branch);
779  if (source_flags.find(branch) != source_flags.end()) {
780  const set<string>& flags(source_flags.find(branch)->second);
782  all_flags.insert(*f);
783  }
784  }
785  if (source_dep.find(branch) != source_dep.end()) {
786  const set<string>& branches(source_dep.find(branch)->second);
787  ITERATE(set<string>, b, branches) {
788  s_CollectAllLeaves(source_dep, source_flags, *b, all_dep, all_flags);
789  }
790  }
791 }
792 
794  list<CProjKey>& depends_ids_arg, const string& mkname, list<string>& liborder,
795  const set<string>* libs_3party, list<string>* expected_3party)
796 {
797  if (depends_ids_arg.empty()) {
798  return;
799  }
800  if (GetApp().m_GraphDepPrecedes.empty()) {
801  return;
802  }
803  CProjBulderApp& app(GetApp());
804  list<string> warnings;
805  list<string> original;
806  list<string> duplicates;
807  list<string> missing;
808  map<string, string> missing_suffix;
809  set<string> alldepends;
810  set<string> allflags;
811  list<CProjKey> depends_ids( depends_ids_arg);
812 
813  for(list<CProjKey>::const_iterator p = depends_ids.begin();
814  p != depends_ids.end(); ++p) {
815  for(list<CProjKey>::const_iterator i = p;
816  ++i != depends_ids.end();) {
817  if (*i == *p) {
818  duplicates.push_back(i->Id());
819  break;
820  }
821  }
822  original.push_back(p->Id());
823  s_CollectAllLeaves( app.m_GraphDepPrecedes, app.m_GraphDepFlags, p->Id(), alldepends, allflags);
824  }
825  if (expected_3party != nullptr) {
826  ITERATE( set<string>, s, allflags) {
827  expected_3party->push_back(*s);
828  }
829  }
830  ITERATE( set<string>, s, alldepends) {
831  string id(*s);
832  string s_suffix;
833  CSymResolver::StripSuffix(id, &s_suffix);
834  list<CProjKey>::const_iterator p = depends_ids.begin();
835  for(; p != depends_ids.end(); ++p) {
836  if (p->Id() == id) {
837  break;
838  }
839  }
840  if (p == depends_ids.end()) {
841  for(p = depends_ids.begin(); p != depends_ids.end(); ++p) {
842  if (app.m_GraphDepIncludes[p->Id()].find(id) != app.m_GraphDepIncludes[p->Id()].end()) {
843  break;
844  }
845  }
846  if (p == depends_ids.end()) {
847  if (libs_3party == nullptr ||
848  libs_3party->find(id) == libs_3party->end()) {
850  !app.GetSite().IsLibWithChoice(id) &&
851  !app.GetSite().Is3PartyLibWithChoice(id)) {
852  missing.push_back(id);
853  missing_suffix[id] = s_suffix;
854  }
855  } else if (expected_3party != nullptr) {
857  expected_3party->push_back( id);
858  } else {
859  expected_3party->push_back( "-l" + id);
860  }
861  }
862  }
863  }
864  }
865  if (!missing.empty()) {
866  warnings.push_back("missing dependencies: " + NStr::Join(missing,","));
867  if (app.m_AddMissingDep && libs_3party != nullptr) {
868  ITERATE( list<string>, m, missing) {
869  depends_ids.push_back(CProjKey(CProjKey::eLib, *m, missing_suffix[*m]));
870  }
871  }
872  }
873  if (!duplicates.empty()) {
874  warnings.push_back("duplicate dependencies: " + NStr::Join(duplicates,","));
875  }
876 #if 1
877  set<string> projlibs;
878  bool fix = (!liborder.empty() && liborder.begin()->empty()) ||
879  !duplicates.empty() || depends_ids_arg.size() != depends_ids.size();
880  if (fix) {
881  liborder.clear();
882  }
883  if (!app.m_GraphDepPrecedes.empty()) {
884  set<string> libsofar;
885  for(list<CProjKey>::const_iterator p = depends_ids.begin();
886  p != depends_ids.end(); ++p) {
887  list<string> wrong;
888  bool obsolete = false;
889  ITERATE(set<string>, s, libsofar) {
890  if (app.m_GraphDepPrecedes.find(p->Id()) != app.m_GraphDepPrecedes.end()) {
891  if (app.m_GraphDepPrecedes[p->Id()].find(*s) != app.m_GraphDepPrecedes[p->Id()].end()) {
892  wrong.push_back(*s);
893  }
894  }
895  if (app.m_GraphDepIncludes[p->Id()].find(*s) != app.m_GraphDepIncludes[p->Id()].end()) {
896  fix=true;
897  obsolete = true;
898  projlibs.erase(*s);
899  projlibs.insert(p->Id());
900  warnings.push_back("obsolete library: " + *s + " already included into " + p->Id());
901  }
902  if (app.m_GraphDepIncludes[*s].find(p->Id()) != app.m_GraphDepIncludes[*s].end()) {
903  fix=true;
904  obsolete = true;
905  projlibs.erase(p->Id());
906  projlibs.insert(*s);
907  warnings.push_back("obsolete library: " + p->Id() + " already included into " + *s);
908  }
909  }
910  if (!wrong.empty()) {
911  fix=true;
912 #if 0
913  if (find(missing.begin(), missing.end(), p->Id()) == missing.end()) {
914  warnings.push_back("wrong library order: " + p->Id() + " should precede " + NStr::Join(wrong,","));
915  }
916 #endif
917  }
918  libsofar.insert(p->Id());
919  if (!obsolete) {
920  projlibs.insert(p->Id());
921  }
922  }
923 // all libs should be known
924  {
925  list<string> unknown;
926  ITERATE (set<string>, p, projlibs) {
927  if (app.m_GraphDepPrecedes.find(*p) == app.m_GraphDepPrecedes.end()) {
928  unknown.push_back(*p);
929  }
930  }
931  if (!unknown.empty()) {
932  fix = false;
933  warnings.push_back("unknown libraries: " + NStr::Join(unknown,","));
934  }
935  }
936  }
937  if (fix) {
938  if (app.m_GraphDepRank.empty()) {
939  ITERATE (set<string>, p, projlibs) {
940  liborder.push_back(*p);
941  }
942  } else {
943  vector< list<string> > recommend;
944  for (set<string>::const_iterator p= projlibs.begin(); p != projlibs.end(); ++p) {
945  size_t rank = app.m_GraphDepRank[*p];
946  while (recommend.size() < rank+1) {
947  list<string> t;
948  recommend.push_back(t);
949  }
950  recommend[rank].push_back(*p);
951  }
952  list<string> advice;
953  for (size_t a= recommend.size(); a!= 0; --a) {
954  advice.insert(advice.end(), recommend[a-1].begin(), recommend[a-1].end());
955  }
956 #if 0
957  warnings.push_back("present library order: " + NStr::Join(original,","));
958  warnings.push_back("recommended library order: " + NStr::Join(advice,","));
959 #endif
960  list<string> advice_full;
961  ITERATE( list<string>, a, advice) {
962  for(list<CProjKey>::const_iterator p = depends_ids.begin();
963  p != depends_ids.end(); ++p) {
964  if (*a == p->Id()) {
965  advice_full.push_back( p->FullId());
966  break;
967  }
968  }
969  }
970  liborder = advice_full;
971  }
972  }
973 #if 0
974  if (!warnings.empty() && expected_3party != nullptr) {
975  if (libs_3party == nullptr) {
976  warnings.push_front("====== Library order warnings (3rd party libs) ======");
977  } else {
978  warnings.push_front("====== Library order warnings (toolkit libs) ======");
979  }
981  NStr::Join(warnings,"\n"));
982  }
983 #endif
984 #else
985 /*
986  this compares dependency rank,
987  BUT rank does not mean that one library really needs another one;
988  maybe, they are just in different dependency branches.
989  That is, while, in general, it is good to place higher rank libs first,
990  in reality, it is not necessarily a problem.
991 
992  ALSO, this is very slow, most likely because of large number of warning generated
993 */
994  if (!app.m_GraphDepRank.empty()) {
995  set<string> libsofar;
996  for(list<CProjKey>::const_iterator p = depends_ids.begin();
997  p != depends_ids.end(); ++p) {
998  list<string> wrong;
999  ITERATE(set<string>, s, libsofar) {
1000  if (app.m_GraphDepRank[*s] < app.m_GraphDepRank[p->Id()]) {
1001  wrong.push_back(*s);
1002  }
1003  if (app.m_GraphDepIncludes[p->Id()].find(*s) != app.m_GraphDepIncludes[p->Id()].end()) {
1005  "obsolete library: " << *s << " already included into " << p->Id());
1006  }
1007  if (app.m_GraphDepIncludes[*s].find(p->Id()) != app.m_GraphDepIncludes[*s].end()) {
1009  "obsolete library: " << p->Id() << " already included into " << *s);
1010  }
1011  }
1012  if (!wrong.empty()) {
1014  "wrong library order: " << p->Id() << " should precede " << NStr::Join(wrong,","));
1015  }
1016  libsofar.insert(p->Id());
1017  }
1018  }
1019 #endif
1020  if (depends_ids_arg.size() != depends_ids.size()) {
1021  depends_ids_arg = depends_ids;
1022  }
1023 }
1024 
1025 void SMakeProjectT::ConvertLibDepends(const list<string>& depends,
1026  list<CProjKey>* depends_ids,
1027  const string* mkname,
1028  list<string>* expected_3party)
1029 {
1030  list<string> depends_libs;
1031  SMakeProjectT::ConvertLibDependsMacro(depends, depends_libs);
1032 
1033  const CMsvcSite& site = GetApp().GetSite();
1034  ITERATE(list<string>, p, depends_libs) {
1035  string id = *p;
1036  string suffix;
1038  if(CSymResolver::IsDefine(id)) {
1039  string def;
1041  list<string> resolved_def;
1043  ITERATE(list<string>, r, resolved_def) {
1044  id = *r;
1045  if (!site.IsLibWithChoice(id) ||
1046  site.GetChoiceForLib(id) == CMsvcSite::eLib) {
1047  depends_ids->push_back(CProjKey(CProjKey::eLib, id, suffix));
1048  }
1049  }
1050  } else if (SMakeProjectT::IsConfigurableDefine(id)) {
1051  } else if (id.empty()) {
1052  } else {
1053  if (!site.IsLibWithChoice(id) ||
1054  site.GetChoiceForLib(id) == CMsvcSite::eLib) {
1055  depends_ids->push_back(CProjKey(CProjKey::eLib, id, suffix));
1056  }
1057  }
1058  }
1059 
1060  if (mkname != NULL && !GetApp().IsScanningWholeTree()) {
1061  VerifyLibDepends(*depends_ids, *mkname, GetApp().m_LibraryOrder[ *mkname],
1062  &GetApp().m_3PartyLibs, expected_3party);
1063  }
1064 
1065  depends_ids->sort();
1066  depends_ids->unique();
1067 }
1068 
1069 void SMakeProjectT::ConvertLibDependsMacro(const list<string>& depends,
1070  list<string>& depends_libs)
1071 {
1072  const CMsvcSite& site = GetApp().GetSite();
1073  ITERATE(list<string>, p, depends) {
1074  const string& id = *p;
1075  if (id[0] == '#') {
1076  break;
1077  }
1078  string lib = site.ProcessMacros(id,false);
1079  if (!lib.empty()) {
1080  depends_libs.push_back(lib);
1081  } else {
1082  if (CSymResolver::IsDefine(id) &&
1083  site.GetMacros().GetValue(CSymResolver::StripDefine(id),lib)) {
1084  list<string> res;
1086  ITERATE( list<string>, r, res) {
1087  if (NStr::StartsWith(*r, "-l")) {
1088  depends_libs.push_back(r->substr(2));
1089  } else {
1090  depends_libs.push_back(*r);
1091  }
1092  }
1093  } else {
1094  depends_libs.push_back(id);
1095  }
1096  }
1097  }
1098 }
1099 
1100 
1101 bool SMakeProjectT::IsConfigurableDefine(const string& define)
1102 {
1103  if (NStr::StartsWith(define, "@")) {
1104  string::size_type end = define.find("@",1);
1105  return end != string::npos && ( ++end == define.size() || define[end] == '\0');
1106  }
1107  return false;
1108 
1109 }
1110 
1111 
1112 string SMakeProjectT::StripConfigurableDefine(const string& define)
1113 {
1114  return IsConfigurableDefine(define) ?
1115  define.substr(1, define.length() - 2): "";
1116 }
1117 
1118 bool SMakeProjectT::HasConfigurableDefine(const string& define)
1119 {
1120  return count(define.begin(), define.end(), '@') > 1;
1121 }
1122 
1123 string SMakeProjectT::ExtractConfigurableDefine (const string& define)
1124 {
1125  string::size_type start, end;
1126  start = define.find("@");
1127  end = define.find("@",start+1);
1128  if (end == string::npos) {
1129  PTB_WARNING_EX(kEmptyStr, ePTB_MacroInvalid, "Possibly incorrect MACRO definition in: " + define);
1130  return define;
1131  }
1132  return define.substr(start,end-start+1);
1133 }
1134 
1135 //-----------------------------------------------------------------------------
1137  list<string>* libs_list)
1138 {
1140  makefile.m_Contents.find("NCBI_C_LIBS");
1141  if (k == makefile.m_Contents.end()) {
1142  return;
1143  }
1144  const list<string>& values = k->second;
1145 
1146  ITERATE(list<string>, p, values) {
1147  const string& val = *p;
1148  if ( NStr::StartsWith(val, "-l") ) {
1149  string lib_id = val.substr(2);
1150  libs_list->push_back(lib_id);
1151  } else {
1152  libs_list->push_back(val);
1153  }
1154  }
1155 
1156  libs_list->sort();
1157  libs_list->unique();
1158 }
1159 
1160 CProjKey SAppProjectT::DoCreate(const string& source_base_dir,
1161  const string& proj_name,
1162  const string& applib_mfilepath,
1163  const TFiles& makeapp ,
1165  EMakeFileType maketype)
1166 {
1167  CProjectItemsTree::TFiles::const_iterator m = makeapp.find(applib_mfilepath);
1168  if (m == makeapp.end()) {
1169  /// FIXME: items may not be really missing here; they may just be
1170  /// excluded based on user preference
1171  /**
1172  PTB_WARNING_EX(applib_mfilepath, ePTB_MissingMakefile,
1173  "Makefile not found");
1174  **/
1175  return CProjKey();
1176  }
1177 
1178  const CSimpleMakeFileContents& makefile = m->second;
1179  string full_makefile_name = CDirEntry(applib_mfilepath).GetName();
1180  string full_makefile_path = applib_mfilepath;
1181 
1183  //project id
1184  k = makefile.m_Contents.find("APP");
1185  if (k == makefile.m_Contents.end() || k->second.empty()) {
1186  if (GetApp().IsScanningWholeTree()) {
1187  PTB_WARNING_EX(full_makefile_path, ePTB_InvalidMakefile,
1188  "APP is not specified: " << full_makefile_name);
1189  } else {
1190  PTB_ERROR_EX(full_makefile_path, ePTB_InvalidMakefile,
1191  "APP is not specified: " << full_makefile_name);
1192  }
1193  return CProjKey();
1194  }
1195  string proj_id = k->second.front();
1196  {{
1197  CProjKey proj_key(CProjKey::eApp, proj_id);
1198  CProjectItemsTree::TProjects::const_iterator z = tree->m_Projects.find(proj_key);
1199  if (z != tree->m_Projects.end()) {
1200  if (z->second.m_MakeType < eMakeType_Excluded) {
1201  PTB_WARNING_EX(full_makefile_path, ePTB_ConfigurationError,
1202  "Application " << proj_id << " already defined at "
1203  << tree->m_Projects[proj_key].m_SourcesBaseDir);
1204  if (maketype == eMakeType_Excluded || GetApp().IsScanningWholeTree()) {
1205  return CProjKey();
1206  } else {
1207  GetApp().RegisterSuspiciousProject(proj_key);
1208  }
1209  } else {
1210  tree->m_Projects.erase(proj_key);
1211  }
1212  }
1213  }}
1214 
1215  k = makefile.m_Contents.find("SRC");
1216  if (k == makefile.m_Contents.end()) {
1217  if (GetApp().IsScanningWholeTree()) {
1218  PTB_WARNING_EX(full_makefile_path, ePTB_InvalidMakefile,
1219  "SRC is not specified: " << full_makefile_name);
1220  } else {
1221  PTB_ERROR_EX(full_makefile_path, ePTB_InvalidMakefile,
1222  "SRC is not specified: " << full_makefile_name);
1223  }
1224  return CProjKey();
1225  }
1226 
1227  //sources - relative paths from source_base_dir
1228  //We'll create relative pathes from them
1229  CProjSRCResolver src_resolver(applib_mfilepath,
1230  source_base_dir, k->second);
1231  list<string> sources;
1232  src_resolver.ResolveTo(&sources);
1233 
1235  k = makefile.m_Contents.find("UNIX_SRC");
1236  if (k != makefile.m_Contents.end()) {
1237  CProjSRCResolver unix_src_resolver(applib_mfilepath,
1238  source_base_dir, k->second);
1239  list<string> unix_sources;
1240  unix_src_resolver.ResolveTo(&unix_sources);
1241  copy(unix_sources.begin(), unix_sources.end(), back_inserter(sources));
1242  }
1243  }
1244 
1245  //depends
1246  list<string> depends;
1247  k = makefile.m_Contents.find("LIB");
1248  if (GetApp().GetBuildType().GetType() == CBuildType::eStatic) {
1250  makefile.m_Contents.find("STATIC_LIB");
1251  if (tmp_k != makefile.m_Contents.end()) {
1252  k = tmp_k;
1253  }
1254  }
1255  if (k != makefile.m_Contents.end()) {
1256 // depends = k->second;
1257  ITERATE(list<string>, i, k->second) {
1258 #if 0
1259  depends.push_back(
1261  "-static", kEmptyStr));
1262 #else
1263  depends.push_back( *i);
1264 #endif
1265  }
1266  }
1267  //Adjust depends by information from msvc Makefile
1268  CMsvcProjectMakefile project_makefile( CDirEntry::ConcatPath(
1269  source_base_dir, CreateMsvcProjectMakefileName(proj_name, CProjKey::eApp)));
1270 
1271  list<string> added_depends;
1272  project_makefile.GetAdditionalLIB(SConfigInfo(), &added_depends);
1273 
1274  list<string> excluded_depends;
1275  project_makefile.GetExcludedLIB(SConfigInfo(), &excluded_depends);
1276 
1277  list<string> adj_depends(depends);
1278  copy(added_depends.begin(),
1279  added_depends.end(), back_inserter(adj_depends));
1280 
1281  PLibExclude pred(proj_name, excluded_depends);
1282  EraseIf(adj_depends, pred);
1283 
1284  list<string> expected_3party;
1285  list<CProjKey> depends_ids;
1286  SMakeProjectT::ConvertLibDepends(adj_depends, &depends_ids,
1287  &applib_mfilepath, &expected_3party);
1288 
1289  list<CProjKey> unconditional_depends_ids;
1290  k = m->second.m_Contents.find("USR_DEP");
1291  if (k != m->second.m_Contents.end()) {
1292  const list<string> depends = k->second;
1293  SMakeProjectT::ConvertLibDepends(depends, &unconditional_depends_ids);
1294  copy(unconditional_depends_ids.begin(),
1295  unconditional_depends_ids.end(), back_inserter(depends_ids));
1296  }
1297  k = m->second.m_Contents.find("MSVC_DEP");
1298  if (k != m->second.m_Contents.end()) {
1299  const list<string> deps = k->second;
1300  ITERATE(list<string>, p, deps) {
1301  depends_ids.push_back(CProjKey(CProjKey::eMsvc, *p));
1302  }
1303  }
1304  ///////////////////////////////////
1305 
1306  //requires
1307  list<string> reqs;
1308  list<string> req_lst;
1309  if (makefile.CollectValues("REQUIRES", req_lst,
1311  project_makefile.Redefine(req_lst,reqs);
1312  }
1313 
1314  //LIBS
1315  list<string> libs_3_party;
1316  k = makefile.m_Contents.find("LIBS");
1317  if (GetApp().GetBuildType().GetType() == CBuildType::eStatic) {
1319  makefile.m_Contents.find("STATIC_LIBS");
1320  if (tmp_k != makefile.m_Contents.end()) {
1321  k = tmp_k;
1322  }
1323  }
1324  if (k != makefile.m_Contents.end() || !expected_3party.empty()) {
1325  list<string> libs_flags;
1326  if (k != makefile.m_Contents.end()) {
1327  libs_flags = k->second;
1328  }
1329  SMakeProjectT::Create3PartyLibs(libs_flags, expected_3party, &libs_3_party, &applib_mfilepath);
1330  }
1331 
1332  //CPPFLAGS
1333  list<string> include_dirs;
1334  list<string> defines;
1335  k = makefile.m_Contents.find("CPPFLAGS");
1336  if (k != makefile.m_Contents.end()) {
1337  const list<string>& cpp_flags = k->second;
1339  source_base_dir, &include_dirs);
1340  SMakeProjectT::CreateDefines(cpp_flags, &defines);
1341  }
1342  bool style_objcpp = false;
1343  k = makefile.m_Contents.find("CXXFLAGS");
1344  if (k != makefile.m_Contents.end()) {
1345  const list<string>& cxx_flags = k->second;
1346  style_objcpp = find(cxx_flags.begin(), cxx_flags.end(), "objective-c++") != cxx_flags.end();
1347  }
1348 
1349  //NCBI_C_LIBS - Special case for NCBI C Toolkit
1350  k = makefile.m_Contents.find("NCBI_C_LIBS");
1351  list<string> ncbi_clibs;
1352  if (k != makefile.m_Contents.end()) {
1353  libs_3_party.push_back("NCBI_C_LIBS");
1354  CreateNcbiCToolkitLibs(makefile, &ncbi_clibs);
1355  }
1356 
1357  CProjItem project(CProjKey::eApp,
1358  proj_name,
1359  proj_id,
1360  source_base_dir,
1361  sources,
1362  depends_ids,
1363  reqs,
1364  libs_3_party,
1365  include_dirs,
1366  defines,
1367  maketype,
1368  IdentifySlnGUID(source_base_dir, CProjKey(CProjKey::eApp, proj_id)));
1369 
1370  project.m_NcbiCLibs = ncbi_clibs;
1371  project.m_StyleObjcpp = style_objcpp;
1372  project.m_MkName = applib_mfilepath;
1373  project.m_DataSource = CSimpleMakeFileContents(applib_mfilepath);;
1374 
1375  //DATATOOL_SRC
1376  list<CDataToolGeneratedSrc> datatool_sources;
1377  k = makefile.m_Contents.find("DATATOOL_SRC");
1378  if ( k != makefile.m_Contents.end() ) {
1379  const list<string> datatool_src_list = k->second;
1380  ITERATE(list<string>, i, datatool_src_list) {
1381 
1382  const string& src = *i;
1383  //Will process .asn or .dtd files
1384  string source_file_path =
1385  CDirEntry::ConcatPath(source_base_dir, src);
1386  source_file_path = CDirEntry::NormalizePath(source_file_path);
1387  if ( CDirEntry(source_file_path + ".asn").Exists() )
1388  source_file_path += ".asn";
1389  else if ( CDirEntry(source_file_path + ".dtd").Exists() )
1390  source_file_path += ".dtd";
1391  else if ( CDirEntry(source_file_path + ".xsd").Exists() )
1392  source_file_path += ".xsd";
1393 
1394  CDataToolGeneratedSrc data_tool_src;
1395  CDataToolGeneratedSrc::LoadFrom(source_file_path, &data_tool_src);
1396  if ( !data_tool_src.IsEmpty() )
1397  datatool_sources.push_back(data_tool_src);
1398  }
1399  }
1400  if ( !datatool_sources.empty() ) {
1401  project.m_DatatoolSources = datatool_sources;
1402  if (GetApp().m_Dtdep && !GetApp().GetDatatoolId().empty()) {
1403  project.m_Depends.push_back(CProjKey(CProjKey::eApp, GetApp().GetDatatoolId()));
1404  }
1405  }
1406 
1407 // assemble check info
1408  string check_info;
1409  string check_dir = CDirEntry::CreateRelativePath(
1410  GetApp().GetProjectTreeInfo().m_Src, source_base_dir);
1411  NStr::ReplaceInPlace(check_dir,"\\","/");
1412  if (NStr::EndsWith(check_dir,'/')) {
1413  check_dir.erase(check_dir.size()-1,1);
1414  }
1415  string check_testname(proj_name);
1416  string check_appname(proj_id);
1417 
1418  string check_copy;
1419  k = makefile.m_Contents.find("CHECK_COPY");
1420  if ( k != makefile.m_Contents.end() && !k->second.empty() ) {
1421  check_copy = NStr::Join(k->second, " ");
1422  }
1423  string check_timeout("200");
1424  k = makefile.m_Contents.find("CHECK_TIMEOUT");
1425  if ( k != makefile.m_Contents.end() && !k->second.empty() ) {
1426  check_timeout = NStr::Join(k->second, " ");
1427  }
1428  GetApp().GetSite().CollectRequires(reqs);
1429  bool check_requires_ok = true;
1430  string check_requires;
1431  k = makefile.m_Contents.find("CHECK_REQUIRES");
1432  if ( k != makefile.m_Contents.end() && !k->second.empty() ) {
1433  GetApp().GetSite().CollectRequires(k->second);
1434  ITERATE(list<string>, p, k->second) {
1435  if ( !GetApp().GetSite().IsProvided(*p) ) {
1436  check_requires_ok = false;
1437  break;
1438  }
1439  }
1440  check_requires = NStr::Join(k->second, " ");
1441  }
1442  if (check_requires_ok) {
1443  k = makefile.m_Contents.find("REQUIRES");
1444  if ( k != makefile.m_Contents.end() && !k->second.empty() ) {
1445  if (!check_requires.empty()) {
1446  check_requires += " ";
1447  }
1448  check_requires += NStr::Join(k->second, " ");
1449  }
1450  }
1451 
1452  string check_authors;
1453  list<string> lst_authors;
1454  if (makefile.CollectValues("WATCHERS", lst_authors,
1456  check_authors = NStr::Join(lst_authors, " ");
1457  project.m_Watchers = check_authors;
1458  } else {
1459  k = makefile.m_Contents.find("CHECK_AUTHORS");
1460  if ( k != makefile.m_Contents.end() && !k->second.empty() ) {
1461  check_authors = NStr::Join(k->second, " ");
1462  }
1463  }
1464 
1465  k = makefile.m_Contents.find("CHECK_CMD");
1466 // !!!
1467 // Disable checking test requires in PTB, move checks back to scripts to correctly
1468 // process disabled tests due requires and report it to DB.
1469 // if ( check_requires_ok && k != makefile.m_Contents.end() ) {
1470  if ( k != makefile.m_Contents.end() ) {
1471  const list<string> check_cmd_list = k->second;
1472  string test_name("/CHECK_NAME=");
1473  ITERATE(list<string>, i, check_cmd_list) {
1474  string check_cmd(*i), check_name;
1475  string::size_type n = check_cmd.find(test_name);
1476  if (n != string::npos) {
1477  check_name = check_cmd.substr(n+test_name.size());
1478  check_cmd = check_cmd.substr(0,n);
1479  }
1480  NStr::TruncateSpacesInPlace(check_cmd);
1482  check << check_dir
1483  << s_check_separator << check_testname
1484  << s_check_separator << check_appname
1485  << s_check_separator << check_cmd
1487  << s_check_separator << check_copy
1488  << s_check_separator << check_timeout
1489  << s_check_separator << check_requires
1490  << s_check_separator << check_authors;
1491  project.m_CheckInfo.push_back( CNcbiOstrstreamToString(check) );
1492  }
1493  }
1494 
1495  project.m_ProjTags.push_back("exe");
1496  if (find(reqs.begin(), reqs.end(), "internal") == reqs.end() ) {
1497  project.m_ProjTags.push_back("public");
1498  } else {
1499  project.m_ProjTags.push_back("internal");
1500  }
1501  makefile.CollectValues("PROJ_TAG", project.m_ProjTags,
1503 
1504  list<string> pch_lst;
1505  if (makefile.CollectValues("USE_PCH", pch_lst,
1507  project.m_Pch = pch_lst.front();
1508  }
1509 
1510  CProjKey proj_key(CProjKey::eApp, proj_id);
1511  tree->m_Projects[proj_key] = project;
1512 
1513  return proj_key;
1514 }
1515 
1516 
1517 //-----------------------------------------------------------------------------
1518 CProjKey SLibProjectT::DoCreate(const string& source_base_dir,
1519  const string& proj_name,
1520  const string& applib_mfilepath,
1521  const TFiles& makelib ,
1523  EMakeFileType maketype)
1524 {
1525  TFiles::const_iterator m = makelib.find(applib_mfilepath);
1526  if (m == makelib.end()) {
1527  /// FIXME: items may not be really missing here; they may just be
1528  /// excluded based on user preference
1529  /**
1530  PTB_WARNING_EX(applib_mfilepath, ePTB_MissingMakefile,
1531  "Makefile not found");
1532  **/
1533  return CProjKey();
1534  }
1535 
1536 // const CSimpleMakeFileContents& makefile = m->second;
1537  string full_makefile_name = CDirEntry(applib_mfilepath).GetName();
1538  string full_makefile_path = applib_mfilepath;
1539 
1541  //project name
1542  k = m->second.m_Contents.find("LIB");
1543  if (GetApp().GetBuildType().GetType() == CBuildType::eStatic) {
1545  m->second.m_Contents.find("STATIC_LIB");
1546  if (tmp_k != m->second.m_Contents.end()) {
1547  k = tmp_k;
1548  }
1549  }
1550  if (k == m->second.m_Contents.end() ||
1551  k->second.empty()) {
1552  if (GetApp().IsScanningWholeTree()) {
1553  PTB_WARNING_EX(full_makefile_path, ePTB_InvalidMakefile,
1554  "LIB is not specified: " << full_makefile_name);
1555  } else {
1556  PTB_ERROR_EX(full_makefile_path, ePTB_InvalidMakefile,
1557  "LIB is not specified: " << full_makefile_name);
1558  }
1559  return CProjKey();
1560  }
1561  string proj_id = k->second.front();
1562  {{
1563  CProjKey proj_key(CProjKey::eLib, proj_id);
1564  CProjectItemsTree::TProjects::const_iterator z = tree->m_Projects.find(proj_key);
1565  if (z != tree->m_Projects.end()) {
1566  if (z->second.m_MakeType < eMakeType_Excluded) {
1567  PTB_WARNING_EX(full_makefile_path, ePTB_ConfigurationError,
1568  "Library " << proj_id << " already defined at "
1569  << tree->m_Projects[proj_key].m_SourcesBaseDir);
1570  if (maketype == eMakeType_Excluded || GetApp().IsScanningWholeTree()) {
1571  return CProjKey();
1572  } else {
1573  GetApp().RegisterSuspiciousProject(proj_key);
1574  }
1575  } else {
1576  tree->m_Projects.erase(proj_key);
1577  }
1578 
1579  }
1580  }}
1581 
1582  k = m->second.m_Contents.find("SRC");
1583  if (k == m->second.m_Contents.end()) {
1584  if (GetApp().IsScanningWholeTree()) {
1585  PTB_WARNING_EX(full_makefile_path, ePTB_InvalidMakefile,
1586  "SRC is not specified: " << full_makefile_name);
1587  } else {
1588  PTB_ERROR_EX(full_makefile_path, ePTB_InvalidMakefile,
1589  "SRC is not specified: " << full_makefile_name);
1590  }
1591  return CProjKey();
1592  }
1593 
1594  // sources - relative pathes from source_base_dir
1595  // We'll create relative pathes from them)
1596  CProjSRCResolver src_resolver(applib_mfilepath,
1597  source_base_dir, k->second);
1598  list<string> sources;
1599  src_resolver.ResolveTo(&sources);
1600 
1602  k = m->second.m_Contents.find("UNIX_SRC");
1603  if (k != m->second.m_Contents.end()) {
1604  CProjSRCResolver unix_src_resolver(applib_mfilepath,
1605  source_base_dir, k->second);
1606  list<string> unix_sources;
1607  unix_src_resolver.ResolveTo(&unix_sources);
1608  copy(unix_sources.begin(), unix_sources.end(), back_inserter(sources));
1609  }
1610  }
1611 
1612  // depends
1613  list<CProjKey> depends_ids;
1614  list<CProjKey> unconditional_depends_ids;
1615  k = m->second.m_Contents.find("ASN_DEP");
1616  if (k != m->second.m_Contents.end()) {
1617  const list<string> depends = k->second;
1618  SMakeProjectT::ConvertLibDepends(depends, &unconditional_depends_ids);
1619  copy(unconditional_depends_ids.begin(),
1620  unconditional_depends_ids.end(), back_inserter(depends_ids));
1621  }
1622  k = m->second.m_Contents.find("USR_DEP");
1623  if (k != m->second.m_Contents.end()) {
1624  const list<string> depends = k->second;
1625  SMakeProjectT::ConvertLibDepends(depends, &unconditional_depends_ids);
1626  copy(unconditional_depends_ids.begin(),
1627  unconditional_depends_ids.end(), back_inserter(depends_ids));
1628  }
1629  k = m->second.m_Contents.find("MSVC_DEP");
1630  if (k != m->second.m_Contents.end()) {
1631  const list<string> deps = k->second;
1632  ITERATE(list<string>, p, deps) {
1633  depends_ids.push_back(CProjKey(CProjKey::eMsvc, *p));
1634  }
1635  }
1636 
1637  string dll_host;
1638  string lib_or_dll;
1639  k = m->second.m_Contents.find("LIB_OR_DLL");
1640  if (k != m->second.m_Contents.end()) {
1641  lib_or_dll = k->second.front();
1642  }
1643  if (NStr::CompareNocase(lib_or_dll,"dll") == 0 ||
1644  NStr::CompareNocase(lib_or_dll,"both") == 0 ||
1645  NStr::CompareNocase(lib_or_dll,"@USUAL_AND_DLL@") == 0) {
1646  dll_host = proj_id;
1647  }
1648  bool need_dll = (!dll_host.empty() &&
1650 
1651  //requires
1652  list<string> reqs;
1653  list<string> req_lst;
1654  if (m->second.CollectValues("REQUIRES",req_lst,
1656  CMsvcProjectMakefile project_makefile( CDirEntry::ConcatPath(
1657  source_base_dir, CreateMsvcProjectMakefileName(proj_name, CProjKey::eLib)));
1658  project_makefile.Redefine(req_lst,reqs);
1659  }
1660 
1661  //CPPFLAGS
1662  list<string> include_dirs;
1663  list<string> defines;
1664  k = m->second.m_Contents.find("CPPFLAGS");
1665  if (k != m->second.m_Contents.end()) {
1666  const list<string>& cpp_flags = k->second;
1668  source_base_dir, &include_dirs);
1669  SMakeProjectT::CreateDefines(cpp_flags, &defines);
1670 
1671  }
1672  bool style_objcpp = false;
1673  k = m->second.m_Contents.find("CXXFLAGS");
1674  if (k != m->second.m_Contents.end()) {
1675  const list<string>& cxx_flags = k->second;
1676  style_objcpp = find(cxx_flags.begin(), cxx_flags.end(), "objective-c++") != cxx_flags.end();
1677  }
1678 
1679  bool isbundle = false;
1680  k = m->second.m_Contents.find("DLL_TYPE");
1681  if (k != m->second.m_Contents.end() && k->second.front() == "plugin") {
1682  isbundle = true;
1683  }
1684 // if (!lib_or_dll.empty() ||
1685 // CMsvc7RegSettings::GetMsvcPlatform() >= CMsvc7RegSettings::eUnix) {
1686 // if (GetApp().GetBuildType().GetType() == CBuildType::eDll) {
1687  list<string> dll_depends;
1688  k = m->second.m_Contents.find("DLL_LIB");
1689  if (GetApp().m_AllDllBuild) {
1691  m->second.m_Contents.find("DLL_DLIB");
1692  if (tmp_k != m->second.m_Contents.end()) {
1693  k = tmp_k;
1694  }
1695  }
1696  if (k != m->second.m_Contents.end()) {
1697  ITERATE(list<string>, i, k->second) {
1698 #if 0
1699  dll_depends.push_back(
1701  "-static", kEmptyStr));
1702 #else
1703  dll_depends.push_back(*i);
1704 #endif
1705  }
1706  }
1707  list<string> expected_3party;
1708  list<CProjKey> dll_depends_ids;
1709  SMakeProjectT::ConvertLibDepends(dll_depends, &dll_depends_ids,
1710  need_dll ? &applib_mfilepath : NULL,
1711  need_dll ? &expected_3party : NULL);
1712  copy(dll_depends_ids.begin(),
1713  dll_depends_ids.end(),
1714  back_inserter(depends_ids));
1715 // }
1716 // }
1717 
1718  //LIBS
1719  list<string> libs_3_party;
1720  k = m->second.m_Contents.find("LIBS");
1721  if (GetApp().GetBuildType().GetType() == CBuildType::eStatic) {
1723  m->second.m_Contents.find("STATIC_LIBS");
1724  if (tmp_k != m->second.m_Contents.end()) {
1725  k = tmp_k;
1726  }
1727  }
1728  if (k != m->second.m_Contents.end() || !expected_3party.empty()) {
1729  list<string> libs_flags;
1730  if (k != m->second.m_Contents.end()) {
1731  libs_flags = k->second;
1732  }
1733  SMakeProjectT::Create3PartyLibs(libs_flags, expected_3party, &libs_3_party,
1734  need_dll ? &applib_mfilepath : NULL);
1735  }
1736 
1737  CProjKey proj_key(CProjKey::eLib, proj_id);
1738  tree->m_Projects[proj_key] = CProjItem(CProjKey::eLib,
1739  proj_name,
1740  proj_id,
1741  source_base_dir,
1742  sources,
1743  depends_ids,
1744  reqs,
1745  libs_3_party,
1746  include_dirs,
1747  defines,
1748  maketype,
1749  IdentifySlnGUID(source_base_dir, proj_key));
1750 
1751  GetApp().GetSite().CollectRequires(reqs);
1752  (tree->m_Projects[proj_key]).m_StyleObjcpp = style_objcpp;
1753  (tree->m_Projects[proj_key]).m_MkName = applib_mfilepath;
1754  (tree->m_Projects[proj_key]).m_DataSource = CSimpleMakeFileContents(applib_mfilepath);
1755  if (CDirEntry(full_makefile_name).GetExt() == ".metal") {
1756  (tree->m_Projects[proj_key]).m_IsMetallib = true;
1757  }
1758 
1759  k = m->second.m_Contents.find("HEADER_EXPORT");
1760  if (k != m->second.m_Contents.end()) {
1761  (tree->m_Projects[proj_key]).m_ExportHeaders = k->second;
1762  }
1763  k = m->second.m_Contents.find("PACKAGE_EXPORT");
1764  if (k != m->second.m_Contents.end()) {
1765  (tree->m_Projects[proj_key]).m_ExportHeadersDest = k->second.front();
1766  }
1767  list<string> lst_watchers;
1768  if (m->second.CollectValues("WATCHERS", lst_watchers,
1770  tree->m_Projects[proj_key].m_Watchers = NStr::Join(lst_watchers, " ");
1771  }
1772 
1773  tree->m_Projects[proj_key].m_ProjTags.push_back("lib");
1774  if (find(reqs.begin(), reqs.end(), "internal") == reqs.end() ) {
1775  tree->m_Projects[proj_key].m_ProjTags.push_back("public");
1776  } else {
1777  tree->m_Projects[proj_key].m_ProjTags.push_back("internal");
1778  }
1779  m->second.CollectValues("PROJ_TAG", tree->m_Projects[proj_key].m_ProjTags,
1781 
1782  list<string> pch_lst;
1783  if (m->second.CollectValues("USE_PCH", pch_lst,
1785  tree->m_Projects[proj_key].m_Pch = pch_lst.front();
1786  }
1787 
1788  if (!dll_host.empty() && GetApp().GetBuildType().GetType() == CBuildType::eDll) {
1789  tree->m_Projects[proj_key].m_DllHost = dll_host;
1790  CProjKey proj_dll(CProjKey::eDll, dll_host);
1791  if (tree->m_Projects.find(proj_dll) == tree->m_Projects.end()) {
1792  CProjItem item_dll = tree->m_Projects[proj_dll];
1793  item_dll.m_ProjType = CProjKey::eDll;
1794 #if 0
1795  item_dll.m_Name = dll_host;
1796  item_dll.m_ID = dll_host;
1797 #else
1798  item_dll.m_Name = proj_name;
1799  item_dll.m_ID = proj_id;
1800 #endif
1801  item_dll.m_SourcesBaseDir = source_base_dir;
1802  item_dll.m_MakeType = maketype;
1803  item_dll.m_HostedLibs.push_back(proj_id);
1804  item_dll.m_GUID = IdentifySlnGUID(source_base_dir, proj_dll);
1805  item_dll.m_IsBundle = isbundle;
1806  item_dll.m_External = true;
1807  item_dll.m_StyleObjcpp = style_objcpp;
1808  item_dll.m_MkName = applib_mfilepath;
1809  item_dll.m_DataSource = CSimpleMakeFileContents(applib_mfilepath);
1810  item_dll.m_ProjTags = tree->m_Projects[proj_key].m_ProjTags;
1811  item_dll.m_ProjTags.push_back("dll");
1812  tree->m_Projects[proj_dll] = item_dll;
1813  }
1814  }
1815  ITERATE(list<CProjKey>, u, unconditional_depends_ids) {
1816  (tree->m_Projects[proj_key]).m_UnconditionalDepends.insert( *u);
1817  }
1818  return proj_key;
1819 }
1820 
1822  const string& source_base_dir,
1823  const string& proj_name,
1824  const string& proj_id,
1826  EMakeFileType maketype)
1827 {
1828  string spec_proj_name = proj_name;
1829  string spec_proj_id = proj_id;
1830 
1831  list<string> s_empty;
1832  list<CProjKey> d_empty;
1834  CProjKey proj_key(type, spec_proj_id);
1835  tree->m_Projects[proj_key] = CProjItem(type,
1836  spec_proj_name,
1837  spec_proj_id,
1838  source_base_dir,
1839  s_empty,
1840  d_empty,
1841  s_empty,
1842  s_empty,
1843  s_empty,
1844  s_empty,
1845  maketype,
1846  IdentifySlnGUID(source_base_dir, proj_key));
1847  return proj_key;
1848 }
1849 
1850 CProjItem CreateUtilityProjectItem( const string& prj_dir, const string& name)
1851 {
1852  string spec_proj_name = name;
1853  string spec_proj_id = NStr::Replace(name, "-", "_");
1854 
1855  list<string> s_empty;
1856  list<CProjKey> d_empty;
1858  CProjKey proj_key(type, spec_proj_id);
1859  return CProjItem(type,
1860  spec_proj_name,
1861  spec_proj_id,
1862  prj_dir,
1863  s_empty,
1864  d_empty,
1865  s_empty,
1866  s_empty,
1867  s_empty,
1868  s_empty,
1870  IdentifySlnGUID(prj_dir, proj_key));
1871 }
1872 
1873 //-----------------------------------------------------------------------------
1874 CProjKey SDllProjectT::DoCreate(const string& source_base_dir,
1875  const string& proj_name,
1876  const string& applib_mfilepath,
1877  const TFiles& makedll ,
1879  EMakeFileType maketype)
1880 {
1881  TFiles::const_iterator m = makedll.find(applib_mfilepath);
1882  if (m == makedll.end()) {
1883 
1884  PTB_WARNING_EX(kEmptyStr, ePTB_ProjectNotFound, "Dll Makefile not found: " << applib_mfilepath);
1885  return CProjKey();
1886  }
1888 
1889  //DLL
1890  k = m->second.m_Contents.find("DLL");
1891  if (k == m->second.m_Contents.end() ||
1892  k->second.empty()) {
1893  PTB_WARNING_EX(kEmptyStr, ePTB_ConfigurationError, "No DLL specified in Makefile." << proj_name
1894  << ".dll at " << applib_mfilepath);
1895  return CProjKey();
1896  }
1897  string proj_id = k->second.front();
1898  {{
1899  CProjKey proj_key(CProjKey::eDll, proj_id);
1900  CProjectItemsTree::TProjects::const_iterator z = tree->m_Projects.find(proj_key);
1901  if (z != tree->m_Projects.end()) {
1902  if (z->second.m_MakeType < eMakeType_Excluded) {
1903  const CProjItem& item = tree->m_Projects[proj_key];
1904  if (item.m_HostedLibs.size() != 1 || item.m_HostedLibs.front() != proj_id) {
1905  string full_makefile_path = applib_mfilepath;
1906  PTB_WARNING_EX(full_makefile_path, ePTB_ConfigurationError,
1907  "DLL " << proj_id << " already defined at "
1908  << tree->m_Projects[proj_key].m_SourcesBaseDir);
1909  if (maketype == eMakeType_Excluded || GetApp().IsScanningWholeTree()) {
1910  return CProjKey();
1911  } else {
1912  GetApp().RegisterSuspiciousProject(proj_key);
1913  }
1914  }
1915  } else {
1916  tree->m_Projects.erase(proj_key);
1917  }
1918  }
1919  }}
1920 
1921  //CPPFLAGS
1922  list<string> include_dirs;
1923  list<string> defines;
1924  k = m->second.m_Contents.find("CPPFLAGS");
1925  if (k != m->second.m_Contents.end()) {
1926  const list<string>& cpp_flags = k->second;
1928  source_base_dir, &include_dirs);
1929  SMakeProjectT::CreateDefines(cpp_flags, &defines);
1930 
1931  }
1932  bool style_objcpp = false;
1933  k = m->second.m_Contents.find("CXXFLAGS");
1934  if (k != m->second.m_Contents.end()) {
1935  const list<string>& cxx_flags = k->second;
1936  style_objcpp = find(cxx_flags.begin(), cxx_flags.end(), "objective-c++") != cxx_flags.end();
1937  }
1938 
1939  list<CProjKey> depends_ids;
1940  k = m->second.m_Contents.find("DEPENDENCIES");
1941  if (k != m->second.m_Contents.end()) {
1942  const list<string> depends = k->second;
1943  SMakeProjectT::ConvertLibDepends(depends, &depends_ids /*, &applib_mfilepath*/);
1944  }
1945 
1946  list<string> reqs;
1947  reqs.push_back("DLL");
1948 
1949  list<string> sources;
1950  list<string> libs_3_party;
1951 
1952  CProjKey proj_key(CProjKey::eDll, proj_id);
1953  tree->m_Projects[proj_key] = CProjItem(CProjKey::eDll,
1954  proj_name,
1955  proj_id,
1956  source_base_dir,
1957  sources,
1958  depends_ids,
1959  reqs,
1960  libs_3_party,
1961  include_dirs,
1962  defines,
1963  maketype,
1964  IdentifySlnGUID(source_base_dir, proj_key));
1965  tree->m_Projects[proj_key].m_External = true;
1966  tree->m_Projects[proj_key].m_StyleObjcpp = style_objcpp;
1967  tree->m_Projects[proj_key].m_MkName = applib_mfilepath;
1968  tree->m_Projects[proj_key].m_DataSource = CSimpleMakeFileContents(applib_mfilepath);;
1969 
1970  k = m->second.m_Contents.find("HOSTED_LIBS");
1971  if (k != m->second.m_Contents.end()) {
1972  tree->m_Projects[proj_key].m_HostedLibs = k->second;
1973  }
1974  k = m->second.m_Contents.find("DLL_TYPE");
1975  if (k != m->second.m_Contents.end() && k->second.front() == "plugin") {
1976  tree->m_Projects[proj_key].m_IsBundle = true;
1977  }
1978  list<string> lst_watchers;
1979  if (m->second.CollectValues("WATCHERS", lst_watchers,
1981  tree->m_Projects[proj_key].m_Watchers = NStr::Join(lst_watchers, " ");
1982  }
1983  tree->m_Projects[proj_key].m_ProjTags.push_back("dll");
1984  m->second.CollectValues("PROJ_TAG", tree->m_Projects[proj_key].m_ProjTags,
1986  return proj_key;
1987 }
1988 
1989 //-----------------------------------------------------------------------------
1990 CProjKey SAsnProjectT::DoCreate(const string& source_base_dir,
1991  const string& proj_name,
1992  const string& applib_mfilepath,
1993  const TFiles& makeapp,
1994  const TFiles& makelib,
1996  const SMakeProjectT::SMakeInInfo& makeinfo)
1997 {
1998  TAsnType asn_type = GetAsnProjectType(applib_mfilepath, makeapp, makelib);
1999  if (asn_type == eMultiple) {
2000  return SAsnProjectMultipleT::DoCreate(source_base_dir,
2001  proj_name,
2002  applib_mfilepath,
2003  makeapp,
2004  makelib,
2005  tree, makeinfo);
2006  }
2007  if(asn_type == eSingle) {
2008  return SAsnProjectSingleT::DoCreate(source_base_dir,
2009  proj_name,
2010  applib_mfilepath,
2011  makeapp,
2012  makelib,
2013  tree, makeinfo);
2014  }
2015  return CProjKey();
2016 }
2017 
2018 
2020  const TFiles& makeapp,
2021  const TFiles& makelib)
2022 {
2023  TFiles::const_iterator p = makeapp.find(applib_mfilepath);
2024  if ( p != makeapp.end() ) {
2025  const CSimpleMakeFileContents& fc = p->second;
2026  if (fc.m_Contents.find("ASN") != fc.m_Contents.end() )
2027  return eMultiple;
2028  else
2029  return eSingle;
2030  }
2031 
2032  p = makelib.find(applib_mfilepath);
2033  if ( p != makelib.end() ) {
2034  const CSimpleMakeFileContents& fc = p->second;
2035  if (fc.m_Contents.find("ASN") != fc.m_Contents.end() )
2036  return eMultiple;
2037  else
2038  return eSingle;
2039  }
2040  return eNoAsn;
2041 }
2042 
2043 
2044 //-----------------------------------------------------------------------------
2045 CProjKey SAsnProjectSingleT::DoCreate(const string& source_base_dir,
2046  const string& proj_name,
2047  const string& applib_mfilepath,
2048  const TFiles& makeapp,
2049  const TFiles& makelib,
2051  const SMakeProjectT::SMakeInInfo& makeinfo)
2052 {
2053  EMakeFileType maketype = makeinfo.m_MakeType;
2054  CProjItem::TProjType proj_type =
2055  IsMakeLibFile( CDirEntry(applib_mfilepath).GetName()) ? CProjKey::eLib : CProjKey::eApp;
2056 
2057  CProjKey proj_id =
2058  proj_type == CProjKey::eLib?
2059  SLibProjectT::DoCreate(source_base_dir,
2060  proj_name, applib_mfilepath, makelib, tree, maketype) :
2061  SAppProjectT::DoCreate(source_base_dir,
2062  proj_name, applib_mfilepath, makeapp, tree, maketype);
2063  if ( proj_id.Id().empty() )
2064  return CProjKey();
2065 
2066  TProjects::iterator p = tree->m_Projects.find(proj_id);
2067  if (p == tree->m_Projects.end()) {
2068  PTB_ERROR_EX(kEmptyStr, ePTB_ProjectNotFound, "ASN project not found: " + proj_id.Id());
2069  return CProjKey();
2070  }
2071  CProjItem& project = p->second;
2072 
2073  //Will process .asn or .dtd files
2074  string source_file_path = CDirEntry::ConcatPath(source_base_dir, proj_name);
2075  switch (makeinfo.m_Type) {
2077  if ( CDirEntry(source_file_path + ".asn").Exists() )
2078  source_file_path += ".asn";
2079  break;
2081  if ( CDirEntry(source_file_path + ".dtd").Exists() )
2082  source_file_path += ".dtd";
2083  break;
2085  if ( CDirEntry(source_file_path + ".xsd").Exists() )
2086  source_file_path += ".xsd";
2087  break;
2089  if ( CDirEntry(source_file_path + ".wsdl").Exists() )
2090  source_file_path += ".wsdl";
2091  break;
2093  if ( CDirEntry(source_file_path + ".jsd").Exists() )
2094  source_file_path += ".jsd";
2095  break;
2097  if ( CDirEntry(source_file_path + ".proto").Exists() )
2098  source_file_path += ".proto";
2099  break;
2100  default:
2101  break;
2102  }
2103  if ( !CDirEntry(source_file_path).Exists() ) {
2104  ERR_POST(
2105  (GetApp().IsScanningWholeTree() ? Warning : Error)
2106  << MDiagFile(kEmptyStr)
2107  << "Data specification for ASN project not found: " << source_file_path);
2108  return CProjKey();
2109  }
2110 
2111  CDataToolGeneratedSrc data_tool_src;
2112  CDataToolGeneratedSrc::LoadFrom(source_file_path, &data_tool_src);
2113  if ( !data_tool_src.IsEmpty()) {
2114  project.m_DatatoolSources.push_back(data_tool_src);
2115  if (GetApp().m_Dtdep && !GetApp().GetDatatoolId().empty() && makeinfo.m_Type != SMakeProjectT::SMakeInInfo::eProtobuf) {
2116  project.m_Depends.push_back(CProjKey(CProjKey::eApp, GetApp().GetDatatoolId()));
2117  }
2119  string rel_path = CDirEntry::CreateRelativePath(GetApp().GetProjectTreeInfo().m_Src, source_base_dir);
2120  string incl_path = CDirEntry::NormalizePath( CDirEntry::ConcatPath(GetApp().GetProjectTreeInfo().m_Include, rel_path));
2121  project.m_IncludeDirs.push_back(incl_path);
2122  project.m_Pch = "FALSE";
2123  }
2124  }
2125 
2126  return proj_id;
2127 }
2128 
2129 
2130 //-----------------------------------------------------------------------------
2131 CProjKey SAsnProjectMultipleT::DoCreate(const string& source_base_dir,
2132  const string& proj_name,
2133  const string& applib_mfilepath,
2134  const TFiles& makeapp,
2135  const TFiles& makelib,
2137  const SMakeProjectT::SMakeInInfo& makeinfo)
2138 {
2139  EMakeFileType maketype = makeinfo.m_MakeType;
2140  CProjItem::TProjType proj_type =
2141  IsMakeLibFile( CDirEntry(applib_mfilepath).GetName()) ? CProjKey::eLib : CProjKey::eApp;
2142 
2143 
2144  const TFiles& makefile = proj_type == CProjKey::eLib? makelib : makeapp;
2145  TFiles::const_iterator m = makefile.find(applib_mfilepath);
2146  if (m == makefile.end()) {
2147 
2148  PTB_WARNING_EX(kEmptyStr, ePTB_ProjectNotFound, "AsnProject Makefile not found: " << applib_mfilepath);
2149  return CProjKey();
2150  }
2151  const CSimpleMakeFileContents& fc = m->second;
2152 
2153  // ASN
2155  fc.m_Contents.find("ASN");
2156  if (k == fc.m_Contents.end()) {
2157 
2158  PTB_WARNING_EX(kEmptyStr, ePTB_ConfigurationError, "No ASN specified in Makefile: project " << proj_name
2159  << " at " << applib_mfilepath);
2160  return CProjKey();
2161  }
2162  const list<string> asn_names = k->second;
2163 
2164  list<CDataToolGeneratedSrc> datatool_sources;
2165  ITERATE(list<string>, p, asn_names) {
2166  const string& asn = *p;
2167 
2168  // this dir
2169  string asn_path_abs = CDirEntry::NormalizePath(source_base_dir);
2170  asn_path_abs = CDirEntry::AddTrailingPathSeparator(asn_path_abs);
2171  asn_path_abs = CDirEntry::ConcatPath(asn_path_abs, asn);
2172  if ( CDirEntry(asn_path_abs + ".asn").Exists() )
2173  asn_path_abs += ".asn";
2174  else if ( CDirEntry(asn_path_abs + ".dtd").Exists() )
2175  asn_path_abs += ".dtd";
2176  else if ( CDirEntry(asn_path_abs + ".xsd").Exists() )
2177  asn_path_abs += ".xsd";
2178  else {
2179  // one level up
2180  string parent_dir_abs = ParentDir(source_base_dir);
2181  string asn_dir_abs = CDirEntry::ConcatPath(parent_dir_abs, asn);
2182  asn_dir_abs = CDirEntry::NormalizePath(asn_dir_abs);
2183  asn_dir_abs = CDirEntry::AddTrailingPathSeparator(asn_dir_abs);
2184 
2185  asn_path_abs = CDirEntry::ConcatPath(asn_dir_abs, asn);
2186  if ( CDirEntry(asn_path_abs + ".asn").Exists() )
2187  asn_path_abs += ".asn";
2188  else if ( CDirEntry(asn_path_abs + ".dtd").Exists() )
2189  asn_path_abs += ".dtd";
2190  else if ( CDirEntry(asn_path_abs + ".xsd").Exists() )
2191  asn_path_abs += ".xsd";
2192  else {
2193  // one level down
2194  string asn_dir_abs = CDirEntry::ConcatPath(source_base_dir, asn);
2195  asn_dir_abs = CDirEntry::NormalizePath(asn_dir_abs);
2196  asn_dir_abs = CDirEntry::AddTrailingPathSeparator(asn_dir_abs);
2197 
2198  asn_path_abs = CDirEntry::ConcatPath(asn_dir_abs, asn);
2199  if ( CDirEntry(asn_path_abs + ".asn").Exists() )
2200  asn_path_abs += ".asn";
2201  else if ( CDirEntry(asn_path_abs + ".dtd").Exists() )
2202  asn_path_abs += ".dtd";
2203  else if ( CDirEntry(asn_path_abs + ".xsd").Exists() )
2204  asn_path_abs += ".xsd";
2205  else {
2206  PTB_ERROR_EX(asn_path_abs, ePTB_FileNotFound,
2207  "ASN spec file not found");
2208  }
2209  }
2210  }
2211 
2212  CDataToolGeneratedSrc data_tool_src;
2213  CDataToolGeneratedSrc::LoadFrom(asn_path_abs, &data_tool_src);
2214  if ( !data_tool_src.IsEmpty() )
2215  datatool_sources.push_back(data_tool_src);
2216 
2217  }
2218 
2219  // SRC
2220  k = fc.m_Contents.find("SRC");
2221  if (k == fc.m_Contents.end()) {
2222 
2223  PTB_WARNING_EX(kEmptyStr, ePTB_ConfigurationError, "No SRC specified in Makefile: project " << proj_name
2224  << " at " << applib_mfilepath);
2225  return CProjKey();
2226  }
2227  list<string> src_list = k->second;
2229  k = fc.m_Contents.find("UNIX_SRC");
2230  if (k != fc.m_Contents.end()) {
2231  copy(k->second.begin(), k->second.end(), back_inserter(src_list));
2232  }
2233  }
2234  list<string> sources;
2235  ITERATE(list<string>, p, src_list) {
2236  const string& src = *p;
2237  if ( !CSymResolver::IsDefine(src) )
2238  sources.push_back(src);
2239  }
2240 
2241  CProjKey proj_id =
2242  proj_type == CProjKey::eLib?
2243  SLibProjectT::DoCreate(source_base_dir,
2244  proj_name, applib_mfilepath, makelib, tree, maketype) :
2245  SAppProjectT::DoCreate(source_base_dir,
2246  proj_name, applib_mfilepath, makeapp, tree, maketype);
2247  if ( proj_id.Id().empty() )
2248  return CProjKey();
2249 
2250  TProjects::iterator pid = tree->m_Projects.find(proj_id);
2251  if (pid == tree->m_Projects.end()) {
2252  PTB_WARNING_EX(kEmptyStr, ePTB_ProjectNotFound, "ASN project not found: " << proj_id.Id()
2253  << " at " << applib_mfilepath);
2254  return CProjKey();
2255  }
2256  CProjItem& project = pid->second;
2257 
2258  // Adjust created proj item
2259  //SRC -
2260  project.m_Sources.clear();
2261  ITERATE(list<string>, p, src_list) {
2262  const string& src = *p;
2263  if ( !CSymResolver::IsDefine(src) )
2264  project.m_Sources.push_front(src);
2265  }
2266  ITERATE( list<CDataToolGeneratedSrc>, dts, datatool_sources) {
2267  const string& asn = dts->m_SourceCPP;
2268  project.m_Sources.remove(asn);
2269  project.m_Sources.remove(asn + "__");
2270  project.m_Sources.remove(asn + "___");
2271  string src = CDirEntry::ConcatPath(CDirEntry::CreateRelativePath( source_base_dir, dts->m_SourceBaseDir), asn);
2272  project.m_Sources.push_back(src + "__");
2273  project.m_Sources.push_back(src + "___");
2274  }
2275 
2276  if ( !datatool_sources.empty() ) {
2277  project.m_DatatoolSources = datatool_sources;
2278  if (GetApp().m_Dtdep && !GetApp().GetDatatoolId().empty()) {
2279  project.m_Depends.push_back(CProjKey(CProjKey::eApp, GetApp().GetDatatoolId()));
2280  }
2281  }
2282 
2283  return proj_id;
2284 }
2285 
2286 //-----------------------------------------------------------------------------
2287 CProjKey SMsvcProjectT::DoCreate(const string& source_base_dir,
2288  const string& proj_name,
2289  const string& applib_mfilepath,
2290  const TFiles& makemsvc,
2292  EMakeFileType maketype)
2293 {
2294  TFiles::const_iterator m = makemsvc.find(applib_mfilepath);
2295  if (m == makemsvc.end()) {
2296 
2297  PTB_WARNING_EX(kEmptyStr, ePTB_ProjectNotFound, "Native Makefile not found: " << applib_mfilepath);
2298  return CProjKey();
2299  }
2300 
2302  //project id
2303  string proj_id;
2305  proj_id = proj_name;
2306  } else {
2308  k = m->second.m_Contents.find(is_xcode ? "XCODE_PROJ" : "MSVC_PROJ");
2309  if (k == m->second.m_Contents.end() ||
2310  k->second.empty()) {
2311 
2312  PTB_WARNING_EX(kEmptyStr, ePTB_ConfigurationError, "No MSVC_PROJ specified in Makefile: project " << proj_name
2313  << " at " << applib_mfilepath);
2314  return CProjKey();
2315  }
2316  proj_id = k->second.front();
2317  }
2318  {{
2319  CProjKey proj_key(CProjKey::eMsvc, proj_id);
2320  CProjectItemsTree::TProjects::const_iterator z = tree->m_Projects.find(proj_key);
2321  if (z != tree->m_Projects.end()) {
2322  if (z->second.m_MakeType < eMakeType_Excluded) {
2323  string full_makefile_path = applib_mfilepath;
2324  PTB_WARNING_EX(full_makefile_path, ePTB_ConfigurationError,
2325  "Native project \'" << proj_id << "\' already defined at "
2326  << tree->m_Projects[proj_key].m_SourcesBaseDir);
2327  if (maketype == eMakeType_Excluded || GetApp().IsScanningWholeTree()) {
2328  return CProjKey();
2329  } else {
2330  GetApp().RegisterSuspiciousProject(proj_key);
2331  }
2332  } else {
2333  tree->m_Projects.erase(proj_key);
2334  }
2335  }
2336  }}
2337 
2338  string vcproj_file;
2339  list<string> sources;
2342  // VCPROJ - will map to src
2343  string vcproj_key("VCPROJ");
2345  vcproj_key = "VCXPROJ";
2346  }
2347  k = m->second.m_Contents.find(vcproj_key);
2348  if (k == m->second.m_Contents.end()) {
2349 
2350  PTB_WARNING_EX(kEmptyStr, ePTB_ConfigurationError, "No " << vcproj_key <<" specified in Makefile: project " << proj_name
2351  << " at " << applib_mfilepath);
2352  return CProjKey();
2353  }
2354  ITERATE(list<string>, s, k->second) {
2355  string d = GetApp().ProcessLocationMacros( *s );
2356  vcproj_file = d;
2357  if (CDirEntry::IsAbsolutePath(d)) {
2358  d = CDirEntry::CreateRelativePath( source_base_dir, d);
2359  }
2360  sources.push_back( d );
2361  break;
2362  }
2363  }
2364 
2365  // depends -
2366  list<CProjKey> depends_ids;
2367  k = m->second.m_Contents.find("LIB_DEP");
2368  if (k != m->second.m_Contents.end()) {
2369  const list<string> deps = k->second;
2370  ITERATE(list<string>, p, deps) {
2371  depends_ids.push_back(CProjKey(CProjKey::eLib, *p));
2372  }
2373  }
2374  k = m->second.m_Contents.find("APP_DEP");
2375  if (k != m->second.m_Contents.end()) {
2376  const list<string> deps = k->second;
2377  ITERATE(list<string>, p, deps) {
2378  depends_ids.push_back(CProjKey(CProjKey::eApp, *p));
2379  }
2380  }
2381  k = m->second.m_Contents.find("DLL_DEP");
2382  if (k != m->second.m_Contents.end()) {
2383  const list<string> deps = k->second;
2384  ITERATE(list<string>, p, deps) {
2385  depends_ids.push_back(CProjKey(CProjKey::eDll, *p));
2386  }
2387  }
2388  k = m->second.m_Contents.find("MSVC_DEP");
2389  if (k != m->second.m_Contents.end()) {
2390  const list<string> deps = k->second;
2391  ITERATE(list<string>, p, deps) {
2392  depends_ids.push_back(CProjKey(CProjKey::eMsvc, *p));
2393  }
2394  }
2395  k = m->second.m_Contents.find("USR_DEP");
2396  if (k != m->second.m_Contents.end()) {
2397  const list<string> deps = k->second;
2398  list<CProjKey> ids;
2400  copy(ids.begin(), ids.end(), back_inserter(depends_ids));
2401  }
2402 
2403  //requires
2404  list<string> reqs;
2405  list<string> req_lst;
2406  if (m->second.CollectValues("REQUIRES", req_lst,
2408  CMsvcProjectMakefile project_makefile( CDirEntry::ConcatPath(
2409  source_base_dir, CreateMsvcProjectMakefileName(proj_name, CProjKey::eMsvc)));
2410  project_makefile.Redefine(req_lst,reqs);
2411  }
2412 
2413  list<string> libs_3_party;
2414  list<string> include_dirs;
2415  list<string> defines;
2416 
2417  CMsvcProjectMakefile project_makefile
2418  ((CDirEntry::ConcatPath( source_base_dir,
2419  CreateMsvcProjectMakefileName(proj_name,
2420  CProjKey::eMsvc))));
2421  CProjKey proj_key(CProjKey::eMsvc, proj_id);
2422  CProjItem project(CProjKey::eMsvc,
2423  proj_name,
2424  proj_id,
2425  source_base_dir,
2426  sources,
2427  depends_ids,
2428  reqs,
2429  libs_3_party,
2430  include_dirs,
2431  defines,
2432  maketype,
2433  IdentifySlnGUID(vcproj_file, proj_key));
2434 
2435  m->second.CollectValues("PROJ_TAG", project.m_ProjTags,
2437 
2438  list<string> watchers;
2439  if (m->second.CollectValues("WATCHERS", watchers,
2441  project.m_Watchers = NStr::Join(watchers, " ");
2442  }
2443 
2444  project.m_MkName = applib_mfilepath;
2445  tree->m_Projects[proj_key] = project;
2446 
2447  return proj_key;
2448 }
2449 //-----------------------------------------------------------------------------
2450 
2452 {
2453  CProjBulderApp& app(GetApp());
2455  for (p = tree.m_Projects.begin(); p != tree.m_Projects.end(); ++p) {
2456  if (p->first.Type() != CProjKey::eApp) {
2457  continue;
2458  }
2459  const CProjItem& project = p->second;
2460 
2461  list<string> list_lib;
2462  if (!project.m_DataSource.GetValue("LIB", list_lib)) {
2463  continue;
2464  }
2465  list<string> lib_list_in, lib_list_in0;
2466  for( const string& lib : list_lib) {
2467  if (lib.at(0) == '#') {
2468  break;
2469  }
2470  else if (!CSymResolver::IsDefine(lib) && CSymResolver::HasDefine(lib)) {
2471  string def = FilterDefine(lib);
2472  string val = CSymResolver::StripDefine(def);
2473  list<string> tmp;
2474  if (project.m_DataSource.GetValue(val, tmp)) {
2475  copy(tmp.begin(), tmp.end(), back_inserter(lib_list_in));
2476  } else {
2477  lib_list_in.push_back(def);
2478  }
2479  } else {
2480  lib_list_in.push_back(lib);
2481  }
2482  }
2483  if (lib_list_in.empty()) {
2484  continue;
2485  }
2486  lib_list_in0 = lib_list_in;
2487 
2488  map< string, set<string> > lib_contents;
2489  map< string, set<string> > lib_dependencies;
2490 
2491  list<string> lib_list_out[2];
2492  size_t pass=0;
2493  for (pass=0; pass<4; ++pass) {
2494 
2495  if (pass > 1) {
2496  lib_list_out[0] = lib_list_out[1];
2497  lib_list_out[1].clear();
2498  }
2499  list<string>& list_in = pass == 0 ? lib_list_in : lib_list_out[0];
2500  list<string>& list_out = pass == 0 ? lib_list_out[0] : lib_list_out[1];
2501 
2502  bool failed = false;
2503  for (list<string>::const_iterator l = list_in.begin(); ; ++l) {
2504 
2505 // list_in may change (grow) during the cycle
2506  if (l == list_in.end()) {
2507  break;
2508  }
2509  const string& lib = *l;
2510  if (failed) {
2511  list_out.push_back(lib);
2512  continue;
2513  }
2514 
2515 // this item contents
2516  list<string> resolved;
2517  if (!CSymResolver::IsDefine(lib) ||
2518  !project.m_DataSource.GetValue(CSymResolver::StripDefine(lib), resolved)) {
2519  resolver.Resolve(lib, &resolved);
2520  }
2521  for_each(resolved.begin(), resolved.end(), [&lib_contents, &lib](const string& ce) {
2522  string e(ce);
2523  CSymResolver::StripSuffix(e);
2524  if (!e.empty() && e.at(0) != '@') {
2525  lib_contents[lib].insert(e);
2526  }});
2527 
2528 // this item dependencies
2529  set<string> alldepends;
2530  set<string> allflags;
2531  for( const string& lib_item : lib_contents[lib]) {
2532  s_CollectAllLeaves( app.m_GraphDepPrecedes, app.m_GraphDepFlags, lib_item, alldepends, allflags);
2533  }
2534  for_each(alldepends.begin(), alldepends.end(), [&lib_dependencies, &lib](const string& ce){
2535  string e(ce);
2536  CSymResolver::StripSuffix(e);
2537  if (!e.empty() && e.at(0) != '@') {
2538  lib_dependencies[lib].insert(e);
2539  }});
2540 
2541  list<string>::iterator iout = list_out.begin();
2542  bool do_append = true;
2543 
2544 // check that this item dependencies do not contain items in 'out' list
2545  for (; iout != list_out.end(); ++iout) {
2546  for( const string& lib_dep : lib_dependencies[lib]) {
2547  if (lib_contents[*iout].find(lib_dep) != lib_contents[*iout].end()) {
2548  do_append = false;
2549  break;
2550  }
2551  }
2552  if (!do_append) {
2553  break;
2554  }
2555  }
2556 
2557  // good to append
2558  if (do_append) {
2559  list_out.push_back(lib);
2560  continue;
2561  }
2562 
2563  list<string>::const_iterator i = iout;
2564  set<string> already_there;
2565  bool do_replace = false;
2566 
2567 // maybe we could drop item at iout, because new one includes it
2568 // compare lib_contents[*iout] with the contents of the new item
2569  already_there.clear();
2570  for( const string& lib_item : lib_contents[*iout]) {
2571  if (lib_contents[lib].find(lib_item) != lib_contents[lib].end()) {
2572  already_there.insert(lib_item);
2573  }
2574  }
2575  if (already_there.size() == lib_contents[*iout].size() &&
2576  already_there.size() != lib_contents[lib].size()) {
2577  // it seems that the new item can replace old one
2578  // make a note to check that it indeed may be inserted here
2579  do_replace = true;
2580  }
2581 
2582 // is there a need to add this item?
2583 // compare this item contents with what is already there
2584  already_there.clear();
2585  for (i = iout; i != list_out.end(); ++i) {
2586  for( const string& lib_item : lib_contents[lib]) {
2587  if (lib_contents[*i].find(lib_item) != lib_contents[*i].end()) {
2588  already_there.insert(lib_item);
2589  }
2590  }
2591  }
2592  if (already_there.size() == lib_contents[lib].size()) {
2593  // this is a duplicate which is already included
2594  continue;
2595  }
2596  // if this item adds only few new libraries, maybe we would better
2597  // add them expicitely instead
2598  if (//!do_replace &&
2599  already_there.size() != 0 &&
2600  already_there.size() >= (lib_contents[lib].size() * 3)/4) {
2601  for( const string& lib_item : lib_contents[lib]) {
2602  if (already_there.find(lib_item) == already_there.end()) {
2603  list_in.push_back(lib_item);
2604  }
2605  }
2606  continue;
2607  }
2608 
2609 // if we insert it at iout, check that items that follow do not depend on it
2610  do_append = false;
2611  bool do_insert = true;
2612  i = iout;
2613  if (do_replace) {
2614  ++i;
2615  }
2616  for (; i != list_out.end(); ++i) {
2617  for( const string& lib_dep : lib_dependencies[*i]) {
2618  if (lib_contents[lib].find(lib_dep) != lib_contents[lib].end()) {
2619 // maybe both include the same library.
2620 // if so, that is acceptable
2621  if (lib_contents[*i].find(lib_dep) != lib_contents[*i].end()) {
2622  do_append = true;
2623  continue;
2624  }
2625  do_insert = false;
2626  break;
2627  }
2628  }
2629  if (!do_insert) {
2630  break;
2631  }
2632  }
2633 
2634 // good to insert
2635  if (do_insert) {
2636  i = iout;
2637  if (do_append && ++i == list_out.end()) {
2638  list_out.push_back(lib);
2639  } else {
2640  if (do_replace) {
2641  iout = list_out.erase(iout);
2642  }
2643  list_out.insert(iout, lib);
2644  }
2645  continue;
2646  }
2647 
2648 // once again, try to append, allowing identical libraries in both
2649  do_append = true;
2650 // check that this item dependencies do not contain items in 'out' list
2651  for (i=iout; i != list_out.end(); ++i) {
2652  for( const string& lib_dep : lib_dependencies[lib]) {
2653  if (lib_contents[*i].find(lib_dep) != lib_contents[*i].end()) {
2654  if (lib_contents[lib].find(lib_dep) != lib_contents[lib].end()) {
2655  continue;
2656  }
2657  do_append = false;
2658  break;
2659  }
2660  }
2661  if (!do_append) {
2662  break;
2663  }
2664  }
2665 
2666  // not sure about this one
2667  if (do_replace) {
2668  list_out.erase(iout);
2669  for( const string& lib_item : already_there) {
2670  list_out.remove(lib_item);
2671  }
2672  }
2673  // good to append
2674  if (do_append) {
2675  list_out.push_back(lib);
2676  continue;
2677  }
2678 // Do not know what to do
2679 // keep it as is, in a hope that it will work
2680 // failed = true;
2681  list_out.push_back(lib);
2682  }
2683 
2684  if (list_in.size() == list_out.size() &&
2685  equal(list_in.begin(), list_in.end(), list_out.begin())) {
2686  break;
2687  }
2688  }
2689  if (pass != 0) {
2690  list<string> warnings;
2691  warnings.push_back("====== Library order warnings (toolkit libs) ======");
2692  warnings.push_back("present library order: " + NStr::Join(lib_list_in0," "));
2693  if (lib_list_out[0].size() == lib_list_out[1].size() &&
2694  equal(lib_list_out[0].begin(), lib_list_out[0].end(), lib_list_out[1].begin())) {
2695  warnings.push_back("recommended library order: " + NStr::Join(lib_list_out[0]," "));
2696 
2697  set<string> all_libs, all_deps;
2698  for(const string& lib_item: lib_list_out[0]) {
2699  all_libs.insert( lib_contents[lib_item].begin(),lib_contents[lib_item].end());
2700  all_deps.insert( lib_dependencies[lib_item].begin(),lib_dependencies[lib_item].end());
2701  }
2702  set<string> all_missing;
2703  for(const string& lib_item: all_deps) {
2704  if (all_libs.find(lib_item) == all_libs.end()) {
2705  all_missing.insert(lib_item);
2706  }
2707  }
2708  if (!all_missing.empty()) {
2709  warnings.push_back("missing libraries: " + NStr::Join(all_missing," "));
2710  }
2711  } else {
2712  warnings.push_back("Failed to identify recommended library order");
2713  if (pass >= 2) {
2714  warnings.push_back("candidate1: " + NStr::Join(lib_list_out[0]," "));
2715  warnings.push_back("candidate2: " + NStr::Join(lib_list_out[1]," "));
2716  }
2717  }
2718  PTB_WARNING_EX(project.m_DataSource.GetFileName(),ePTB_InvalidMakefile, NStr::Join(warnings,"\n"));
2719  }
2720  }
2721 }
2722 //-----------------------------------------------------------------------------
2723 
2724 
2725 void
2727  const string& root_src_path,
2729 {
2730  SMakeFiles subtree_makefiles;
2731 
2732  ProcessDir(root_src_path,
2733  true,
2734  filter,
2735  &subtree_makefiles, eMakeType_Undefined, NULL);
2736 
2737  // Resolve macrodefines
2738  list<string> metadata_files;
2739  GetApp().GetMetaDataFiles(&metadata_files);
2740  CSymResolver resolver;
2742  resolver.Append( GetApp().GetSite().GetMacros());
2743  }
2744  ITERATE(list<string>, p, metadata_files) {
2745  string fileloc;
2746  if (!GetApp().m_BuildRoot.empty()) {
2747  fileloc = CDirEntry::ConcatPath(GetApp().m_BuildRoot,*p);
2748  }
2749  if (fileloc.empty() || !CFile(fileloc).Exists()) {
2750  fileloc = CDirEntry::ConcatPath(root_src_path, CDirEntry::ConvertToOSPath(*p));
2751  }
2752  if (!CDirEntry(fileloc).Exists() && !GetApp().m_ExtSrcRoot.empty()) {
2754  GetApp().m_ExtSrcRoot,
2755  GetApp().GetConfig().Get("ProjectTree", "src")),
2757  }
2758  if (!CDirEntry(fileloc).Exists()) {
2759  fileloc = CDirEntry::ConcatPath(CDirEntry(GetApp().m_Solution).GetDir(),*p);
2760  }
2761  if (CDirEntry(fileloc).Exists()) {
2762  CSymResolver sym(fileloc);
2763  bool is_good = true;
2764  string reqs;
2765  if (sym.GetValue("REQUIRES", reqs)) {
2766  list<string> items;
2768  for(const string& i : items) {
2769  if (!GetApp().GetSite().IsProvided(i)) {
2770  PTB_WARNING_EX(kEmptyStr, ePTB_FileExcluded, "Custom metadata " << fileloc << " rejected because of unmet requirement: " << i);
2771  is_good = false;
2772  break;
2773  }
2774  }
2775  }
2776  if (is_good) {
2777  PTB_INFO("Resolve macros using rules from " << fileloc);
2778  resolver.Append( sym, true);;
2779  }
2780  }
2781  }
2782  ResolveDefs(resolver, subtree_makefiles);
2783  GetApp().UpdateDepGraph( subtree_makefiles.m_Lib);
2784 
2785  // Build projects tree
2786  CProjectItemsTree::CreateFrom(root_src_path,
2787  subtree_makefiles.m_In,
2788  subtree_makefiles.m_Lib,
2789  subtree_makefiles.m_Dll,
2790  subtree_makefiles.m_App,
2791  subtree_makefiles.m_User, tree);
2792 
2793  if (!GetApp().IsScanningWholeTree()) {
2794  s_AnalyzeLibraryOrder(resolver, *tree);
2795  }
2796 }
2797 
2798 
2799 void
2801  const string& root_src_path,
2803 {
2804  // Build subtree
2805  CProjectItemsTree target_tree;
2806 
2807  BuildOneProjectTree(filter, root_src_path, &target_tree);
2808 
2809  if (GetApp().IsScanningWholeTree()) {
2810  *tree = target_tree;
2812  t->second.m_MakeType = eMakeType_Excluded;
2813  t->second.m_External = true;
2814  }
2815  return;
2816  }
2817 
2818  GetApp().ExcludeProjectsByTag(target_tree);
2819  if ( GetApp().m_InteractiveCfg &&
2820  !GetApp().Gui_ConfirmProjects(target_tree))
2821  {
2822  GetApp().SetFail();
2823  return;
2824  }
2825  GetApp().ExcludeUnrequestedProjects(target_tree);
2826 
2827  for (;;) {
2828  size_t orig_size = target_tree.m_Projects.size();
2829  // Analyze subtree dependencies
2830  list<CProjKey> external_depends;
2831  target_tree.GetExternalDepends(&external_depends);
2832 
2833  // We have to add more projects to the target tree
2834  if ( !external_depends.empty()) {
2835  list<CProjKey> depends_to_resolve = external_depends;
2836  while ( !depends_to_resolve.empty() ) {
2837  bool modified = false;
2838  ITERATE(list<CProjKey>, p, depends_to_resolve) {
2839  // id of the project we have to resolve
2840  const CProjKey& prj_id = *p;
2842  GetApp().GetWholeTree().m_Projects.find(prj_id);
2843 
2844  if (n != GetApp().GetWholeTree().m_Projects.end()) {
2845  //insert this project into the target_tree
2846  target_tree.m_Projects[prj_id] = n->second;
2847  modified = true;
2848  } else {
2849  /// FIXME: is this needed?
2850  _TRACE("Project not found: " + prj_id.Id());
2851  }
2852  }
2853 
2854  if (!modified) {
2855  //done - no projects has been added to target_tree
2856  AddDatatoolSourcesDepends(&target_tree);
2857  *tree = target_tree;
2858  return;
2859  } else {
2860  //continue resolving dependencies
2861  target_tree.GetExternalDepends(&depends_to_resolve);
2862  }
2863  }
2864  }
2865 
2866  AddDatatoolSourcesDepends(&target_tree);
2867  if (orig_size == target_tree.m_Projects.size()) {
2868  break;
2869  }
2870  }
2871  *tree = target_tree;
2872 }
2873 
2874 
2875 void CProjectTreeBuilder::ProcessDir(const string& dir_name,
2876  bool is_root,
2877  const IProjectFilter* filter,
2878  SMakeFiles* makefiles,
2879  EMakeFileType maketype,
2880  const CSimpleMakeFileContents* parent)
2881 {
2882  // Node - Makefile.in should present
2883  // this is true if and only if there are also Makefile.*.lib or
2884  // Makefile.*.app project makefiles to process
2885  string node_path =
2886  CDirEntry::ConcatPath(dir_name,
2887  GetApp().GetProjectTreeInfo().m_TreeNode);
2888  if ( !is_root && !CDirEntry(node_path).Exists() ) {
2891  CDir(dir_name).GetEntries("Makefile.*.lib", flags);
2892  if (entries.empty()) {
2893  entries = CDir(dir_name).GetEntries("Makefile.*.app", flags);
2894  }
2895  if ( !entries.empty() ) {
2897  "Makefile.in missing");
2898  }
2899 
2900  string bld_sys = CDirEntry::DeleteTrailingPathSeparator(
2901  CDirEntry(GetApp().GetConfigPath()).GetDir());
2902  if (NStr::CompareNocase(bld_sys,dir_name) == 0) {
2903  CDir dir(dir_name);
2904  CDir::TEntries contents;
2905  contents = dir.GetEntries(GetApp().GetProjectTreeInfo().m_CustomMetaData);
2906  ITERATE(CDir::TEntries, p, contents) {
2907  GetApp().AddCustomMetaData( (*p)->GetPath());
2908  }
2909  contents = dir.GetEntries(GetApp().GetProjectTreeInfo().m_CustomConfH);
2910  ITERATE(CDir::TEntries, p, contents) {
2911  GetApp().AddCustomConfH( (*p)->GetPath());
2912  }
2913  }
2914  return;
2915  }
2916  if (!is_root &&
2918  // on UNIX the build tree is already configured,
2919  // we check if this particular subtree is enabled (ie, exists) there
2920  string subtree =
2922  GetApp().GetProjectTreeInfo().m_Src, dir_name);
2923  subtree = CDirEntry::ConcatPath(CDirEntry(GetApp().m_Solution).GetDir(), subtree);
2924  if (!CDirEntry(subtree).Exists()) {
2925  PTB_INFO_EX(subtree, ePTB_NoError,
2926  "skipped missing subtree");
2927  return;
2928  }
2929  }
2930 
2931  bool weak=false;
2932  bool process_projects = !is_root && filter->CheckProject(dir_name,&weak);
2933  if (!process_projects && !weak && !is_root) {
2934  return;
2935  }
2936 
2937  // Process Makefile.in
2938  const CSimpleMakeFileContents* mkin = NULL;
2939  map<string, EMakeFileType> subprojects;
2940  map<string, EMakeFileType> appprojects;
2941  map<string, EMakeFileType> libprojects;
2942  map<string, EMakeFileType> dllprojects;
2943  map<string, EMakeFileType> userprojects;
2944  vector<string> ordered_subprojects;
2945  string topbuilddir;
2946  bool has_metal = false;
2947  bool get_order = GetApp().IsScanningWholeTree();
2948  if (is_root && get_order) {
2949  topbuilddir = GetApp().GetRegSettings().GetTopBuilddir();
2950  }
2951 
2952  if ( process_projects || weak || !topbuilddir.empty()) {
2953  string node(topbuilddir.empty() ? node_path : topbuilddir);
2954  ProcessMakeInFile(node, makefiles, maketype, parent);
2955  TFiles::const_iterator p = makefiles->m_In.find(node);
2956  if (p != makefiles->m_In.end()) {
2957  const CSimpleMakeFileContents& makefile = p->second;
2958  mkin = &makefile;
2960  int j;
2961  string subproj[] = {"SUB_PROJ","EXPENDABLE_SUB_PROJ","POTENTIAL_SUB_PROJ",""};
2963  if (filter->ExcludePotential()) {
2964  subtype[2] = eMakeType_Excluded;
2965  }
2966  for (j=0; !subproj[j].empty(); ++j) {
2967  k = makefile.m_Contents.find(subproj[j]);
2968  if (k != makefile.m_Contents.end()) {
2969  const list<string>& values = k->second;
2970  for (list<string>::const_iterator i=values.begin(); i!=values.end(); ++i) {
2971  if (i->at(0) == '#') {
2972  break;
2973  }
2974  subprojects[*i] = max(maketype, subtype[j]);
2975  ordered_subprojects.push_back(*i);
2976  }
2977  }
2978  }
2979  if ( process_projects ) {
2980  string userproj[] = {"UNIX_PROJ","EXPENDABLE_UNIX_PROJ", ""};
2983  userproj[0] = is_xcode ? "XCODE_PROJ" : "MSVC_PROJ";
2984  userproj[1] = "";
2985  }
2987  for (j=0; !userproj[j].empty(); ++j) {
2988  k = makefile.m_Contents.find(userproj[j]);
2989  if (k != makefile.m_Contents.end()) {
2990  const list<string>& values = k->second;
2991  for (list<string>::const_iterator i=values.begin(); i!=values.end(); ++i) {
2992  if (i->at(0) == '#') {
2993  break;
2994  }
2996  userprojects["Makefile." + *i] = max(maketype, usertype[j]);
2997  userprojects["Makefile." + *i + ".in"] = max(maketype, usertype[j]);
2998  if (get_order) {
2999  s_WriteBuildOrder(dir_name,"Makefile." + *i);
3000  s_WriteBuildOrder(dir_name,"Makefile." + *i + ".in");
3001  }
3002  } else {
3003  string mkname("Makefile." + *i);
3005  mkname += ".msvcproj";
3006  }
3007  userprojects[mkname] = max(maketype, usertype[j]);
3008  if (get_order) {
3009  s_WriteBuildOrder(dir_name,mkname);
3010  }
3011  }
3012  }
3013  }
3014  }
3015  string libproj[] = {"ASN_PROJ","DTD_PROJ","XSD_PROJ","WSDL_PROJ","JSD_PROJ", "PROTOBUF_PROJ",
3016  "LIB_PROJ","EXPENDABLE_LIB_PROJ","POTENTIAL_LIB_PROJ",""};
3017  EMakeFileType libtype[] = {
3021  for (j=0; !libproj[j].empty(); ++j) {
3022  k = makefile.m_Contents.find(libproj[j]);
3023  if (k != makefile.m_Contents.end()) {
3024  const list<string>& values = k->second;
3025  for (list<string>::const_iterator i=values.begin(); i!=values.end(); ++i) {
3026  if (i->at(0) == '#') {
3027  break;
3028  }
3029  string mkname("Makefile." + *i + ".lib");
3030  libprojects[mkname] = max(maketype, libtype[j]);
3031  if (get_order) {
3032  s_WriteBuildOrder(dir_name,mkname);
3033  }
3034  }
3035  }
3036  }
3037  string dllproj[] = {"DLL_PROJ","EXPENDABLE_DLL_PROJ","POTENTIAL_DLL_PROJ",""};
3040  for (j=0; !dllproj[j].empty(); ++j) {
3041  k = makefile.m_Contents.find(dllproj[j]);
3042  if (k != makefile.m_Contents.end()) {
3043  const list<string>& values = k->second;
3044  for (list<string>::const_iterator i=values.begin(); i!=values.end(); ++i) {
3045  if (i->at(0) == '#') {
3046  break;
3047  }
3048  string mkname("Makefile." + *i + ".dll");
3049  dllprojects[mkname] = max(maketype, dlltype[j]);
3050  if (get_order) {
3051  s_WriteBuildOrder(dir_name,mkname);
3052  }
3053  }
3054  }
3055  }
3056  string metallib[] = {"METAL_PROJ", ""};
3057  EMakeFileType metaltype[] = { eMakeType_Undefined};
3058  for (j=0; !metallib[j].empty(); ++j) {
3059  k = makefile.m_Contents.find(metallib[j]);
3060  if (k != makefile.m_Contents.end()) {
3061  const list<string>& values = k->second;
3062  for (list<string>::const_iterator i=values.begin(); i!=values.end(); ++i) {
3063  if (i->at(0) == '#') {
3064  break;
3065  }
3066  string mkname("Makefile." + *i + ".metal");
3067  libprojects[mkname] = max(maketype, metaltype[j]);
3068  if (get_order) {
3069  s_WriteBuildOrder(dir_name,mkname);
3070  }
3071  has_metal = true;
3072  }
3073  }
3074  }
3075  string appproj[] = {"APP_PROJ","EXPENDABLE_APP_PROJ","POTENTIAL_APP_PROJ",""};
3077  if (filter->ExcludePotential()) {
3078  apptype[2] = eMakeType_Excluded;
3079  }
3080  for (j=0; !appproj[j].empty(); ++j) {
3081  k = makefile.m_Contents.find(appproj[j]);
3082  if (k != makefile.m_Contents.end()) {
3083  const list<string>& values = k->second;
3084  for (list<string>::const_iterator i=values.begin(); i!=values.end(); ++i) {
3085  if (i->at(0) == '#') {
3086  break;
3087  }
3088  string mkname("Makefile." + *i + ".app");
3089  appprojects[mkname] = max(maketype, apptype[j]);
3090  if (get_order) {
3091  s_WriteBuildOrder(dir_name,mkname);
3092  }
3093  }
3094  }
3095  }
3096  }
3097  }
3098  }
3099 
3100  // Process Makefile.*.lib
3101  if ( process_projects && !libprojects.empty()) {
3102  CDir dir(dir_name);
3103  CDir::TEntries contents = dir.GetEntries("Makefile.*.lib");
3104  ITERATE(CDir::TEntries, p, contents) {
3105  const AutoPtr<CDirEntry>& dir_entry = *p;
3106  const string name = dir_entry->GetName();
3107  if (libprojects.find(name) != libprojects.end() &&
3109  ProcessMakeLibFile(dir_entry->GetPath(), makefiles, libprojects[name], mkin);
3110 
3111  }
3112  if (has_metal) {
3113  contents = dir.GetEntries("Makefile.*.metal");
3114  ITERATE(CDir::TEntries, p, contents) {
3115  const AutoPtr<CDirEntry>& dir_entry = *p;
3116  const string name = dir_entry->GetName();
3117  if (libprojects.find(name) != libprojects.end()) {
3118  ProcessMakeLibFile(dir_entry->GetPath(), makefiles, libprojects[name], mkin);
3119  }
3120  }
3121  }
3122  }
3123  // Process Makefile.*.dll
3124  if ( process_projects && !dllprojects.empty()) {
3125  CDir dir(dir_name);
3126  CDir::TEntries contents = dir.GetEntries("Makefile.*.dll");
3127  ITERATE(CDir::TEntries, p, contents) {
3128  const AutoPtr<CDirEntry>& dir_entry = *p;
3129  const string name = dir_entry->GetName();
3130  if (dllprojects.find(name) != dllprojects.end() &&
3132  ProcessMakeDllFile(dir_entry->GetPath(), makefiles, dllprojects[name], mkin);
3133 
3134  }
3135  }
3136  // Process Makefile.*.app
3137  if ( process_projects && !appprojects.empty() ) {
3138  CDir dir(dir_name);
3139  CDir::TEntries contents = dir.GetEntries("Makefile.*.app");
3140  ITERATE(CDir::TEntries, p, contents) {
3141  const AutoPtr<CDirEntry>& dir_entry = *p;
3142  const string name = dir_entry->GetName();
3143  if (appprojects.find(name) != appprojects.end() &&
3145  ProcessMakeAppFile(dir_entry->GetPath(), makefiles, appprojects[name], mkin);
3146 
3147  }
3148  }
3149  // Process Makefile.*.msvcproj
3150  if ( process_projects && !userprojects.empty() ) {
3151  CDir dir(dir_name);
3152 // CDir::TEntries contents = dir.GetEntries("Makefile.*.msvcproj");
3153  CDir::TEntries contents = dir.GetEntries("Makefile.*");
3154  ITERATE(CDir::TEntries, p, contents) {
3155  const AutoPtr<CDirEntry>& dir_entry = *p;
3156  const string name = dir_entry->GetName();
3157  if (userprojects.find(name) != userprojects.end() /*&&
3158  SMakeProjectT::IsUserProjFile(name)*/ )
3159  ProcessUserProjFile(dir_entry->GetPath(), makefiles, userprojects[name], mkin);
3160 
3161  }
3162  }
3163 
3164  if ( process_projects) {
3165  /*if (!GetApp().IsScanningWholeTree())*/ {
3166  CDir dir(dir_name);
3167  CDir::TEntries contents = dir.GetEntries(GetApp().GetProjectTreeInfo().m_CustomMetaData);
3168  ITERATE(CDir::TEntries, p, contents) {
3169  GetApp().AddCustomMetaData( (*p)->GetPath());
3170  }
3171  contents = dir.GetEntries(GetApp().GetProjectTreeInfo().m_CustomConfH);
3172  ITERATE(CDir::TEntries, p, contents) {
3173  GetApp().AddCustomConfH( (*p)->GetPath());
3174  }
3175  }
3176  }
3177 
3178  // Convert subprojects to subdirs
3179  map<string, EMakeFileType> subprojects_dirs;
3180  vector<string> ordered_subprojects_dirs;
3181 
3182  // begin with explicitely requested subprojects
3183  ITERATE( vector<string>, p, ordered_subprojects) {
3184  string name(*p);
3185  CDirEntry dir_entry( CDirEntry::ConcatPath(dir_name, name));
3186  if ( dir_entry.IsDir() ) {
3187  if (subprojects.find(name) != subprojects.end()) {
3188  subprojects_dirs[dir_entry.GetPath()] = subprojects[name];
3189  } else {
3190  subprojects_dirs[dir_entry.GetPath()] =
3192  }
3193  if (find(ordered_subprojects_dirs.begin(), ordered_subprojects_dirs.end(), name) ==
3194  ordered_subprojects_dirs.end()) {
3195  ordered_subprojects_dirs.push_back(name);
3196  } else {
3198  "Duplicate entry: " << name);
3199  }
3200  }
3201  }
3202 
3203 // if ( is_root || (!process_projects && weak) ) {
3204  CDir dir(dir_name);
3205  CDir::TEntries contents = dir.GetEntries("*");
3206  ITERATE(CDir::TEntries, p, contents) {
3207  const AutoPtr<CDirEntry>& dir_entry = *p;
3208  if ( !dir_entry->IsDir() ) {
3209  continue;
3210  }
3211  string name = dir_entry->GetName();
3212 // if ( name == "." || name == ".." || name == "CVS" || name == ".svn" ||
3213  if ( name[0] == '.' || name == "CVS" ||
3214  name == string(1,CDir::GetPathSeparator()) ) {
3215  continue;
3216  }
3217  if (find(ordered_subprojects_dirs.begin(), ordered_subprojects_dirs.end(), name) !=
3218  ordered_subprojects_dirs.end()) {
3219  // already processed
3220  continue;
3221  }
3222  if (subprojects.find(name) != subprojects.end()) {
3223  subprojects_dirs[dir_entry->GetPath()] = subprojects[name];
3224  } else {
3225  subprojects_dirs[dir_entry->GetPath()] =
3227  }
3228  if (find(ordered_subprojects_dirs.begin(), ordered_subprojects_dirs.end(), name) ==
3229  ordered_subprojects_dirs.end()) {
3230  ordered_subprojects_dirs.push_back(name);
3231  }
3232  }
3233  {
3235  for (s = subprojects.begin(); s != subprojects.end(); ++s) {
3236  if (s->first.find('/') != string::npos) {
3237  CDir dir_entry(CDirEntry::NormalizePath(
3238  CDirEntry::ConcatPath(dir_name, s->first)));
3239  if (dir_entry.IsDir()) {
3240  subprojects_dirs[dir_entry.GetPath()] = subprojects[s->first];
3241  }
3242  }
3243  }
3244  }
3245 /*
3246  } else {
3247  // for non-root only subprojects
3248  map<string, EMakeFileType>::const_iterator p;
3249  for (p = subprojects.begin(); p != subprojects.end(); ++p) {
3250  const string& subproject = p->first;
3251  string subproject_dir =
3252  CDirEntry::ConcatPath(dir_name, subproject);
3253  subprojects_dirs[subproject_dir] = p->second;
3254  }
3255  }
3256 */
3257 
3258  // Process subproj ( e.t. subdirs )
3259  ITERATE( vector<string>, ps, ordered_subprojects_dirs) {
3260  const string& subproject_dir = CDirEntry::ConcatPath(dir_name, *ps);
3261  ProcessDir(subproject_dir, false, filter, makefiles, subprojects_dirs[subproject_dir], mkin);
3262  }
3263 
3264 }
3265 
3266 
3268  SMakeFiles* makefiles,
3270  const CSimpleMakeFileContents* parent)
3271 {
3273  fc.SetParent(parent);
3274  if ( !fc.m_Contents.empty() ) {
3275  makefiles->m_In[file_name] = fc;
3277  } else {
3278  PTB_WARNING(file_name, "ignored; empty");
3279  }
3280 }
3281 
3282 
3284  SMakeFiles* makefiles,
3286  const CSimpleMakeFileContents* parent)
3287 {
3289  fc.SetParent(parent);
3290  if ( !fc.m_Contents.empty() ) {
3291  makefiles->m_Lib[file_name] = fc;
3293  } else {
3294  PTB_WARNING(file_name, "ignored; empty");
3295  }
3296 }
3297 
3299  SMakeFiles* makefiles,
3301  const CSimpleMakeFileContents* parent)
3302 {
3303  string s = "MakeDll : " + file_name + " ";
3304 
3306  fc.SetParent(parent);
3307  if ( !fc.m_Contents.empty() ) {
3308  makefiles->m_Dll[file_name] = fc;
3309  } else {
3310  PTB_INFO(s << "rejected (is empty)");
3311  }
3312 }
3313 
3314 
3316  SMakeFiles* makefiles,
3318  const CSimpleMakeFileContents* parent)
3319 {
3321  fc.SetParent(parent);
3322  if ( !fc.m_Contents.empty() ) {
3323  makefiles->m_App[file_name] = fc;
3325  } else {
3326  PTB_WARNING(file_name, "ignored; empty");
3327  }
3328 }
3329 
3330 
3332  SMakeFiles* makefiles,
3334  const CSimpleMakeFileContents* parent)
3335 {
3338  fc.SetParent(parent);
3339  if ( allow_empty || !fc.m_Contents.empty() ) {
3340  makefiles->m_User[file_name] = fc;
3342  } else {
3343  PTB_WARNING(file_name, "ignored; empty");
3344  }
3345 }
3346 
3347 //recursive resolving
3349  SMakeFiles& makefiles)
3350 {
3351  {{
3352  _TRACE("*** Resolving macrodefinitions in App projects ***");
3353  //App
3354  set<string> keys;
3355  keys.insert("LIB");
3356  keys.insert("LIBS");
3357  if (GetApp().GetBuildType().GetType() == CBuildType::eStatic) {
3358  keys.insert("STATIC_LIB");
3359  keys.insert("STATIC_LIBS");
3360  }
3361  keys.insert("NCBI_C_LIBS");
3362  SMakeProjectT::DoResolveDefs(resolver, makefiles.m_App, keys);
3363  }}
3364 
3365  {{
3366  _TRACE("*** Resolving macrodefinitions in Lib projects ***");
3367  //Lib
3368  set<string> keys;
3369  keys.insert("LIB");
3370  keys.insert("LIBS");
3371  if (GetApp().GetBuildType().GetType() == CBuildType::eStatic) {
3372  keys.insert("STATIC_LIB");
3373  keys.insert("STATIC_LIBS");
3374  }
3375  keys.insert("SRC");
3376  keys.insert("DLL_LIB");
3377  if (GetApp().GetBuildType().GetType() == CBuildType::eDll) {
3378  keys.insert("DLL_DLIB");
3379  }
3380  SMakeProjectT::DoResolveDefs(resolver, makefiles.m_Lib, keys);
3381  }}
3382 
3383  {{
3384  _TRACE("*** Resolving macrodefinitions in Msvc projects ***");
3385  set<string> keys;
3386  keys.insert("DLL_DEP");
3387  SMakeProjectT::DoResolveDefs(resolver, makefiles.m_User, keys);
3388  }}
3389  {{
3390  set<string> keys;
3391  SMakeProjectT::DoResolveDefs(resolver, makefiles.m_In, keys);
3392  SMakeProjectT::DoResolveDefs(resolver, makefiles.m_Dll, keys);
3393  }}
3394 }
3395 
3396 
3397 //analyze modules
3399  map<string, CProjKey>* datatool_ids)
3400 {
3401  ITERATE(CProjectItemsTree::TProjects, p, tree.m_Projects) {
3402  const CProjKey& project_id = p->first;
3403  if (project_id.Type() == CProjKey::eDataSpec) {
3404  continue;
3405  }
3406  const CProjItem& project = p->second;
3407  ITERATE(list<CDataToolGeneratedSrc>, n, project.m_DatatoolSources) {
3408  const CDataToolGeneratedSrc& src = *n;
3409  string src_abs_path =
3411  string src_rel_path =
3413  (GetApp().GetProjectTreeInfo().m_Src,
3414  src_abs_path);
3415  (*datatool_ids)[src_rel_path] = project_id;
3416  }
3417  }
3418 }
3419 
3420 
3422 {
3423  //datatool src rel path / project ID
3424 
3425  // 1. Collect all projects with datatool-generated-sources
3426  map<string, CProjKey> whole_datatool_ids;
3427  bool whole_collected = false;
3428  if (GetApp().IsScanningWholeTree()) {
3429  whole_collected = true;
3430  s_CollectDatatoolIds(GetApp().GetWholeTree(), &whole_datatool_ids);
3431  }
3432 
3433  // 2. Extent tree to accomodate more ASN projects if necessary
3434  bool tree_extented = false;
3435  map<string, CProjKey> datatool_ids;
3436 
3437  do {
3438 
3439  tree_extented = false;
3440  s_CollectDatatoolIds(*tree, &datatool_ids);
3441 
3443 
3445 // const CProjKey& project_id = p->first;
3446  CProjItem& project = p->second;
3447  ITERATE(list<CDataToolGeneratedSrc>, n, project.m_DatatoolSources) {
3448  const CDataToolGeneratedSrc& src = *n;
3449  ITERATE(list<string>, i, src.m_ImportModules) {
3450  const string& module = *i;
3452  datatool_ids.find(module);
3453  if (j == datatool_ids.end()) {
3454  if (!whole_collected) {
3455  whole_collected = true;
3456  s_CollectDatatoolIds(GetApp().GetWholeTree(), &whole_datatool_ids);
3457  }
3458  j = whole_datatool_ids.find(module);
3459  if (j != whole_datatool_ids.end()) {
3460  const CProjKey& depends_id = j->second;
3461 #if 1
3462 datatool_ids[module] = depends_id;
3463 added[depends_id] = GetApp().GetWholeTree().m_Projects.find(depends_id)->second;
3464 #else
3465  tree->m_Projects[depends_id] =
3466  GetApp().GetWholeTree().m_Projects.find(depends_id)->second;
3467  tree_extented = true;
3468 #endif
3469  }
3470  }
3471  }
3472  }
3473  }
3474 #if 1
3475  tree_extented = !added.empty();
3477  tree->m_Projects[p->first] = p->second;
3478  }
3479 #endif
3480  } while( tree_extented );
3481 
3482 
3483  CProjKey proj_key(CProjKey::eDataSpec, GetApp().GetDataspecProjId());
3484  CProjectItemsTree::TProjects::iterator z = tree->m_Projects.find(proj_key);
3485 
3486  // 3. Finally - generate depends
3488  const CProjKey& project_id = p->first;
3489  if (project_id.Type() == CProjKey::eDataSpec) {
3490  continue;
3491  }
3492  CProjItem& project = p->second;
3493  ITERATE(list<CDataToolGeneratedSrc>, n, project.m_DatatoolSources) {
3494  const CDataToolGeneratedSrc& src = *n;
3495  if (z != tree->m_Projects.end()) {
3496  z->second.m_DatatoolSources.push_back(src);
3497  }
3498  ITERATE(list<string>, i, src.m_ImportModules) {
3499  const string& module = *i;
3501  datatool_ids.find(module);
3502  if (j != datatool_ids.end()) {
3503  const CProjKey& depends_id = j->second;
3504  if (depends_id != project_id) {
3505  project.m_Depends.push_back(depends_id);
3506  project.m_Depends.sort();
3507  project.m_Depends.unique();
3508  }
3509  }
3510  }
3511  }
3512  }
3513 
3514 }
3515 
3516 
AutoPtr –.
Definition: ncbimisc.hpp:401
EBuildType GetType(void) const
static void LoadFrom(const string &source_file_path, CDataToolGeneratedSrc *src)
CDirEntry –.
Definition: ncbifile.hpp:262
CDir –.
Definition: ncbifile.hpp:1695
CFile –.
Definition: ncbifile.hpp:1604
static EMsvcPlatform GetMsvcPlatform(void)
static string GetTopBuilddir(void)
static EMsvcVersion GetMsvcVersion(void)
bool IsEmpty(void) const
CMsvcProjectMakefile –.
bool Redefine(const string &value, list< string > &redef) const
void Append(list< string > &values, const string &def) const
virtual void GetAdditionalLIB(const SConfigInfo &config, list< string > *lib_ids) const
virtual void GetExcludedLIB(const SConfigInfo &config, list< string > *lib_ids) const
CMsvcSite –.
Definition: msvc_site.hpp:131
bool IsLibWithChoice(const string &lib_id) const
Definition: msvc_site.cpp:485
void CollectRequires(const list< string > &reqs) const
Definition: msvc_site.cpp:469
bool ResolveDefine(const string &define, string &resolved) const
Definition: msvc_site.cpp:418
bool Is3PartyLibWithChoice(const string &lib3party_id) const
Definition: msvc_site.cpp:506
void GetLibChoiceIncludes(const string &cpp_flags_define, list< string > *abs_includes) const
Definition: msvc_site.cpp:582
CNcbiOstrstreamToString class helps convert CNcbiOstrstream to a string Sample usage:
Definition: ncbistre.hpp:802
CProjBulderApp –.
set< string > m_Frameworks
void UpdateDepGraph(CProjectTreeBuilder::TFiles &files)
void AddCustomMetaData(const string &file)
const CBuildType & GetBuildType(void)
map< string, list< string > > m_3PartyLibraryOrder
map< string, set< string > > m_GraphDepIncludes
map< string, size_t > m_GraphDepRank
set< string > m_3PartyLibs
map< string, list< string > > m_LibraryOrder
void SetFail(int exit_code=1)
void RegisterSuspiciousProject(const CProjKey &proj)
void ExcludeUnrequestedProjects(CProjectItemsTree &tree) const
void AddCustomConfH(const string &file)
void GetMetaDataFiles(list< string > *files) const
string ProcessLocationMacros(string data)
const CProjectItemsTree & GetWholeTree(void)
const CMsvc7RegSettings & GetRegSettings(void)
void ExcludeProjectsByTag(CProjectItemsTree &tree) const
map< string, set< string > > m_GraphDepFlags
bool IsScanningWholeTree(void) const
map< string, set< string > > m_GraphDepPrecedes
const CMsvcSite & GetSite(void)
CProjItem –.
Definition: proj_item.hpp:54
list< string > m_IncludeDirs
Resolved contents of CPPFLAG ( -I<m_IncludeDir> -I/..) Absolute pathes.
Definition: proj_item.hpp:113
list< string > m_Sources
List of source files without extension ( *.cpp or *.c ) - with relative pathes from m_SourcesBaseDir.
Definition: proj_item.hpp:99
bool m_StyleObjcpp
Definition: proj_item.hpp:149
CSimpleMakeFileContents m_DataSource
Definition: proj_item.hpp:152
list< CProjKey > m_Depends
What projects this project is depend upon (IDs).
Definition: proj_item.hpp:102
list< CDataToolGeneratedSrc > m_DatatoolSources
Source files *.asn , *.dtd to be processed by datatool app.
Definition: proj_item.hpp:116
bool m_External
Definition: proj_item.hpp:148
TProjType m_ProjType
Type of the project.
Definition: proj_item.hpp:89
bool m_IsBundle
Definition: proj_item.hpp:146
EMakeFileType m_MakeType
Type of the project.
Definition: proj_item.hpp:125
string m_ID
ID of atomic project.
Definition: proj_item.hpp:86
list< string > m_HostedLibs
Definition: proj_item.hpp:131
string m_MkName
Definition: proj_item.hpp:150
string m_GUID
project GUID
Definition: proj_item.hpp:128
string m_Pch
Precompiled header.
Definition: proj_item.hpp:95
string m_Watchers
Definition: proj_item.hpp:136
list< string > m_NcbiCLibs
Libraries from NCBI C Toolkit to link with.
Definition: proj_item.hpp:122
list< string > m_ProjTags
Definition: proj_item.hpp:143
string m_Name
Name of atomic project.
Definition: proj_item.hpp:83
string m_SourcesBaseDir
Base directory of source files (....c++/src/a/ )
Definition: proj_item.hpp:92
list< string > m_CheckInfo
Definition: proj_item.hpp:137
CProjKey –.
const string & Id(void) const
Definition: proj_item.cpp:112
TProjType Type(void) const
Definition: proj_item.cpp:106
Resolver for SRC keys in Makefiles:
void ResolveTo(list< string > *sources_dst)
CProjectItemsTree –.
Definition: proj_tree.hpp:54
static void CreateFrom(const string &root_src, const TFiles &makein, const TFiles &makelib, const TFiles &makedll, const TFiles &makeapp, const TFiles &makemsvc, CProjectItemsTree *tree)
Definition: proj_tree.cpp:94
TProjects m_Projects
Definition: proj_tree.hpp:70
void GetExternalDepends(list< CProjKey > *externalDepends) const
Get depends that are not inside this project tree.
Definition: proj_tree.cpp:253
static bool VerifyBuildOrder(const CProjItem &item, list< string > dependencies, const CProjectItemsTree &tree)
static void ProcessDir(const string &dir_name, bool is_root, const IProjectFilter *filter, SMakeFiles *makefiles, EMakeFileType maketype, const CSimpleMakeFileContents *parent)
static void ProcessMakeLibFile(const string &file_name, SMakeFiles *makefiles, EMakeFileType type, const CSimpleMakeFileContents *parent)
static void BuildOneProjectTree(const IProjectFilter *filter, const string &root_src_path, CProjectItemsTree *tree)
Build one project tree and do not resolve (include) depends.
static void ProcessUserProjFile(const string &file_name, SMakeFiles *makefiles, EMakeFileType type, const CSimpleMakeFileContents *parent)
static void ResolveDefs(CSymResolver &resolver, SMakeFiles &makefiles)
static void AddDatatoolSourcesDepends(CProjectItemsTree *tree)
static void ProcessMakeAppFile(const string &file_name, SMakeFiles *makefiles, EMakeFileType type, const CSimpleMakeFileContents *parent)
static void ProcessMakeInFile(const string &file_name, SMakeFiles *makefiles, EMakeFileType type, const CSimpleMakeFileContents *parent)
static void BuildProjectTree(const IProjectFilter *filter, const string &root_src_path, CProjectItemsTree *tree)
Build project tree and include all projects this tree depends upon.
static void ProcessMakeDllFile(const string &file_name, SMakeFiles *makefiles, EMakeFileType type, const CSimpleMakeFileContents *parent)
CSimpleMakeFileContents –.
EMakeFileType GetMakeType(void) const
bool CollectValues(const string &key, list< string > &values, EHowToCollect how) const
bool GetValue(const string &key, string &value) const
void Resolve(const string &define, list< string > *resolved_def)
Definition: resolver.cpp:81
CSymResolver & Append(const CSymResolver &src, bool warn_redef=false)
Definition: resolver.cpp:213
static string StripDefine(const string &define)
Definition: resolver.cpp:75
static bool HasDefine(const string &param)
Definition: resolver.cpp:266
static bool StripSuffix(string &libname, string *suffix=nullptr)
Definition: resolver.cpp:243
static bool IsDefine(const string &param)
Definition: resolver.cpp:258
bool GetValue(const string &key, string &value) const
Definition: resolver.hpp:93
Utilits for Project Tree Builder:
Definition: proj_utils.hpp:43
virtual bool ExcludePotential(void) const =0
virtual bool CheckProject(const string &project_base_dir, bool *weak=0) const =0
MDiagFile –.
size_type size() const
Definition: map.hpp:148
const_iterator begin() const
Definition: map.hpp:151
const_iterator end() const
Definition: map.hpp:152
bool empty() const
Definition: map.hpp:149
void clear()
Definition: map.hpp:169
const_iterator find(const key_type &key) const
Definition: map.hpp:153
iterator_bool insert(const value_type &val)
Definition: set.hpp:149
const_iterator begin() const
Definition: set.hpp:135
void clear()
Definition: set.hpp:153
size_type size() const
Definition: set.hpp:132
bool empty() const
Definition: set.hpp:133
const_iterator find(const key_type &key) const
Definition: set.hpp:137
void erase(iterator pos)
Definition: set.hpp:151
const_iterator end() const
Definition: set.hpp:136
pre_order_iterator begin() const
Definition: tree_msvc7.hpp:573
iter erase(iter)
Definition: tree_msvc7.hpp:546
pre_order_iterator end() const
Definition: tree_msvc7.hpp:579
static uch flags
constexpr auto begin(const ct_const_array< T, N > &in) noexcept
constexpr auto end(const ct_const_array< T, N > &in) noexcept
const char * file_name[]
string MakeFileTypeAsString(EMakeFileType type)
EMakeFileType
@ eMakeType_Undefined
@ eMakeType_Potential
@ eMakeType_Expendable
@ eMakeType_Excluded
int failed
Definition: dbmorecmds.c:10
#define check(s)
Definition: describecol2.c:21
static char tmp[3200]
Definition: utf8.c:42
static char test_name[128]
Definition: utf8_2.c:34
#define ITERATE(Type, Var, Cont)
ITERATE macro to sequence through container elements.
Definition: ncbimisc.hpp:815
#define NON_CONST_ITERATE(Type, Var, Cont)
Non constant version of ITERATE macro.
Definition: ncbimisc.hpp:822
#define NULL
Definition: ncbistd.hpp:225
#define _TRACE(message)
Definition: ncbidbg.hpp:122
#define ERR_POST(message)
Error posting with file, line number information but without error codes.
Definition: ncbidiag.hpp:186
void Error(CExceptionArgs_Base &args)
Definition: ncbiexpt.hpp:1197
void Warning(CExceptionArgs_Base &args)
Definition: ncbiexpt.hpp:1191
static string NormalizePath(const string &path, EFollowLinks follow_links=eIgnoreLinks)
Normalize a path.
Definition: ncbifile.cpp:820
TEntries GetEntries(const string &mask=kEmptyStr, TGetEntriesFlags flags=0) const
Get directory entries based on the specified "mask".
Definition: ncbifile.cpp:3846
static bool IsAbsolutePath(const string &path)
Check if a "path" is absolute for the current OS.
Definition: ncbifile.cpp:508
int TGetEntriesFlags
Binary OR of "EGetEntriesFlags".
Definition: ncbifile.hpp:1779
static string DeleteTrailingPathSeparator(const string &path)
Delete trailing path separator, if any.
Definition: ncbifile.cpp:465
static string AddTrailingPathSeparator(const string &path)
Add trailing path separator, if needed.
Definition: ncbifile.cpp:455
static string CreateRelativePath(const string &path_from, const string &path_to)
Create a relative path between two points in the file system specified by their absolute paths.
Definition: ncbifile.cpp:599
bool IsDir(EFollowLinks follow=eFollowLinks) const
Check whether a directory entry is a directory.
Definition: ncbifile.hpp:3946
static string ConvertToOSPath(const string &path)
Convert "path" on any OS to the current OS-dependent path.
Definition: ncbifile.cpp:745
static char GetPathSeparator(void)
Get path separator symbol specific for the current platform.
Definition: ncbifile.cpp:433
static string ConcatPath(const string &first, const string &second)
Concatenate two parts of the path for the current OS.
Definition: ncbifile.cpp:776
string GetName(void) const
Get the base entry name with extension (if any).
Definition: ncbifile.hpp:3916
list< TEntry > TEntries
Definition: ncbifile.hpp:1750
const string & GetPath(void) const
Get entry path.
Definition: ncbifile.hpp:3910
string GetExt(void) const
Get extension name.
Definition: ncbifile.hpp:3932
@ fIgnoreRecursive
Suppress "self recursive" elements (the directories "." and "..").
Definition: ncbifile.hpp:1755
#define END_NCBI_SCOPE
End previously defined NCBI scope.
Definition: ncbistl.hpp:103
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
Definition: ncbistl.hpp:100
#define kEmptyStr
Definition: ncbistr.hpp:123
static int CompareNocase(const CTempString s1, SIZE_TYPE pos, SIZE_TYPE n, const char *s2)
Case-insensitive compare of a substring with another string.
Definition: ncbistr.cpp:219
static list< string > & Split(const CTempString str, const CTempString delim, list< string > &arr, TSplitFlags flags=0, vector< SIZE_TYPE > *token_pos=NULL)
Split a string using specified delimiters.
Definition: ncbistr.cpp:3461
static bool EndsWith(const CTempString str, const CTempString end, ECase use_case=eCase)
Check if a string ends with a specified suffix value.
Definition: ncbistr.hpp:5430
#define NPOS
Definition: ncbistr.hpp:133
static void TruncateSpacesInPlace(string &str, ETrunc where=eTrunc_Both)
Truncate spaces in a string (in-place)
Definition: ncbistr.cpp:3201
static string Join(const TContainer &arr, const CTempString &delim)
Join strings using the specified delimiter.
Definition: ncbistr.hpp:2697
static string & Replace(const string &src, const string &search, const string &replace, string &dst, SIZE_TYPE start_pos=0, SIZE_TYPE max_replace=0, SIZE_TYPE *num_replace=0)
Replace occurrences of a substring within a string.
Definition: ncbistr.cpp:3314
static bool StartsWith(const CTempString str, const CTempString start, ECase use_case=eCase)
Check if a string starts with a specified prefix value.
Definition: ncbistr.hpp:5412
static string & ReplaceInPlace(string &src, const string &search, const string &replace, SIZE_TYPE start_pos=0, SIZE_TYPE max_replace=0, SIZE_TYPE *num_replace=0)
Replace occurrences of a substring within a string.
Definition: ncbistr.cpp:3405
static int CompareCase(const CTempString s1, SIZE_TYPE pos, SIZE_TYPE n, const char *s2)
Case-sensitive compare of a substring with another string.
Definition: ncbistr.cpp:135
@ fSplit_Truncate
Definition: ncbistr.hpp:2501
@ fSplit_Tokenize
All delimiters are merged and trimmed, to get non-empty tokens only.
Definition: ncbistr.hpp:2508
@ fSplit_CanQuote
Definition: ncbistr.hpp:2506
@ fSplit_MergeDelimiters
Merge adjacent delimiters.
Definition: ncbistr.hpp:2498
int i
yy_size_t n
static MDB_envinfo info
Definition: mdb_load.c:37
string CreateMsvcProjectMakefileName(const string &project_name, CProjItem::TProjType type)
Create project makefile name.
#define LIST_SEPARATOR
Separator for list values in registry.
CProjKey CreateProjKey(const string &project_name)
string IdentifySlnGUID(const string &source_dir, const CProjKey &proj)
void EraseIf(C &cont, const P &pred)
Erase if predicate is true.
const TYPE & Get(const CNamedParameterList *param)
constexpr bool empty(list< Ts... >) noexcept
const struct ncbi::grid::netcache::search::fields::SIZE size
const struct ncbi::grid::netcache::search::fields::KEY key
unsigned int a
Definition: ncbi_localip.c:102
EIPRangeType t
Definition: ncbi_localip.c:101
ESERV_Site site
T max(T x_, T y_)
double r(size_t dimension_, const Int4 *score_, const double *prob_, double theta_)
void copy(Njn::Matrix< S > *matrix_, const Njn::Matrix< T > &matrix0_)
Definition: njn_matrix.hpp:613
double f(double x_, const double &y_)
Definition: njn_root.hpp:188
#define fc
static const char * suffix[]
Definition: pcregrep.c:408
CProjBulderApp & GetApp(void)
access to App singleton
static size_t s_BuildOrder
void s_CollectDatatoolIds(const CProjectItemsTree &tree, map< string, CProjKey > *datatool_ids)
CProjItem CreateUtilityProjectItem(const string &prj_dir, const string &name)
static void s_CollectAllLeaves(const map< string, set< string > > &source_dep, const map< string, set< string > > &source_flags, const string &branch, set< string > &all_dep, set< string > &all_flags)
const char * s_check_separator
void s_WriteBuildOrder(const string &dir_name, const string &mkname)
static map< string, size_t > s_buildOrder_byname
void s_AnalyzeLibraryOrder(CSymResolver &resolver, const CProjectItemsTree &tree)
string ParentDir(const string &dir_abs)
Definition: proj_utils.cpp:36
#define PTB_INFO_EX(file, err_code, msg)
#define PTB_WARNING(file, msg)
#define PTB_ERROR_EX(file, err_code, msg)
#define PTB_INFO(msg)
@ ePTB_MacroInvalid
@ ePTB_ProjectExcluded
@ ePTB_ProjectNotFound
@ ePTB_NoError
@ ePTB_InvalidMakefile
@ ePTB_FileNotFound
@ ePTB_ConfigurationError
@ ePTB_MissingMakefile
@ ePTB_FileExcluded
@ ePTB_MacroUndefined
#define PTB_WARNING_EX(file, err_code, msg)
#define PTB_TRACE_EX(file, err_code, msg)
string FilterDefine(const string &define)
Definition: resolver.cpp:326
static bool check_name(const char *name)
Definition: setenv.c:26
bool operator()(const string &lib_id) const
set< string > m_ExcludedLib
PLibExclude(const string &prj_name, const list< string > &excluded_lib_ids)
static CProjKey DoCreate(const string &source_base_dir, const string &proj_name, const string &applib_mfilepath, const TFiles &makeapp, CProjectItemsTree *tree, EMakeFileType maketype)
static void CreateNcbiCToolkitLibs(const CSimpleMakeFileContents &makefile, list< string > *libs_list)
static CProjKey DoCreate(const string &source_base_dir, const string &proj_name, const string &applib_mfilepath, const TFiles &makeapp, const TFiles &makelib, CProjectItemsTree *tree, const SMakeProjectT::SMakeInInfo &makeinfo)
static CProjKey DoCreate(const string &source_base_dir, const string &proj_name, const string &applib_mfilepath, const TFiles &makeapp, const TFiles &makelib, CProjectItemsTree *tree, const SMakeProjectT::SMakeInInfo &makeinfo)
static CProjKey DoCreate(const string &source_base_dir, const string &proj_name, const string &applib_mfilepath, const TFiles &makeapp, const TFiles &makelib, CProjectItemsTree *tree, const SMakeProjectT::SMakeInInfo &makeinfo)
static TAsnType GetAsnProjectType(const string &applib_mfilepath, const TFiles &makeapp, const TFiles &makelib)
SConfigInfo –.
static CProjKey DoCreate(const string &source_base_dir, const string &proj_name, const string &applib_mfilepath, const TFiles &makeapp, CProjectItemsTree *tree, EMakeFileType maketype)
static CProjKey DoCreateDataSpec(const string &source_base_dir, const string &proj_name, const string &proj_id, CProjectItemsTree *tree, EMakeFileType maketype)
static CProjKey DoCreate(const string &source_base_dir, const string &proj_name, const string &applib_mfilepath, const TFiles &makeapp, CProjectItemsTree *tree, EMakeFileType maketype)
static bool IsMakeAppFile(const string &name)
static void DoResolveDefs(CSymResolver &resolver, CProjectItemsTree::TFiles &files, const set< string > &keys)
static void VerifyLibDepends(list< CProjKey > &depends_ids, const string &mkname, list< string > &liborder, const set< string > *libs_3party=nullptr, list< string > *expected_3party=nullptr)
static bool IsMakeDllFile(const string &name)
static bool IsConfigurableDefine(const string &define)
static void ConvertLibDepends(const list< string > &depends_libs, list< CProjKey > *depends_ids, const string *mkname=NULL, list< string > *expected_3party=NULL)
static string CreateMakeAppLibFileName(const string &base_dir, const string &projname, SMakeInInfo::TMakeinType type=SMakeInInfo::eUnknown)
static void Create3PartyLibs(const list< string > &libs_flags, const list< string > &expected_flags, list< string > *libs_list, const string *mkname=NULL)
list< SMakeInInfo > TMakeInInfoList
static void CreateIncludeDirs(const list< string > &cpp_flags, const string &source_base_dir, list< string > *include_dirs)
static void CreateDefines(const list< string > &cpp_flags, list< string > *defines)
static void AnalyzeMakeIn(const CSimpleMakeFileContents &makein_contents, TMakeInInfoList *info)
static string ExtractConfigurableDefine(const string &define)
static bool HasConfigurableDefine(const string &define)
static void ConvertLibDependsMacro(const list< string > &depends, list< string > &depends_libs)
static string GetOneIncludeDir(const string &flag, const string &token)
static string StripConfigurableDefine(const string &define)
static bool IsMakeInFile(const string &name)
static bool IsMakeLibFile(const string &name)
static CProjItem::TProjType GetProjType(const string &base_dir, const string &projname, SMakeInInfo::TMakeinType type=SMakeInInfo::eUnknown)
static void CreateFullPathes(const string &dir, const list< string > files, list< string > *full_pathes)
static CProjKey DoCreate(const string &source_base_dir, const string &proj_name, const string &applib_mfilepath, const TFiles &makemsvc, CProjectItemsTree *tree, EMakeFileType maketype)
Definition: type.c:6
done
Definition: token1.c:1
static wxAcceleratorEntry entries[3]
Modified on Sun Jun 23 05:18:17 2024 by modify_doxy.py rev. 669887