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

Go to the SVN repository for this file.

1 /* $Id: msvc_prj_utils.cpp 89181 2020-03-04 19:52:40Z 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 "msvc_prj_utils.hpp"
32 #include "proj_builder_app.hpp"
33 #include "msvc_prj_defines.hpp"
34 #include "ptb_err_codes.hpp"
35 #include <corelib/ncbi_system.hpp>
36 
37 #ifdef NCBI_COMPILER_MSVC
38 # include <serial/objostrxml.hpp>
39 # include <serial/objistr.hpp>
40 # include <serial/serial.hpp>
41 
42 # include <objbase.h>
43 #endif
44 
45 
46 
48 
49 #if NCBI_COMPILER_MSVC
50 
51 CVisualStudioProject* LoadFromXmlFile(const string& file_path)
52 {
53  unique_ptr<CObjectIStream> in(CObjectIStream::Open(eSerial_Xml,
54  file_path,
56  if ( in->fail() )
57  NCBI_THROW(CProjBulderAppException, eFileOpen, file_path);
58 
59  unique_ptr<CVisualStudioProject> prj(new CVisualStudioProject());
60  in->Read(prj.get(), prj->GetThisTypeInfo());
61  return prj.release();
62 }
63 
64 
65 void SaveToXmlFile(const string& file_path, const CSerialObject& project)
66 {
67  // Create dir if no such dir...
68  string dir;
69  CDirEntry::SplitPath(file_path, &dir);
70  CDir project_dir(dir);
71  if ( !project_dir.Exists() ) {
72  CDir(dir).CreatePath();
73  }
74 
75  CNcbiOfstream ofs(file_path.c_str(),
77  if ( !ofs )
78  NCBI_THROW(CProjBulderAppException, eFileCreation, file_path);
79 
82  xs.SetReferenceSchema();
83  xs.SetUseSchemaLocation(false);
84  } else {
85  xs.SetReferenceDTD(false);
86  }
87  xs.SetEncoding(eEncoding_UTF8);
88  xs.SetDefaultStringEncoding(eEncoding_UTF8);
89 
90  xs << project;
91 }
92 
93 void SaveIfNewer(const string& file_path, const CSerialObject& project)
94 {
95  // If no such file then simple write it
96  if ( !CDirEntry(file_path).Exists() ) {
97  SaveToXmlFile(file_path, project);
98  GetApp().RegisterGeneratedFile( file_path );
99  PTB_INFO_EX(file_path, ePTB_FileModified,
100  "Project created");
101  return;
102  }
103 
104  // Save new file to tmp path.
105  string candidate_file_path = file_path + ".candidate";
106  SaveToXmlFile(candidate_file_path, project);
107  if (PromoteIfDifferent(file_path, candidate_file_path)) {
109  "Project updated");
110  } else {
111  PTB_TRACE("Left intact: " << file_path);
112  }
113 }
114 
115 void SaveIfNewer (const string& file_path,
116  const CSerialObject& project,
117  const string& ignore)
118 {
119  string candidate_file_path = file_path + ".candidate";
120  SaveToXmlFile(candidate_file_path, project);
121  if (!PromoteIfDifferent(file_path, candidate_file_path, ignore)) {
122  PTB_TRACE("Left intact: " << file_path);
123  }
124 }
125 
126 #endif //NCBI_COMPILER_MSVC
127 
128 bool PromoteIfDifferent(const string& present_path,
129  const string& candidate_path,
130  const string& ignore)
131 {
132  CNcbiIfstream ifs_present(present_path.c_str(),
133  IOS_BASE::in | IOS_BASE::binary);
134  if (ifs_present.is_open()) {
135  CNcbiIfstream ifs_new (candidate_path.c_str(),
136  IOS_BASE::in | IOS_BASE::binary);
137  if ( !ifs_new ) {
138  NCBI_THROW(CProjBulderAppException, eFileOpen, candidate_path);
139  }
140  string str_present, str_new;
141  bool eol_present=false, eol_new = false;
142  for (;;) {
143  eol_present=false;
144  for (;;) {
145  if (!NcbiGetlineEOL(ifs_present, str_present) ) {
146  break;
147  }
148  NStr::TruncateSpacesInPlace(str_present);
149  if (!NStr::StartsWith(str_present, ignore)) {
150  eol_present=true;
151  break;
152  }
153  }
154  eol_new = false;
155  for (;;) {
156  if (!NcbiGetlineEOL(ifs_new, str_new) ) {
157  break;
158  }
160  if (!NStr::StartsWith(str_new, ignore)) {
161  eol_new=true;
162  break;
163  }
164  }
165  if (!eol_present && !eol_new) {
166  ifs_new.close();
167  CDirEntry(candidate_path).Remove();
168  return false;
169  }
170  if (NStr::CompareCase(str_present, str_new) != 0) {
171  break;
172  }
173  }
174  ifs_present.close();
175  }
176  CDirEntry(present_path).Remove();
177  for (int a=0; a<2 && !CDirEntry(candidate_path).Rename(present_path); ++a)
178  SleepSec(1);
179  GetApp().RegisterGeneratedFile( present_path );
180  return true;
181 }
182 
183 bool PromoteIfDifferent(const string& present_path,
184  const string& candidate_path)
185 {
186  // Open both files
187  CNcbiIfstream ifs_present(present_path.c_str(),
188  IOS_BASE::in | IOS_BASE::binary);
189  if ( !ifs_present ) {
190  CDirEntry(present_path).Remove();
191  for (int a=0; a<2 && !CDirEntry(candidate_path).Rename(present_path); ++a)
192  SleepSec(1);
193  GetApp().RegisterGeneratedFile( present_path );
194  return true;
195  }
196 
197  ifs_present.seekg(0, ios::end);
198  size_t file_length_present = ifs_present.tellg() - streampos(0);
199 
200  ifs_present.seekg(0, ios::beg);
201 
202  CNcbiIfstream ifs_new (candidate_path.c_str(),
203  IOS_BASE::in | IOS_BASE::binary);
204  if ( !ifs_new ) {
205  NCBI_THROW(CProjBulderAppException, eFileOpen, candidate_path);
206  }
207 
208  ifs_new.seekg(0, ios::end);
209  size_t file_length_new = ifs_new.tellg() - streampos(0);
210  ifs_new.seekg(0, ios::beg);
211 
212  if (file_length_present != file_length_new) {
213  ifs_present.close();
214  ifs_new.close();
215  CDirEntry(present_path).Remove();
216  for (int a=0; a<2 && !CDirEntry(candidate_path).Rename(present_path); ++a)
217  SleepSec(1);
218  GetApp().RegisterGeneratedFile( present_path );
219  return true;
220  }
221 
222  // Load both to memory
223  typedef AutoPtr<char, ArrayDeleter<char> > TAutoArray;
224  TAutoArray buf_present = TAutoArray(new char [file_length_present]);
225  TAutoArray buf_new = TAutoArray(new char [file_length_new]);
226 
227  ifs_present.read(buf_present.get(), file_length_present);
228  ifs_new.read (buf_new.get(), file_length_new);
229 
230  ifs_present.close();
231  ifs_new.close();
232 
233  // If candidate file is not the same as present file it'll be a new file
234  if (memcmp(buf_present.get(), buf_new.get(), file_length_present) != 0) {
235  CDirEntry(present_path).Remove();
236  for (int a=0; a<2 && !CDirEntry(candidate_path).Rename(present_path); ++a)
237  SleepSec(1);
238  GetApp().RegisterGeneratedFile( present_path );
239  return true;
240  } else {
241  CDirEntry(candidate_path).Remove();
242  }
243  return false;
244 }
245 
246 //-----------------------------------------------------------------------------
247 
249 {
250 public:
251  CGuidGenerator(void);
252  ~CGuidGenerator(void);
253 
254  string DoGenerateSlnGUID();
255  bool Insert(const string& guid, const string& path);
256  const string& GetGuidUser(const string& guid) const;
257 
258 private:
259  string Generate12Chars(void);
260 
261  const string root_guid; // root GUID for MSVC solutions
262  const string guid_base;
263  unsigned int m_Seed;
265 };
266 
268 
269 string GenerateSlnGUID(void)
270 {
271  return guid_gen.DoGenerateSlnGUID();
272 }
273 
274 string IdentifySlnGUID(const string& source_dir, const CProjKey& proj)
275 {
276  string vcproj;
277  if (proj.Type() == CProjKey::eMsvc) {
278  vcproj = source_dir;
279  } else {
281  vcproj = CDirEntry::ConcatPath(vcproj,
282  GetApp().GetRegSettings().m_CompilersSubdir);
283  vcproj = CDirEntry::ConcatPath(vcproj,
284  GetApp().GetBuildType().GetTypeStr());
285  vcproj = CDirEntry::ConcatPath(vcproj,
286  GetApp().GetRegSettings().m_ProjectsSubdir);
287  vcproj = CDirEntry::ConcatPath(vcproj,
289  GetApp().GetProjectTreeInfo().m_Src, source_dir));
290  vcproj = CDirEntry::AddTrailingPathSeparator(vcproj);
291  vcproj += CreateProjectName(proj);
293  }
294  string guid;
295  if ( CDirEntry(vcproj).Exists() ) {
296  char buf[1024];
297  CNcbiIfstream is(vcproj.c_str(), IOS_BASE::in);
298  if (is.is_open()) {
299  while ( !is.eof() ) {
300  is.getline(buf, sizeof(buf));
301  buf[sizeof(buf)-1] = char(0);
302  string data(buf);
303  string::size_type start, end;
304  start = data.find("ProjectGUID");
305  if (start == string::npos) {
306  start = data.find("ProjectGuid");
307  }
308  if (start != string::npos) {
309  start = data.find('{',start);
310  if (start != string::npos) {
311  end = data.find('}',++start);
312  if (end != string::npos) {
313  guid = data.substr(start,end-start);
314  }
315  }
316  break;
317  }
318  }
319  }
320  }
321  if (!guid.empty() && !guid_gen.Insert(guid,vcproj)) {
323  "MSVC Project GUID already in use by "
324  << guid_gen.GetGuidUser(guid));
325  if (proj.Type() != CProjKey::eMsvc) {
326  guid.erase();
327  }
328  }
329  if (!guid.empty()) {
330  return "{" + guid + "}";
331  }
332  return GenerateSlnGUID();
333 }
334 
335 
337  :root_guid("8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942"),
338  guid_base("8BC9CEB8-8B4A-11D0-8D11-"),
339  m_Seed(0)
340 {
341 }
342 
343 
345 {
346 }
347 
348 
350 {
351  CNcbiOstrstream ost;
352  ost.unsetf(ios::showbase);
353  ost.setf (ios::uppercase);
354  ost << hex << setw(12) << setfill('A') << m_Seed++ << ends << flush;
355  return ost.str();
356 }
357 
358 bool CGuidGenerator::Insert(const string& guid, const string& path)
359 {
360  if (!guid.empty() && guid != root_guid) {
361  if (m_Trace.find(guid) == m_Trace.end()) {
362  m_Trace[guid] = path;
363  return true;
364  }
365  if (!path.empty()) {
366  return m_Trace[guid] == path;
367  }
368  }
369  return false;
370 }
371 
372 const string& CGuidGenerator::GetGuidUser(const string& guid) const
373 {
375  if (i != m_Trace.end()) {
376  return i->second;
377  }
378  return kEmptyStr;
379 }
380 
382 {
383  for ( ;; ) {
384  //GUID prototype
385  string proto;// = guid_base + Generate12Chars();
386 #if NCBI_COMPILER_MSVC
387  GUID guid;
388  if (SUCCEEDED(CoCreateGuid(&guid))) {
390  out.fill('0');
391  out.flags(ios::hex | ios::uppercase);
392  out << setw(8) << guid.Data1 << '-'
393  << setw(4) << guid.Data2 << '-'
394  << setw(4) << guid.Data3 << '-'
395  << setw(2) << (unsigned int)guid.Data4[0]
396  << setw(2) << (unsigned int)guid.Data4[1] << '-'
397  << setw(2) << (unsigned int)guid.Data4[2]
398  << setw(2) << (unsigned int)guid.Data4[3]
399  << setw(2) << (unsigned int)guid.Data4[4]
400  << setw(2) << (unsigned int)guid.Data4[5]
401  << setw(2) << (unsigned int)guid.Data4[6]
402  << setw(2) << (unsigned int)guid.Data4[7];
403  proto = CNcbiOstrstreamToString(out);
404  } else {
405  proto = guid_base + Generate12Chars();
406  }
407 #else
408  proto = guid_base + Generate12Chars();
409 #endif
410  if (Insert(proto,kEmptyStr)) {
411  return "{" + proto + "}";
412  }
413  }
414 }
415 
416 
417 string SourceFileExt(const string& file_path)
418 {
419  string ext;
420  CDirEntry::SplitPath(file_path, NULL, NULL, &ext);
421 
422  bool explicit_c = NStr::CompareNocase(ext, ".c" )== 0;
423  if (explicit_c && CFile(file_path).Exists()) {
424  return ".c";
425  }
426  bool explicit_cpp = NStr::CompareNocase(ext, ".cpp")== 0
427  || NStr::CompareNocase(ext, ".cxx")== 0
428  || NStr::CompareNocase(ext, ".cc")== 0;
429  if (explicit_cpp && CFile(file_path).Exists()) {
430  return ext;
431  }
432  string file = file_path + ".cpp";
433  if ( CFile(file).Exists() ) {
434  return ".cpp";
435  }
436  file += ".in";
437  if ( CFile(file).Exists() ) {
438  return ".cpp.in";
439  }
440  file = file_path + ".c";
441  if ( CFile(file).Exists() ) {
442  return ".c";
443  }
444  file += ".in";
445  if ( CFile(file).Exists() ) {
446  return ".c.in";
447  }
448  file += ".metal";
449  if ( CFile(file).Exists() ) {
450  return ".metal";
451  }
452  return "";
453 }
454 
455 
456 //-----------------------------------------------------------------------------
458  :m_Debug(false), m_VTuneAddon(false), m_Unicode(false), m_rtType(rtUnknown)
459 {
460 }
461 
462 SConfigInfo::SConfigInfo(const string& name,
463  bool debug,
464  const string& runtime_library)
465  :m_Name (name),
466  m_RuntimeLibrary(runtime_library),
467  m_Debug (debug),
468  m_VTuneAddon(false),
469  m_Unicode(false),
470  m_rtType(rtUnknown)
471 {
472  DefineRtType();
473 }
474 
475 void SConfigInfo::SetRuntimeLibrary(const string& lib)
476 {
477  m_RuntimeLibrary = CMsvcMetaMakefile::TranslateOpt(lib, "Configuration", "RuntimeLibrary");
478  DefineRtType();
479 }
480 
482 {
483  if (m_RuntimeLibrary == "0" || m_RuntimeLibrary == "MultiThreaded") {
485  } else if (m_RuntimeLibrary == "1" || m_RuntimeLibrary == "MultiThreadedDebug") {
487  } else if (m_RuntimeLibrary == "2" || m_RuntimeLibrary == "MultiThreadedDLL") {
489  } else if (m_RuntimeLibrary == "3" || m_RuntimeLibrary == "MultiThreadedDebugDLL") {
491  } else if (m_RuntimeLibrary == "4") {
493  } else if (m_RuntimeLibrary == "5") {
495  }
496 }
497 
499 {
500  if (m_VTuneAddon && m_Unicode) {
501  return string("VTune_Unicode_") + m_Name;
502  } else if (m_VTuneAddon) {
503  return string("VTune_") + m_Name;
504  } else if (m_Unicode) {
505  return string("Unicode_") + m_Name;
506  } else {
507  return m_Name;
508  }
509 }
510 
511 bool SConfigInfo::operator== (const SConfigInfo& cfg) const
512 {
513  return
514  m_Name == cfg.m_Name &&
515  m_Debug == cfg.m_Debug &&
516  m_VTuneAddon == cfg.m_VTuneAddon &&
517  m_Unicode == cfg.m_Unicode &&
518  m_rtType == cfg.m_rtType;
519 }
520 
521 bool s_Config_less(const SConfigInfo& x, const SConfigInfo& y)
522 {
524 }
525 
527  const list<string>& config_names,
528  list<SConfigInfo>* configs)
529 {
530  ITERATE(list<string>, p, config_names) {
531 
532  const string& config_name = *p;
534  config.m_Name = config_name;
535  config.m_Debug = registry.GetString(config_name,
536  "debug",
537  "FALSE") != "FALSE";
538  config.SetRuntimeLibrary( registry.GetString(config_name,
539  "runtimeLibraryOption","0"));
540  configs->push_back(config);
541 #if 0
542 // per CXX-4211
543  if (( config.m_Debug && GetApp().m_TweakVTuneD) ||
544  (!config.m_Debug && GetApp().m_TweakVTuneR))
545  {
546  config.m_VTuneAddon = true;
547  configs->push_back(config);
548  config.m_VTuneAddon = false;
549  }
550 #else
551  if (GetApp().m_AddUnicode) {
552  config.m_Unicode = true;
553  configs->push_back(config);
554  }
555  if (GetApp().m_TweakVTuneR) {
556  if (!config.m_Debug /*&& config.m_rtType == SConfigInfo::rtMultiThreadedDLL*/)
557  {
558  config.m_Unicode = false;
559  config.m_VTuneAddon = true;
560  configs->push_back(config);
561  if (GetApp().m_AddUnicode) {
562  config.m_Unicode = true;
563  configs->push_back(config);
564  }
565  }
566  }
567 #endif
568  }
569  configs->sort(s_Config_less);
570 }
571 
572 
573 //-----------------------------------------------------------------------------
574 #if defined(NCBI_XCODE_BUILD) || defined(PSEUDO_XCODE)
578 
582 
583 #elif defined(NCBI_COMPILER_MSVC)
584 
585 #if _MSC_VER >= 1900
589 #elif _MSC_VER >= 1800
593 #elif _MSC_VER >= 1700
597 #elif _MSC_VER >= 1600
601 #elif _MSC_VER >= 1500
605 #elif _MSC_VER >= 1400
609 #else
613 #endif
614 
615 #ifdef _WIN64
619 #else
623 #endif
624 
625 #else // NCBI_COMPILER_MSVC
626 
630 
634 
635 #endif // NCBI_COMPILER_MSVC
637 
639 {
640 #if defined(NCBI_XCODE_BUILD) || defined(PSEUDO_XCODE)
641 /*
642  string native( CNcbiApplication::Instance()->GetEnvironment().Get("HOSTTYPE"));
643  if (!native.empty()) {
644  sm_MsvcPlatformName = native;
645  }
646  string xcode( CNcbiApplication::Instance()->GetEnvironment().Get("XCODE_VERSION_MAJOR"));
647  if (xcode >= "0300") {
648  sm_MsvcVersion = eXCode30;
649  sm_MsvcVersionName = "30";
650  }
651  sm_MsvcPlatform = eXCode;
652 */
653 // sm_RequestedArchs = sm_MsvcPlatformName;
654 
655  int ide = GetApp().m_Ide;
656  if (ide != 0) {
657  int i = ide;
658  if (i == 30) {
660  sm_MsvcVersionName = "30";
661  } else {
662  NCBI_THROW(CProjBulderAppException, eBuildConfiguration, "Unsupported IDE version");
663  }
664  }
665  if (!GetApp().m_Arch.empty()) {
666  string a = GetApp().m_Arch;
669  string tmp;
671  }
672 #elif defined(NCBI_COMPILER_MSVC)
673  int ide = GetApp().m_Ide;
674  if (ide != 0) {
675  switch (ide) {
676  case 710:
678  sm_MsvcVersionName = "710";
679  break;
680  case 800:
682  sm_MsvcVersionName = "800";
683  break;
684  case 900:
686  sm_MsvcVersionName = "900";
687  break;
688  case 1000:
690  sm_MsvcVersionName = "1000";
691  break;
692  case 1100:
694  sm_MsvcVersionName = "1100";
695  break;
696  case 1200:
698  sm_MsvcVersionName = "1200";
699  break;
700  case 1400:
703  break;
704  case 1500:
705  default:
708 // NCBI_THROW(CProjBulderAppException, eBuildConfiguration, "Unsupported IDE version");
709  break;
710  }
711  }
712  if (!GetApp().m_Arch.empty()) {
713  string a = GetApp().m_Arch;
714  if (a == "Win32") {
717  } else if (a == "x64") {
720  } else {
721  NCBI_THROW(CProjBulderAppException, eBuildConfiguration, "Unsupported build platform");
722  }
723  }
724 #endif
725 }
726 
728 {
729  if (GetMsvcPlatform() == eUnix) {
730  return UNIX_REG_SECTION;
731  } else if (GetMsvcPlatform() == eXCode) {
732  return XCODE_REG_SECTION;
733  }
734  return MSVC_REG_SECTION;
735 }
736 
738 {
739  string s(GetMsvcRegSection());
740  if (GetMsvcPlatform() == eUnix) {
741  return s;
742  } else if (GetMsvcPlatform() == eXCode) {
743  s += GetMsvcVersionName();
744  string arch(GetRequestedArchs());
745  if (arch != "i386") {
746  NStr::ReplaceInPlace(arch, ",", " ");
747  list<string> lst;
749  lst.sort();
750  arch = NStr::Join(lst,"_");
751  s += "." + arch;
752  }
753  return s;
754  }
755  s += GetMsvcVersionName();
756  if (GetMsvcPlatform() != eMsvcWin32) {
757  s += "." + GetMsvcPlatformName();
758  }
759  return s;
760 }
761 
763 {
764 }
765 
767 {
768  if (GetMsvcVersion() == eMsvc710) {
769  return "7.10";
770  } else if (GetMsvcVersion() == eMsvc800) {
771  return "8.00";
772  } else if (GetMsvcVersion() == eMsvc900) {
773  return "9.00";
774  } else if (GetMsvcVersion() == eMsvc1000 ||
775  GetMsvcVersion() == eMsvc1100 ||
776  GetMsvcVersion() == eMsvc1200) {
777  return "10.0.30319.1";
778  }
779  return "";
780 }
782 {
783  if (GetMsvcVersion() == eMsvc710) {
784  return "8.00";
785  } else if (GetMsvcVersion() == eMsvc800) {
786  return "9.00";
787  } else if (GetMsvcVersion() == eMsvc900) {
788  return "10.00\n# Visual Studio 2008";
789  } else if (GetMsvcVersion() == eMsvc1000) {
790  return "11.00\n# Visual Studio 2010";
791  } else if (GetMsvcVersion() == eMsvc1100) {
792  return "12.00\n# Visual Studio 2012";
793  } else if (GetMsvcVersion() == eMsvc1200) {
794  return "12.00\n# Visual Studio 2013";
795  } else if (GetMsvcVersion() >= eMsvc1400) {
796  return GetApp().GetRegSettings().m_Version;
797  }
798  return "";
799 }
800 
802 {
803  if (GetMsvcPlatform() < eUnix) {
804  if (GetMsvcVersion() < eMsvc1000) {
805  return MSVC_CONFIGNAME;
806  } else {
807  return "$(Configuration)";
808  }
809  } else if (GetMsvcPlatform() == eXCode) {
810  return XCODE_CONFIGNAME;
811  }
812  return "";
813 }
814 
816 {
817  if (GetMsvcPlatform() < eUnix) {
818  if (GetMsvcVersion() < eMsvc1000) {
819  return MSVC_PROJECT_FILE_EXT;
820  } else {
821  return ".vcxproj";
822  }
823  } else if (GetMsvcPlatform() == eXCode) {
824  return ".xcodeproj";
825  }
826  return "";
827 }
828 
830 {
831  string section(CMsvc7RegSettings::GetMsvcRegSection());
832  string top( GetApp().GetConfig().GetString(section, "TopBuilddir", ""));
833  if (!top.empty()) {
834  top = CDirEntry::ConcatPath(CDirEntry(GetApp().m_Solution).GetDir(), top);
835  if (!CFile(top).Exists()) {
836  top.clear();
837  }
838 
839  }
840  return top;
841 }
842 
843 bool IsSubdir(const string& abs_parent_dir, const string& abs_dir)
844 {
845  return NStr::StartsWith(abs_dir, abs_parent_dir);
846 }
847 
848 
849 string GetOpt(const CPtbRegistry& registry,
850  const string& section,
851  const string& opt,
852  const string& config)
853 {
854  string section_spec = section + '.' + config;
855  string val_spec = registry.Get(section_spec, opt);
856  if ( !val_spec.empty() )
857  return val_spec;
858 
859  return registry.Get(section, opt);
860 }
861 
862 
863 string GetOpt(const CPtbRegistry& registry,
864  const string& section,
865  const string& opt,
866  const SConfigInfo& config)
867 {
869  const string& platform = CMsvc7RegSettings::GetMsvcPlatformName();
870  string build = GetApp().GetBuildType().GetTypeStr();
871  string spec = config.m_Debug ? "debug": "release";
872  string cfgName(config.m_Name), cfgFullName(config.GetConfigFullName());
873  string value, s;
874 
875  if (cfgName != cfgFullName) {
876  s.assign(section).append(1,'.').append(build).append(1,'.').append(spec).append(1,'.').append(cfgFullName);
877  value = registry.Get(s, opt); if (!value.empty()) { return value;}
878 
879  s.assign(section).append(1,'.').append(spec).append(1,'.').append(cfgFullName);
880  value = registry.Get(s, opt); if (!value.empty()) { return value;}
881  }
882  s.assign(section).append(1,'.').append(build).append(1,'.').append(spec).append(1,'.').append(cfgName);
883  value = registry.Get(s, opt); if (!value.empty()) { return value;}
884 
885  s.assign(section).append(1,'.').append(spec).append(1,'.').append(cfgName);
886  value = registry.Get(s, opt); if (!value.empty()) { return value;}
887 
888  s.assign(section).append(1,'.').append(build).append(1,'.').append(spec);
889  value = registry.Get(s, opt); if (!value.empty()) { return value;}
890 
891  s.assign(section).append(1,'.').append(version).append(1,'.').append(spec);
892  value = registry.Get(s, opt); if (!value.empty()) { return value;}
893 
894  s.assign(section).append(1,'.').append(spec);
895  value = registry.Get(s, opt); if (!value.empty()) { return value;}
896 
897  s.assign(section).append(1,'.').append(build);
898  value = registry.Get(s, opt); if (!value.empty()) { return value;}
899 
900  s.assign(section).append(1,'.').append(platform);
901  value = registry.Get(s, opt); if (!value.empty()) { return value;}
902 
903  s.assign(section).append(1,'.').append(version);
904  value = registry.Get(s, opt); if (!value.empty()) { return value;}
905 
906  s.assign(section);
907  value = registry.Get(s, opt); if (!value.empty()) { return value;}
908  return value;
909 }
910 
911 
912 
913 string ConfigName(const string& config)
914 {
916 }
917 
918 
919 //-----------------------------------------------------------------------------
920 #if NCBI_COMPILER_MSVC
921 
922 CSrcToFilterInserterWithPch::CSrcToFilterInserterWithPch
923  (const string& project_id,
924  const list<SConfigInfo>& configs,
925  const string& project_dir)
926  : m_ProjectId (project_id),
927  m_Configs (configs),
928 // see __USE_DISABLED_CFGS__ in msvc_prj_generator.cpp
929 #if 1
930  m_AllConfigs (GetApp().GetRegSettings().m_ConfigInfo),
931 #else
932  m_AllConfigs (configs),
933 #endif
934  m_ProjectDir (project_dir)
935 {
936 }
937 
938 
939 CSrcToFilterInserterWithPch::~CSrcToFilterInserterWithPch(void)
940 {
941 }
942 
943 
944 void CSrcToFilterInserterWithPch::InsertFile(CRef<CFilter>& filter,
945  const string& rel_source_file,
946  const string& pch_default,
947  const string& enable_cfg)
948 {
949  CRef<CFFile> file(new CFFile());
950  file->SetAttlist().SetRelativePath(rel_source_file);
951  //
952  TPch pch_usage = DefinePchUsage(m_ProjectDir, rel_source_file, pch_default);
953  //
954  // For each configuration
955  ITERATE(list<SConfigInfo>, iconfig, m_AllConfigs) {
956  const string& config = (*iconfig).GetConfigFullName();
957  CRef<CFileConfiguration> file_config(new CFileConfiguration());
958  file_config->SetAttlist().SetName(ConfigName(config));
959 
960  if (m_Configs.size() != m_AllConfigs.size() &&
961  find(m_Configs.begin(), m_Configs.end(), *iconfig) == m_Configs.end()) {
962  file_config->SetAttlist().SetExcludedFromBuild("true");
963  }
964  else if ( !enable_cfg.empty() && enable_cfg != config ) {
965  file_config->SetAttlist().SetExcludedFromBuild("true");
966  }
967 
968  CRef<CTool> compilerl_tool(new CTool());
969  compilerl_tool->SetAttlist().SetName("VCCLCompilerTool");
970 
971  if (pch_usage.first == eCreate) {
972  compilerl_tool->SetAttlist().SetPreprocessorDefinitions
973  (GetApp().GetMetaMakefile().GetPchUsageDefine());
974  compilerl_tool->SetAttlist().SetUsePrecompiledHeader("1");
975  compilerl_tool->SetAttlist().SetPrecompiledHeaderThrough
976  (pch_usage.second);
977  } else if (pch_usage.first == eUse) {
978  compilerl_tool->SetAttlist().SetPreprocessorDefinitions
979  (GetApp().GetMetaMakefile().GetPchUsageDefine());
980 #if 0
981 // moved into msvc_prj_generator.cpp to become project default
983  compilerl_tool->SetAttlist().SetUsePrecompiledHeader("2");
984  } else {
985  compilerl_tool->SetAttlist().SetUsePrecompiledHeader("3");
986  }
987 #endif
988  if (pch_usage.second != pch_default) {
989  compilerl_tool->SetAttlist().SetPrecompiledHeaderThrough
990  (pch_usage.second);
991  }
992  }
993  else {
994  compilerl_tool->SetAttlist().SetUsePrecompiledHeader("0");
995 // compilerl_tool->SetAttlist().SetPrecompiledHeaderThrough("");
996  }
997  file_config->SetTool(*compilerl_tool);
998  file->SetFileConfiguration().push_back(file_config);
999  }
1001  ce->SetFile(*file);
1002  filter->SetFF().SetFF().push_back(ce);
1003  return;
1004 }
1005 
1006 
1007 void
1008 CSrcToFilterInserterWithPch::operator()(CRef<CFilter>& filter,
1009  const string& rel_source_file,
1010  const string& pch_default)
1011 {
1012  if ( NStr::Find(rel_source_file, ".@config@") == NPOS ) {
1013  // Ordinary file
1014  InsertFile(filter, rel_source_file, pch_default);
1015  } else {
1016  // Configurable file
1017 
1018  // Exclude from build all file versions
1019  // except one for current configuration.
1020  ITERATE(list<SConfigInfo>, icfg, m_AllConfigs) {
1021  const string& cfg = (*icfg).GetConfigFullName();
1022  string source_file = NStr::Replace(rel_source_file,
1023  ".@config@", "." + cfg);
1024  InsertFile(filter, source_file, pch_default, cfg);
1025  }
1026  }
1027 }
1028 
1029 CSrcToFilterInserterWithPch::TPch
1030 CSrcToFilterInserterWithPch::DefinePchUsage(const string& project_dir,
1031  const string& rel_source_file,
1032  const string& pch_file)
1033 {
1034  if ( pch_file.empty() )
1035  return TPch(eNotUse, "");
1036 
1037  string abs_source_file =
1038  CDirEntry::ConcatPath(project_dir, rel_source_file);
1039  abs_source_file = CDirEntry::NormalizePath(abs_source_file);
1040 
1041  // .c files - not use PCH
1042  string ext;
1043  CDirEntry::SplitPath(abs_source_file, NULL, NULL, &ext);
1044  if ( NStr::CompareNocase(ext, ".c") == 0)
1045  return TPch(eNotUse, "");
1046 
1047 /*
1048  MSVC documentation says:
1049  Although you can use only one precompiled header (.pch) file per source file,
1050  you can use multiple .pch files in a project.
1051  Apple XCode:
1052  Each target can have only one prefix header
1053 */
1054  if (m_PchHeaders.find(pch_file) == m_PchHeaders.end()) {
1055  // New PCH - this source file will create it
1056  m_PchHeaders.insert(pch_file);
1057  return TPch(eCreate, pch_file);
1058  } else {
1059  // Use PCH (previously created)
1060  return TPch(eUse, pch_file);
1061  }
1062 }
1063 
1064 
1065 //-----------------------------------------------------------------------------
1066 
1067 CBasicProjectsFilesInserter::CBasicProjectsFilesInserter
1068  (CVisualStudioProject* vcproj,
1069  const string& project_id,
1070  const list<SConfigInfo>& configs,
1071  const string& project_dir)
1072  : m_Vcproj (vcproj),
1073  m_SrcInserter(project_id, configs, project_dir),
1074  m_Filters (project_dir)
1075 {
1076  m_Filters.Initilize();
1077 }
1078 
1079 
1080 CBasicProjectsFilesInserter::~CBasicProjectsFilesInserter(void)
1081 {
1082 }
1083 
1084 void CBasicProjectsFilesInserter::AddSourceFile(
1085  const string& rel_file_path, const string& pch_default)
1086 {
1087  m_Filters.AddSourceFile(m_SrcInserter, rel_file_path, pch_default);
1088 }
1089 
1090 void CBasicProjectsFilesInserter::AddHeaderFile(const string& rel_file_path)
1091 {
1092  m_Filters.AddHeaderFile(rel_file_path);
1093 }
1094 
1095 void CBasicProjectsFilesInserter::AddInlineFile(const string& rel_file_path)
1096 {
1097  m_Filters.AddInlineFile(rel_file_path);
1098 }
1099 
1100 void CBasicProjectsFilesInserter::Finalize(void)
1101 {
1102  if (m_Filters.m_SourceFiles->IsSetFF()) {
1103  m_Vcproj->SetFiles().SetFilter().push_back(m_Filters.m_SourceFiles);
1104  }
1105  if ( m_Filters.m_HeaderFilesPrivate->IsSetFF() ) {
1107  ce->SetFilter(*m_Filters.m_HeaderFilesPrivate);
1108  m_Filters.m_HeaderFiles->SetFF().SetFF().push_back(ce);
1109  }
1110  if ( m_Filters.m_HeaderFilesImpl->IsSetFF() ) {
1112  ce->SetFilter(*m_Filters.m_HeaderFilesImpl);
1113  m_Filters.m_HeaderFiles->SetFF().SetFF().push_back(ce);
1114  }
1115  if (m_Filters.m_HeaderFiles->IsSetFF()) {
1116  m_Vcproj->SetFiles().SetFilter().push_back(m_Filters.m_HeaderFiles);
1117  }
1118  if (m_Filters.m_InlineFiles->IsSetFF()) {
1119  m_Vcproj->SetFiles().SetFilter().push_back(m_Filters.m_InlineFiles);
1120  }
1121 }
1122 
1123 //-----------------------------------------------------------------------------
1124 
1125 static bool s_IsPrivateHeader(const string& header_abs_path)
1126 {
1127  string src_dir = GetApp().GetProjectTreeInfo().m_Src;
1128  return header_abs_path.find(src_dir) != NPOS;
1129 
1130 }
1131 
1132 static bool s_IsImplHeader(const string& header_abs_path)
1133 {
1134  string src_trait = CDirEntry::GetPathSeparator() +
1137  return header_abs_path.find(src_trait) != NPOS;
1138 }
1139 
1140 //-----------------------------------------------------------------------------
1141 
1142 CBasicProjectsFilesInserter::SFiltersItem::SFiltersItem(void)
1143 {
1144 }
1145 CBasicProjectsFilesInserter::SFiltersItem::SFiltersItem
1146  (const string& project_dir)
1147  :m_ProjectDir(project_dir)
1148 {
1149 }
1150 
1151 void CBasicProjectsFilesInserter::SFiltersItem::Initilize(void)
1152 {
1153  m_SourceFiles.Reset(new CFilter());
1154  m_SourceFiles->SetAttlist().SetName("Source Files");
1155  m_SourceFiles->SetAttlist().SetFilter
1156  ("cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx");
1157 
1158  m_HeaderFiles.Reset(new CFilter());
1159  m_HeaderFiles->SetAttlist().SetName("Header Files");
1160  m_HeaderFiles->SetAttlist().SetFilter("h;hpp;hxx;hm;inc");
1161 
1162  m_HeaderFilesPrivate.Reset(new CFilter());
1163  m_HeaderFilesPrivate->SetAttlist().SetName("Private");
1164  m_HeaderFilesPrivate->SetAttlist().SetFilter("h;hpp;hxx;hm;inc");
1165 
1166  m_HeaderFilesImpl.Reset(new CFilter());
1167  m_HeaderFilesImpl->SetAttlist().SetName("Impl");
1168  m_HeaderFilesImpl->SetAttlist().SetFilter("h;hpp;hxx;hm;inc");
1169 
1170  m_InlineFiles.Reset(new CFilter());
1171  m_InlineFiles->SetAttlist().SetName("Inline Files");
1172  m_InlineFiles->SetAttlist().SetFilter("inl");
1173 }
1174 
1175 
1176 void CBasicProjectsFilesInserter::SFiltersItem::AddSourceFile
1177  (CSrcToFilterInserterWithPch& inserter_w_pch,
1178  const string& rel_file_path,
1179  const string& pch_default)
1180 {
1181  inserter_w_pch(m_SourceFiles, rel_file_path, pch_default);
1182 }
1183 
1184 void CBasicProjectsFilesInserter::SFiltersItem::AddHeaderFile
1185  (const string& rel_file_path)
1186 {
1187  CRef< CFFile > file(new CFFile());
1188  file->SetAttlist().SetRelativePath(rel_file_path);
1189 
1191  ce->SetFile(*file);
1192 
1193  string abs_header_path =
1194  CDirEntry::ConcatPath(m_ProjectDir, rel_file_path);
1195  abs_header_path = CDirEntry::NormalizePath(abs_header_path);
1196  if ( s_IsPrivateHeader(abs_header_path) ) {
1197  m_HeaderFilesPrivate->SetFF().SetFF().push_back(ce);
1198  } else if ( s_IsImplHeader(abs_header_path) ) {
1199  m_HeaderFilesImpl->SetFF().SetFF().push_back(ce);
1200  } else {
1201  m_HeaderFiles->SetFF().SetFF().push_back(ce);
1202  }
1203 }
1204 
1205 
1206 void CBasicProjectsFilesInserter::SFiltersItem::AddInlineFile
1207  (const string& rel_file_path)
1208 {
1209  CRef< CFFile > file(new CFFile());
1210  file->SetAttlist().SetRelativePath(rel_file_path);
1211 
1213  ce->SetFile(*file);
1214  m_InlineFiles->SetFF().SetFF().push_back(ce);
1215 }
1216 
1217 
1218 //-----------------------------------------------------------------------------
1219 
1220 CDllProjectFilesInserter::CDllProjectFilesInserter
1221  (CVisualStudioProject* vcproj,
1222  const CProjKey dll_project_key,
1223  const list<SConfigInfo>& configs,
1224  const string& project_dir)
1225  :m_Vcproj (vcproj),
1226  m_DllProjectKey (dll_project_key),
1227  m_SrcInserter (dll_project_key.Id(),
1228  configs,
1229  project_dir),
1230  m_ProjectDir (project_dir),
1231  m_PrivateFilters(project_dir)
1232 {
1233  // Private filters initilization
1234  m_PrivateFilters.m_SourceFiles.Reset(new CFilter());
1235  m_PrivateFilters.m_SourceFiles->SetAttlist().SetName("Source Files");
1236  m_PrivateFilters.m_SourceFiles->SetAttlist().SetFilter
1237  ("cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx");
1238 
1239  m_PrivateFilters.m_HeaderFiles.Reset(new CFilter());
1240  m_PrivateFilters.m_HeaderFiles->SetAttlist().SetName("Header Files");
1241  m_PrivateFilters.m_HeaderFiles->SetAttlist().SetFilter("h;hpp;hxx;hm;inc");
1242 
1243  m_PrivateFilters.m_HeaderFilesPrivate.Reset(new CFilter());
1244  m_PrivateFilters.m_HeaderFilesPrivate->SetAttlist().SetName("Private");
1245  m_PrivateFilters.m_HeaderFilesPrivate->SetAttlist().SetFilter("h;hpp;hxx;hm;inc");
1246 
1247  m_PrivateFilters.m_HeaderFilesImpl.Reset(new CFilter());
1248  m_PrivateFilters.m_HeaderFilesImpl->SetAttlist().SetName("Impl");
1249  m_PrivateFilters.m_HeaderFilesImpl->SetAttlist().SetFilter("h;hpp;hxx;hm;inc");
1250 
1251  m_PrivateFilters.m_InlineFiles.Reset(new CFilter());
1252  m_PrivateFilters.m_InlineFiles->SetAttlist().SetName("Inline Files");
1253  m_PrivateFilters.m_InlineFiles->SetAttlist().SetFilter("inl");
1254 
1255  // Hosted Libraries filter (folder)
1256  m_HostedLibrariesRootFilter.Reset(new CFilter());
1257  m_HostedLibrariesRootFilter->SetAttlist().SetName("Hosted Libraries");
1258  m_HostedLibrariesRootFilter->SetAttlist().SetFilter("");
1259 }
1260 
1261 
1262 CDllProjectFilesInserter::~CDllProjectFilesInserter(void)
1263 {
1264 }
1265 
1266 
1267 void CDllProjectFilesInserter::AddSourceFile (
1268  const string& rel_file_path, const string& pch_default)
1269 {
1270  string abs_path = CDirEntry::ConcatPath(m_ProjectDir, rel_file_path);
1271  abs_path = CDirEntry::NormalizePath(abs_path);
1272 
1273  CProjKey proj_key = GetApp().GetDllFilesDistr().GetSourceLib(abs_path, m_DllProjectKey);
1274 
1275  if (proj_key == CProjKey()) {
1276  m_PrivateFilters.AddSourceFile(m_SrcInserter, rel_file_path, pch_default);
1277  return;
1278  }
1279 
1280  THostedLibs::iterator p = m_HostedLibs.find(proj_key);
1281  if (p != m_HostedLibs.end()) {
1282  TFiltersItem& filters_item = p->second;
1283  filters_item.AddSourceFile(m_SrcInserter, rel_file_path, pch_default);
1284  return;
1285  }
1286 
1287  TFiltersItem new_item(m_ProjectDir);
1288  new_item.Initilize();
1289  new_item.AddSourceFile(m_SrcInserter, rel_file_path, pch_default);
1290  m_HostedLibs[proj_key] = new_item;
1291 }
1292 
1293 void CDllProjectFilesInserter::AddHeaderFile(const string& rel_file_path)
1294 {
1295  string abs_path = CDirEntry::ConcatPath(m_ProjectDir, rel_file_path);
1296  abs_path = CDirEntry::NormalizePath(abs_path);
1297 
1298  CProjKey proj_key = GetApp().GetDllFilesDistr().GetHeaderLib(abs_path, m_DllProjectKey);
1299 
1300  if (proj_key == CProjKey()) {
1302  GetApp().GetWholeTree().m_Projects.find(m_DllProjectKey);
1303  if (p != GetApp().GetWholeTree().m_Projects.end()) {
1304  const CProjItem& proj_item = p->second;
1305  if (NStr::StartsWith(abs_path, proj_item.m_SourcesBaseDir, NStr::eNocase)) {
1306  m_PrivateFilters.AddHeaderFile(rel_file_path);
1307  }
1308  }
1309  return;
1310  }
1311 
1312  THostedLibs::iterator p = m_HostedLibs.find(proj_key);
1313  if (p != m_HostedLibs.end()) {
1314  TFiltersItem& filters_item = p->second;
1315  filters_item.AddHeaderFile(rel_file_path);
1316  return;
1317  }
1318 
1319  TFiltersItem new_item(m_ProjectDir);
1320  new_item.Initilize();
1321  new_item.AddHeaderFile(rel_file_path);
1322  m_HostedLibs[proj_key] = new_item;
1323 }
1324 
1325 void CDllProjectFilesInserter::AddInlineFile(const string& rel_file_path)
1326 {
1327  string abs_path = CDirEntry::ConcatPath(m_ProjectDir, rel_file_path);
1328  abs_path = CDirEntry::NormalizePath(abs_path);
1329 
1330  CProjKey proj_key = GetApp().GetDllFilesDistr().GetInlineLib(abs_path, m_DllProjectKey);
1331 
1332  if (proj_key == CProjKey()) {
1333  m_PrivateFilters.AddInlineFile(rel_file_path);
1334  return;
1335  }
1336 
1337  THostedLibs::iterator p = m_HostedLibs.find(proj_key);
1338  if (p != m_HostedLibs.end()) {
1339  TFiltersItem& filters_item = p->second;
1340  filters_item.AddInlineFile(rel_file_path);
1341  return;
1342  }
1343 
1344  TFiltersItem new_item(m_ProjectDir);
1345  new_item.Initilize();
1346  new_item.AddInlineFile(rel_file_path);
1347  m_HostedLibs[proj_key] = new_item;
1348 }
1349 
1350 
1351 void CDllProjectFilesInserter::Finalize(void)
1352 {
1353  m_Vcproj->SetFiles().SetFilter().push_back(m_PrivateFilters.m_SourceFiles);
1354 
1355  if ( !m_PrivateFilters.m_HeaderFilesPrivate->IsSetFF() ) {
1357  ce->SetFilter(*m_PrivateFilters.m_HeaderFilesPrivate);
1358  m_PrivateFilters.m_HeaderFiles->SetFF().SetFF().push_back(ce);
1359  }
1360  if ( !m_PrivateFilters.m_HeaderFilesImpl->IsSetFF() ) {
1362  ce->SetFilter(*m_PrivateFilters.m_HeaderFilesImpl);
1363  m_PrivateFilters.m_HeaderFiles->SetFF().SetFF().push_back(ce);
1364  }
1365  m_Vcproj->SetFiles().SetFilter().push_back(m_PrivateFilters.m_HeaderFiles);
1366 
1367  m_Vcproj->SetFiles().SetFilter().push_back(m_PrivateFilters.m_InlineFiles);
1368 
1369  NON_CONST_ITERATE(THostedLibs, p, m_HostedLibs) {
1370 
1371  const CProjKey& proj_key = p->first;
1372  TFiltersItem& filters_item = p->second;
1373 
1374  CRef<CFilter> hosted_lib_filter(new CFilter());
1375  hosted_lib_filter->SetAttlist().SetName(CreateProjectName(proj_key));
1376  hosted_lib_filter->SetAttlist().SetFilter("");
1377 
1378  {{
1380  ce->SetFilter(*(filters_item.m_SourceFiles));
1381  hosted_lib_filter->SetFF().SetFF().push_back(ce);
1382  }}
1383 
1384  if ( filters_item.m_HeaderFilesPrivate->IsSetFF() ) {
1386  ce->SetFilter(*filters_item.m_HeaderFilesPrivate);
1387  filters_item.m_HeaderFiles->SetFF().SetFF().push_back(ce);
1388  }
1389  if ( filters_item.m_HeaderFilesImpl->IsSetFF() ) {
1391  ce->SetFilter(*filters_item.m_HeaderFilesImpl);
1392  filters_item.m_HeaderFiles->SetFF().SetFF().push_back(ce);
1393  }
1394  {{
1396  ce->SetFilter(*(filters_item.m_HeaderFiles));
1397  hosted_lib_filter->SetFF().SetFF().push_back(ce);
1398  }}
1399  {{
1401  ce->SetFilter(*(filters_item.m_InlineFiles));
1402  hosted_lib_filter->SetFF().SetFF().push_back(ce);
1403  }}
1404  {{
1406  ce->SetFilter(*hosted_lib_filter);
1407  m_HostedLibrariesRootFilter->SetFF().SetFF().push_back(ce);
1408  }}
1409  }
1410  m_Vcproj->SetFiles().SetFilter().push_back(m_HostedLibrariesRootFilter);
1411 }
1412 
1413 
1414 //-----------------------------------------------------------------------------
1415 
1416 void AddCustomBuildFileToFilter(CRef<CFilter>& filter,
1417  const list<SConfigInfo> configs,
1418  const string& project_dir,
1419  const SCustomBuildInfo& build_info)
1420 {
1421  CRef<CFFile> file(new CFFile());
1422  file->SetAttlist().SetRelativePath
1423  (CDirEntry::CreateRelativePath(project_dir,
1424  build_info.m_SourceFile));
1425 
1426  ITERATE(list<SConfigInfo>, n, configs) {
1427  // Iterate all configurations
1428  const string& config = (*n).GetConfigFullName();
1429 
1430  CRef<CFileConfiguration> file_config(new CFileConfiguration());
1431  file_config->SetAttlist().SetName(ConfigName(config));
1432 
1433  CRef<CTool> custom_build(new CTool());
1434  custom_build->SetAttlist().SetName("VCCustomBuildTool");
1435  custom_build->SetAttlist().SetDescription(build_info.m_Description);
1436  custom_build->SetAttlist().SetCommandLine(build_info.m_CommandLine);
1437  custom_build->SetAttlist().SetOutputs(build_info.m_Outputs);
1438  custom_build->SetAttlist().SetAdditionalDependencies
1439  (build_info.m_AdditionalDependencies);
1440  file_config->SetTool(*custom_build);
1441 
1442  file->SetFileConfiguration().push_back(file_config);
1443  }
1445  ce->SetFile(*file);
1446  filter->SetFF().SetFF().push_back(ce);
1447 }
1448 
1449 #endif //NCBI_COMPILER_MSVC
1450 
1451 
1452 bool SameRootDirs(const string& dir1, const string& dir2)
1453 {
1454  if ( dir1.empty() )
1455  return false;
1456  if ( dir2.empty() )
1457  return false;
1458 #if NCBI_COMPILER_MSVC
1459  return tolower((unsigned char)(dir1[0])) == tolower((unsigned char)(dir2[0]));
1460 // return dir1[0] == dir2[0];
1461 #else
1462  if (dir1[0] == '/' && dir2[0] == '/') {
1463  string::size_type n1= dir1.find_first_of('/', 1);
1464  string::size_type n2= dir2.find_first_of('/', 1);
1465  if (n1 != string::npos && n1 == n2) {
1466  return dir1.compare(0,n1,dir2,0,n2) == 0;
1467  }
1468  }
1469 #endif
1470  return false;
1471 }
1472 
1473 
1474 string CreateProjectName(const CProjKey& project_id)
1475 {
1476  switch (project_id.Type()) {
1477  case CProjKey::eApp:
1478  return project_id.Id() + ".exe";
1479  case CProjKey::eLib:
1480  return project_id.Id() + ".lib";
1481  case CProjKey::eDll:
1482  return project_id.Id() + ".dll";
1483  case CProjKey::eMsvc:
1485  return project_id.Id() + ".unix";
1486  }
1487  return project_id.Id();// + ".vcproj";
1488  case CProjKey::eDataSpec:
1489  return project_id.Id() + ".dataspec";
1490  case CProjKey::eUtility:
1491  return project_id.Id();
1492  default:
1493  NCBI_THROW(CProjBulderAppException, eProjectType, project_id.Id());
1494  return "";
1495  }
1496 }
1497 
1498 CProjKey CreateProjKey(const string& project_name)
1499 {
1501  CDirEntry d(project_name);
1502  string ext(d.GetExt());
1503  string base(d.GetBase());
1504  if (ext == ".exe") {
1505  type = CProjKey::eApp;
1506  } else if (ext == ".lib") {
1507  type = CProjKey::eLib;
1508  } else if (ext == ".dll") {
1509  type = CProjKey::eDll;
1510  } else if (ext == ".dataspec") {
1512  } else {
1514  }
1515  return CProjKey(type,base);
1516 }
1517 
1518 
1519 //-----------------------------------------------------------------------------
1520 
1522  :m_Type(dll_flag? eDll: eStatic)
1523 {
1524 
1525 }
1526 
1527 
1529 {
1530  return m_Type;
1531 }
1532 
1533 
1534 string CBuildType::GetTypeStr(void) const
1535 {
1536  switch (m_Type) {
1537  case eStatic:
1538  return "static";
1539  case eDll:
1540  return "dll";
1541  }
1543  eProjectType,
1545  return "";
1546 }
1547 
1548 
1549 //-----------------------------------------------------------------------------
1550 
1552 {
1553 }
1554 
1555 void CDllSrcFilesDistr::RegisterSource(const string& src_file_path,
1556  const CProjKey& dll_project_id,
1557  const CProjKey& lib_project_id)
1558 {
1559  m_SourcesMap[ TDllSrcKey(src_file_path,dll_project_id) ] = lib_project_id;
1560 }
1561 
1562 void CDllSrcFilesDistr::RegisterHeader(const string& hdr_file_path,
1563  const CProjKey& dll_project_id,
1564  const CProjKey& lib_project_id)
1565 {
1566  m_HeadersMap[ TDllSrcKey(hdr_file_path,dll_project_id) ] = lib_project_id;
1567 }
1568 
1569 void CDllSrcFilesDistr::RegisterInline(const string& inl_file_path,
1570  const CProjKey& dll_project_id,
1571  const CProjKey& lib_project_id)
1572 {
1573  m_InlinesMap[ TDllSrcKey(inl_file_path,dll_project_id) ] = lib_project_id;
1574 }
1575 
1576 void CDllSrcFilesDistr::RegisterExtraFile(const string& ex_file_path,
1577  const CProjKey& dll_project_id,
1578  const CProjKey& lib_project_id)
1579 {
1580  m_ExtraFileMap[ TDllSrcKey(ex_file_path,dll_project_id) ] = lib_project_id;
1581 }
1582 
1583 CProjKey CDllSrcFilesDistr::GetSourceLib(const string& src_file_path,
1584  const CProjKey& dll_project_id) const
1585 {
1586  TDllSrcKey key(src_file_path, dll_project_id);
1588  if (p != m_SourcesMap.end()) {
1589  const CProjKey& lib_id = p->second;
1590  return lib_id;
1591  }
1592  return CProjKey();
1593 }
1594 
1595 
1596 CProjKey CDllSrcFilesDistr::GetHeaderLib(const string& hdr_file_path,
1597  const CProjKey& dll_project_id) const
1598 {
1599  TDllSrcKey key(hdr_file_path, dll_project_id);
1601  if (p != m_HeadersMap.end()) {
1602  const CProjKey& lib_id = p->second;
1603  return lib_id;
1604  }
1605  return CProjKey();
1606 }
1607 
1608 CProjKey CDllSrcFilesDistr::GetInlineLib(const string& inl_file_path,
1609  const CProjKey& dll_project_id) const
1610 {
1611  TDllSrcKey key(inl_file_path, dll_project_id);
1613  if (p != m_InlinesMap.end()) {
1614  const CProjKey& lib_id = p->second;
1615  return lib_id;
1616  }
1617  return CProjKey();
1618 }
1619 
1620 CProjKey CDllSrcFilesDistr::GetExtraFileLib(const string& ex_file_path,
1621  const CProjKey& dll_project_id) const
1622 {
1623  TDllSrcKey key(ex_file_path, dll_project_id);
1625  if (p != m_ExtraFileMap.end()) {
1626  const CProjKey& lib_id = p->second;
1627  return lib_id;
1628  }
1629  return CProjKey();
1630 }
1631 
1632 CProjKey CDllSrcFilesDistr::GetFileLib(const string& file_path,
1633  const CProjKey& dll_project_id) const
1634 {
1635  CProjKey empty;
1636  if (dll_project_id.Type() != CProjKey::eDll) {
1637  return empty;
1638  }
1639  CProjKey test;
1640  test = GetSourceLib(file_path, dll_project_id);
1641  if (test != empty) {
1642  return test;
1643  }
1644  test = GetHeaderLib(file_path, dll_project_id);
1645  if (test != empty) {
1646  return test;
1647  }
1648  test = GetInlineLib(file_path, dll_project_id);
1649  if (test != empty) {
1650  return test;
1651  }
1652  test = GetExtraFileLib(file_path, dll_project_id);
1653  if (test != empty) {
1654  return test;
1655  }
1656  return empty;
1657 }
1658 
1659 
1660 const CDataToolGeneratedSrc*
1661 IsProducedByDatatool(const string& src_path_abs,
1662  const CProjItem& project)
1663 {
1664  if ( project.m_DatatoolSources.empty() ) {
1665  ITERATE( list<CProjKey>, d, project.m_Depends) {
1666  if (d->Type() == CProjKey::eDataSpec) {
1669  if (n != GetApp().GetWholeTree().m_Projects.end()) {
1670  const CDataToolGeneratedSrc *pFound =
1671  IsProducedByDatatool(src_path_abs, n->second);
1672  if (pFound) {
1673  return pFound;
1674  }
1675  }
1676  }
1677  }
1678  return NULL;
1679  }
1680 
1681  string src_base;
1682  CDirEntry::SplitPath(src_path_abs, NULL, &src_base);
1683 
1684  // guess name.asn file name from name__ or name___
1685  string asn_base;
1686  if ( NStr::EndsWith(src_base, "___") ) {
1687  asn_base = src_base.substr(0, src_base.length() -3);
1688  } else if ( NStr::EndsWith(src_base, "__") ) {
1689  asn_base = src_base.substr(0, src_base.length() -2);
1690  } else {
1691  return NULL;
1692  }
1693  string asn_name = asn_base + ".asn";
1694  string dtd_name = asn_base + ".dtd";
1695  string xsd_name = asn_base + ".xsd";
1696  string wsdl_name = asn_base + ".wsdl";
1697  string jsd_name = asn_base + ".jsd";
1698 
1699  //try to find this name in datatool generated sources container
1700  ITERATE(list<CDataToolGeneratedSrc>, p, project.m_DatatoolSources) {
1701  const CDataToolGeneratedSrc& asn = *p;
1702  if ((asn.m_SourceFile == asn_name) ||
1703  (asn.m_SourceFile == dtd_name) ||
1704  (asn.m_SourceFile == xsd_name) ||
1705  (asn.m_SourceFile == wsdl_name) ||
1706  (asn.m_SourceFile == jsd_name)
1707  ) {
1708  return &(*p);
1709  }
1710  }
1711 
1712  try {
1713  ITERATE(list<CDataToolGeneratedSrc>, p, project.m_DatatoolSources) {
1714  const CDataToolGeneratedSrc& asn = *p;
1715  string def( CDirEntry::ConcatPath(asn.m_SourceBaseDir, CDirEntry(asn.m_SourceFile).GetBase()) + ".def");
1716  if (CFile(def).Exists()) {
1717  CNcbiIfstream in(def.c_str(), IOS_BASE::in | IOS_BASE::binary);
1718  CNcbiRegistry reg(in);
1719  if (reg.GetString("-", "-oc", "") == asn_base) {
1720  return &(*p);
1721  }
1722  }
1723  }
1724  } catch (...) {
1725  }
1726  return NULL;
1727 }
1728 
static int trunc
Definition: array_out.c:8
#define false
Definition: bool.h:36
AutoPtr –.
Definition: ncbimisc.hpp:401
string GetTypeStr(void) const
EBuildType GetType(void) const
EBuildType m_Type
CBuildType(void)
CDirEntry –.
Definition: ncbifile.hpp:262
CDir –.
Definition: ncbifile.hpp:1695
void RegisterExtraFile(const string &inl_file_path, const CProjKey &dll_project_id, const CProjKey &lib_project_id)
pair< string, CProjKey > TDllSrcKey
CProjKey GetHeaderLib(const string &hdr_file_path, const CProjKey &dll_project_id) const
void RegisterSource(const string &src_file_path, const CProjKey &dll_project_id, const CProjKey &lib_project_id)
CProjKey GetFileLib(const string &file_path, const CProjKey &dll_project_id) const
CProjKey GetSourceLib(const string &src_file_path, const CProjKey &dll_project_id) const
CProjKey GetExtraFileLib(const string &ex_file_path, const CProjKey &dll_project_id) const
void RegisterInline(const string &inl_file_path, const CProjKey &dll_project_id, const CProjKey &lib_project_id)
CProjKey GetInlineLib(const string &inl_file_path, const CProjKey &dll_project_id) const
void RegisterHeader(const string &hrd_file_path, const CProjKey &dll_project_id, const CProjKey &lib_project_id)
CFFile –.
Definition: File.hpp:66
CFileConfiguration –.
CFile –.
Definition: ncbifile.hpp:1604
CFilter –.
Definition: Filter.hpp:66
unsigned int m_Seed
map< string, string > m_Trace
const string root_guid
const string & GetGuidUser(const string &guid) const
string Generate12Chars(void)
const string guid_base
string DoGenerateSlnGUID()
bool Insert(const string &guid, const string &path)
static string GetVcprojExt(void)
static EMsvcPlatform GetMsvcPlatform(void)
static string sm_MsvcPlatformName
static string GetMsvcSection(void)
static string sm_RequestedArchs
static string sm_MsvcVersionName
static const string & GetMsvcVersionName(void)
static string GetProjectFileFormatVersion(void)
static const string & GetMsvcPlatformName(void)
static EMsvcVersion sm_MsvcVersion
static void IdentifyPlatform(void)
static string GetTopBuilddir(void)
static string GetSolutionFileFormatVersion(void)
static string GetConfigNameKeyword(void)
static const string & GetRequestedArchs(void)
static EMsvcPlatform sm_MsvcPlatform
static EMsvcVersion GetMsvcVersion(void)
static string GetMsvcRegSection(void)
static string TranslateOpt(const string &value, const string &section, const string &opt)
CNcbiOstrstreamToString class helps convert CNcbiOstrstream to a string Sample usage:
Definition: ncbistre.hpp:802
CNcbiRegistry –.
Definition: ncbireg.hpp:913
CObjectOStreamXml –.
Definition: objostrxml.hpp:54
CProjBulderAppException –.
const CBuildType & GetBuildType(void)
CDllSrcFilesDistr & GetDllFilesDistr(void)
void RegisterGeneratedFile(const string &file)
const SProjectTreeInfo & GetProjectTreeInfo(void)
const CProjectItemsTree & GetWholeTree(void)
const CMsvc7RegSettings & GetRegSettings(void)
CProjItem –.
Definition: proj_item.hpp:54
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
string m_SourcesBaseDir
Base directory of source files (....c++/src/a/ )
Definition: proj_item.hpp:92
CProjKey –.
const string & Id(void) const
Definition: proj_item.cpp:112
TProjType Type(void) const
Definition: proj_item.cpp:106
TProjects m_Projects
Definition: proj_tree.hpp:70
CRef –.
Definition: ncbiobj.hpp:618
Base class for all serializable objects.
Definition: serialbase.hpp:150
CTool –.
Definition: Tool.hpp:66
CVisualStudioProject –.
const_iterator end() const
Definition: map.hpp:152
const_iterator find(const key_type &key) const
Definition: map.hpp:153
static CMemoryRegistry registry
Definition: cn3d_tools.cpp:81
char value[7]
Definition: config.c:431
struct config config
std::ofstream out("events_result.xml")
main entry point for tests
void debug()
#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
@ eNoOwnership
No ownership is assumed.
Definition: ncbi_types.h:135
string
Definition: cgiapp.hpp:687
#define NULL
Definition: ncbistd.hpp:225
#define NCBI_THROW(exception_class, err_code, message)
Generic macro to throw an exception, given the exception class, error code and message string.
Definition: ncbiexpt.hpp:704
static string NormalizePath(const string &path, EFollowLinks follow_links=eIgnoreLinks)
Normalize a path.
Definition: ncbifile.cpp:820
string GetBase(void) const
Get the base entry name without extension.
Definition: ncbifile.hpp:3924
bool CreatePath(TCreateFlags flags=fCreate_Default) const
Create the directory path recursively possibly more than one at a time.
Definition: ncbifile.cpp:4106
bool Rename(const string &new_path, TRenameFlags flags=fRF_Default)
Rename entry.
Definition: ncbifile.cpp:2456
virtual bool Remove(TRemoveFlags flags=eRecursive) const
Remove a directory entry.
Definition: ncbifile.cpp:2595
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
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 GetExt(void) const
Get extension name.
Definition: ncbifile.hpp:3932
static void SplitPath(const string &path, string *dir=0, string *base=0, string *ext=0)
Split a path string into its basic components.
Definition: ncbifile.cpp:358
@ eSerial_StdWhenAny
Definition: serialdef.hpp:132
@ eSerial_Xml
XML.
Definition: serialdef.hpp:75
static CObjectIStream * Open(ESerialDataFormat format, CNcbiIstream &inStream, bool deleteInStream)
Create serial object reader and attach it to an input stream.
Definition: objistr.cpp:195
virtual const string & Get(const string &section, const string &name, TFlags flags=0) const
Get the parameter value.
Definition: ncbireg.cpp:262
virtual string GetString(const string &section, const string &name, const string &default_value, TFlags flags=0) const
Get the parameter string value.
Definition: ncbireg.cpp:321
#define END_NCBI_SCOPE
End previously defined NCBI scope.
Definition: ncbistl.hpp:103
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
Definition: ncbistl.hpp:100
CNcbiIstream & NcbiGetlineEOL(CNcbiIstream &is, string &str, string::size_type *count=NULL)
Read from "is" to "str" the next line (taking into account platform specifics of End-of-Line)
IO_PREFIX::ofstream CNcbiOfstream
Portable alias for ofstream.
Definition: ncbistre.hpp:500
IO_PREFIX::ifstream CNcbiIfstream
Portable alias for ifstream.
Definition: ncbistre.hpp:439
#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:3457
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:5429
#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:3197
static string IntToString(int value, TNumToStringFlags flags=0, int base=10)
Convert int to string.
Definition: ncbistr.hpp:5083
static SIZE_TYPE Find(const CTempString str, const CTempString pattern, ECase use_case=eCase, EDirection direction=eForwardSearch, SIZE_TYPE occurrence=0)
Find the pattern in the string.
Definition: ncbistr.cpp:2887
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:3310
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:5411
static bool SplitInTwo(const CTempString str, const CTempString delim, string &str1, string &str2, TSplitFlags flags=0)
Split a string into two pieces using the specified delimiters.
Definition: ncbistr.cpp:3550
static enable_if< is_arithmetic< TNumeric >::value||is_convertible< TNumeric, Int8 >::value, string >::type NumericToString(TNumeric value, TNumToStringFlags flags=0, int base=10)
Convert numeric value to string.
Definition: ncbistr.hpp:673
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:3401
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
@ eEncoding_UTF8
Definition: ncbistr.hpp:201
@ fSplit_Truncate
Definition: ncbistr.hpp:2501
@ fSplit_MergeDelimiters
Merge adjacent delimiters.
Definition: ncbistr.hpp:2498
@ eNocase
Case insensitive compare.
Definition: ncbistr.hpp:1206
unsigned int
A callback function used to compare two keys in a database.
Definition: types.hpp:1210
FILE * file
char * buf
int i
if(yy_accept[yy_current_state])
yy_size_t n
static void hex(unsigned char c)
Definition: mdb_dump.c:56
static int version
Definition: mdb_load.c:29
#define MSVC_PROJECT_FILE_EXT
MSVC 7.10 project defines.
#define MSVC_CONFIGNAME
#define XCODE_REG_SECTION
#define UNIX_REG_SECTION
#define MSVC_REG_SECTION
#define XCODE_CONFIGNAME
string GenerateSlnGUID(void)
Generate pseudo-GUID.
string ConfigName(const string &config)
return <config>|Win32 as needed by MSVC compiler
CGuidGenerator guid_gen
string SourceFileExt(const string &file_path)
Get extension for source file without extension.
bool s_Config_less(const SConfigInfo &x, const SConfigInfo &y)
const CDataToolGeneratedSrc * IsProducedByDatatool(const string &src_path_abs, const CProjItem &project)
bool SameRootDirs(const string &dir1, const string &dir2)
Checks if 2 dirs has the same root.
string GetOpt(const CPtbRegistry &registry, const string &section, const string &opt, const string &config)
void LoadConfigInfoByNames(const CNcbiRegistry &registry, const list< string > &config_names, list< SConfigInfo > *configs)
bool PromoteIfDifferent(const string &present_path, const string &candidate_path, const string &ignore)
CProjKey CreateProjKey(const string &project_name)
string IdentifySlnGUID(const string &source_dir, const CProjKey &proj)
string CreateProjectName(const CProjKey &project_id)
Project naming schema.
bool IsSubdir(const string &abs_parent_dir, const string &abs_dir)
Is abs_dir a parent of abs_parent_dir.
constexpr bool empty(list< Ts... >) noexcept
const struct ncbi::grid::netcache::search::fields::KEY key
unsigned int a
Definition: ncbi_localip.c:102
void SleepSec(unsigned long sec, EInterruptOnSignal onsignal=eRestartOnSignal)
Sleep.
int tolower(Uchar c)
Definition: ncbictype.hpp:72
std::istream & in(std::istream &in_, double &x_)
static char tmp[2048]
Definition: utf8.c:42
CProjBulderApp & GetApp(void)
access to App singleton
#define PTB_INFO_EX(file, err_code, msg)
@ ePTB_FileModified
@ ePTB_ConfigurationError
#define PTB_WARNING_EX(file, err_code, msg)
#define PTB_TRACE(msg)
SConfigInfo –.
bool operator==(const SConfigInfo &cfg) const
string m_RuntimeLibrary
enum SConfigInfo::@944 m_rtType
string GetConfigFullName(void) const
void SetRuntimeLibrary(const string &lib)
SCustomBuildInfo –.
string m_AdditionalDependencies
string m_Compilers
<compilers> branch of tree
Definition: proj_utils.hpp:74
string m_Src
<src> branch of tree
Definition: proj_utils.hpp:71
string m_Impl
<impl> sub-branch of include/* project path
Definition: proj_utils.hpp:80
Definition: type.c:6
int test(int srctype, const void *srcdata, int srclen, int dsttype, int dstlen)
Definition: t0019.c:43
Modified on Fri Dec 01 04:48:14 2023 by modify_doxy.py rev. 669887