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

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: proj_tree_builder.cpp,v $
  4.  * PRODUCTION Revision 1000.3  2004/06/16 17:02:39  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.13
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /* $Id: proj_tree_builder.cpp,v 1000.3 2004/06/16 17:02:39 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/proj_tree_builder.hpp>
  39. #include <app/project_tree_builder/proj_builder_app.hpp>
  40. #include <app/project_tree_builder/proj_src_resolver.hpp>
  41. #include <app/project_tree_builder/msvc_prj_defines.hpp>
  42. #include <app/project_tree_builder/proj_projects.hpp>
  43. BEGIN_NCBI_SCOPE
  44. struct PLibExclude
  45. {
  46.     PLibExclude(const list<string>& excluded_lib_ids)
  47.     {
  48.         copy(excluded_lib_ids.begin(), excluded_lib_ids.end(), 
  49.              inserter(m_ExcludedLib, m_ExcludedLib.end()) );
  50.     }
  51.     bool operator() (const string& lib_id) const
  52.     {
  53.         return m_ExcludedLib.find(lib_id) != m_ExcludedLib.end();
  54.     }
  55. private:
  56.     set<string> m_ExcludedLib;
  57. };
  58. //-----------------------------------------------------------------------------
  59. CProjItem::TProjType SMakeProjectT::GetProjType(const string& base_dir,
  60.                                                 const string& projname)
  61. {
  62.     string fname = "Makefile." + projname;
  63.     
  64.     if ( CDirEntry(CDirEntry::ConcatPath
  65.                (base_dir, fname + ".lib")).Exists() )
  66.         return CProjKey::eLib;
  67.     else if (CDirEntry(CDirEntry::ConcatPath
  68.                (base_dir, fname + ".app")).Exists() )
  69.         return CProjKey::eApp;
  70.     else if (CDirEntry(CDirEntry::ConcatPath
  71.                (base_dir, fname + ".msvcproj")).Exists() )
  72.         return CProjKey::eMsvc;
  73.     LOG_POST(Error << "No .lib or .app projects for : " + projname +
  74.                       " in directory: " + base_dir);
  75.     return CProjKey::eNoProj;
  76. }
  77. bool SMakeProjectT::IsMakeInFile(const string& name)
  78. {
  79.     return name == "Makefile.in";
  80. }
  81. bool SMakeProjectT::IsMakeLibFile(const string& name)
  82. {
  83.     return NStr::StartsWith(name, "Makefile")  &&  
  84.        NStr::EndsWith(name, ".lib");
  85. }
  86. bool SMakeProjectT::IsMakeAppFile(const string& name)
  87. {
  88.     return NStr::StartsWith(name, "Makefile")  &&  
  89.        NStr::EndsWith(name, ".app");
  90. }
  91. bool SMakeProjectT::IsUserProjFile(const string& name)
  92. {
  93.     return NStr::StartsWith(name, "Makefile")  &&  
  94.        NStr::EndsWith(name, ".msvcproj");
  95. }
  96. void SMakeProjectT::DoResolveDefs(CSymResolver& resolver, 
  97.                                   TFiles& files,
  98.                                   const set<string>& keys)
  99. {
  100.     NON_CONST_ITERATE(CProjectTreeBuilder::TFiles, p, files) {
  101.     NON_CONST_ITERATE(CSimpleMakeFileContents::TContents, 
  102.                           n, 
  103.                           p->second.m_Contents) {
  104.             
  105.             const string& key    = n->first;
  106.             list<string>& values = n->second;
  107.     if (keys.find(key) != keys.end()) {
  108.                 list<string> new_vals;
  109.                 bool modified = false;
  110.                 NON_CONST_ITERATE(list<string>, k, values) {
  111.                     //iterate all values and try to resolve 
  112.                     const string& val = *k;
  113.                     if( !CSymResolver::IsDefine(val) ) {
  114.                         new_vals.push_back(val);
  115.                     } else {
  116.                         list<string> resolved_def;
  117.                         string val_define = FilterDefine(val);
  118.                     resolver.Resolve(val_define, &resolved_def);
  119.                     if ( resolved_def.empty() )
  120.                     new_vals.push_back(val); //not resolved - keep old val
  121.                         else {
  122.                             //was resolved
  123.                             ITERATE(list<string>, l, resolved_def) {
  124.                                 const string& define = *l;
  125.                                 if ( IsConfigurableDefine(define) ) {
  126.                                     string resolved_def_str = 
  127.                                         GetApp().GetSite().ResolveDefine
  128.                                                      (StripConfigurableDefine
  129.                                                                      (define));
  130.                                     if ( !resolved_def_str.empty() ) {
  131.                                         list<string> resolved_defs;
  132.                                         NStr::Split(resolved_def_str, 
  133.                                                     LIST_SEPARATOR, 
  134.                                                     resolved_defs);
  135.                                         copy(resolved_defs.begin(),
  136.                                              resolved_defs.end(),
  137.                                              back_inserter(new_vals));
  138.                                     } else {
  139.                                         new_vals.push_back(define);
  140.                                     }
  141.                                 } else {
  142.                                     new_vals.push_back(define);
  143.                                 }
  144.                             }
  145.                     modified = true;
  146.                         }
  147.                     }
  148.                 }
  149.                 if (modified)
  150.                     values = new_vals; // by ref!
  151.     }
  152.         }
  153.     }
  154. }
  155. string SMakeProjectT::GetOneIncludeDir(const string& flag, const string& token)
  156. {
  157.     size_t token_pos = flag.find(token);
  158.     if (token_pos != NPOS && 
  159.         token_pos + token.length() < flag.length()) {
  160.         return flag.substr(token_pos + token.length()); 
  161.     }
  162.     return "";
  163. }
  164. void SMakeProjectT::CreateIncludeDirs(const list<string>& cpp_flags,
  165.                                       const string&       source_base_dir,
  166.                                       list<string>*       include_dirs)
  167. {
  168.     include_dirs->clear();
  169.     ITERATE(list<string>, p, cpp_flags) {
  170.         const string& flag = *p;
  171.         const string token("-I$(includedir)");
  172.         // process -I$(includedir)
  173.         string token_val;
  174.         token_val = SMakeProjectT::GetOneIncludeDir(flag, "-I$(includedir)");
  175.         if ( !token_val.empty() ) {
  176.             string dir = 
  177.                 CDirEntry::ConcatPath(GetApp().GetProjectTreeInfo().m_Include,
  178.                                       token_val);
  179.             dir = CDirEntry::NormalizePath(dir);
  180.             dir = CDirEntry::AddTrailingPathSeparator(dir);
  181.             include_dirs->push_back(dir);
  182.         }
  183.         // process -I$(srcdir)
  184.         token_val = SMakeProjectT::GetOneIncludeDir(flag, "-I$(srcdir)");
  185.         if ( !token_val.empty() )  {
  186.             string dir = 
  187.                 CDirEntry::ConcatPath(source_base_dir,
  188.                                       token_val);
  189.             dir = CDirEntry::NormalizePath(dir);
  190.             dir = CDirEntry::AddTrailingPathSeparator(dir);
  191.             include_dirs->push_back(dir);
  192.         }
  193.         
  194.         // process defines like NCBI_C_INCLUDE
  195.         if(CSymResolver::IsDefine(flag)) {
  196.             string dir = GetApp().GetSite().ResolveDefine
  197.                                              (CSymResolver::StripDefine(flag));
  198.             if ( !dir.empty() && CDirEntry(dir).IsDir() ) {
  199.                 include_dirs->push_back(dir);    
  200.             }
  201.         }
  202.         // process additional include dirs for LibChoices
  203.         if(CSymResolver::IsDefine(flag)) {
  204.             string sflag = CSymResolver::StripDefine(flag);
  205.             list<string> libchoices_abs_includes ;
  206.             GetApp().GetSite().GetLibChoiceIncludes(sflag, 
  207.                                                     &libchoices_abs_includes);
  208.             ITERATE(list<string>, n, libchoices_abs_includes) {
  209.                 const string& dir = *n;
  210.                 if ( !dir.empty() && CDirEntry(dir).IsDir() ) {
  211.                     include_dirs->push_back(dir);    
  212.                 }
  213.             }
  214.         }
  215.     }
  216.     include_dirs->sort();
  217.     include_dirs->unique();
  218. }
  219. void SMakeProjectT::CreateDefines(const list<string>& cpp_flags,
  220.                                   list<string>*       defines)
  221. {
  222.     defines->clear();
  223.     ITERATE(list<string>, p, cpp_flags) {
  224.         const string& flag = *p;
  225.         if ( NStr::StartsWith(flag, "-D") ) {
  226.             defines->push_back(flag.substr(2));
  227.         }
  228.     }
  229. }
  230. void SMakeProjectT::Create3PartyLibs(const list<string>& libs_flags, 
  231.                                      list<string>*       libs_list)
  232. {
  233.     libs_list->clear();
  234.     ITERATE(list<string>, p, libs_flags) {
  235.         const string& flag = *p;
  236.         if ( IsConfigurableDefine(flag) ) {
  237.             libs_list->push_back(StripConfigurableDefine(flag));    
  238.         }
  239.     }
  240. }
  241. void SMakeProjectT::AnalyzeMakeIn
  242.     (const CSimpleMakeFileContents& makein_contents,
  243.      TMakeInInfoList*               info)
  244. {
  245.     info->clear();
  246.     CSimpleMakeFileContents::TContents::const_iterator p = 
  247.         makein_contents.m_Contents.find("LIB_PROJ");
  248.     if (p != makein_contents.m_Contents.end()) {
  249.         info->push_back(SMakeInInfo(SMakeInInfo::eLib, p->second)); 
  250.     }
  251.     p = makein_contents.m_Contents.find("APP_PROJ");
  252.     if (p != makein_contents.m_Contents.end()) {
  253.         info->push_back(SMakeInInfo(SMakeInInfo::eApp, p->second)); 
  254.     }
  255.     p = makein_contents.m_Contents.find("ASN_PROJ");
  256.     if (p != makein_contents.m_Contents.end()) {
  257.         info->push_back(SMakeInInfo(SMakeInInfo::eAsn, p->second)); 
  258.     }
  259.     p = makein_contents.m_Contents.find("MSVC_PROJ");
  260.     if (p != makein_contents.m_Contents.end()) {
  261.         info->push_back(SMakeInInfo(SMakeInInfo::eMsvc, p->second)); 
  262.     }
  263.     //TODO - DLL_PROJ
  264. }
  265. string SMakeProjectT::CreateMakeAppLibFileName
  266.                 (const string&            base_dir,
  267.                  const string&            projname)
  268. {
  269.     CProjItem::TProjType proj_type = 
  270.             SMakeProjectT::GetProjType(base_dir, projname);
  271.     string fname = "Makefile." + projname;
  272.     
  273.     if (proj_type==CProjKey::eLib)
  274.         return fname + ".lib";
  275.     if (proj_type==CProjKey::eApp)
  276.         return fname + ".app";
  277.     if (proj_type==CProjKey::eMsvc)
  278.         return fname + ".msvcproj";
  279.     return "";
  280. }
  281. void SMakeProjectT::CreateFullPathes(const string&      dir, 
  282.                                      const list<string> files,
  283.                                      list<string>*      full_pathes)
  284. {
  285.     ITERATE(list<string>, p, files) {
  286.         string full_path = CDirEntry::ConcatPath(dir, *p);
  287.         full_pathes->push_back(full_path);
  288.     }
  289. }
  290. void SMakeProjectT::ConvertLibDepends(const list<string>& depends_libs, 
  291.                                       list<CProjKey>*     depends_ids)
  292. {
  293.     depends_ids->clear();
  294.     ITERATE(list<string>, p, depends_libs)
  295.     {
  296.         const string& id = *p;
  297.         depends_ids->push_back(CProjKey(CProjKey::eLib, id));
  298.     }
  299. }
  300. bool SMakeProjectT::IsConfigurableDefine(const string& define)
  301. {
  302.     return  NStr::StartsWith(define, "@")  &&
  303.             NStr::EndsWith  (define, "@");
  304. }
  305. string SMakeProjectT::StripConfigurableDefine(const string& define)
  306. {
  307.     return IsConfigurableDefine(define) ? 
  308.                 define.substr(1, define.length() - 2): "";
  309. }
  310. //-----------------------------------------------------------------------------
  311. void SAppProjectT::CreateNcbiCToolkitLibs(const CSimpleMakeFileContents& makefile,
  312.                                           list<string>* libs_list)
  313. {
  314.     CSimpleMakeFileContents::TContents::const_iterator k = 
  315.     makefile.m_Contents.find("NCBI_C_LIBS");
  316.     if (k == makefile.m_Contents.end()) {
  317.         return;
  318.     }
  319.     const list<string>& values = k->second;
  320.     ITERATE(list<string>, p, values) {
  321.         const string& val = *p;
  322.         if ( NStr::StartsWith(val, "-l") ) {
  323.             string lib_id = val.substr(2);
  324.             libs_list->push_back(lib_id);
  325.         } else {
  326.             libs_list->push_back(val);
  327.         }
  328.     }
  329.     libs_list->sort();
  330.     libs_list->unique();
  331. }
  332. CProjKey SAppProjectT::DoCreate(const string& source_base_dir,
  333.                                 const string& proj_name,
  334.                                 const string& applib_mfilepath,
  335.                                 const TFiles& makeapp , 
  336.                                 CProjectItemsTree* tree)
  337. {
  338.     CProjectItemsTree::TFiles::const_iterator m = makeapp.find(applib_mfilepath);
  339.     if (m == makeapp.end()) {
  340.         LOG_POST(Info << "No Makefile.*.app for Makefile.in :"
  341.                   + applib_mfilepath);
  342.         return CProjKey();
  343.     }
  344.     
  345.     const CSimpleMakeFileContents& makefile = m->second;
  346.     CSimpleMakeFileContents::TContents::const_iterator k = 
  347.         makefile.m_Contents.find("SRC");
  348.     if (k == makefile.m_Contents.end()) {
  349.         LOG_POST(Warning << "No SRC key in Makefile.*.app :"
  350.                   + applib_mfilepath);
  351.         return CProjKey();
  352.     }
  353.     //sources - relative  pathes from source_base_dir
  354.     //We'll create relative pathes from them
  355.     CProjSRCResolver src_resolver(applib_mfilepath, 
  356.                                   source_base_dir, k->second);
  357.     list<string> sources;
  358.     src_resolver.ResolveTo(&sources);
  359.     //depends
  360.     list<string> depends;
  361.     k = makefile.m_Contents.find("LIB");
  362.     if (k != makefile.m_Contents.end())
  363.         depends = k->second;
  364.     //Adjust depends by information from msvc Makefile
  365.     CMsvcProjectMakefile project_makefile
  366.                        ((CDirEntry::ConcatPath
  367.                           (source_base_dir, 
  368.                            CreateMsvcProjectMakefileName(proj_name, 
  369.                                                          CProjKey::eApp))));
  370.     list<string> added_depends;
  371.     project_makefile.GetAdditionalLIB(SConfigInfo(), &added_depends);
  372.     list<string> excluded_depends;
  373.     project_makefile.GetExcludedLIB(SConfigInfo(), &excluded_depends);
  374.     list<string> adj_depends(depends);
  375.     copy(added_depends.begin(), 
  376.          added_depends.end(), back_inserter(adj_depends));
  377.     adj_depends.sort();
  378.     adj_depends.unique();
  379.     PLibExclude pred(excluded_depends);
  380.     EraseIf(adj_depends, pred);
  381.     list<CProjKey> depends_ids;
  382.     SMakeProjectT::ConvertLibDepends(adj_depends, &depends_ids);
  383.     ///////////////////////////////////
  384.     //requires
  385.     list<string> requires;
  386.     k = makefile.m_Contents.find("REQUIRES");
  387.     if (k != makefile.m_Contents.end())
  388.         requires = k->second;
  389.     //project name
  390.     k = makefile.m_Contents.find("APP");
  391.     if (k == makefile.m_Contents.end()  ||  
  392.                                            k->second.empty()) {
  393.         LOG_POST(Error << "No APP key or empty in Makefile.*.app :"
  394.                   + applib_mfilepath);
  395.         return CProjKey();
  396.     }
  397.     string proj_id = k->second.front();
  398.     //LIBS
  399.     list<string> libs_3_party;
  400.     k = makefile.m_Contents.find("LIBS");
  401.     if (k != makefile.m_Contents.end()) {
  402.         const list<string> libs_flags = k->second;
  403.         SMakeProjectT::Create3PartyLibs(libs_flags, &libs_3_party);
  404.     }
  405.     
  406.     //CPPFLAGS
  407.     list<string> include_dirs;
  408.     list<string> defines;
  409.     k = makefile.m_Contents.find("CPPFLAGS");
  410.     if (k != makefile.m_Contents.end()) {
  411.         const list<string> cpp_flags = k->second;
  412.         SMakeProjectT::CreateIncludeDirs(cpp_flags, 
  413.                                          source_base_dir, &include_dirs);
  414.         SMakeProjectT::CreateDefines(cpp_flags, &defines);
  415.     }
  416.     //NCBI_C_LIBS - Special case for NCBI C Toolkit
  417.     k = makefile.m_Contents.find("NCBI_C_LIBS");
  418.     list<string> ncbi_clibs;
  419.     if (k != makefile.m_Contents.end()) {
  420.         libs_3_party.push_back("NCBI_C_LIBS");
  421.         CreateNcbiCToolkitLibs(makefile, &ncbi_clibs);
  422.     }
  423.     
  424.     CProjItem project(CProjKey::eApp, 
  425.                       proj_name, 
  426.                       proj_id,
  427.                       source_base_dir,
  428.                       sources, 
  429.                       depends_ids,
  430.                       requires,
  431.                       libs_3_party,
  432.                       include_dirs,
  433.                       defines);
  434.     //
  435.     project.m_NcbiCLibs = ncbi_clibs;
  436.     //DATATOOL_SRC
  437.     k = makefile.m_Contents.find("DATATOOL_SRC");
  438.     if ( k != makefile.m_Contents.end() ) {
  439.         //Add depends from datatoool for ASN projects
  440.         project.m_Depends.push_back(CProjKey(CProjKey::eApp, GetApp().GetDatatoolId()));
  441.         const list<string> datatool_src_list = k->second;
  442.         ITERATE(list<string>, i, datatool_src_list) {
  443.             const string& src = *i;
  444.             //Will process .asn or .dtd files
  445.             string source_file_path = 
  446.                 CDirEntry::ConcatPath(source_base_dir, src);
  447.             source_file_path = CDirEntry::NormalizePath(source_file_path);
  448.             if ( CDirEntry(source_file_path + ".asn").Exists() )
  449.                 source_file_path += ".asn";
  450.             else if ( CDirEntry(source_file_path + ".dtd").Exists() )
  451.                 source_file_path += ".dtd";
  452.             CDataToolGeneratedSrc data_tool_src;
  453.             CDataToolGeneratedSrc::LoadFrom(source_file_path, &data_tool_src);
  454.             if ( !data_tool_src.IsEmpty() )
  455.                 project.m_DatatoolSources.push_back(data_tool_src);
  456.         }
  457.     }
  458.     CProjKey proj_key(CProjKey::eApp, proj_id);
  459.     tree->m_Projects[proj_key] = project;
  460.     return proj_key;
  461. }
  462. //-----------------------------------------------------------------------------
  463. CProjKey SLibProjectT::DoCreate(const string& source_base_dir,
  464.                                 const string& proj_name,
  465.                                 const string& applib_mfilepath,
  466.                                 const TFiles& makelib , 
  467.                                 CProjectItemsTree* tree)
  468. {
  469.     TFiles::const_iterator m = makelib.find(applib_mfilepath);
  470.     if (m == makelib.end()) {
  471.         LOG_POST(Info << "No Makefile.*.lib for Makefile.in :"
  472.                   + applib_mfilepath);
  473.         return CProjKey();
  474.     }
  475.     CSimpleMakeFileContents::TContents::const_iterator k = 
  476.         m->second.m_Contents.find("SRC");
  477.     if (k == m->second.m_Contents.end()) {
  478.         LOG_POST(Warning << "No SRC key in Makefile.*.lib :"
  479.                   + applib_mfilepath);
  480.         return CProjKey();
  481.     }
  482.     // sources - relative pathes from source_base_dir
  483.     // We'll create relative pathes from them)
  484.     CProjSRCResolver src_resolver(applib_mfilepath, 
  485.                                   source_base_dir, k->second);
  486.     list<string> sources;
  487.     src_resolver.ResolveTo(&sources);
  488.     // depends - TODO
  489.     list<CProjKey> depends_ids;
  490.     k = m->second.m_Contents.find("ASN_DEP");
  491.     if (k != m->second.m_Contents.end()) {
  492.         const list<string> depends = k->second;
  493.         SMakeProjectT::ConvertLibDepends(depends, &depends_ids);
  494.     }
  495.     //requires
  496.     list<string> requires;
  497.     k = m->second.m_Contents.find("REQUIRES");
  498.     if (k != m->second.m_Contents.end())
  499.         requires = k->second;
  500.     //project name
  501.     k = m->second.m_Contents.find("LIB");
  502.     if (k == m->second.m_Contents.end()  ||  
  503.                                            k->second.empty()) {
  504.         LOG_POST(Error << "No LIB key or empty in Makefile.*.lib :"
  505.                   + applib_mfilepath);
  506.         return CProjKey();
  507.     }
  508.     string proj_id = k->second.front();
  509.     //LIBS
  510.     list<string> libs_3_party;
  511.     k = m->second.m_Contents.find("LIBS");
  512.     if (k != m->second.m_Contents.end()) {
  513.         const list<string> libs_flags = k->second;
  514.         SMakeProjectT::Create3PartyLibs(libs_flags, &libs_3_party);
  515.     }
  516.     //CPPFLAGS
  517.     list<string> include_dirs;
  518.     list<string> defines;
  519.     k = m->second.m_Contents.find("CPPFLAGS");
  520.     if (k != m->second.m_Contents.end()) {
  521.         const list<string> cpp_flags = k->second;
  522.         SMakeProjectT::CreateIncludeDirs(cpp_flags, 
  523.                                          source_base_dir, &include_dirs);
  524.         SMakeProjectT::CreateDefines(cpp_flags, &defines);
  525.     }
  526.     CProjKey proj_key(CProjKey::eLib, proj_id);
  527.     tree->m_Projects[proj_key] = CProjItem(CProjKey::eLib,
  528.                                            proj_name, 
  529.                                            proj_id,
  530.                                            source_base_dir,
  531.                                            sources, 
  532.                                            depends_ids,
  533.                                            requires,
  534.                                            libs_3_party,
  535.                                            include_dirs,
  536.                                            defines);
  537.     return proj_key;
  538. }
  539. //-----------------------------------------------------------------------------
  540. CProjKey SAsnProjectT::DoCreate(const string& source_base_dir,
  541.                                 const string& proj_name,
  542.                                 const string& applib_mfilepath,
  543.                                 const TFiles& makeapp, 
  544.                                 const TFiles& makelib, 
  545.                                 CProjectItemsTree* tree)
  546. {
  547.     TAsnType asn_type = GetAsnProjectType(applib_mfilepath, makeapp, makelib);
  548.     if (asn_type == eMultiple) {
  549.         return SAsnProjectMultipleT::DoCreate(source_base_dir,
  550.                                               proj_name,
  551.                                               applib_mfilepath,
  552.                                               makeapp, 
  553.                                               makelib, 
  554.                                               tree);
  555.     }
  556.     if(asn_type == eSingle) {
  557.         return SAsnProjectSingleT::DoCreate(source_base_dir,
  558.                                               proj_name,
  559.                                               applib_mfilepath,
  560.                                               makeapp, 
  561.                                               makelib, 
  562.                                               tree);
  563.     }
  564.     LOG_POST(Error << "Unsupported ASN project" + NStr::IntToString(asn_type));
  565.     return CProjKey();
  566. }
  567. SAsnProjectT::TAsnType SAsnProjectT::GetAsnProjectType(const string& applib_mfilepath,
  568.                                                        const TFiles& makeapp,
  569.                                                        const TFiles& makelib)
  570. {
  571.     TFiles::const_iterator p = makeapp.find(applib_mfilepath);
  572.     if ( p != makeapp.end() ) {
  573.         const CSimpleMakeFileContents& fc = p->second;
  574.         if (fc.m_Contents.find("ASN") != fc.m_Contents.end() )
  575.             return eMultiple;
  576.         else
  577.             return eSingle;
  578.     }
  579.     p = makelib.find(applib_mfilepath);
  580.     if ( p != makelib.end() ) {
  581.         const CSimpleMakeFileContents& fc = p->second;
  582.         if (fc.m_Contents.find("ASN") != fc.m_Contents.end() )
  583.             return eMultiple;
  584.         else
  585.             return eSingle;
  586.     }
  587.     LOG_POST(Error << "Can not define ASN project: " + applib_mfilepath);
  588.     return eNoAsn;
  589. }
  590. //-----------------------------------------------------------------------------
  591. CProjKey SAsnProjectSingleT::DoCreate(const string& source_base_dir,
  592.                                       const string& proj_name,
  593.                                       const string& applib_mfilepath,
  594.                                       const TFiles& makeapp, 
  595.                                       const TFiles& makelib, 
  596.                                       CProjectItemsTree* tree)
  597. {
  598.     CProjItem::TProjType proj_type = 
  599.         SMakeProjectT::GetProjType(source_base_dir, proj_name);
  600.     
  601.     CProjKey proj_id = 
  602.         proj_type == CProjKey::eLib? 
  603.             SLibProjectT::DoCreate(source_base_dir, 
  604.                                proj_name, applib_mfilepath, makelib, tree) : 
  605.             SAppProjectT::DoCreate(source_base_dir, 
  606.                                proj_name, applib_mfilepath, makeapp, tree);
  607.     if ( proj_id.Id().empty() )
  608.         return CProjKey();
  609.     
  610.     TProjects::iterator p = tree->m_Projects.find(proj_id);
  611.     if (p == tree->m_Projects.end()) {
  612.         LOG_POST(Error << "Can not find ASN project with id : " + proj_id.Id());
  613.         return CProjKey();
  614.     }
  615.     CProjItem& project = p->second;
  616.     //Add depends from datatoool for ASN projects
  617.     project.m_Depends.push_back(CProjKey(CProjKey::eApp,
  618.                                          GetApp().GetDatatoolId()));
  619.     //Will process .asn or .dtd files
  620.     string source_file_path = CDirEntry::ConcatPath(source_base_dir, proj_name);
  621.     if ( CDirEntry(source_file_path + ".asn").Exists() )
  622.         source_file_path += ".asn";
  623.     else if ( CDirEntry(source_file_path + ".dtd").Exists() )
  624.         source_file_path += ".dtd";
  625.     CDataToolGeneratedSrc data_tool_src;
  626.     CDataToolGeneratedSrc::LoadFrom(source_file_path, &data_tool_src);
  627.     if ( !data_tool_src.IsEmpty() )
  628.         project.m_DatatoolSources.push_back(data_tool_src);
  629.     return proj_id;
  630. }
  631. //-----------------------------------------------------------------------------
  632. CProjKey SAsnProjectMultipleT::DoCreate(const string& source_base_dir,
  633.                                         const string& proj_name,
  634.                                         const string& applib_mfilepath,
  635.                                         const TFiles& makeapp, 
  636.                                         const TFiles& makelib, 
  637.                                         CProjectItemsTree* tree)
  638. {
  639.     CProjItem::TProjType proj_type = 
  640.         SMakeProjectT::GetProjType(source_base_dir, proj_name);
  641.     
  642.     const TFiles& makefile = proj_type == CProjKey::eLib? makelib : makeapp;
  643.     TFiles::const_iterator m = makefile.find(applib_mfilepath);
  644.     if (m == makefile.end()) {
  645.         LOG_POST(Info << "No Makefile.*.lib/app  for Makefile.in :"
  646.                   + applib_mfilepath);
  647.         return CProjKey();
  648.     }
  649.     const CSimpleMakeFileContents& fc = m->second;
  650.     // ASN
  651.     CSimpleMakeFileContents::TContents::const_iterator k = 
  652.         fc.m_Contents.find("ASN");
  653.     if (k == fc.m_Contents.end()) {
  654.         LOG_POST(Error << "No ASN key in multiple ASN  project:"
  655.                   + applib_mfilepath);
  656.         return CProjKey();
  657.     }
  658.     const list<string> asn_names = k->second;
  659.     string parent_dir_abs = ParentDir(source_base_dir);
  660.     list<CDataToolGeneratedSrc> datatool_sources;
  661.     ITERATE(list<string>, p, asn_names) {
  662.         const string& asn = *p;
  663.         // one level up
  664.         string asn_dir_abs = CDirEntry::ConcatPath(parent_dir_abs, asn);
  665.         asn_dir_abs = CDirEntry::NormalizePath(asn_dir_abs);
  666.         asn_dir_abs = CDirEntry::AddTrailingPathSeparator(asn_dir_abs);
  667.     
  668.         string asn_path_abs = CDirEntry::ConcatPath(asn_dir_abs, asn);
  669.         if ( CDirEntry(asn_path_abs + ".asn").Exists() )
  670.             asn_path_abs += ".asn";
  671.         else if ( CDirEntry(asn_dir_abs + ".dtd").Exists() )
  672.             asn_path_abs += ".dtd";
  673.         CDataToolGeneratedSrc data_tool_src;
  674.         CDataToolGeneratedSrc::LoadFrom(asn_path_abs, &data_tool_src);
  675.         if ( !data_tool_src.IsEmpty() )
  676.             datatool_sources.push_back(data_tool_src);
  677.     }
  678.     // SRC
  679.     k = fc.m_Contents.find("SRC");
  680.     if (k == fc.m_Contents.end()) {
  681.         LOG_POST(Error << "No SRC key in multiple ASN  project:"
  682.                   + applib_mfilepath);
  683.         return CProjKey();
  684.     }
  685.     const list<string> src_list = k->second;
  686.     list<string> sources;
  687.     ITERATE(list<string>, p, src_list) {
  688.         const string& src = *p;
  689.         if ( !CSymResolver::IsDefine(src) )
  690.             sources.push_back(src);
  691.     }
  692.     CProjKey proj_id = 
  693.         proj_type == CProjKey::eLib? 
  694.         SLibProjectT::DoCreate(source_base_dir, 
  695.                                proj_name, applib_mfilepath, makelib, tree) :
  696.         SAppProjectT::DoCreate(source_base_dir, 
  697.                                proj_name, applib_mfilepath, makeapp, tree);
  698.     if ( proj_id.Id().empty() )
  699.         return CProjKey();
  700.     
  701.     TProjects::iterator p = tree->m_Projects.find(proj_id);
  702.     if (p == tree->m_Projects.end()) {
  703.         LOG_POST(Error << "Can not find ASN project with id : " +proj_id.Id());
  704.         return CProjKey();
  705.     }
  706.     CProjItem& project = p->second;
  707.     // Adjust created proj item
  708.     //SRC - 
  709.     project.m_Sources.clear();
  710.     ITERATE(list<string>, p, src_list) {
  711.         const string& src = *p;
  712.         if ( !CSymResolver::IsDefine(src) )
  713.             project.m_Sources.push_front(src);    
  714.     }
  715.     project.m_Sources.push_back(proj_name + "__");
  716.     project.m_Sources.push_back(proj_name + "___");
  717.     ITERATE(list<string>, p, asn_names) {
  718.         const string& asn = *p;
  719.         if (asn == proj_name)
  720.             continue;
  721.         string src(1, CDirEntry::GetPathSeparator());
  722.         src += "..";
  723.         src += CDirEntry::GetPathSeparator();
  724.         src += asn;
  725.         src += CDirEntry::GetPathSeparator();
  726.         src += asn;
  727.         project.m_Sources.push_back(src + "__");
  728.         project.m_Sources.push_back(src + "___");
  729.     }
  730.     project.m_DatatoolSources = datatool_sources;
  731.     //Add depends from datatoool for ASN projects
  732.     project.m_Depends.push_back(CProjKey(CProjKey::eApp, 
  733.                                          GetApp().GetDatatoolId()));
  734.     return proj_id;
  735. }
  736. //-----------------------------------------------------------------------------
  737. CProjKey SMsvcProjectT::DoCreate(const string&      source_base_dir,
  738.                                  const string&      proj_name,
  739.                                  const string&      applib_mfilepath,
  740.                                  const TFiles&      makemsvc, 
  741.                                  CProjectItemsTree* tree)
  742. {
  743.     TFiles::const_iterator m = makemsvc.find(applib_mfilepath);
  744.     if (m == makemsvc.end()) {
  745.         LOG_POST(Info << "No User makefile.*.* for Makefile.in :"
  746.                   + applib_mfilepath);
  747.         return CProjKey();
  748.     }
  749.     // VCPROJ - will map to src
  750.     CSimpleMakeFileContents::TContents::const_iterator k = 
  751.         m->second.m_Contents.find("VCPROJ");
  752.     if (k == m->second.m_Contents.end()) {
  753.         LOG_POST(Warning << "No VCPROJ key in User Makefile.*.* :"
  754.                   + applib_mfilepath);
  755.         return CProjKey();
  756.     }
  757.     list<string> sources = k->second;
  758.     // depends - 
  759.     list<CProjKey> depends_ids;
  760.     k = m->second.m_Contents.find("LIB_DEP");
  761.     if (k != m->second.m_Contents.end()) {
  762.         const list<string> deps = k->second;
  763.         ITERATE(list<string>, p, deps) {
  764.             depends_ids.push_back(CProjKey(CProjKey::eLib, *p));
  765.         }
  766.     }
  767.     k = m->second.m_Contents.find("APP_DEP");
  768.     if (k != m->second.m_Contents.end()) {
  769.         const list<string> deps = k->second;
  770.         ITERATE(list<string>, p, deps) {
  771.             depends_ids.push_back(CProjKey(CProjKey::eApp, *p));
  772.         }
  773.     }
  774.     k = m->second.m_Contents.find("DLL_DEP");
  775.     if (k != m->second.m_Contents.end()) {
  776.         const list<string> deps = k->second;
  777.         ITERATE(list<string>, p, deps) {
  778.             depends_ids.push_back(CProjKey(CProjKey::eDll, *p));
  779.         }
  780.     }
  781.     k = m->second.m_Contents.find("MSVC_DEP");
  782.     if (k != m->second.m_Contents.end()) {
  783.         const list<string> deps = k->second;
  784.         ITERATE(list<string>, p, deps) {
  785.             depends_ids.push_back(CProjKey(CProjKey::eMsvc, *p));
  786.         }
  787.     }
  788.     //requires
  789.     list<string> requires;
  790.     k = m->second.m_Contents.find("REQUIRES");
  791.     if (k != m->second.m_Contents.end())
  792.         requires = k->second;
  793.     //project id
  794.     k = m->second.m_Contents.find("MSVC_PROJ");
  795.     if (k == m->second.m_Contents.end()  ||  
  796.                                            k->second.empty()) {
  797.         LOG_POST(Error << "No LIB key or empty in Makefile.*.lib :"
  798.                   + applib_mfilepath);
  799.         return CProjKey();
  800.     }
  801.     string proj_id = k->second.front();
  802.     list<string> libs_3_party;
  803.     list<string> include_dirs;
  804.     list<string> defines;
  805.     CProjKey proj_key(CProjKey::eMsvc, proj_id);
  806.     tree->m_Projects[proj_key] = CProjItem(CProjKey::eMsvc,
  807.                                            proj_name, 
  808.                                            proj_id,
  809.                                            source_base_dir,
  810.                                            sources, 
  811.                                            depends_ids,
  812.                                            requires,
  813.                                            libs_3_party,
  814.                                            include_dirs,
  815.                                            defines);
  816.     return proj_key;
  817. }
  818. //-----------------------------------------------------------------------------
  819. void 
  820. CProjectTreeBuilder::BuildOneProjectTree(const IProjectFilter* filter,
  821.                                          const string&         root_src_path,
  822.                                          CProjectItemsTree*    tree)
  823. {
  824.     SMakeFiles subtree_makefiles;
  825.     ProcessDir(root_src_path, 
  826.                true,
  827.                filter,
  828.                &subtree_makefiles);
  829.     // Resolve macrodefines
  830.     list<string> metadata_files;
  831.     GetApp().GetMetaDataFiles(&metadata_files);
  832.     CSymResolver resolver;
  833.     ITERATE(list<string>, p, metadata_files) {
  834.     resolver += CSymResolver(CDirEntry::ConcatPath(root_src_path, *p));
  835. }
  836.     ResolveDefs(resolver, subtree_makefiles);
  837.     // Build projects tree
  838.     CProjectItemsTree::CreateFrom(root_src_path,
  839.                                   subtree_makefiles.m_In, 
  840.                                   subtree_makefiles.m_Lib, 
  841.                                   subtree_makefiles.m_App,
  842.                                   subtree_makefiles.m_User, tree);
  843. }
  844. void 
  845. CProjectTreeBuilder::BuildProjectTree(const IProjectFilter* filter,
  846.                                       const string&         root_src_path,
  847.                                       CProjectItemsTree*    tree)
  848. {
  849.     // Bulid subtree
  850.     CProjectItemsTree target_tree;
  851.     BuildOneProjectTree(filter, root_src_path, &target_tree);
  852.     // Analyze subtree depends
  853.     list<CProjKey> external_depends;
  854.     target_tree.GetExternalDepends(&external_depends);
  855.     // We have to add more projects to the target tree
  856.     if ( !external_depends.empty()  &&  !filter->PassAll() ) {
  857.         list<CProjKey> depends_to_resolve = external_depends;
  858.         while ( !depends_to_resolve.empty() ) {
  859.             bool modified = false;
  860.             ITERATE(list<CProjKey>, p, depends_to_resolve) {
  861.                 // id of project we have to resolve
  862.                 const CProjKey& prj_id = *p;
  863.                 CProjectItemsTree::TProjects::const_iterator n = 
  864.                                GetApp().GetWholeTree().m_Projects.find(prj_id);
  865.             
  866.                 if (n != GetApp().GetWholeTree().m_Projects.end()) {
  867.                     //insert this project to target_tree
  868.                     target_tree.m_Projects[prj_id] = n->second;
  869.                     modified = true;
  870.                 } else {
  871.                     LOG_POST (Error << "No project with id :" + prj_id.Id());
  872.                 }
  873.             }
  874.             if (!modified) {
  875.                 //we done - no more projects was added to target_tree
  876.                 AddDatatoolSourcesDepends(&target_tree);
  877.                 *tree = target_tree;
  878.                 return;
  879.             } else {
  880.                 //continue resolving dependences
  881.                 target_tree.GetExternalDepends(&depends_to_resolve);
  882.             }
  883.         }
  884.     }
  885.     AddDatatoolSourcesDepends(&target_tree);
  886.     *tree = target_tree;
  887. }
  888. void CProjectTreeBuilder::ProcessDir(const string&         dir_name, 
  889.                                      bool                  is_root,
  890.                                      const IProjectFilter* filter,
  891.                                      SMakeFiles*           makefiles)
  892. {
  893. #if 1
  894.     // Do not collect makefile from root directory
  895.     CDir dir(dir_name);
  896.     CDir::TEntries contents = dir.GetEntries("*");
  897.     ITERATE(CDir::TEntries, i, contents) {
  898.         string name  = (*i)->GetName();
  899.         if ( name == "."  ||  name == ".."  ||  
  900.              name == string(1,CDir::GetPathSeparator()) ) {
  901.             continue;
  902.         }
  903.         string path = (*i)->GetPath();
  904.         if ( (*i)->IsFile()  &&  
  905.              !is_root        &&  
  906.              filter->CheckProject(CDirEntry(path).GetDir()) ) {
  907.             if ( SMakeProjectT::IsMakeInFile(name) )
  908.             ProcessMakeInFile(path, makefiles);
  909.             else if ( SMakeProjectT::IsMakeLibFile(name) )
  910.             ProcessMakeLibFile(path, makefiles);
  911.             else if ( SMakeProjectT::IsMakeAppFile(name) )
  912.             ProcessMakeAppFile(path, makefiles);
  913.             else if ( SMakeProjectT::IsUserProjFile(name) )
  914.             ProcessUserProjFile(path, makefiles);
  915.         } 
  916.         else if ( (*i)->IsDir() ) {
  917.             ProcessDir(path, false, filter, makefiles);
  918.         }
  919.     }
  920. #endif
  921. #if 0
  922.     // Node - Makefile.in should present
  923.     string node_path = 
  924.         CDirEntry::ConcatPath(dir_name, 
  925.                               GetApp().GetProjectTreeInfo().m_TreeNode);
  926.     if ( !CDirEntry(node_path).Exists() )
  927.         return;
  928.     
  929.     bool process_projects = !is_root && filter->CheckProject(dir_name);
  930.     
  931.     // Process Makefile.*.lib
  932.     if ( process_projects ) {
  933.         CDir dir(dir_name);
  934.         CDir::TEntries contents = dir.GetEntries("Makefile.*.lib");
  935.         ITERATE(CDir::TEntries, p, contents) {
  936.             const AutoPtr<CDirEntry>& dir_entry = *p;
  937.             if ( SMakeProjectT::IsMakeLibFile(dir_entry->GetName()) )
  938.             ProcessMakeLibFile(dir_entry->GetPath(), makefiles);
  939.         }
  940.     }
  941.     // Process Makefile.*.app
  942.     if ( process_projects ) {
  943.         CDir dir(dir_name);
  944.         CDir::TEntries contents = dir.GetEntries("Makefile.*.app");
  945.         ITERATE(CDir::TEntries, p, contents) {
  946.             const AutoPtr<CDirEntry>& dir_entry = *p;
  947.             if ( SMakeProjectT::IsMakeAppFile(dir_entry->GetName()) )
  948.             ProcessMakeAppFile(dir_entry->GetPath(), makefiles);
  949.         }
  950.     }
  951.     // Process Makefile.*.msvcproj
  952.     if ( process_projects ) {
  953.         CDir dir(dir_name);
  954.         CDir::TEntries contents = dir.GetEntries("Makefile.*.msvcproj");
  955.         ITERATE(CDir::TEntries, p, contents) {
  956.             const AutoPtr<CDirEntry>& dir_entry = *p;
  957.             if ( SMakeProjectT::IsUserProjFile(dir_entry->GetName()) )
  958.             ProcessUserProjFile(dir_entry->GetPath(), makefiles);
  959.         }
  960.     }
  961.     // Process Makefile.in
  962.     list<string> subprojects;
  963.     if ( process_projects ) {
  964.         ProcessMakeInFile(node_path, makefiles);
  965.         TFiles::const_iterator p = makefiles->m_In.find(node_path);
  966.         const CSimpleMakeFileContents& makefile = p->second;
  967.         // 
  968.         CSimpleMakeFileContents::TContents::const_iterator k = 
  969.             makefile.m_Contents.find("SUB_PROJ");
  970.         if (k != makefile.m_Contents.end()) {
  971.             const list<string>& values = k->second;
  972.             copy(values.begin(), 
  973.                  values.end(), 
  974.                  back_inserter(subprojects));
  975.         }
  976.         k = makefile.m_Contents.find("EXPENDABLE_SUB_PROJ");
  977.         if (k != makefile.m_Contents.end()) {
  978.             const list<string>& values = k->second;
  979.             copy(values.begin(), 
  980.                  values.end(), 
  981.                  back_inserter(subprojects));
  982.         }
  983.     }
  984.     subprojects.sort();
  985.     subprojects.unique();
  986.     // Convert subprojects to subdirs
  987.     list<string> subprojects_dirs;
  988.     if ( is_root ) {
  989.         // for root node we'll take all subdirs
  990.         CDir dir(dir_name);
  991.         CDir::TEntries contents = dir.GetEntries("*");
  992.         ITERATE(CDir::TEntries, p, contents) {
  993.             const AutoPtr<CDirEntry>& dir_entry = *p;
  994.             string name  = dir_entry->GetName();
  995.             if ( name == "."  ||  name == ".."  ||  
  996.                  name == string(1,CDir::GetPathSeparator()) ) {
  997.                 continue;
  998.             }
  999.             if ( dir_entry->IsDir() ) {
  1000.                 subprojects_dirs.push_back(dir_entry->GetPath());
  1001.             }
  1002.         }
  1003.     } else {
  1004.         // for non-root only subprojects
  1005.         ITERATE(list<string>, p, subprojects) {
  1006.             const string& subproject = *p;
  1007.             string subproject_dir = 
  1008.                 CDirEntry::ConcatPath(dir_name, subproject);
  1009.             subprojects_dirs.push_back(subproject_dir);
  1010.         }
  1011.     }
  1012.     // Process subproj ( e.t. subdirs )
  1013.     ITERATE(list<string>, p, subprojects_dirs) {
  1014.         const string& subproject_dir = *p;
  1015.         ProcessDir(subproject_dir, false, filter, makefiles);
  1016.     }
  1017. #endif
  1018. }
  1019. void CProjectTreeBuilder::ProcessMakeInFile(const string& file_name, 
  1020.                                             SMakeFiles*   makefiles)
  1021. {
  1022.     LOG_POST(Info << "Processing MakeIn: " + file_name);
  1023.     CSimpleMakeFileContents fc(file_name);
  1024.     if ( !fc.m_Contents.empty() )
  1025.     makefiles->m_In[file_name] = fc;
  1026. }
  1027. void CProjectTreeBuilder::ProcessMakeLibFile(const string& file_name, 
  1028.                                              SMakeFiles*   makefiles)
  1029. {
  1030.     LOG_POST(Info << "Processing MakeLib: " + file_name);
  1031.     CSimpleMakeFileContents fc(file_name);
  1032.     if ( !fc.m_Contents.empty() )
  1033.     makefiles->m_Lib[file_name] = fc;
  1034. }
  1035. void CProjectTreeBuilder::ProcessMakeAppFile(const string& file_name, 
  1036.                                              SMakeFiles*   makefiles)
  1037. {
  1038.     LOG_POST(Info << "Processing MakeApp: " + file_name);
  1039.     CSimpleMakeFileContents fc(file_name);
  1040.     if ( !fc.m_Contents.empty() )
  1041.     makefiles->m_App[file_name] = fc;
  1042. }
  1043. void CProjectTreeBuilder::ProcessUserProjFile(const string& file_name, 
  1044.                                              SMakeFiles*   makefiles)
  1045. {
  1046.     LOG_POST(Info << "Processing MakeApp: " + file_name);
  1047.     CSimpleMakeFileContents fc(file_name);
  1048.     if ( !fc.m_Contents.empty() )
  1049.     makefiles->m_User[file_name] = fc;
  1050. }
  1051. //recursive resolving
  1052. void CProjectTreeBuilder::ResolveDefs(CSymResolver& resolver, 
  1053.                                       SMakeFiles&   makefiles)
  1054. {
  1055.     {{
  1056.         //App
  1057.         set<string> keys;
  1058.         keys.insert("LIB");
  1059.         keys.insert("LIBS");
  1060.         keys.insert("NCBI_C_LIBS");
  1061.         SMakeProjectT::DoResolveDefs(resolver, makefiles.m_App, keys);
  1062.     }}
  1063.     {{
  1064.         //Lib
  1065.         set<string> keys;
  1066.         keys.insert("LIBS");
  1067.         SMakeProjectT::DoResolveDefs(resolver, makefiles.m_Lib, keys);
  1068.     }}
  1069. }
  1070. //analyze modules
  1071. void s_CollectDatatoolIds(const CProjectItemsTree& tree,
  1072.                           map<string, CProjKey>*   datatool_ids)
  1073. {
  1074.     ITERATE(CProjectItemsTree::TProjects, p, tree.m_Projects) {
  1075.         const CProjKey&  project_id = p->first;
  1076.         const CProjItem& project    = p->second;
  1077.         ITERATE(list<CDataToolGeneratedSrc>, n, project.m_DatatoolSources) {
  1078.             const CDataToolGeneratedSrc& src = *n;
  1079.             string src_abs_path = 
  1080.                 CDirEntry::ConcatPath(src.m_SourceBaseDir, src.m_SourceFile);
  1081.             string src_rel_path = 
  1082.                 CDirEntry::CreateRelativePath
  1083.                                  (GetApp().GetProjectTreeInfo().m_Src, 
  1084.                                   src_abs_path);
  1085.             (*datatool_ids)[src_rel_path] = project_id;
  1086.         }
  1087.     }
  1088. }
  1089. void CProjectTreeBuilder::AddDatatoolSourcesDepends(CProjectItemsTree* tree)
  1090. {
  1091.     //datatool src rel path / project ID
  1092.     // 1. Collect all projects with datatool-generated-sources
  1093.     map<string, CProjKey> whole_datatool_ids;
  1094.     s_CollectDatatoolIds(GetApp().GetWholeTree(), &whole_datatool_ids);
  1095.     // 2. Extent tree to accomodate more ASN projects if necessary
  1096.     bool tree_extented = false;
  1097.     map<string, CProjKey> datatool_ids;
  1098.     do {
  1099.         
  1100.         tree_extented = false;
  1101.         s_CollectDatatoolIds(*tree, &datatool_ids);
  1102.         NON_CONST_ITERATE(CProjectItemsTree::TProjects, p, tree->m_Projects) {
  1103.             const CProjKey&  project_id = p->first;
  1104.             CProjItem& project          = p->second;
  1105.             ITERATE(list<CDataToolGeneratedSrc>, n, project.m_DatatoolSources) {
  1106.                 const CDataToolGeneratedSrc& src = *n;
  1107.                 ITERATE(list<string>, i, src.m_ImportModules) {
  1108.                     const string& module = *i;
  1109.                     map<string, CProjKey>::const_iterator j = 
  1110.                         datatool_ids.find(module);
  1111.                     if (j == datatool_ids.end()) {
  1112.                         j = whole_datatool_ids.find(module);
  1113.                         if (j != whole_datatool_ids.end()) {
  1114.                             const CProjKey& depends_id = j->second;
  1115.                             tree->m_Projects[depends_id] = 
  1116.                                 GetApp().GetWholeTree().m_Projects.find(depends_id)->second;
  1117.                             tree_extented = true;
  1118.                         }
  1119.                     }
  1120.                 }
  1121.             }
  1122.         }
  1123.     } while( tree_extented );
  1124.     // 3. Finally - generate depends
  1125.     NON_CONST_ITERATE(CProjectItemsTree::TProjects, p, tree->m_Projects) {
  1126.         const CProjKey&  project_id = p->first;
  1127.         CProjItem& project          = p->second;
  1128.         ITERATE(list<CDataToolGeneratedSrc>, n, project.m_DatatoolSources) {
  1129.             const CDataToolGeneratedSrc& src = *n;
  1130.             ITERATE(list<string>, i, src.m_ImportModules) {
  1131.                 const string& module = *i;
  1132.                 map<string, CProjKey>::const_iterator j = 
  1133.                     datatool_ids.find(module);
  1134.                 if (j != datatool_ids.end()) {
  1135.                     const CProjKey& depends_id = j->second;
  1136.                     if (depends_id != project_id) {
  1137.                         project.m_Depends.push_back(depends_id);
  1138.                         project.m_Depends.sort();
  1139.                         project.m_Depends.unique();
  1140.                     }
  1141.                 }
  1142.             }
  1143.         }
  1144.     }
  1145. }
  1146. END_NCBI_SCOPE
  1147. /*
  1148.  * ===========================================================================
  1149.  * $Log: proj_tree_builder.cpp,v $
  1150.  * Revision 1000.3  2004/06/16 17:02:39  gouriano
  1151.  * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.13
  1152.  *
  1153.  * Revision 1.13  2004/06/16 16:29:11  gorelenk
  1154.  * Changed directories traversing proc.
  1155.  *
  1156.  * Revision 1.12  2004/06/16 14:26:05  gorelenk
  1157.  * Re-designed CProjectTreeBuilder::ProcessDir .
  1158.  *
  1159.  * Revision 1.11  2004/06/15 14:14:31  gorelenk
  1160.  * Changed CProjectTreeBuilder::ProcessDir - changed procedure of
  1161.  * subdirs iteration .
  1162.  *
  1163.  * Revision 1.10  2004/06/14 18:57:59  gorelenk
  1164.  * Changed CProjectTreeBuilder::ProcessDir
  1165.  * - added support of EXPENDABLE_SUB_PROJ .
  1166.  *
  1167.  * Revision 1.9  2004/06/14 14:18:21  gorelenk
  1168.  * Changed CProjectTreeBuilder::ProcessDir - added SUB_PROJ processing.
  1169.  *
  1170.  * Revision 1.8  2004/05/21 21:41:41  gorelenk
  1171.  * Added PCH ncbi_pch.hpp
  1172.  *
  1173.  * Revision 1.7  2004/05/13 14:55:35  gorelenk
  1174.  * Changed SMakeProjectT::CreateIncludeDirs .
  1175.  *
  1176.  * Revision 1.6  2004/05/10 19:50:42  gorelenk
  1177.  * Implemented SMsvcProjectT .
  1178.  *
  1179.  * Revision 1.5  2004/04/06 17:15:47  gorelenk
  1180.  * Implemented member-functions IsConfigurableDefine and
  1181.  * StripConfigurableDefine of struct SMakeProjectT.
  1182.  * Changed implementations of SMakeProjectT::DoResolveDefs
  1183.  * SMakeProjectT::Create3PartyLibs and SAppProjectT::CreateNcbiCToolkitLibs.
  1184.  *
  1185.  * Revision 1.4  2004/03/23 14:41:50  gorelenk
  1186.  * Changed implementations of CProjectTreeBuilder::AddDatatoolSourcesDepends
  1187.  * and CProjectTreeBuilder::BuildProjectTree.
  1188.  *
  1189.  * Revision 1.3  2004/03/16 23:53:14  gorelenk
  1190.  * Changed implementations of:
  1191.  * SAppProjectT::DoCreate and
  1192.  * SAppProjectT::CreateNcbiCToolkitLibs .
  1193.  *
  1194.  * Revision 1.2  2004/03/04 23:31:10  gorelenk
  1195.  * Added call to AddDatatoolSourcesDepends in implementation of
  1196.  * CProjectTreeBuilder::BuildProjectTree.
  1197.  *
  1198.  * Revision 1.1  2004/03/02 16:23:57  gorelenk
  1199.  * Initial revision.
  1200.  *
  1201.  * ===========================================================================
  1202.  */