src/build-system/project_tree_builder/msvc_project_context.cpp

Go to the documentation of this file.
00001 /* $Id: msvc_project_context.cpp 168338 2009-08-14 13:40:34Z gouriano $
00002  * ===========================================================================
00003  *
00004  *                            PUBLIC DOMAIN NOTICE
00005  *               National Center for Biotechnology Information
00006  *
00007  *  This software/database is a "United States Government Work" under the
00008  *  terms of the United States Copyright Act.  It was written as part of
00009  *  the author's official duties as a United States Government employee and
00010  *  thus cannot be copyrighted.  This software/database is freely available
00011  *  to the public for use. The National Library of Medicine and the U.S.
00012  *  Government have not placed any restriction on its use or reproduction.
00013  *
00014  *  Although all reasonable efforts have been taken to ensure the accuracy
00015  *  and reliability of the software and data, the NLM and the U.S.
00016  *  Government do not and cannot warrant the performance or results that
00017  *  may be obtained by using this software or data. The NLM and the U.S.
00018  *  Government disclaim all warranties, express or implied, including
00019  *  warranties of performance, merchantability or fitness for any particular
00020  *  purpose.
00021  *
00022  *  Please cite the author in any work or product based on this material.
00023  *
00024  * ===========================================================================
00025  *
00026  * Author:  Viatcheslav Gorelenkov
00027  *
00028  */
00029 
00030 #include <ncbi_pch.hpp>
00031 #include "stl_msvc_usage.hpp"
00032 
00033 #include "msvc_project_context.hpp"
00034 #include "msvc_tools_implement.hpp"
00035 #include "proj_builder_app.hpp"
00036 #include "msvc_site.hpp"
00037 #include "msvc_prj_defines.hpp"
00038 #include "ptb_err_codes.hpp"
00039 #include "proj_tree_builder.hpp"
00040 
00041 #include <algorithm>
00042 #include <set>
00043 
00044 
00045 BEGIN_NCBI_SCOPE
00046 
00047 map<string, set<string> > CMsvcPrjProjectContext::s_EnabledPackages;
00048 map<string, set<string> > CMsvcPrjProjectContext::s_DisabledPackages;
00049 
00050 //-----------------------------------------------------------------------------
00051 CMsvcPrjProjectContext::CMsvcPrjProjectContext(const CProjItem& project)
00052     : m_Project(project)
00053 {
00054     m_MakeType = project.m_MakeType;
00055     //MSVC project name created from project type and project ID
00056     m_ProjectName  = CreateProjectName(CProjKey(project.m_ProjType, 
00057                                                 project.m_ID));
00058     m_ProjectId    = project.m_ID;
00059     m_ProjType     = project.m_ProjType;
00060 
00061     m_SourcesBaseDir = project.m_SourcesBaseDir;
00062     m_Requires       = project.m_Requires;
00063     
00064     // Get msvc project makefile
00065     m_MsvcProjectMakefile.reset
00066         (new CMsvcProjectMakefile
00067                     (CDirEntry::ConcatPath
00068                             (project.m_SourcesBaseDir,
00069                              CreateMsvcProjectMakefileName(project))));
00070 
00071     // Done if this is ready MSVC project
00072     if ( project.m_ProjType == CProjKey::eMsvc)
00073         return;
00074 
00075     // Collect all dirs of source files into m_SourcesDirsAbs:
00076     set<string> sources_dirs;
00077     sources_dirs.insert(m_SourcesBaseDir);
00078     ITERATE(list<string>, p, project.m_Sources) {
00079 
00080         const string& src_rel = *p;
00081         string src_path = CDirEntry::ConcatPath(m_SourcesBaseDir, src_rel);
00082         src_path = CDirEntry::NormalizePath(src_path);
00083 
00084         string dir;
00085         CDirEntry::SplitPath(src_path, &dir);
00086         sources_dirs.insert(dir);
00087     }
00088     copy(sources_dirs.begin(), 
00089          sources_dirs.end(), 
00090          back_inserter(m_SourcesDirsAbs));
00091 
00092 
00093     // Creating project dir:
00094     m_ProjectDir = GetApp().GetProjectTreeInfo().m_Compilers;
00095     m_ProjectDir = 
00096         CDirEntry::ConcatPath(m_ProjectDir, 
00097                                 GetApp().GetRegSettings().m_CompilersSubdir);
00098     m_ProjectDir = 
00099         CDirEntry::ConcatPath(m_ProjectDir, 
00100                                 GetApp().GetBuildType().GetTypeStr());
00101     m_ProjectDir =
00102         CDirEntry::ConcatPath(m_ProjectDir,
00103                                 GetApp().GetRegSettings().m_ProjectsSubdir);
00104     m_ProjectDir = 
00105         CDirEntry::ConcatPath(m_ProjectDir, 
00106                                 CDirEntry::CreateRelativePath
00107                                     (GetApp().GetProjectTreeInfo().m_Src, 
00108                                     m_SourcesBaseDir));
00109     m_ProjectDir = CDirEntry::AddTrailingPathSeparator(m_ProjectDir);
00110 
00111     string lib_dir = GetApp().GetBuildRoot();
00112     if (lib_dir.empty()) {
00113         lib_dir = GetApp().GetProjectTreeInfo().m_Compilers;
00114         lib_dir = CDirEntry::ConcatPath(lib_dir, 
00115                                         GetApp().GetRegSettings().m_CompilersSubdir);
00116     }
00117     string type_dir = CDirEntry::ConcatPath(lib_dir, 
00118                                             GetApp().GetBuildType().GetTypeStr());
00119 // it is either root/buildtype/[lib|bin]/$ConfigurationName
00120 // or just      root/$ConfigurationName
00121     if (CDirEntry(type_dir).Exists()) {
00122         m_StaticLibRoot  = CDirEntry::ConcatPath(type_dir, "lib");
00123         m_DynamicLibRoot = CDirEntry::ConcatPath(type_dir, "bin");
00124     } else {
00125         m_StaticLibRoot = m_DynamicLibRoot = lib_dir;
00126     }
00127 // find sources
00128     string t, try_dir, inc_dir;
00129     for ( t = try_dir = m_StaticLibRoot; ; try_dir = t) {
00130         inc_dir = CDirEntry::ConcatPath(try_dir, 
00131             GetApp().GetConfig().Get("ProjectTree", "include"));
00132         if (CDirEntry(inc_dir).Exists()) {
00133             m_SrcRoot = CDirEntry(inc_dir).GetDir();
00134             break;
00135         }
00136         t = CDirEntry(try_dir).GetDir();
00137         if (t == try_dir) {
00138             break;
00139         }
00140     }
00141 
00142     // Generate include dirs:
00143     // Include dirs for appropriate src dirs
00144     set<string> include_dirs;
00145     ITERATE(list<string>, p, project.m_Sources) {
00146         //create full path for src file
00147         const string& src_rel = *p;
00148         string src_abs  = CDirEntry::ConcatPath(m_SourcesBaseDir, src_rel);
00149         src_abs = CDirEntry::NormalizePath(src_abs);
00150         //part of path (from <src> dir)
00151         string rel_path  = 
00152             CDirEntry::CreateRelativePath(GetApp().GetProjectTreeInfo().m_Src, 
00153                                           src_abs);
00154         //add this part to <include> dir
00155         string incl_path = CDirEntry::NormalizePath(
00156             CDirEntry::ConcatPath(GetApp().GetProjectTreeInfo().m_Include, 
00157                                   rel_path));
00158         string incl_dir;
00159         CDirEntry::SplitPath(incl_path, &incl_dir);
00160         include_dirs.insert(incl_dir);
00161 
00162         //impl include sub-dir
00163         string impl_dir = 
00164             CDirEntry::ConcatPath(incl_dir, 
00165                                   GetApp().GetProjectTreeInfo().m_Impl);
00166         impl_dir = CDirEntry::AddTrailingPathSeparator(impl_dir);
00167         include_dirs.insert(impl_dir);
00168     }
00169     m_IncludeDirsAbs = project.m_Includes;
00170     m_InlineDirsAbs  = project.m_Inlines;
00171 
00172     SConfigInfo cfg_info; // default is enough
00173     list<string> headers_in_include;
00174     list<string> inlines_in_include;
00175     set<string>::const_iterator i;
00176     list<string>::const_iterator h, hs;
00177     GetMsvcProjectMakefile().GetHeadersInInclude( cfg_info, &headers_in_include);
00178     GetMsvcProjectMakefile().GetInlinesInInclude( cfg_info, &inlines_in_include);
00179     for (i = include_dirs.begin(); i != include_dirs.end(); ++i) {
00180         for (h = headers_in_include.begin(); h != headers_in_include.end(); ++h) {
00181             m_IncludeDirsAbs.push_back(CDirEntry::ConcatPath(*i, *h));
00182         }
00183         for (h = inlines_in_include.begin(); h != inlines_in_include.end(); ++h) {
00184             m_InlineDirsAbs.push_back(CDirEntry::ConcatPath(*i, *h));
00185         }
00186     }
00187     list<string> headers_in_src;
00188     list<string> inlines_in_src;
00189     GetMsvcProjectMakefile().GetHeadersInSrc( cfg_info, &headers_in_src);
00190     GetMsvcProjectMakefile().GetInlinesInSrc( cfg_info, &inlines_in_src);
00191     for (hs = m_SourcesDirsAbs.begin(); hs != m_SourcesDirsAbs.end(); ++hs) {
00192         for (h = headers_in_src.begin(); h != headers_in_src.end(); ++h) {
00193             m_IncludeDirsAbs.push_back(CDirEntry::ConcatPath(*hs, *h));
00194         }
00195         for (h = inlines_in_src.begin(); h != inlines_in_src.end(); ++h) {
00196             m_InlineDirsAbs.push_back(CDirEntry::ConcatPath(*hs, *h));
00197         }
00198     }
00199 
00200     m_IncludeDirsAbs.sort();
00201     m_IncludeDirsAbs.unique();
00202     m_InlineDirsAbs.sort();
00203     m_InlineDirsAbs.unique();
00204 
00205     // Get custom build files and adjust pathes 
00206     GetMsvcProjectMakefile().GetCustomBuildInfo(&m_CustomBuildInfo);
00207 
00208     // Collect include dirs, specified in project Makefiles
00209     m_ProjectIncludeDirs = project.m_IncludeDirs;
00210 
00211     // LIBS from Makefiles
00212     if (!project.m_Libs3Party.empty()) {
00213         // m_ProjectLibs = project.m_Libs3Party;
00214         list<string> installed_3party;
00215         GetApp().GetSite().GetThirdPartyLibsToInstall(&installed_3party);
00216 
00217         ITERATE(list<string>, p, project.m_Libs3Party) {
00218             const string& lib_id = *p;
00219             if ( GetApp().GetSite().IsLibWithChoice(lib_id) ) {
00220                 if ( GetApp().GetSite().GetChoiceForLib(lib_id) == CMsvcSite::eLib )
00221                     m_ProjectLibs.push_back(lib_id);
00222             } else {
00223                 m_ProjectLibs.push_back(lib_id);
00224             }
00225 
00226             ITERATE(list<string>, i, installed_3party) {
00227                 const string& component = *i;
00228                 bool lib_ok = true;
00229                 ITERATE(list<SConfigInfo>, j, GetApp().GetRegSettings().m_ConfigInfo) {
00230                     const SConfigInfo& config = *j;
00231                     SLibInfo lib_info;
00232                     GetApp().GetSite().GetLibInfo(component, config, &lib_info);
00233                     if (find( lib_info.m_Macro.begin(), lib_info.m_Macro.end(), lib_id) ==
00234                             lib_info.m_Macro.end()) {
00235                         lib_ok = false;
00236                         break;
00237                     }
00238                 }
00239                 if (lib_ok) {
00240                     m_Requires.push_back(component);
00241                 }
00242             }
00243         }
00244     }
00245     m_Requires.sort();
00246     m_Requires.unique();
00247 
00248     // Proprocessor definitions from makefiles:
00249     m_Defines = project.m_Defines;
00250     if (GetApp().GetBuildType().GetType() == CBuildType::eDll) {
00251         m_Defines.push_back(GetApp().GetConfig().Get(CMsvc7RegSettings::GetMsvcSection(), "DllBuildDefine"));
00252     }
00253     // Pre-Builds for LIB projects:
00254     {
00255         ITERATE(set<CProjKey>, p, project.m_UnconditionalDepends) {
00256             CProjKey proj_key = *p;
00257             {
00258                 const CProjectItemsTree* curr_tree = GetApp().GetCurrentBuildTree();
00259                 if (GetApp().GetIncompleteBuildTree()) {
00260                     // do not attempt to prebuild what is missing
00261                     if (GetApp().GetIncompleteBuildTree()->m_Projects.find(proj_key) ==
00262                         GetApp().GetIncompleteBuildTree()->m_Projects.end()) {
00263                         continue;
00264                     }
00265                 } else if (curr_tree) {
00266                     if (curr_tree->m_Projects.find(proj_key) ==
00267                         curr_tree->m_Projects.end()) {
00268                         
00269                         bool depfound = false;
00270                         string dll(GetDllHost(*curr_tree, proj_key.Id()));
00271                         if (!dll.empty()) {
00272                             CProjKey id_alt(CProjKey::eDll,dll);
00273                             if (curr_tree->m_Projects.find(id_alt) !=
00274                                 curr_tree->m_Projects.end()) {
00275                                 proj_key = id_alt;
00276                                 depfound = true;
00277                             }
00278                         }
00279                         if (!depfound) {
00280                             PTB_WARNING_EX(
00281                                 CDirEntry::ConcatPath(m_SourcesBaseDir, m_ProjectName),
00282                                     ePTB_ProjectNotFound, "depends on missing project: " << proj_key.Id());
00283                         }
00284                     }
00285                 }
00286                 if (!SMakeProjectT::IsConfigurableDefine(proj_key.Id())) {
00287                     m_PreBuilds.push_back(proj_key);
00288                 }
00289             }
00290         }
00291     }
00292 
00293     // Libraries from NCBI C Toolkit
00294     m_NcbiCLibs = project.m_NcbiCLibs;
00295 }
00296 
00297 
00298 string CMsvcPrjProjectContext::AdditionalIncludeDirectories
00299                                             (const SConfigInfo& cfg_info) const
00300 {
00301     list<string> add_include_dirs_list;
00302     list<string> dirs;
00303     string dir;
00304 
00305     if (!GetApp().m_IncDir.empty()) {
00306         string config_inc = CDirEntry::AddTrailingPathSeparator(GetApp().m_IncDir);
00307         config_inc = CDirEntry::CreateRelativePath(m_ProjectDir, config_inc);
00308         add_include_dirs_list.push_back( config_inc );
00309     }
00310 
00311     // project dir
00312     string tree_inc = CDirEntry::CreateRelativePath(m_ProjectDir, 
00313         GetApp().GetProjectTreeInfo().m_Include);
00314     tree_inc = CDirEntry::AddTrailingPathSeparator(tree_inc);
00315     add_include_dirs_list.push_back( tree_inc );
00316     
00317     // internal, if present
00318     string internal_inc = CDirEntry::ConcatPath(tree_inc,"internal");
00319     if (CDirEntry(CDirEntry::NormalizePath(CDirEntry::ConcatPath(m_ProjectDir,internal_inc))).IsDir()) {
00320         add_include_dirs_list.push_back( CDirEntry::AddTrailingPathSeparator(internal_inc) );
00321     }
00322     
00323     //take into account project include dirs
00324     ITERATE(list<string>, p, m_ProjectIncludeDirs) {
00325         const string& dir_abs = *p;
00326         dirs.clear();
00327         if (CSymResolver::IsDefine(dir_abs)) {
00328             GetApp().GetSite().GetLibInclude( dir_abs, cfg_info, &dirs);
00329         } else {
00330             dirs.push_back(dir_abs);
00331         }
00332         for (list<string>::const_iterator i = dirs.begin(); i != dirs.end(); ++i) {
00333             dir = *i;
00334             add_include_dirs_list.push_back(SameRootDirs(m_ProjectDir,dir) ?
00335                     CDirEntry::CreateRelativePath(m_ProjectDir, dir) :
00336                     dir);
00337         }
00338     }
00339 
00340     //MSVC Makefile additional include dirs
00341     list<string> makefile_add_incl_dirs;
00342     GetMsvcProjectMakefile().GetAdditionalIncludeDirs(cfg_info, 
00343                                                     &makefile_add_incl_dirs);
00344 
00345     ITERATE(list<string>, p, makefile_add_incl_dirs) {
00346         const string& dir = *p;
00347         string dir_abs = 
00348             CDirEntry::AddTrailingPathSeparator
00349                 (CDirEntry::ConcatPath(m_SourcesBaseDir, dir));
00350         dir_abs = CDirEntry::NormalizePath(dir_abs);
00351         dir_abs = 
00352             CDirEntry::CreateRelativePath
00353                         (m_ProjectDir, dir_abs);
00354         add_include_dirs_list.push_back(dir_abs);
00355     }
00356 
00357     // Additional include dirs for 3-party libs
00358     list<string> libs_list;
00359     CreateLibsList(&libs_list);
00360     ITERATE(list<string>, p, libs_list) {
00361         GetApp().GetSite().GetLibInclude(*p, cfg_info, &dirs);
00362         for (list<string>::const_iterator i = dirs.begin(); i != dirs.end(); ++i) {
00363             dir = *i;
00364             if ( !dir.empty() ) {
00365                 if (SameRootDirs(m_ProjectDir,dir)) {
00366                     dir = CDirEntry::CreateRelativePath(m_ProjectDir, dir);
00367                 }
00368                 if (find(add_include_dirs_list.begin(),
00369                     add_include_dirs_list.end(), dir) !=add_include_dirs_list.end()) {
00370                     continue;
00371                 }
00372                 add_include_dirs_list.push_back(dir);
00373             }
00374         }
00375     }
00376 
00377     string ext_inc;
00378     const CProjectItemsTree* all_projects = GetApp().GetIncompleteBuildTree();
00379     if (all_projects) {
00380         string inc_dir = CDirEntry::ConcatPath(m_SrcRoot, 
00381             GetApp().GetConfig().Get("ProjectTree", "include"));
00382         if (CDirEntry(inc_dir).Exists()) {
00383             try {
00384                 ext_inc = CDirEntry::CreateRelativePath(m_ProjectDir, inc_dir);
00385             } catch (CFileException&) {
00386                 ext_inc = inc_dir;
00387             }
00388             ext_inc = CDirEntry::AddTrailingPathSeparator(ext_inc);
00389             if (NStr::CompareNocase(tree_inc, ext_inc) != 0) {
00390                 add_include_dirs_list.push_back( ext_inc );
00391             }
00392         }
00393     }
00394     //Leave only unique dirs and join them to string
00395 //    add_include_dirs_list.sort();
00396 //    add_include_dirs_list.unique();
00397     return NStr::Join(add_include_dirs_list, ", ");
00398 }
00399 
00400 
00401 string CMsvcPrjProjectContext::AdditionalLinkerOptions
00402                                             (const SConfigInfo& cfg_info) const
00403 {
00404     list<string> additional_libs;
00405 
00406     // Take into account requires, default and makefiles libs
00407     list<string> libs_list;
00408     CreateLibsList(&libs_list);
00409     ITERATE(list<string>, p, libs_list) {
00410         const string& requires = *p;
00411         if (GetApp().GetSite().Is3PartyLibWithChoice(requires)) {
00412             if (GetApp().GetSite().GetChoiceFor3PartyLib(requires, cfg_info) == CMsvcSite::eLib) {
00413                 continue;
00414             }
00415         }
00416         SLibInfo lib_info;
00417         GetApp().GetSite().GetLibInfo(requires, cfg_info, &lib_info);
00418         if ( CMsvcSite::IsLibOk(lib_info) &&
00419             GetApp().GetSite().IsLibEnabledInConfig(requires, cfg_info)) {
00420             if ( !lib_info.m_Libs.empty() ) {
00421                 copy(lib_info.m_Libs.begin(), lib_info.m_Libs.end(), 
00422                     back_inserter(additional_libs));
00423             }
00424             if ( !lib_info.m_StdLibs.empty() ) {
00425                 copy(lib_info.m_StdLibs.begin(), lib_info.m_StdLibs.end(), 
00426                     back_inserter(additional_libs));
00427             }
00428         } else {
00429             if (!lib_info.IsEmpty() && !lib_info.m_Libs.empty()) {
00430                 PTB_WARNING_EX(lib_info.m_LibPath, ePTB_FileNotFound,
00431                                requires << "|" << cfg_info.GetConfigFullName()
00432                                << " unavailable: missing additional libraries: "
00433                                << NStr::Join(lib_info.m_Libs,","));
00434 
00435             }
00436         }
00437     }
00438 
00439     // NCBI C Toolkit libs
00440     ITERATE(list<string>, p, m_NcbiCLibs) {
00441         string ncbi_lib = *p + ".lib";
00442         additional_libs.push_back(ncbi_lib);        
00443     }
00444 
00445     const CProjectItemsTree* all_projects = GetApp().GetIncompleteBuildTree();
00446     if (all_projects) {
00447         string static_lib_dir  = CDirEntry::ConcatPath(m_StaticLibRoot, cfg_info.GetConfigFullName());
00448         string dynamic_lib_dir = CDirEntry::ConcatPath(m_DynamicLibRoot, cfg_info.GetConfigFullName());
00449         ITERATE(list<CProjKey>, n, m_Project.m_Depends) {
00450             const CProjKey& depend_id = *n;
00451             if (depend_id.Type() == CProjKey::eLib || depend_id.Type() == CProjKey::eDll) {
00452                 CProjectItemsTree::TProjects::const_iterator i =
00453                     all_projects->m_Projects.find(depend_id);
00454                 if (i == all_projects->m_Projects.end()) {
00455                     string lib_path = CDirEntry::ConcatPath(
00456                         depend_id.Type() == CProjKey::eLib ? static_lib_dir : dynamic_lib_dir,
00457                         depend_id.Id());
00458                     lib_path += ".lib";
00459                     CDirEntry lib(lib_path);
00460                     if (!lib.Exists()) {
00461                         if (!GetApp().m_BuildRoot.empty()) {
00462                             PTB_WARNING_EX(lib_path, ePTB_FileNotFound,
00463                                         "Library not found: " << lib_path);
00464                         } else {
00465                             PTB_ERROR_EX(lib_path, ePTB_FileNotFound,
00466                                         "Library not found: " << lib_path);
00467                         }
00468                     }
00469                     additional_libs.push_back(lib.GetName());
00470                 }
00471             }
00472         }
00473     }
00474 
00475     if (CMsvc7RegSettings::GetMsvcPlatform() < CMsvc7RegSettings::eUnix) {
00476         additional_libs.sort();
00477         additional_libs.unique();
00478     }
00479     return NStr::Join(additional_libs, " ");
00480 }
00481 
00482 #if 0
00483 string CMsvcPrjProjectContext::AdditionalLibrarianOptions
00484                                             (const SConfigInfo& cfg_info) const
00485 {
00486     return AdditionalLinkerOptions(cfg_info);
00487 }
00488 #endif
00489 
00490 string CMsvcPrjProjectContext::AdditionalLibraryDirectories
00491                                             (const SConfigInfo& cfg_info) const
00492 {
00493     list<string> dir_list;
00494 // library folder
00495     const CProjectItemsTree* all_projects = GetApp().GetIncompleteBuildTree();
00496     if (all_projects) {
00497         string lib_dir;
00498         try {
00499             lib_dir = CDirEntry::CreateRelativePath(ProjectDir(), m_StaticLibRoot);
00500         } catch (CFileException&) {
00501             lib_dir = m_StaticLibRoot;
00502         }
00503         lib_dir = CDirEntry::ConcatPath(lib_dir, CMsvc7RegSettings::GetConfigNameKeyword());
00504         dir_list.push_back(lib_dir);
00505         if (GetApp().GetBuildType().GetType() == CBuildType::eDll) {
00506             try {
00507                 lib_dir = CDirEntry::CreateRelativePath(ProjectDir(), m_DynamicLibRoot);
00508             } catch (CFileException&) {
00509                 lib_dir = m_DynamicLibRoot;
00510             }
00511             lib_dir = CDirEntry::ConcatPath(lib_dir, CMsvc7RegSettings::GetConfigNameKeyword());
00512             dir_list.push_back(lib_dir);
00513         }
00514     }
00515 
00516     // Take into account requires, default and makefiles libs
00517     list<string> libs_list;
00518     CreateLibsList(&libs_list);
00519     ITERATE(list<string>, p, libs_list) {
00520         const string& requires = *p;
00521         if (GetApp().GetSite().Is3PartyLibWithChoice(requires)) {
00522             if (GetApp().GetSite().GetChoiceFor3PartyLib(requires, cfg_info) == CMsvcSite::eLib) {
00523                 continue;
00524             }
00525         }
00526         SLibInfo lib_info;
00527         GetApp().GetSite().GetLibInfo(requires, cfg_info, &lib_info);
00528         if ( CMsvcSite::IsLibOk(lib_info) &&
00529              GetApp().GetSite().IsLibEnabledInConfig(requires, cfg_info) ) {
00530             if ( !lib_info.m_LibPath.empty() ) {
00531                 dir_list.push_back(lib_info.m_LibPath);
00532             }
00533         } else {
00534             if (!lib_info.IsEmpty()) {
00535                 PTB_WARNING_EX(lib_info.m_LibPath, ePTB_FileNotFound,
00536                                requires << "|" << cfg_info.GetConfigFullName()
00537                                << " unavailable: library folder ignored: "
00538                                << lib_info.m_LibPath);
00539             }
00540         }
00541     }
00542     dir_list.sort();
00543     dir_list.unique();
00544     return NStr::Join(dir_list, ", ");
00545 }
00546 
00547 
00548 void CMsvcPrjProjectContext::CreateLibsList(list<string>* libs_list) const
00549 {
00550     libs_list->clear();
00551     // We'll build libs list.
00552     *libs_list = m_Requires;
00553     //and LIBS from Makefiles:
00554     ITERATE(list<string>, p, m_ProjectLibs) {
00555         const string& lib = *p;
00556         list<string> components;
00557         GetApp().GetSite().GetComponents(lib, &components);
00558         copy(components.begin(), 
00559              components.end(), back_inserter(*libs_list));
00560 
00561     }
00562     libs_list->sort();
00563     libs_list->unique();
00564     //take into account default libs from site:
00565     libs_list->push_back(MSVC_DEFAULT_LIBS_TAG);
00566 }
00567 
00568 const CMsvcCombinedProjectMakefile& 
00569 CMsvcPrjProjectContext::GetMsvcProjectMakefile(void) const
00570 {
00571     if ( m_MsvcCombinedProjectMakefile.get() )
00572         return *m_MsvcCombinedProjectMakefile;
00573 
00574     string rules_dir = GetApp().GetProjectTreeInfo().m_Compilers;
00575     rules_dir = 
00576             CDirEntry::ConcatPath(rules_dir, 
00577                                   GetApp().GetRegSettings().m_CompilersSubdir);
00578 
00579 
00580     // temporary fix with const_cast
00581     (const_cast<auto_ptr<CMsvcCombinedProjectMakefile>&>
00582         (m_MsvcCombinedProjectMakefile)).reset(new CMsvcCombinedProjectMakefile
00583                                                   (m_ProjType,
00584                                                    m_MsvcProjectMakefile.get(),
00585                                                    rules_dir,
00586                                                    m_Requires));
00587 
00588     return *m_MsvcCombinedProjectMakefile;
00589 }
00590 
00591 
00592 bool CMsvcPrjProjectContext::IsRequiresOk(const CProjItem& prj, string* unmet)
00593 {
00594     ITERATE(list<string>, p, prj.m_Requires) {
00595         const string& requires = *p;
00596         if ( !GetApp().GetSite().IsProvided(requires) ) {
00597             if (unmet) {
00598                 *unmet = requires;
00599             }
00600             return false;
00601         }
00602     }
00603     return true;
00604 }
00605 
00606 
00607 bool CMsvcPrjProjectContext::IsConfigEnabled(const SConfigInfo& config,
00608     string* unmet, string* unmet_req) const
00609 {
00610     list<string> libs_3party;
00611     ITERATE(list<string>, p, m_ProjectLibs) {
00612         const string& lib = *p;
00613         list<string> components;
00614         GetApp().GetSite().GetComponents(lib, &components);
00615         copy(components.begin(), 
00616              components.end(), back_inserter(libs_3party));
00617     }
00618     list<string> libs_required;
00619     ITERATE(list<string>, p, m_Requires) {
00620         const string& lib = *p;
00621         list<string> components;
00622         GetApp().GetSite().GetComponents(lib, &components);
00623         if (components.empty()) {
00624             libs_required.push_back(lib);
00625         } else {
00626             copy(components.begin(), 
00627                 components.end(), back_inserter(libs_required));
00628         }
00629     }
00630 
00631     // Add requires to test : If there is such library and configuration for 
00632     // this library is disabled then we'll disable this config
00633     copy(m_Requires.begin(), m_Requires.end(), back_inserter(libs_3party));
00634     libs_3party.sort();
00635     libs_3party.unique();
00636 
00637     // Test third-party libs and requires:
00638     const CMsvcSite& site = GetApp().GetSite();
00639     bool result = true;
00640     ITERATE(list<string>, p, libs_3party) {
00641         const string& requires = *p;
00642         SLibInfo lib_info;
00643         site.GetLibInfo(requires, config, &lib_info);
00644         
00645         if ( lib_info.IsEmpty() ) {
00646             bool st = 
00647                 (config.m_rtType == SConfigInfo::rtSingleThreaded ||
00648                  config.m_rtType == SConfigInfo::rtSingleThreadedDebug);
00649             if ((requires == "MT" && st) || (requires == "-MT" && !st)) {
00650                 if (unmet) {
00651                     if (!unmet->empty()) {
00652                         *unmet += ", ";
00653                     }
00654                     *unmet += requires;
00655                 }
00656                 result = false;
00657             }
00658             continue;
00659         }
00660 
00661         if ( !site.IsLibEnabledInConfig(requires, config) ) {
00662             if (unmet) {
00663                 if (!unmet->empty()) {
00664                     *unmet += ", ";
00665                 }
00666                 *unmet += requires;
00667             }
00668             if (find( libs_required.begin(), libs_required.end(), requires )
00669                    != libs_required.end()) {
00670                 result = false;
00671             }
00672             s_DisabledPackages[config.GetConfigFullName()].insert(requires);
00673         } else {
00674             s_EnabledPackages[config.GetConfigFullName()].insert(requires);
00675         }
00676 
00677         if ( !site.IsLibOk(lib_info,true) && !site.Is3PartyLibWithChoice(requires) ) {
00678             if (unmet_req) {
00679                 if (!unmet_req->empty()) {
00680                     *unmet_req += ", ";
00681                 }
00682                 *unmet_req += requires;
00683             }
00684         }
00685     }
00686 
00687     return result;
00688 }
00689 
00690 
00691 const list<string> CMsvcPrjProjectContext::Defines(const SConfigInfo& cfg_info) const
00692 {
00693     list<string> defines(m_Defines);
00694 
00695     list<string> libs_list;
00696     CreateLibsList(&libs_list);
00697     ITERATE(list<string>, p, libs_list) {
00698         const string& lib_id = *p;
00699         if (GetApp().GetSite().Is3PartyLibWithChoice(lib_id)) {
00700             if (GetApp().GetSite().GetChoiceFor3PartyLib(lib_id, cfg_info) == CMsvcSite::eLib) {
00701                 continue;
00702             }
00703         }
00704         SLibInfo lib_info;
00705         GetApp().GetSite().GetLibInfo(lib_id, cfg_info, &lib_info);
00706         if ( !lib_info.m_LibDefines.empty() ) {
00707             copy(lib_info.m_LibDefines.begin(),
00708                  lib_info.m_LibDefines.end(),
00709                  back_inserter(defines));
00710         }
00711     }
00712     defines.sort();
00713     defines.unique();
00714     return defines;
00715 }
00716 
00717 
00718 
00719 //-----------------------------------------------------------------------------
00720 CMsvcPrjGeneralContext::CMsvcPrjGeneralContext
00721     (const SConfigInfo&            config, 
00722      const CMsvcPrjProjectContext& prj_context)
00723      :m_Config          (config),
00724       m_MsvcMetaMakefile(GetApp().GetMetaMakefile())
00725 {
00726     //m_Type
00727     switch ( prj_context.ProjectType() ) {
00728     case CProjKey::eLib:
00729         m_Type = eLib;
00730         break;
00731     case CProjKey::eApp:
00732         m_Type = eExe;
00733         break;
00734     case CProjKey::eDll:
00735         m_Type = eDll;
00736         break;
00737     default:
00738         //TODO - handle Dll(s)
00739         NCBI_THROW(CProjBulderAppException, eProjectType, 
00740                         NStr::IntToString(prj_context.ProjectType()));
00741     }
00742     
00743 
00744     //m_OutputDirectory;
00745     // /compilers/msvc7_prj/
00746     string output_dir_abs = GetApp().GetProjectTreeInfo().m_Compilers;
00747     output_dir_abs = 
00748             CDirEntry::ConcatPath(output_dir_abs, 
00749                                   GetApp().GetRegSettings().m_CompilersSubdir);
00750     output_dir_abs = 
00751             CDirEntry::ConcatPath(output_dir_abs, 
00752                                   GetApp().GetBuildType().GetTypeStr());
00753     if (m_Type == eLib)
00754         output_dir_abs = CDirEntry::ConcatPath(output_dir_abs, "lib");
00755     else if (m_Type == eExe)
00756         output_dir_abs = CDirEntry::ConcatPath(output_dir_abs, "bin");
00757     else if (m_Type == eDll) // same dir as exe 
00758         output_dir_abs = CDirEntry::ConcatPath(output_dir_abs, "bin"); 
00759     else {
00760         //TODO - handle Dll(s)
00761         NCBI_THROW(CProjBulderAppException, 
00762                    eProjectType, NStr::IntToString(m_Type));
00763     }
00764 
00765     output_dir_abs = 
00766         CDirEntry::ConcatPath(output_dir_abs, CMsvc7RegSettings::GetConfigNameKeyword());
00767     m_OutputDirectory = 
00768         CDirEntry::CreateRelativePath(prj_context.ProjectDir(), 
00769                                       output_dir_abs);
00770 
00771 #if 0
00772 
00773     const string project_tag(string(1,CDirEntry::GetPathSeparator()) + 
00774                              "compilers" +
00775                              CDirEntry::GetPathSeparator() + 
00776                              GetApp().GetRegSettings().m_CompilersSubdir +
00777                              CDirEntry::GetPathSeparator());
00778     
00779     string project_dir = prj_context.ProjectDir();
00780     string output_dir_prefix = 
00781         string (project_dir, 
00782                 0, 
00783                 project_dir.find(project_tag) + project_tag.length());
00784     
00785     output_dir_prefix = 
00786         CDirEntry::ConcatPath(output_dir_prefix, 
00787                               GetApp().GetBuildType().GetTypeStr());
00788 
00789     if (m_Type == eLib)
00790         output_dir_prefix = CDirEntry::ConcatPath(output_dir_prefix, "lib");
00791     else if (m_Type == eExe)
00792         output_dir_prefix = CDirEntry::ConcatPath(output_dir_prefix, "bin");
00793     else if (m_Type == eDll) // same dir as exe 
00794         output_dir_prefix = CDirEntry::ConcatPath(output_dir_prefix, "bin"); 
00795     else {
00796         //TODO - handle Dll(s)
00797         NCBI_THROW(CProjBulderAppException, 
00798                    eProjectType, NStr::IntToString(m_Type));
00799     }
00800 
00801     //output to ..static\DebugDLL or ..dll\DebugDLL
00802     string output_dir_abs = 
00803         CDirEntry::ConcatPath(output_dir_prefix, config.GetConfigFullName());
00804     m_OutputDirectory = 
00805         CDirEntry::CreateRelativePath(project_dir, output_dir_abs);
00806 #endif
00807 }
00808 
00809 //------------------------------------------------------------------------------
00810 static IConfiguration* s_CreateConfiguration
00811     (const CMsvcPrjGeneralContext& general_context,
00812      const CMsvcPrjProjectContext& project_context);
00813 
00814 static ICompilerTool* s_CreateCompilerTool
00815     (const CMsvcPrjGeneralContext& general_context,
00816      const CMsvcPrjProjectContext& project_context);
00817 
00818 static ILinkerTool* s_CreateLinkerTool
00819     (const CMsvcPrjGeneralContext& general_context,
00820      const CMsvcPrjProjectContext& project_context);
00821 
00822 static ILibrarianTool* s_CreateLibrarianTool
00823     (const CMsvcPrjGeneralContext& general_context,
00824      const CMsvcPrjProjectContext& project_context);
00825 
00826 static IResourceCompilerTool* s_CreateResourceCompilerTool
00827     (const CMsvcPrjGeneralContext& general_context,
00828      const CMsvcPrjProjectContext& project_context);
00829 
00830 //-----------------------------------------------------------------------------
00831 CMsvcTools::CMsvcTools(const CMsvcPrjGeneralContext& general_context,
00832                        const CMsvcPrjProjectContext& project_context)
00833 {
00834     //configuration
00835     m_Configuration.reset
00836         (s_CreateConfiguration(general_context, project_context));
00837     //compiler
00838     m_Compiler.reset
00839         (s_CreateCompilerTool(general_context, project_context));
00840     //Linker:
00841     m_Linker.reset(s_CreateLinkerTool(general_context, project_context));
00842     //Librarian
00843     m_Librarian.reset(s_CreateLibrarianTool
00844                                      (general_context, project_context));
00845     //Dummies
00846     m_CustomBuid.reset    (new CCustomBuildToolDummyImpl());
00847     m_MIDL.reset          (new CMIDLToolDummyImpl());
00848     m_PostBuildEvent.reset(new CPostBuildEventToolDummyImpl());
00849 
00850     //Pre-build event - special case for LIB projects
00851     if (project_context.ProjectType() == CProjKey::eLib) {
00852         m_PreBuildEvent.reset(new CPreBuildEventToolLibImpl
00853                                                 (project_context.PreBuilds(),
00854                                                  project_context.GetMakeType()));
00855     } else {
00856         m_PreBuildEvent.reset(new CPreBuildEventTool(project_context.PreBuilds(),
00857                                                      project_context.GetMakeType()));
00858     }
00859     m_PreLinkEvent.reset(new CPreLinkEventToolDummyImpl());
00860 
00861     //Resource Compiler
00862     m_ResourceCompiler.reset(s_CreateResourceCompilerTool
00863                                      (general_context,project_context));
00864 
00865     //Dummies
00866     m_WebServiceProxyGenerator.reset
00867         (new CWebServiceProxyGeneratorToolDummyImpl());
00868 
00869     m_XMLDataGenerator.reset
00870         (new CXMLDataGeneratorToolDummyImpl());
00871 
00872     m_ManagedWrapperGenerator.reset
00873         (new CManagedWrapperGeneratorToolDummyImpl());
00874 
00875     m_AuxiliaryManagedWrapperGenerator.reset
00876         (new CAuxiliaryManagedWrapperGeneratorToolDummyImpl());
00877 }
00878 
00879 
00880 IConfiguration* CMsvcTools::Configuration(void) const
00881 {
00882     return m_Configuration.get();
00883 }
00884 
00885 
00886 ICompilerTool* CMsvcTools::Compiler(void) const
00887 {
00888     return m_Compiler.get();
00889 }
00890 
00891 
00892 ILinkerTool* CMsvcTools::Linker(void) const
00893 {
00894     return m_Linker.get();
00895 }
00896 
00897 
00898 ILibrarianTool* CMsvcTools::Librarian(void) const
00899 {
00900     return m_Librarian.get();
00901 }
00902 
00903 
00904 ICustomBuildTool* CMsvcTools::CustomBuid(void) const
00905 {
00906     return m_CustomBuid.get();
00907 }
00908 
00909 
00910 IMIDLTool* CMsvcTools::MIDL(void) const
00911 {
00912     return m_MIDL.get();
00913 }
00914 
00915 
00916 IPostBuildEventTool* CMsvcTools::PostBuildEvent(void) const
00917 {
00918     return m_PostBuildEvent.get();
00919 }
00920 
00921 
00922 IPreBuildEventTool* CMsvcTools::PreBuildEvent(void) const
00923 {
00924     return m_PreBuildEvent.get();
00925 }
00926 
00927 
00928 IPreLinkEventTool* CMsvcTools::PreLinkEvent(void) const
00929 {
00930     return m_PreLinkEvent.get();
00931 }
00932 
00933 
00934 IResourceCompilerTool* CMsvcTools::ResourceCompiler(void) const
00935 {
00936     return m_ResourceCompiler.get();
00937 }
00938 
00939 
00940 IWebServiceProxyGeneratorTool* CMsvcTools::WebServiceProxyGenerator(void) const
00941 {
00942     return m_WebServiceProxyGenerator.get();
00943 }
00944 
00945 
00946 IXMLDataGeneratorTool* CMsvcTools::XMLDataGenerator(void) const
00947 {
00948     return m_XMLDataGenerator.get();
00949 }
00950 
00951 
00952 IManagedWrapperGeneratorTool* CMsvcTools::ManagedWrapperGenerator(void) const
00953 {
00954     return m_ManagedWrapperGenerator.get();
00955 }
00956 
00957 
00958 IAuxiliaryManagedWrapperGeneratorTool* 
00959                        CMsvcTools::AuxiliaryManagedWrapperGenerator(void) const
00960 {
00961     return m_AuxiliaryManagedWrapperGenerator.get();
00962 }
00963 
00964 
00965 CMsvcTools::~CMsvcTools()
00966 {
00967 }
00968 
00969 
00970 static bool s_IsExe(const CMsvcPrjGeneralContext& general_context,
00971                     const CMsvcPrjProjectContext& project_context)
00972 {
00973     return general_context.m_Type == CMsvcPrjGeneralContext::eExe;
00974 }
00975 
00976 
00977 static bool s_IsLib(const CMsvcPrjGeneralContext& general_context,
00978                     const CMsvcPrjProjectContext& project_context)
00979 {
00980     return general_context.m_Type == CMsvcPrjGeneralContext::eLib;
00981 }
00982 
00983 
00984 static bool s_IsDll(const CMsvcPrjGeneralContext& general_context,
00985                     const CMsvcPrjProjectContext& project_context)
00986 {
00987     return general_context.m_Type == CMsvcPrjGeneralContext::eDll;
00988 }
00989 
00990 
00991 static bool s_IsDebug(const CMsvcPrjGeneralContext& general_context,
00992                       const CMsvcPrjProjectContext& project_context)
00993 {
00994     return general_context.m_Config.m_Debug;
00995 }
00996 
00997 
00998 static bool s_IsRelease(const CMsvcPrjGeneralContext& general_context,
00999                         const CMsvcPrjProjectContext& project_context)
01000 {
01001     return !(general_context.m_Config.m_Debug);
01002 }
01003 
01004 
01005 //-----------------------------------------------------------------------------
01006 // Creators:
01007 static IConfiguration* 
01008 s_CreateConfiguration(const CMsvcPrjGeneralContext& general_context,
01009                       const CMsvcPrjProjectContext& project_context)
01010 {
01011     if ( s_IsExe(general_context, project_context) )
01012         return new CConfigurationImpl<SApp>
01013                        (general_context.OutputDirectory(), 
01014                         general_context.ConfigurationName());
01015 
01016     if ( s_IsLib(general_context, project_context) )
01017         return new CConfigurationImpl<SLib>
01018                         (general_context.OutputDirectory(), 
01019                          general_context.ConfigurationName());
01020 
01021     if ( s_IsDll(general_context, project_context) )
01022         return new CConfigurationImpl<SDll>
01023                         (general_context.OutputDirectory(), 
01024                          general_context.ConfigurationName());
01025     return NULL;
01026 }
01027 
01028 
01029 static ICompilerTool* 
01030 s_CreateCompilerTool(const CMsvcPrjGeneralContext& general_context,
01031                      const CMsvcPrjProjectContext& project_context)
01032 {
01033     return new CCompilerToolImpl
01034        (project_context.AdditionalIncludeDirectories(general_context.m_Config),
01035         project_context.GetMsvcProjectMakefile(),
01036         general_context.m_Config.m_RuntimeLibrary,
01037         general_context.GetMsvcMetaMakefile(),
01038         general_context.m_Config,
01039         general_context.m_Type,
01040         project_context.Defines(general_context.m_Config),
01041         project_context.ProjectId());
01042 }
01043 
01044 
01045 static ILinkerTool* 
01046 s_CreateLinkerTool(const CMsvcPrjGeneralContext& general_context,
01047                    const CMsvcPrjProjectContext& project_context)
01048 {
01049     //---- EXE ----
01050     if ( s_IsExe  (general_context, project_context) )
01051         return new CLinkerToolImpl<SApp>
01052                        (project_context.AdditionalLinkerOptions
01053                                             (general_context.m_Config),
01054                         project_context.AdditionalLibraryDirectories
01055                                             (general_context.m_Config),
01056                         project_context.ProjectId(),
01057                         project_context.GetMsvcProjectMakefile(),
01058                         general_context.GetMsvcMetaMakefile(),
01059                         general_context.m_Config);
01060 
01061 
01062     //---- LIB ----
01063     if ( s_IsLib(general_context, project_context) )
01064         return new CLinkerToolDummyImpl();
01065 
01066     //---- DLL ----
01067     if ( s_IsDll  (general_context, project_context) )
01068         return new CLinkerToolImpl<SDll>
01069                        (project_context.AdditionalLinkerOptions
01070                                             (general_context.m_Config),
01071                         project_context.AdditionalLibraryDirectories
01072                                             (general_context.m_Config),
01073                         project_context.ProjectId(),
01074                         project_context.GetMsvcProjectMakefile(),
01075                         general_context.GetMsvcMetaMakefile(),
01076                         general_context.m_Config);
01077 
01078     // unsupported tool
01079     return NULL;
01080 }
01081 
01082 
01083 static ILibrarianTool* 
01084 s_CreateLibrarianTool(const CMsvcPrjGeneralContext& general_context,
01085                       const CMsvcPrjProjectContext& project_context)
01086 {
01087     if ( s_IsLib  (general_context, project_context) )
01088         return new CLibrarianToolImpl
01089                                 (project_context.ProjectId(),
01090                                  project_context.GetMsvcProjectMakefile(),
01091                                  general_context.GetMsvcMetaMakefile(),
01092                                  general_context.m_Config);
01093 
01094     // dummy tool
01095     return new CLibrarianToolDummyImpl();
01096 }
01097 
01098 
01099 static IResourceCompilerTool* s_CreateResourceCompilerTool
01100                                 (const CMsvcPrjGeneralContext& general_context,
01101                                  const CMsvcPrjProjectContext& project_context)
01102 {
01103 
01104     if ( s_IsDll  (general_context, project_context)  &&
01105          s_IsDebug(general_context, project_context) )
01106         return new CResourceCompilerToolImpl<SDebug>
01107        (project_context.AdditionalIncludeDirectories(general_context.m_Config),
01108         project_context.GetMsvcProjectMakefile(),
01109         general_context.GetMsvcMetaMakefile(),
01110         general_context.m_Config);
01111 
01112     if ( s_IsDll    (general_context, project_context)  &&
01113          s_IsRelease(general_context, project_context) )
01114         return new CResourceCompilerToolImpl<SRelease>
01115        (project_context.AdditionalIncludeDirectories(general_context.m_Config),
01116         project_context.GetMsvcProjectMakefile(),
01117         general_context.GetMsvcMetaMakefile(),
01118         general_context.m_Config);
01119 
01120     if ( s_IsExe  (general_context, project_context)  &&
01121          s_IsDebug(general_context, project_context) )
01122         return new CResourceCompilerToolImpl<SDebug>
01123        (project_context.AdditionalIncludeDirectories(general_context.m_Config),
01124         project_context.GetMsvcProjectMakefile(),
01125         general_context.GetMsvcMetaMakefile(),
01126         general_context.m_Config);
01127 
01128 
01129     if ( s_IsExe    (general_context, project_context)  &&
01130          s_IsRelease(general_context, project_context) )
01131         return new CResourceCompilerToolImpl<SRelease>
01132        (project_context.AdditionalIncludeDirectories(general_context.m_Config),
01133         project_context.GetMsvcProjectMakefile(),
01134         general_context.GetMsvcMetaMakefile(),
01135         general_context.m_Config);
01136 
01137 
01138     // dummy tool
01139     return new CResourceCompilerToolDummyImpl();
01140 }
01141 
01142 
01143 END_NCBI_SCOPE
01144 
01145 

Generated on Wed Dec 9 04:13:01 2009 for NCBI C++ ToolKit by  doxygen 1.4.6
Modified on Wed Dec 09 08:17:54 2009 by modify_doxy.py rev. 173732