msvc_prj_utils.cpp
上传用户:yhdzpy8989
上传日期:2007-06-13
资源大小:13604k
文件大小:37k
源码类别:

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: msvc_prj_utils.cpp,v $
  4.  * PRODUCTION Revision 1000.3  2004/06/16 17:02:32  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.31
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /* $Id: msvc_prj_utils.cpp,v 1000.3 2004/06/16 17:02:32 gouriano Exp $
  10.  * ===========================================================================
  11.  *
  12.  *                            PUBLIC DOMAIN NOTICE
  13.  *               National Center for Biotechnology Information
  14.  *
  15.  *  This software/database is a "United States Government Work" under the
  16.  *  terms of the United States Copyright Act.  It was written as part of
  17.  *  the author's official duties as a United States Government employee and
  18.  *  thus cannot be copyrighted.  This software/database is freely available
  19.  *  to the public for use. The National Library of Medicine and the U.S.
  20.  *  Government have not placed any restriction on its use or reproduction.
  21.  *
  22.  *  Although all reasonable efforts have been taken to ensure the accuracy
  23.  *  and reliability of the software and data, the NLM and the U.S.
  24.  *  Government do not and cannot warrant the performance or results that
  25.  *  may be obtained by using this software or data. The NLM and the U.S.
  26.  *  Government disclaim all warranties, express or implied, including
  27.  *  warranties of performance, merchantability or fitness for any particular
  28.  *  purpose.
  29.  *
  30.  *  Please cite the author in any work or product based on this material.
  31.  *
  32.  * ===========================================================================
  33.  *
  34.  * Author:  Viatcheslav Gorelenkov
  35.  *
  36.  */
  37. #include <ncbi_pch.hpp>
  38. #include <app/project_tree_builder/msvc_prj_utils.hpp>
  39. #include <app/project_tree_builder/proj_builder_app.hpp>
  40. #include <app/project_tree_builder/msvc_prj_defines.hpp>
  41. #include <serial/objostrxml.hpp>
  42. #include <serial/objistr.hpp>
  43. #include <serial/serial.hpp>
  44. BEGIN_NCBI_SCOPE
  45. CVisualStudioProject * LoadFromXmlFile(const string& file_path)
  46. {
  47.     auto_ptr<CObjectIStream> in(CObjectIStream::Open(eSerial_Xml, 
  48.                                                     file_path, 
  49.                                                     eSerial_StdWhenAny));
  50.     if ( in->fail() )
  51.     NCBI_THROW(CProjBulderAppException, eFileOpen, file_path);
  52.     
  53.     auto_ptr<CVisualStudioProject> prj(new CVisualStudioProject());
  54.     in->Read(prj.get(), prj->GetThisTypeInfo());
  55.     return prj.release();
  56. }
  57. void SaveToXmlFile  (const string&               file_path, 
  58.                      const CVisualStudioProject& project)
  59. {
  60.     // Create dir if no such dir...
  61.     string dir;
  62.     CDirEntry::SplitPath(file_path, &dir);
  63.     CDir project_dir(dir);
  64.     if ( !project_dir.Exists() ) {
  65.         CDir(dir).CreatePath();
  66.     }
  67.     CNcbiOfstream  ofs(file_path.c_str(), 
  68.                        IOS_BASE::out | IOS_BASE::trunc );
  69.     if ( !ofs )
  70.     NCBI_THROW(CProjBulderAppException, eFileCreation, file_path);
  71.     CObjectOStreamXml xs(ofs, false);
  72.     xs.SetReferenceDTD(false);
  73.     xs.SetEncoding(CObjectOStreamXml::eEncoding_Windows_1252);
  74.     xs << project;
  75. }
  76. void PromoteIfDifferent(const string& present_path, 
  77.                         const string& candidate_path)
  78. {
  79.     // Open both files
  80.     CNcbiIfstream ifs_present(present_path.c_str(), 
  81.                               IOS_BASE::in | IOS_BASE::binary);
  82.     if ( !ifs_present ) {
  83.         NCBI_THROW(CProjBulderAppException, eFileOpen, present_path);
  84.     }
  85.     ifs_present.seekg(0, ios::end);
  86.     size_t file_length_present = ifs_present.tellg() - streampos(0);
  87.     ifs_present.seekg(0, ios::beg);
  88.     CNcbiIfstream ifs_new (candidate_path.c_str(), 
  89.                               IOS_BASE::in | IOS_BASE::binary);
  90.     if ( !ifs_new ) {
  91.         NCBI_THROW(CProjBulderAppException, eFileOpen, candidate_path);
  92.     }
  93.     ifs_new.seekg(0, ios::end);
  94.     size_t file_length_new = ifs_new.tellg() - streampos(0);
  95.     ifs_new.seekg(0, ios::beg);
  96.     if (file_length_present != file_length_new) {
  97.         ifs_present.close();
  98.         ifs_new.close();
  99.         CDirEntry(present_path).Remove();
  100.         CDirEntry(candidate_path).Rename(present_path);
  101.         return;
  102.     }
  103.     // Load both to memory
  104.     typedef AutoPtr<char, ArrayDeleter<char> > TAutoArray;
  105.     TAutoArray buf_present = TAutoArray(new char [file_length_present]);
  106.     TAutoArray buf_new     = TAutoArray(new char [file_length_new]);
  107.     ifs_present.read(buf_present.get(), file_length_present);
  108.     ifs_new.read    (buf_new.get(),     file_length_new);
  109.     ifs_present.close();
  110.     ifs_new.close();
  111.     // If candidate file is not the same as present file it'll be a new file
  112.     if (memcmp(buf_present.get(), buf_new.get(), file_length_present) != 0) {
  113.         CDirEntry(present_path).Remove();
  114.         CDirEntry(candidate_path).Rename(present_path);
  115.         return;
  116.     } else {
  117.         CDirEntry(candidate_path).Remove();
  118.     }
  119. }
  120. void SaveIfNewer    (const string&               file_path, 
  121.                      const CVisualStudioProject& project)
  122. {
  123.     // If no such file then simple write it
  124.     if ( !CDirEntry(file_path).Exists() ) {
  125.         SaveToXmlFile(file_path, project);
  126.         return;
  127.     }
  128.     // Save new file to tmp path.
  129.     string candidate_file_path = file_path + ".candidate";
  130.     SaveToXmlFile(candidate_file_path, project);
  131.     PromoteIfDifferent(file_path, candidate_file_path);
  132. }
  133. //-----------------------------------------------------------------------------
  134. class CGuidGenerator
  135. {
  136. public:
  137.     ~CGuidGenerator(void);
  138.     friend string GenerateSlnGUID(void);
  139. private:
  140.     CGuidGenerator(void);
  141.     const string root_guid; // root GUID for MSVC solutions
  142.     const string guid_base;
  143.     string Generate12Chars(void);
  144.     unsigned int m_Seed;
  145.     string DoGenerateSlnGUID(void);
  146.     set<string> m_Trace;
  147. };
  148. string GenerateSlnGUID(void)
  149. {
  150.     static CGuidGenerator guid_gen;
  151.     return guid_gen.DoGenerateSlnGUID();
  152. }
  153. CGuidGenerator::CGuidGenerator(void)
  154.     :root_guid("8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942"),
  155.      guid_base("8BC9CEB8-8B4A-11D0-8D11-"),
  156.      m_Seed(0)
  157. {
  158. }
  159. CGuidGenerator::~CGuidGenerator(void)
  160. {
  161. }
  162. string CGuidGenerator::Generate12Chars(void)
  163. {
  164.     CNcbiOstrstream ost;
  165.     ost.unsetf(ios::showbase);
  166.     ost.setf  (ios::uppercase);
  167.     ost << hex  << setw(12) << setfill('A') << m_Seed++ << ends << flush;
  168.     return ost.str();
  169. }
  170. string CGuidGenerator::DoGenerateSlnGUID(void)
  171. {
  172.     for ( ;; ) {
  173.         //GUID prototype
  174.         string proto = guid_base + Generate12Chars();
  175.         if (proto != root_guid  &&  m_Trace.find(proto) == m_Trace.end()) {
  176.             m_Trace.insert(proto);
  177.             return "{" + proto + "}";
  178.         }
  179.     }
  180. }
  181.  
  182. string SourceFileExt(const string& file_path)
  183. {
  184.     string ext;
  185.     CDirEntry::SplitPath(file_path, NULL, NULL, &ext);
  186.     
  187.     bool explicit_c   = NStr::CompareNocase(ext, ".c"  )== 0;
  188.     if (explicit_c  &&  CFile(file_path).Exists()) {
  189.         return ".c";
  190.     }
  191.     bool explicit_cpp = NStr::CompareNocase(ext, ".cpp")== 0;
  192.     if (explicit_cpp  &&  CFile(file_path).Exists()) {
  193.         return ".cpp";
  194.     }
  195.     string file_path_cpp = file_path + ".cpp";
  196.     if ( CFile(file_path_cpp).Exists() ) 
  197.         return ".cpp";
  198.     string file_path_c = file_path + ".c";
  199.     if ( CFile(file_path_c).Exists() ) 
  200.         return ".c";
  201.     return "";
  202. }
  203. //-----------------------------------------------------------------------------
  204. SConfigInfo::SConfigInfo(void)
  205.     :m_Debug(false)
  206. {
  207. }
  208. SConfigInfo::SConfigInfo(const string& name, 
  209.                          bool debug, 
  210.                          const string& runtime_library)
  211.     :m_Name          (name),
  212.      m_Debug         (debug),
  213.      m_RuntimeLibrary(runtime_library)
  214. {
  215. }
  216. void LoadConfigInfoByNames(const CNcbiRegistry& registry, 
  217.                            const list<string>&  config_names, 
  218.                            list<SConfigInfo>*   configs)
  219. {
  220.     ITERATE(list<string>, p, config_names) {
  221.         const string& config_name = *p;
  222.         SConfigInfo config;
  223.         config.m_Name  = config_name;
  224.         config.m_Debug = registry.GetString(config_name, 
  225.                                             "debug",
  226.                                             "FALSE") != "FALSE";
  227.         config.m_RuntimeLibrary = registry.GetString(config_name, 
  228.                                                      "runtimeLibraryOption",
  229.                                                      "0");
  230.         configs->push_back(config);
  231.     }
  232. }
  233. //-----------------------------------------------------------------------------
  234. CMsvc7RegSettings::CMsvc7RegSettings(void)
  235. {
  236.     //TODO
  237. }
  238. bool IsSubdir(const string& abs_parent_dir, const string& abs_dir)
  239. {
  240.     return abs_dir.find(abs_parent_dir) == 0;
  241. }
  242. string GetOpt(const CNcbiRegistry& registry, 
  243.               const string& section, 
  244.               const string& opt, 
  245.               const string& config)
  246. {
  247.     string section_spec = section + '.' + config;
  248.     string val_spec = registry.GetString(section_spec, opt, "");
  249.     if ( !val_spec.empty() )
  250.         return val_spec;
  251.     return registry.GetString(section, opt, "");
  252. }
  253. string GetOpt(const CNcbiRegistry& registry, 
  254.               const string&        section, 
  255.               const string&        opt, 
  256.               const SConfigInfo&   config)
  257. {
  258.     string section_spec(section);
  259.     section_spec += config.m_Debug? ".debug": ".release";
  260.     string section_dr(section_spec); //section.debug or section.release
  261.     section_spec += '.';
  262.     section_spec += config.m_Name;
  263.     string val_spec = registry.GetString(section_spec, opt, "");
  264.     if ( !val_spec.empty() )
  265.         return val_spec;
  266.     val_spec = registry.GetString(section_dr, opt, "");
  267.     if ( !val_spec.empty() )
  268.         return val_spec;
  269.     return registry.GetString(section, opt, "");
  270. }
  271. string ConfigName(const string& config)
  272. {
  273.     return config +'|'+ MSVC_PROJECT_PLATFORM;
  274. }
  275. //-----------------------------------------------------------------------------
  276. CSrcToFilterInserterWithPch::CSrcToFilterInserterWithPch
  277.                                         (const string&            project_id,
  278.                                          const list<SConfigInfo>& configs,
  279.                                          const string&            project_dir)
  280.     :m_ProjectId  (project_id),
  281.      m_Configs    (configs),
  282.      m_ProjectDir (project_dir)
  283. {
  284. }
  285. CSrcToFilterInserterWithPch::~CSrcToFilterInserterWithPch(void)
  286. {
  287. }
  288. void 
  289. CSrcToFilterInserterWithPch::operator()(CRef<CFilter>&  filter, 
  290.                                         const string&   rel_source_file)
  291. {
  292.     CRef< CFFile > file(new CFFile());
  293.     file->SetAttlist().SetRelativePath(rel_source_file);
  294.     //
  295.     TPch pch_usage = DefinePchUsage(m_ProjectDir, rel_source_file);
  296.     //
  297.     ITERATE(list<SConfigInfo>, n , m_Configs) {
  298.         // Iterate all configurations
  299.         const string& config = (*n).m_Name;
  300.         CRef<CFileConfiguration> file_config(new CFileConfiguration());
  301.         file_config->SetAttlist().SetName(ConfigName(config));
  302.         CRef<CTool> compilerl_tool(new CTool(""));
  303.         compilerl_tool->SetAttlist().SetName("VCCLCompilerTool");
  304.         if (pch_usage.first == eCreate) {
  305.             compilerl_tool->SetAttlist().SetPreprocessorDefinitions
  306.                              (GetApp().GetMetaMakefile().GetPchUsageDefine());
  307.             compilerl_tool->SetAttlist().SetUsePrecompiledHeader("1");
  308.             compilerl_tool->SetAttlist().SetPrecompiledHeaderThrough
  309.                                                             (pch_usage.second);
  310.         } else if (pch_usage.first == eUse) {
  311.             compilerl_tool->SetAttlist().SetPreprocessorDefinitions
  312.                               (GetApp().GetMetaMakefile().GetPchUsageDefine());
  313.             compilerl_tool->SetAttlist().SetUsePrecompiledHeader("3");
  314.             compilerl_tool->SetAttlist().SetPrecompiledHeaderThrough
  315.                                                             (pch_usage.second);
  316.         }
  317.         else {
  318.             compilerl_tool->SetAttlist().SetUsePrecompiledHeader("0");
  319.             compilerl_tool->SetAttlist().SetPrecompiledHeaderThrough("");
  320.         }
  321.         file_config->SetTool(*compilerl_tool);
  322.         file->SetFileConfiguration().push_back(file_config);
  323.     }
  324.     //
  325.     CRef< CFilter_Base::C_FF::C_E > ce(new CFilter_Base::C_FF::C_E());
  326.     ce->SetFile(*file);
  327.     filter->SetFF().SetFF().push_back(ce);
  328. }
  329. CSrcToFilterInserterWithPch::TPch 
  330. CSrcToFilterInserterWithPch::DefinePchUsage(const string& project_dir,
  331.                                             const string& rel_source_file)
  332. {
  333.     // Check global permission
  334.     if ( !GetApp().GetMetaMakefile().IsPchEnabled() )
  335.         return TPch(eNotUse, "");
  336.     string abs_source_file = 
  337.         CDirEntry::ConcatPath(project_dir, rel_source_file);
  338.     abs_source_file = CDirEntry::NormalizePath(abs_source_file);
  339.     // .c files - not use PCH
  340.     string ext;
  341.     CDirEntry::SplitPath(abs_source_file, NULL, NULL, &ext);
  342.     if ( NStr::CompareNocase(ext, ".c") == 0)
  343.         return TPch(eNotUse, "");
  344.     // PCH usage is defined in msvc master makefile
  345.     string pch_file = 
  346.         GetApp().GetMetaMakefile().GetUsePchThroughHeader
  347.                                        (m_ProjectId,
  348.                                         abs_source_file, 
  349.                                         GetApp().GetProjectTreeInfo().m_Src);
  350.     // No PCH - not use
  351.     if ( pch_file.empty() )
  352.         return TPch(eNotUse, "");
  353.     if (m_PchHeaders.find(pch_file) == m_PchHeaders.end()) {
  354.         // New PCH - this source file will create it
  355.         m_PchHeaders.insert(pch_file);
  356.         return TPch(eCreate, pch_file);
  357.     } else {
  358.         // Use PCH (previously created)
  359.         return TPch(eUse, pch_file);
  360.     }
  361. }
  362. //-----------------------------------------------------------------------------
  363. CBasicProjectsFilesInserter::CBasicProjectsFilesInserter
  364.                                 (CVisualStudioProject*    vcproj,
  365.                                 const string&            project_id,
  366.                                 const list<SConfigInfo>& configs,
  367.                                 const string&            project_dir)
  368.     :m_Vcproj     (vcproj),
  369.      m_SrcInserter(project_id, 
  370.                    configs, 
  371.                    project_dir),
  372.      m_Filters    (project_dir)
  373. {
  374.     m_Filters.Initilize();
  375. }
  376. CBasicProjectsFilesInserter::~CBasicProjectsFilesInserter(void)
  377. {
  378. }
  379. void CBasicProjectsFilesInserter::AddSourceFile(const string& rel_file_path)
  380. {
  381.     m_Filters.AddSourceFile(m_SrcInserter, rel_file_path);
  382. }
  383. void CBasicProjectsFilesInserter::AddHeaderFile(const string& rel_file_path)
  384. {
  385.     m_Filters.AddHeaderFile(rel_file_path);
  386. }
  387. void CBasicProjectsFilesInserter::AddInlineFile(const string& rel_file_path)
  388. {
  389.     m_Filters.AddInlineFile(rel_file_path);
  390. }
  391. void CBasicProjectsFilesInserter::Finalize(void)
  392. {
  393.     m_Vcproj->SetFiles().SetFilter().push_back(m_Filters.m_SourceFiles);
  394.     if ( m_Filters.m_HeaderFilesPrivate->IsSetFF() )
  395.     {
  396.         CRef< CFilter_Base::C_FF::C_E > ce(new CFilter_Base::C_FF::C_E());
  397.         ce->SetFilter(*m_Filters.m_HeaderFilesPrivate);
  398.         m_Filters.m_HeaderFiles->SetFF().SetFF().push_back(ce);
  399.     }
  400.     if ( m_Filters.m_HeaderFilesImpl->IsSetFF() )
  401.     {
  402.         CRef< CFilter_Base::C_FF::C_E > ce(new CFilter_Base::C_FF::C_E());
  403.         ce->SetFilter(*m_Filters.m_HeaderFilesImpl);
  404.         m_Filters.m_HeaderFiles->SetFF().SetFF().push_back(ce);
  405.     }
  406.     m_Vcproj->SetFiles().SetFilter().push_back(m_Filters.m_HeaderFiles);
  407.     m_Vcproj->SetFiles().SetFilter().push_back(m_Filters.m_InlineFiles);
  408. }
  409. //-----------------------------------------------------------------------------
  410. static bool s_IsPrivateHeader(const string& header_abs_path)
  411. {
  412.     string src_dir = GetApp().GetProjectTreeInfo().m_Src;
  413.     return header_abs_path.find(src_dir) != NPOS;
  414. }
  415. static bool s_IsImplHeader(const string& header_abs_path)
  416. {
  417.     string src_trait = CDirEntry::GetPathSeparator()        +
  418.                        GetApp().GetProjectTreeInfo().m_Impl +
  419.                        CDirEntry::GetPathSeparator();
  420.     return header_abs_path.find(src_trait) != NPOS;
  421. }
  422. //-----------------------------------------------------------------------------
  423. CBasicProjectsFilesInserter::SFiltersItem::SFiltersItem(void)
  424. {
  425. }
  426. CBasicProjectsFilesInserter::SFiltersItem::SFiltersItem
  427.                                                     (const string& project_dir)
  428.     :m_ProjectDir(project_dir)
  429. {
  430. }
  431. void CBasicProjectsFilesInserter::SFiltersItem::Initilize(void)
  432. {
  433.     m_SourceFiles.Reset(new CFilter());
  434.     m_SourceFiles->SetAttlist().SetName("Source Files");
  435.     m_SourceFiles->SetAttlist().SetFilter
  436.             ("cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx");
  437.     m_HeaderFiles.Reset(new CFilter());
  438.     m_HeaderFiles->SetAttlist().SetName("Header Files");
  439.     m_HeaderFiles->SetAttlist().SetFilter("h;hpp;hxx;hm;inc;xsd");
  440.     m_HeaderFilesPrivate.Reset(new CFilter());
  441.     m_HeaderFilesPrivate->SetAttlist().SetName("Private");
  442.     m_HeaderFilesPrivate->SetAttlist().SetFilter("h;hpp;hxx;hm;inc;xsd");
  443.     m_HeaderFilesImpl.Reset(new CFilter());
  444.     m_HeaderFilesImpl->SetAttlist().SetName("Impl");
  445.     m_HeaderFilesImpl->SetAttlist().SetFilter("h;hpp;hxx;hm;inc;xsd");
  446.     m_InlineFiles.Reset(new CFilter());
  447.     m_InlineFiles->SetAttlist().SetName("Inline Files");
  448.     m_InlineFiles->SetAttlist().SetFilter("inl");
  449. }
  450. void CBasicProjectsFilesInserter::SFiltersItem::AddSourceFile
  451.                            (CSrcToFilterInserterWithPch& inserter_w_pch,
  452.                             const string&                rel_file_path)
  453. {
  454.     inserter_w_pch(m_SourceFiles, rel_file_path);
  455. }
  456. void CBasicProjectsFilesInserter::SFiltersItem::AddHeaderFile
  457.                                                   (const string& rel_file_path)
  458. {
  459.     CRef< CFFile > file(new CFFile());
  460.     file->SetAttlist().SetRelativePath(rel_file_path);
  461.     CRef< CFilter_Base::C_FF::C_E > ce(new CFilter_Base::C_FF::C_E());
  462.     ce->SetFile(*file);
  463.     
  464.     string abs_header_path = 
  465.         CDirEntry::ConcatPath(m_ProjectDir, rel_file_path);
  466.     abs_header_path = CDirEntry::NormalizePath(abs_header_path);
  467.     if ( s_IsPrivateHeader(abs_header_path) ) {
  468.         m_HeaderFilesPrivate->SetFF().SetFF().push_back(ce);
  469.     } else if ( s_IsImplHeader(abs_header_path) ) {
  470.         m_HeaderFilesImpl->SetFF().SetFF().push_back(ce);
  471.     } else {
  472.         m_HeaderFiles->SetFF().SetFF().push_back(ce);
  473.     }
  474. }
  475. void CBasicProjectsFilesInserter::SFiltersItem::AddInlineFile
  476.                                                   (const string& rel_file_path)
  477. {
  478.     CRef< CFFile > file(new CFFile());
  479.     file->SetAttlist().SetRelativePath(rel_file_path);
  480.     CRef< CFilter_Base::C_FF::C_E > ce(new CFilter_Base::C_FF::C_E());
  481.     ce->SetFile(*file);
  482.     m_InlineFiles->SetFF().SetFF().push_back(ce);
  483. }
  484. //-----------------------------------------------------------------------------
  485. CDllProjectFilesInserter::CDllProjectFilesInserter
  486.                                 (CVisualStudioProject*    vcproj,
  487.                                  const CProjKey           dll_project_key,
  488.                                  const list<SConfigInfo>& configs,
  489.                                  const string&            project_dir)
  490.     :m_Vcproj        (vcproj),
  491.      m_DllProjectKey (dll_project_key),
  492.      m_ProjectDir    (project_dir),
  493.      m_SrcInserter   (dll_project_key.Id(), 
  494.                       configs, 
  495.                       project_dir),
  496.      m_PrivateFilters(project_dir)
  497. {
  498.     // Private filters initilization
  499.     m_PrivateFilters.m_SourceFiles.Reset(new CFilter());
  500.     m_PrivateFilters.m_SourceFiles->SetAttlist().SetName("Source Files");
  501.     m_PrivateFilters.m_SourceFiles->SetAttlist().SetFilter
  502.             ("cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx");
  503.     m_PrivateFilters.m_HeaderFiles.Reset(new CFilter());
  504.     m_PrivateFilters.m_HeaderFiles->SetAttlist().SetName("Header Files");
  505.     m_PrivateFilters.m_HeaderFiles->SetAttlist().SetFilter("h;hpp;hxx;hm;inc;xsd");
  506.     m_PrivateFilters.m_HeaderFilesPrivate.Reset(new CFilter());
  507.     m_PrivateFilters.m_HeaderFilesPrivate->SetAttlist().SetName("Private");
  508.     m_PrivateFilters.m_HeaderFilesPrivate->SetAttlist().SetFilter("h;hpp;hxx;hm;inc;xsd");
  509.     
  510.     m_PrivateFilters.m_HeaderFilesImpl.Reset(new CFilter());
  511.     m_PrivateFilters.m_HeaderFilesImpl->SetAttlist().SetName("Impl");
  512.     m_PrivateFilters.m_HeaderFilesImpl->SetAttlist().SetFilter("h;hpp;hxx;hm;inc;xsd");
  513.     m_PrivateFilters.m_InlineFiles.Reset(new CFilter());
  514.     m_PrivateFilters.m_InlineFiles->SetAttlist().SetName("Inline Files");
  515.     m_PrivateFilters.m_InlineFiles->SetAttlist().SetFilter("inl");
  516.     // Hosted Libraries filter (folder)
  517.     m_HostedLibrariesRootFilter.Reset(new CFilter());
  518.     m_HostedLibrariesRootFilter->SetAttlist().SetName("Hosted Libraries");
  519.     m_HostedLibrariesRootFilter->SetAttlist().SetFilter("");
  520. }
  521. CDllProjectFilesInserter::~CDllProjectFilesInserter(void)
  522. {
  523. }
  524. void CDllProjectFilesInserter::AddSourceFile (const string& rel_file_path)
  525. {
  526.     string abs_path = CDirEntry::ConcatPath(m_ProjectDir, rel_file_path);
  527.     abs_path = CDirEntry::NormalizePath(abs_path);
  528.     
  529.     CProjKey proj_key = GetApp().GetDllFilesDistr().GetSourceLib(abs_path, m_DllProjectKey);
  530.     
  531.     if (proj_key == CProjKey()) {
  532.         m_PrivateFilters.AddSourceFile(m_SrcInserter, rel_file_path);
  533.         return;
  534.     }
  535.     THostedLibs::iterator p = m_HostedLibs.find(proj_key);
  536.     if (p != m_HostedLibs.end()) {
  537.         TFiltersItem& filters_item = p->second;
  538.         filters_item.AddSourceFile(m_SrcInserter, rel_file_path);
  539.         return;
  540.     }
  541.     TFiltersItem new_item(m_ProjectDir);
  542.     new_item.Initilize();
  543.     new_item.AddSourceFile(m_SrcInserter, rel_file_path);
  544.     m_HostedLibs[proj_key] = new_item;
  545. }
  546. void CDllProjectFilesInserter::AddHeaderFile(const string& rel_file_path)
  547. {
  548.     string abs_path = CDirEntry::ConcatPath(m_ProjectDir, rel_file_path);
  549.     abs_path = CDirEntry::NormalizePath(abs_path);
  550.     
  551.     CProjKey proj_key = GetApp().GetDllFilesDistr().GetHeaderLib(abs_path, m_DllProjectKey);
  552.     
  553.     if (proj_key == CProjKey()) {
  554.         m_PrivateFilters.AddHeaderFile(rel_file_path);
  555.         return;
  556.     }
  557.     THostedLibs::iterator p = m_HostedLibs.find(proj_key);
  558.     if (p != m_HostedLibs.end()) {
  559.         TFiltersItem& filters_item = p->second;
  560.         filters_item.AddHeaderFile(rel_file_path);
  561.         return;
  562.     }
  563.     TFiltersItem new_item(m_ProjectDir);
  564.     new_item.Initilize();
  565.     new_item.AddHeaderFile(rel_file_path);
  566.     m_HostedLibs[proj_key] = new_item;
  567. }
  568. void CDllProjectFilesInserter::AddInlineFile(const string& rel_file_path)
  569. {
  570.     string abs_path = CDirEntry::ConcatPath(m_ProjectDir, rel_file_path);
  571.     abs_path = CDirEntry::NormalizePath(abs_path);
  572.     
  573.     CProjKey proj_key = GetApp().GetDllFilesDistr().GetInlineLib(abs_path, m_DllProjectKey);
  574.     
  575.     if (proj_key == CProjKey()) {
  576.         m_PrivateFilters.AddInlineFile(rel_file_path);
  577.         return;
  578.     }
  579.     THostedLibs::iterator p = m_HostedLibs.find(proj_key);
  580.     if (p != m_HostedLibs.end()) {
  581.         TFiltersItem& filters_item = p->second;
  582.         filters_item.AddInlineFile(rel_file_path);
  583.         return;
  584.     }
  585.     TFiltersItem new_item(m_ProjectDir);
  586.     new_item.Initilize();
  587.     new_item.AddInlineFile(rel_file_path);
  588.     m_HostedLibs[proj_key] = new_item;
  589. }
  590. void CDllProjectFilesInserter::Finalize(void)
  591. {
  592.     m_Vcproj->SetFiles().SetFilter().push_back(m_PrivateFilters.m_SourceFiles);
  593.     if ( !m_PrivateFilters.m_HeaderFilesPrivate->IsSetFF() )
  594.     {
  595.         CRef< CFilter_Base::C_FF::C_E > ce(new CFilter_Base::C_FF::C_E());
  596.         ce->SetFilter(*m_PrivateFilters.m_HeaderFilesPrivate);
  597.         m_PrivateFilters.m_HeaderFiles->SetFF().SetFF().push_back(ce);
  598.     }
  599.     if ( !m_PrivateFilters.m_HeaderFilesImpl->IsSetFF() )
  600.     {
  601.         CRef< CFilter_Base::C_FF::C_E > ce(new CFilter_Base::C_FF::C_E());
  602.         ce->SetFilter(*m_PrivateFilters.m_HeaderFilesImpl);
  603.         m_PrivateFilters.m_HeaderFiles->SetFF().SetFF().push_back(ce);
  604.     }
  605.     m_Vcproj->SetFiles().SetFilter().push_back(m_PrivateFilters.m_HeaderFiles);
  606.     m_Vcproj->SetFiles().SetFilter().push_back(m_PrivateFilters.m_InlineFiles);
  607.     NON_CONST_ITERATE(THostedLibs, p, m_HostedLibs) {
  608.         const CProjKey& proj_key     = p->first;
  609.         TFiltersItem&   filters_item = p->second;
  610.         CRef<CFilter> hosted_lib_filter(new CFilter());
  611.         hosted_lib_filter->SetAttlist().SetName(CreateProjectName(proj_key));
  612.         hosted_lib_filter->SetAttlist().SetFilter("");
  613.         {{
  614.             CRef< CFilter_Base::C_FF::C_E > ce(new CFilter_Base::C_FF::C_E());
  615.             ce->SetFilter(*(filters_item.m_SourceFiles));
  616.             hosted_lib_filter->SetFF().SetFF().push_back(ce);
  617.         }}
  618.         if ( filters_item.m_HeaderFilesPrivate->IsSetFF() )
  619.         {
  620.             CRef< CFilter_Base::C_FF::C_E > ce(new CFilter_Base::C_FF::C_E());
  621.             ce->SetFilter(*filters_item.m_HeaderFilesPrivate);
  622.             filters_item.m_HeaderFiles->SetFF().SetFF().push_back(ce);
  623.         }
  624.         if ( filters_item.m_HeaderFilesImpl->IsSetFF() )
  625.         {
  626.             CRef< CFilter_Base::C_FF::C_E > ce(new CFilter_Base::C_FF::C_E());
  627.             ce->SetFilter(*filters_item.m_HeaderFilesImpl);
  628.             filters_item.m_HeaderFiles->SetFF().SetFF().push_back(ce);
  629.         }
  630.         {{
  631.             CRef< CFilter_Base::C_FF::C_E > ce(new CFilter_Base::C_FF::C_E());
  632.             ce->SetFilter(*(filters_item.m_HeaderFiles));
  633.             hosted_lib_filter->SetFF().SetFF().push_back(ce);
  634.         }}
  635.         {{
  636.             CRef< CFilter_Base::C_FF::C_E > ce(new CFilter_Base::C_FF::C_E());
  637.             ce->SetFilter(*(filters_item.m_InlineFiles));
  638.             hosted_lib_filter->SetFF().SetFF().push_back(ce);
  639.         }}
  640.         {{
  641.             CRef< CFilter_Base::C_FF::C_E > ce(new CFilter_Base::C_FF::C_E());
  642.             ce->SetFilter(*hosted_lib_filter);
  643.             m_HostedLibrariesRootFilter->SetFF().SetFF().push_back(ce);
  644.         }}
  645.     }
  646.     m_Vcproj->SetFiles().SetFilter().push_back(m_HostedLibrariesRootFilter);
  647. }
  648. //-----------------------------------------------------------------------------
  649. void AddCustomBuildFileToFilter(CRef<CFilter>&          filter, 
  650.                                 const list<SConfigInfo> configs,
  651.                                 const string&           project_dir,
  652.                                 const SCustomBuildInfo& build_info)
  653. {
  654.     CRef<CFFile> file(new CFFile());
  655.     file->SetAttlist().SetRelativePath
  656.         (CDirEntry::CreateRelativePath(project_dir, 
  657.                                        build_info.m_SourceFile));
  658.     ITERATE(list<SConfigInfo>, n , configs) {
  659.         // Iterate all configurations
  660.         const string& config = (*n).m_Name;
  661.         CRef<CFileConfiguration> file_config(new CFileConfiguration());
  662.         file_config->SetAttlist().SetName(ConfigName(config));
  663.         CRef<CTool> custom_build(new CTool(""));
  664.         custom_build->SetAttlist().SetName("VCCustomBuildTool");
  665.         custom_build->SetAttlist().SetDescription(build_info.m_Description);
  666.         custom_build->SetAttlist().SetCommandLine(build_info.m_CommandLine);
  667.         custom_build->SetAttlist().SetOutputs(build_info.m_Outputs);
  668.         custom_build->SetAttlist().SetAdditionalDependencies
  669.                                       (build_info.m_AdditionalDependencies);
  670.         file_config->SetTool(*custom_build);
  671.         file->SetFileConfiguration().push_back(file_config);
  672.     }
  673.     CRef< CFilter_Base::C_FF::C_E > ce(new CFilter_Base::C_FF::C_E());
  674.     ce->SetFile(*file);
  675.     filter->SetFF().SetFF().push_back(ce);
  676. }
  677. bool SameRootDirs(const string& dir1, const string& dir2)
  678. {
  679.     if ( dir1.empty() )
  680.         return false;
  681.     if ( dir2.empty() )
  682.         return false;
  683.     return dir1[0] == dir2[0];
  684. }
  685. void CreateUtilityProject(const string&            name, 
  686.                           const list<SConfigInfo>& configs, 
  687.                           CVisualStudioProject*    project)
  688. {
  689.     
  690.     {{
  691.         //Attributes:
  692.         project->SetAttlist().SetProjectType  (MSVC_PROJECT_PROJECT_TYPE);
  693.         project->SetAttlist().SetVersion      (MSVC_PROJECT_VERSION);
  694.         project->SetAttlist().SetName         (name);
  695.         project->SetAttlist().SetRootNamespace
  696.             (MSVC_MASTERPROJECT_ROOT_NAMESPACE);
  697.         project->SetAttlist().SetKeyword      (MSVC_MASTERPROJECT_KEYWORD);
  698.     }}
  699.     
  700.     {{
  701.         //Platforms
  702.          CRef<CPlatform> platform(new CPlatform(""));
  703.          platform->SetAttlist().SetName(MSVC_PROJECT_PLATFORM);
  704.          project->SetPlatforms().SetPlatform().push_back(platform);
  705.     }}
  706.     ITERATE(list<SConfigInfo>, p , configs) {
  707.         // Iterate all configurations
  708.         const string& config = (*p).m_Name;
  709.         
  710.         CRef<CConfiguration> conf(new CConfiguration());
  711. #define SET_ATTRIBUTE( node, X, val ) node->SetAttlist().Set##X(val)        
  712.         {{
  713.             //Configuration
  714.             SET_ATTRIBUTE(conf, Name,               ConfigName(config));
  715.             SET_ATTRIBUTE(conf, 
  716.                           OutputDirectory,
  717.                           "$(SolutionDir)$(ConfigurationName)");
  718.             
  719.             SET_ATTRIBUTE(conf, 
  720.                           IntermediateDirectory,  
  721.                           "$(ConfigurationName)");
  722.             
  723.             SET_ATTRIBUTE(conf, ConfigurationType,  "10");
  724.             
  725.             SET_ATTRIBUTE(conf, CharacterSet,       "2");
  726.             
  727.             SET_ATTRIBUTE(conf, ManagedExtensions,  "TRUE");
  728.         }}
  729.         {{
  730.             //VCCustomBuildTool
  731.             CRef<CTool> tool(new CTool(""));
  732.             SET_ATTRIBUTE(tool, Name, "VCCustomBuildTool" );
  733.             conf->SetTool().push_back(tool);
  734.         }}
  735.         {{
  736.             //VCMIDLTool
  737.             CRef<CTool> tool(new CTool(""));
  738.             SET_ATTRIBUTE(tool, Name, "VCMIDLTool" );
  739.             conf->SetTool().push_back(tool);
  740.         }}
  741.         {{
  742.             //VCPostBuildEventTool
  743.             CRef<CTool> tool(new CTool(""));
  744.             SET_ATTRIBUTE(tool, Name, "VCPostBuildEventTool" );
  745.             conf->SetTool().push_back(tool);
  746.         }}
  747.         {{
  748.             //VCPreBuildEventTool
  749.             CRef<CTool> tool(new CTool(""));
  750.             SET_ATTRIBUTE(tool, Name, "VCPreBuildEventTool" );
  751.             conf->SetTool().push_back(tool);
  752.         }}
  753.         project->SetConfigurations().SetConfiguration().push_back(conf);
  754.     }
  755.     {{
  756.         //References
  757.         project->SetReferences("");
  758.     }}
  759.  
  760.     {{
  761.         //Globals
  762.         project->SetGlobals("");
  763.     }}
  764. }
  765. string CreateProjectName(const CProjKey& project_id)
  766. {
  767.     switch (project_id.Type()) {
  768.     case CProjKey::eApp:
  769.         return project_id.Id() + ".exe";
  770.     case CProjKey::eLib:
  771.         return project_id.Id() + ".lib";
  772.     case CProjKey::eDll:
  773.         return project_id.Id() + ".dll";
  774.     case CProjKey::eMsvc:
  775.         return project_id.Id() + ".vcproj";
  776.     default:
  777.         NCBI_THROW(CProjBulderAppException, eProjectType, project_id.Id());
  778.         return "";
  779.     }
  780. }
  781. //-----------------------------------------------------------------------------
  782. CBuildType::CBuildType(bool dll_flag)
  783.     :m_Type(dll_flag? eDll: eStatic)
  784. {
  785.     
  786. }
  787. CBuildType::EBuildType CBuildType::GetType(void) const
  788. {
  789.     return m_Type;
  790. }
  791.     
  792. string CBuildType::GetTypeStr(void) const
  793. {
  794.     switch (m_Type) {
  795.     case eStatic:
  796.         return "static";
  797.     case eDll:
  798.         return "dll";
  799.     }
  800.     NCBI_THROW(CProjBulderAppException, 
  801.                eProjectType, 
  802.                NStr::IntToString(m_Type));
  803.     return "";
  804. }
  805. //-----------------------------------------------------------------------------
  806. CDllSrcFilesDistr::CDllSrcFilesDistr(void)
  807. {
  808. }
  809. void CDllSrcFilesDistr::RegisterSource(const string&   src_file_path, 
  810.                                        const CProjKey& dll_project_id,
  811.                                        const CProjKey& lib_project_id)
  812. {
  813.     m_SourcesMap[ TDllSrcKey(src_file_path,dll_project_id) ] = lib_project_id;
  814. }
  815. void CDllSrcFilesDistr::RegisterHeader(const string&   hdr_file_path, 
  816.                                        const CProjKey& dll_project_id,
  817.                                        const CProjKey& lib_project_id)
  818. {
  819.     m_HeadersMap[ TDllSrcKey(hdr_file_path,dll_project_id) ] = lib_project_id;
  820. }
  821. void CDllSrcFilesDistr::RegisterInline(const string&   inl_file_path, 
  822.                                        const CProjKey& dll_project_id,
  823.                                        const CProjKey& lib_project_id)
  824. {
  825.     m_InlinesMap[ TDllSrcKey(inl_file_path,dll_project_id) ] = lib_project_id;
  826. }
  827. CProjKey CDllSrcFilesDistr::GetSourceLib(const string&   src_file_path, 
  828.                                          const CProjKey& dll_project_id) const
  829. {
  830.     TDllSrcKey key(src_file_path, dll_project_id);
  831.     TDistrMap::const_iterator p = m_SourcesMap.find(key);
  832.     if (p != m_SourcesMap.end()) {
  833.         const CProjKey& lib_id = p->second;
  834.         return lib_id;
  835.     }
  836.     return CProjKey();
  837. }
  838. CProjKey CDllSrcFilesDistr::GetHeaderLib(const string&   hdr_file_path, 
  839.                                          const CProjKey& dll_project_id) const
  840. {
  841.     TDllSrcKey key(hdr_file_path, dll_project_id);
  842.     TDistrMap::const_iterator p = m_HeadersMap.find(key);
  843.     if (p != m_HeadersMap.end()) {
  844.         const CProjKey& lib_id = p->second;
  845.         return lib_id;
  846.     }
  847.     return CProjKey();
  848. }
  849. CProjKey CDllSrcFilesDistr::GetInlineLib(const string&   inl_file_path, 
  850.                                          const CProjKey& dll_project_id) const
  851. {
  852.     TDllSrcKey key(inl_file_path, dll_project_id);
  853.     TDistrMap::const_iterator p = m_InlinesMap.find(key);
  854.     if (p != m_InlinesMap.end()) {
  855.         const CProjKey& lib_id = p->second;
  856.         return lib_id;
  857.     }
  858.     return CProjKey();
  859. }
  860. END_NCBI_SCOPE
  861. /*
  862.  * ===========================================================================
  863.  * $Log: msvc_prj_utils.cpp,v $
  864.  * Revision 1000.3  2004/06/16 17:02:32  gouriano
  865.  * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.31
  866.  *
  867.  * Revision 1.31  2004/06/15 19:01:08  gorelenk
  868.  * Changed CGuidGenerator::Generate12Chars to fix compilation errors on
  869.  * GCC 2.95.
  870.  *
  871.  * Revision 1.30  2004/06/14 20:59:23  gorelenk
  872.  * Added *correct* conversion from streampos to size_t .
  873.  *
  874.  * Revision 1.29  2004/06/14 20:41:20  gorelenk
  875.  * Changed PromoteIfDifferent : added conversion state to avoid compilation
  876.  * errors on GCC 3.3.3 .
  877.  *
  878.  * Revision 1.28  2004/06/14 19:19:08  gorelenk
  879.  * Changed definition of enum in CBuildType .
  880.  *
  881.  * Revision 1.27  2004/06/14 18:02:29  gorelenk
  882.  * Changed size_t to streampos in PromoteIfDifferent .
  883.  *
  884.  * Revision 1.26  2004/06/08 16:32:25  gorelenk
  885.  * Added static functions s_IsPrivateHeader and s_IsImplHeader.
  886.  * Changed imlementation of SFiltersItem ( to take into account
  887.  * new struct members ). Changed implementation of classes
  888.  * CBasicProjectsFilesInserter and CDllProjectFilesInserter.
  889.  *
  890.  * Revision 1.25  2004/05/26 17:59:07  gorelenk
  891.  * Old inserter -> CSrcToFilterInserterWithPch.
  892.  * Implemented CBasicProjectsFilesInserter and CDllProjectFilesInserter .
  893.  *
  894.  * Revision 1.24  2004/05/21 21:41:41  gorelenk
  895.  * Added PCH ncbi_pch.hpp
  896.  *
  897.  * Revision 1.23  2004/05/17 16:14:17  gorelenk
  898.  * Implemented class CDllSrcFilesDistr .
  899.  *
  900.  * Revision 1.22  2004/05/17 14:40:30  gorelenk
  901.  * Changed implementation of CSourceFileToProjectInserter::operator():
  902.  * get rid of hard-coded define for PCH usage.
  903.  *
  904.  * Revision 1.21  2004/05/13 16:15:24  gorelenk
  905.  * Changed CSourceFileToProjectInserter::operator() .
  906.  *
  907.  * Revision 1.20  2004/05/10 19:53:43  gorelenk
  908.  * Changed CreateProjectName .
  909.  *
  910.  * Revision 1.19  2004/05/10 14:29:03  gorelenk
  911.  * Implemented CSourceFileToProjectInserter .
  912.  *
  913.  * Revision 1.18  2004/04/22 18:15:38  gorelenk
  914.  * Changed implementation of SourceFileExt .
  915.  *
  916.  * Revision 1.17  2004/03/10 16:42:44  gorelenk
  917.  * Changed implementation of class CMsvc7RegSettings.
  918.  *
  919.  * Revision 1.16  2004/03/02 23:32:54  gorelenk
  920.  * Added implemetation of class CBuildType member-functions.
  921.  *
  922.  * Revision 1.15  2004/02/20 22:53:26  gorelenk
  923.  * Added analysis of ASN projects depends.
  924.  *
  925.  * Revision 1.14  2004/02/13 20:39:51  gorelenk
  926.  * Minor cosmetic changes.
  927.  *
  928.  * Revision 1.13  2004/02/12 23:15:29  gorelenk
  929.  * Implemented utility projects creation and configure re-build of the app.
  930.  *
  931.  * Revision 1.12  2004/02/12 16:27:57  gorelenk
  932.  * Changed generation of command line for datatool.
  933.  *
  934.  * Revision 1.11  2004/02/10 18:09:12  gorelenk
  935.  * Added definitions of functions SaveIfNewer and PromoteIfDifferent
  936.  * - support for file overwriting only if it was changed.
  937.  *
  938.  * Revision 1.10  2004/02/06 23:14:59  gorelenk
  939.  * Implemented support of ASN projects, semi-auto configure,
  940.  * CPPFLAGS support. Second working version.
  941.  *
  942.  * Revision 1.9  2004/02/05 16:29:49  gorelenk
  943.  * GetComponents was moved to class CMsvcSite.
  944.  *
  945.  * Revision 1.8  2004/02/04 23:35:17  gorelenk
  946.  * Added definition of functions GetComponents and SameRootDirs.
  947.  *
  948.  * Revision 1.7  2004/02/03 17:19:04  gorelenk
  949.  * Changed implementation of class CMsvc7RegSettings.
  950.  * Added implementation of function GetComponents.
  951.  *
  952.  * Revision 1.6  2004/01/30 20:46:55  gorelenk
  953.  * Added support of ASN projects.
  954.  *
  955.  * Revision 1.5  2004/01/28 17:55:49  gorelenk
  956.  * += For msvc makefile support of :
  957.  *                 Requires tag, ExcludeProject tag,
  958.  *                 AddToProject section (SourceFiles and IncludeDirs),
  959.  *                 CustomBuild section.
  960.  * += For support of user local site.
  961.  *
  962.  * Revision 1.4  2004/01/26 19:27:28  gorelenk
  963.  * += MSVC meta makefile support
  964.  * += MSVC project makefile support
  965.  *
  966.  * Revision 1.3  2004/01/22 17:57:54  gorelenk
  967.  * first version
  968.  *
  969.  * ===========================================================================
  970.  */