|
NCBI C++ ToolKit
|
00001 /* $Id: proj_builder_app.cpp 54358 2012-05-10 13:36:48Z 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 "proj_builder_app.hpp" 00032 #include "proj_item.hpp" 00033 #include "proj_tree_builder.hpp" 00034 #include "msvc_prj_utils.hpp" 00035 #include "msvc_prj_generator.hpp" 00036 #include "mac_prj_generator.hpp" 00037 #include "msvc_sln_generator.hpp" 00038 #include "msvc_masterproject_generator.hpp" 00039 #include "proj_utils.hpp" 00040 #include "msvc_configure.hpp" 00041 #include "msvc_prj_defines.hpp" 00042 #include "msvc_configure_prj_generator.hpp" 00043 #include "proj_projects.hpp" 00044 #include "configurable_file.hpp" 00045 #include "ptb_err_codes.hpp" 00046 #include <corelib/ncbitime.hpp> 00047 #include <corelib/expr.hpp> 00048 00049 #include <common/test_assert.h> /* This header must go last */ 00050 00051 00052 BEGIN_NCBI_SCOPE 00053 00054 00055 ///////////////////////////////////////////////////////////////////////////// 00056 /// 00057 /// Windows-specific command-line logger 00058 /// This is used to format error output in such a way that the Windows error 00059 /// logger can pick this up 00060 00061 class CWindowsCmdErrorHandler : public CDiagHandler 00062 { 00063 public: 00064 00065 CWindowsCmdErrorHandler() 00066 { 00067 m_OrigHandler.reset(GetDiagHandler(true)); 00068 CNcbiApplication* app = CNcbiApplication::Instance(); 00069 if (app) { 00070 m_AppName = app->GetProgramDisplayName(); 00071 } else { 00072 m_AppName = "unknown_app"; 00073 } 00074 } 00075 00076 ~CWindowsCmdErrorHandler() 00077 { 00078 } 00079 00080 /// post a message 00081 void Post(const SDiagMessage& msg) 00082 { 00083 if (m_OrigHandler.get()) { 00084 m_OrigHandler->Post(msg); 00085 } 00086 00087 CTempString str(msg.m_Buffer, msg.m_BufferLen); 00088 if (!msg.m_Buffer) { 00089 str.assign(kEmptyStr.c_str(),0); 00090 } 00091 00092 /// screen for error message level data only 00093 /// MSVC doesn't handle the other parts 00094 switch (msg.m_Severity) { 00095 case eDiag_Error: 00096 case eDiag_Critical: 00097 case eDiag_Fatal: 00098 case eDiag_Warning: 00099 break; 00100 00101 case eDiag_Info: 00102 case eDiag_Trace: 00103 if (msg.m_ErrCode == ePTB_NoError) { 00104 /// simple pass-through to stderr 00105 if (strlen(msg.m_File) != 0) { 00106 cerr << msg.m_File << ": "; 00107 } 00108 cerr << str << endl; 00109 return; 00110 } 00111 break; 00112 } 00113 00114 /// REQUIRED: origin 00115 if (strlen(msg.m_File) == 0) { 00116 cerr << m_AppName; 00117 } else { 00118 cerr << msg.m_File; 00119 } 00120 if (msg.m_Line) { 00121 cerr << "(" << msg.m_Line << ")"; 00122 } 00123 cerr << ": "; 00124 00125 /// OPTIONAL: subcategory 00126 //cerr << m_AppName << " "; 00127 00128 /// REQUIRED: category 00129 /// the MSVC system understands only 'error' and 'warning' 00130 switch (msg.m_Severity) { 00131 case eDiag_Error: 00132 case eDiag_Critical: 00133 case eDiag_Fatal: 00134 cerr << "error "; 00135 break; 00136 00137 case eDiag_Warning: 00138 cerr << "warning "; 00139 break; 00140 00141 case eDiag_Info: 00142 case eDiag_Trace: 00143 /// FIXME: find out how to get this in the messages tab 00144 cerr << "info "; 00145 break; 00146 } 00147 00148 /// REQUIRED: error code 00149 cerr << msg.m_ErrCode << ": "; 00150 00151 /// OPTIONAL: text 00152 cerr << str << endl; 00153 } 00154 00155 private: 00156 auto_ptr<CDiagHandler> m_OrigHandler; 00157 00158 /// the original diagnostics handler 00159 string m_AppName; 00160 00161 }; 00162 00163 ///////////////////////////////////////////////////////////////////////////// 00164 00165 00166 // When defined, this environment variable 00167 // instructs PTB to exclude CONFIGURE, INDEX, and HIERARCHICAL VIEW 00168 // projects 00169 const char* s_ptb_skipconfig = "__PTB__SKIP__CONFIG__"; 00170 00171 #ifdef COMBINED_EXCLUDE 00172 struct PIsExcludedByProjectMakefile 00173 { 00174 typedef CProjectItemsTree::TProjects::value_type TValueType; 00175 bool operator() (const TValueType& item) const 00176 { 00177 const CProjItem& project = item.second; 00178 CMsvcPrjProjectContext prj_context(project); 00179 const list<string> implicit_exclude_dirs = 00180 GetApp().GetProjectTreeInfo().m_ImplicitExcludedAbsDirs; 00181 ITERATE(list<string>, p, implicit_exclude_dirs) { 00182 const string& dir = *p; 00183 if ( IsSubdir(dir, project.m_SourcesBaseDir) ) { 00184 // implicitly excluded from build 00185 return prj_context.GetMsvcProjectMakefile().IsExcludeProject 00186 (true); 00187 } 00188 } 00189 // implicitly included to build 00190 return prj_context.GetMsvcProjectMakefile().IsExcludeProject(false); 00191 } 00192 }; 00193 00194 00195 struct PIsExcludedMakefileIn 00196 { 00197 typedef CProjectItemsTree::TProjects::value_type TValueType; 00198 00199 PIsExcludedMakefileIn(const string& root_src_dir) 00200 :m_RootSrcDir(CDirEntry::NormalizePath(root_src_dir)) 00201 { 00202 ProcessDir(root_src_dir); 00203 } 00204 00205 bool operator() (const TValueType& item) const 00206 { 00207 const CProjItem& project = item.second; 00208 00209 const list<string> implicit_exclude_dirs = 00210 GetApp().GetProjectTreeInfo().m_ImplicitExcludedAbsDirs; 00211 ITERATE(list<string>, p, implicit_exclude_dirs) { 00212 const string& dir = *p; 00213 if ( IsSubdir(dir, project.m_SourcesBaseDir) ) { 00214 // implicitly excluded from build 00215 return !IsExcplicitlyIncluded(project.m_SourcesBaseDir); 00216 } 00217 } 00218 return false; 00219 } 00220 00221 private: 00222 string m_RootSrcDir; 00223 00224 typedef map<string, AutoPtr<CPtbRegistry> > TMakefiles; 00225 TMakefiles m_Makefiles; 00226 00227 void ProcessDir(const string& dir_name) 00228 { 00229 CDir dir(dir_name); 00230 CDir::TEntries contents = dir.GetEntries("*"); 00231 ITERATE(CDir::TEntries, i, contents) { 00232 string name = (*i)->GetName(); 00233 if ( name == "." || name == ".." || 00234 name == string(1,CDir::GetPathSeparator()) ) { 00235 continue; 00236 } 00237 string path = (*i)->GetPath(); 00238 00239 if ( (*i)->IsFile() && 00240 name == "Makefile.in.msvc" ) { 00241 m_Makefiles[path] = 00242 AutoPtr<CPtbRegistry> 00243 (new CPtbRegistry(CNcbiIfstream(path.c_str(), 00244 IOS_BASE::in | IOS_BASE::binary))); 00245 } 00246 else if ( (*i)->IsDir() ) { 00247 00248 ProcessDir(path); 00249 } 00250 } 00251 } 00252 00253 bool IsExcplicitlyIncluded(const string& project_base_dir) const 00254 { 00255 string dir = project_base_dir; 00256 for(;;) { 00257 00258 if (dir == m_RootSrcDir) 00259 return false; 00260 string path = CDirEntry::ConcatPath(dir, "Makefile.in.msvc"); 00261 TMakefiles::const_iterator p = 00262 m_Makefiles.find(path); 00263 if ( p != m_Makefiles.end() ) { 00264 string val = 00265 (p->second)->GetString("Common", "ExcludeProject"); 00266 if (val == "FALSE") 00267 return true; 00268 } 00269 00270 dir = CDirEntry::ConcatPath(dir, ".."); 00271 dir = CDirEntry::NormalizePath(dir); 00272 } 00273 00274 return false; 00275 } 00276 }; 00277 00278 00279 template <class T1, class T2, class V> class CCombine 00280 { 00281 public: 00282 CCombine(const T1& t1, const T2& t2) 00283 :m_T1(t1), m_T2(t2) 00284 { 00285 } 00286 bool operator() (const V& v) const 00287 { 00288 return m_T1(v) && m_T2(v); 00289 } 00290 private: 00291 const T1 m_T1; 00292 const T2 m_T2; 00293 }; 00294 #else 00295 // not def COMBINED_EXCLUDE 00296 struct PIsExcludedByProjectMakefile 00297 { 00298 typedef CProjectItemsTree::TProjects::value_type TValueType; 00299 bool operator() (const TValueType& item) const 00300 { 00301 const CProjItem& project = item.second; 00302 CMsvcPrjProjectContext prj_context(project); 00303 const list<string> implicit_exclude_dirs = 00304 GetApp().GetProjectTreeInfo().m_ImplicitExcludedAbsDirs; 00305 ITERATE(list<string>, p, implicit_exclude_dirs) { 00306 const string& dir = *p; 00307 if ( IsSubdir(dir, project.m_SourcesBaseDir) ) { 00308 // implicitly excluded from build 00309 if (prj_context.GetMsvcProjectMakefile().IsExcludeProject(true)) { 00310 LOG_POST(Warning << "Excluded: project " << project.m_Name 00311 << " by ProjectTree/ImplicitExclude"); 00312 return true; 00313 } 00314 return false; 00315 } 00316 } 00317 // implicitly included into build 00318 if (prj_context.GetMsvcProjectMakefile().IsExcludeProject(false)) { 00319 LOG_POST(Warning << "Excluded: project " << project.m_Name 00320 << " by Makefile." << project.m_Name << ".*." 00321 << GetApp().GetRegSettings().m_MakefilesExt); 00322 return true; 00323 } 00324 return false; 00325 } 00326 }; 00327 00328 #endif 00329 00330 struct PIsExcludedByTag 00331 { 00332 typedef CProjectItemsTree::TProjects::value_type TValueType; 00333 bool operator() (const TValueType& item) const 00334 { 00335 const CProjItem& project = item.second; 00336 string unmet; 00337 if ( project.m_ProjType != CProjKey::eDataSpec && 00338 !GetApp().IsAllowedProjectTag(project) ) { 00339 string unmet( NStr::Join(project.m_ProjTags,",")); 00340 PTB_WARNING_EX(project.GetPath(), ePTB_ProjectExcluded, 00341 "Excluded due to proj_tag; this project tags: " << unmet); 00342 return true; 00343 } 00344 return false; 00345 } 00346 }; 00347 00348 struct PIsExcludedByUser 00349 { 00350 typedef CProjectItemsTree::TProjects::value_type TValueType; 00351 bool operator() (const TValueType& item) const 00352 { 00353 const CProjItem& project = item.second; 00354 if (project.m_ProjType != CProjKey::eDll && 00355 project.m_ProjType != CProjKey::eDataSpec && 00356 !GetApp().m_CustomConfiguration.DoesValueContain( 00357 "__AllowedProjects", 00358 CreateProjectName(CProjKey(project.m_ProjType, project.m_ID)), true)) { 00359 PTB_WARNING_EX(project.GetPath(), ePTB_ProjectExcluded, 00360 "Excluded by user request"); 00361 return true; 00362 } 00363 return false; 00364 00365 } 00366 }; 00367 00368 struct PIsExcludedByRequires 00369 { 00370 typedef CProjectItemsTree::TProjects::value_type TValueType; 00371 bool operator() (const TValueType& item) const 00372 { 00373 string unmet; 00374 const CProjItem& project = item.second; 00375 if ( !CMsvcPrjProjectContext::IsRequiresOk(project, &unmet) ) { 00376 PTB_WARNING_EX(project.GetPath(), ePTB_ProjectExcluded, 00377 "Excluded due to unmet requirement: " 00378 << unmet); 00379 return true; 00380 } 00381 return false; 00382 00383 } 00384 }; 00385 00386 struct PIsExcludedByDisuse 00387 { 00388 typedef CProjectItemsTree::TProjects::value_type TValueType; 00389 bool operator() (const TValueType& item) const 00390 { 00391 const CProjItem& project = item.second; 00392 if (project.m_External) { 00393 PTB_WARNING_EX(project.GetPath(), ePTB_ProjectExcluded, 00394 "Excluded unused external"); 00395 return true; 00396 } 00397 return false; 00398 } 00399 }; 00400 00401 00402 //----------------------------------------------------------------------------- 00403 CProjBulderApp::CProjBulderApp(void) 00404 { 00405 SetVersion( CVersionInfo(3,7,4) ); 00406 m_ScanningWholeTree = false; 00407 m_Dll = false; 00408 m_AddMissingLibs = false; 00409 m_ScanWholeTree = true; 00410 m_TweakVTuneR = false; 00411 m_TweakVTuneD = false; 00412 m_AddUnicode = false; 00413 m_CurrentBuildTree = 0; 00414 m_IncompleteBuildTree = 0; 00415 m_ProjTagCmnd = false; 00416 m_ConfirmCfg = false; 00417 m_AllDllBuild = false; 00418 m_InteractiveCfg = false; 00419 m_Dtdep = false; 00420 m_Ide = 0; 00421 m_ExitCode = 0; 00422 } 00423 00424 00425 void CProjBulderApp::Init(void) 00426 { 00427 string logfile = GetLogFile(); 00428 if (CDirEntry(logfile).Exists()) { 00429 RegisterGeneratedFile(CDirEntry::NormalizePath(logfile)); 00430 } 00431 if (CMsvc7RegSettings::GetMsvcPlatform() < CMsvc7RegSettings::eUnix) { 00432 if (logfile != "STDERR") { 00433 SetDiagHandler(new CWindowsCmdErrorHandler); 00434 } 00435 } 00436 // Create command-line argument descriptions class 00437 auto_ptr<CArgDescriptions> arg_desc(new CArgDescriptions); 00438 00439 // Specify USAGE context 00440 string context; 00441 if (CMsvc7RegSettings::GetMsvcPlatform() < CMsvc7RegSettings::eUnix) { 00442 context = "MSVC "; 00443 /* 00444 context += CMsvc7RegSettings::GetProjectFileFormatVersion() + 00445 " (" + CMsvc7RegSettings::GetMsvcPlatformName() + ")"; 00446 */ 00447 } else if (CMsvc7RegSettings::GetMsvcPlatform() > CMsvc7RegSettings::eUnix) { 00448 context = "XCODE "; 00449 /* 00450 context += CMsvc7RegSettings::GetMsvcVersionName() + 00451 " (" + CMsvc7RegSettings::GetMsvcPlatformName() + ")"; 00452 */ 00453 } else { 00454 context = CMsvc7RegSettings::GetMsvcPlatformName(); 00455 } 00456 context += " projects tree builder application"; 00457 arg_desc->SetUsageContext(GetArguments().GetProgramBasename(),context); 00458 00459 // Programm arguments: 00460 00461 arg_desc->AddPositional("root", 00462 "Root directory of the build tree. "\ 00463 "This directory ends with \"c++\".", 00464 CArgDescriptions::eString); 00465 00466 arg_desc->AddPositional("subtree", 00467 "Subtree, or a file with a list of subtrees to build."\ 00468 " Examples: src/corelib/ scripts/projects/ncbi_cpp.lst", 00469 CArgDescriptions::eString); 00470 00471 arg_desc->AddPositional("solution", 00472 "MSVC Solution to build.", 00473 CArgDescriptions::eString); 00474 00475 arg_desc->AddFlag ("dll", 00476 "Dll(s) will be built instead of static libraries.", 00477 true); 00478 00479 arg_desc->AddFlag ("nobuildptb", 00480 "Exclude \"build PTB\" step from CONFIGURE project."); 00481 00482 arg_desc->AddFlag ("ext", 00483 "Use external libraries instead of missing in-tree ones."); 00484 arg_desc->AddFlag ("nws", 00485 "Do not scan the whole source tree for missing projects."); 00486 arg_desc->AddOptionalKey("extroot", "external_build_root", 00487 "Subtree in which to look for external libraries.", 00488 CArgDescriptions::eString); 00489 00490 arg_desc->AddOptionalKey("projtag", "project_tag", 00491 "Expression. Include only projects that match."\ 00492 " Example: \"core && (test || !demo)\"", 00493 CArgDescriptions::eString); 00494 00495 #if defined(NCBI_XCODE_BUILD) || defined(PSEUDO_XCODE) 00496 arg_desc->AddOptionalKey("ide", "xcode_version", 00497 "Target version of Xcode, for example: 30", 00498 CArgDescriptions::eInteger); 00499 arg_desc->AddOptionalKey("arch", "architecture", 00500 "Target architecture, for example: ppc, i386", 00501 CArgDescriptions::eString); 00502 #elif defined(NCBI_COMPILER_MSVC) 00503 arg_desc->AddOptionalKey("ide", "msvc_version", 00504 "Target version of MS Visual Studio, for example: 800, 900, 1000", 00505 CArgDescriptions::eInteger); 00506 arg_desc->AddOptionalKey("arch", "platform", 00507 "Target platform, for example: Win32, x64", 00508 CArgDescriptions::eString); 00509 #endif 00510 00511 arg_desc->AddFlag ("cfg", 00512 "Show GUI to confirm configuration parameters (MS Windows only)."); 00513 arg_desc->AddFlag ("i", 00514 "Run interactively. Can only be used by PTB GUI shell!"); 00515 arg_desc->AddFlag ("dtdep", 00516 "Add dependency on datatool where needed."); 00517 00518 arg_desc->AddOptionalKey("args", "args_file", 00519 "Read arguments from a file", 00520 CArgDescriptions::eString); 00521 00522 // Setup arg.descriptions for this application 00523 SetupArgDescriptions(arg_desc.release()); 00524 } 00525 00526 00527 static 00528 void s_ReportDependenciesStatus(const CCyclicDepends::TDependsCycles& cycles, 00529 CProjectItemsTree::TProjects& tree) 00530 { 00531 bool reported = false; 00532 ITERATE(CCyclicDepends::TDependsCycles, p, cycles) { 00533 const CCyclicDepends::TDependsChain& cycle = *p; 00534 bool real_cycle = false; 00535 string host0, host; 00536 ITERATE(CCyclicDepends::TDependsChain, m, cycle) { 00537 host = tree[*m].m_DllHost; 00538 if (m == cycle.begin()) { 00539 host0 = host; 00540 } else { 00541 real_cycle = (host0 != host) || (host0.empty() && host.empty()); 00542 if (real_cycle) { 00543 break; 00544 } 00545 } 00546 } 00547 if (!real_cycle) { 00548 continue; 00549 } 00550 string str_chain("Dependency cycle found: "); 00551 ITERATE(CCyclicDepends::TDependsChain, n, cycle) { 00552 const CProjKey& proj_id = *n; 00553 if (n != cycle.begin()) { 00554 str_chain += " - "; 00555 } 00556 str_chain += proj_id.Id(); 00557 } 00558 LOG_POST(Warning << str_chain); 00559 reported = true; 00560 CCyclicDepends::TDependsChain::const_iterator i = cycle.end(); 00561 const CProjKey& last = *(--i); 00562 const CProjKey& prev = *(--i); 00563 if (last.Type() == CProjKey::eLib && prev.Type() == CProjKey::eLib) { 00564 CProjectItemsTree::TProjects::const_iterator t = tree.find(prev); 00565 if (t != tree.end()) { 00566 CProjItem item = t->second; 00567 item.m_Depends.remove(last); 00568 tree[prev] = item; 00569 LOG_POST(Warning << "Removing LIB dependency: " 00570 << prev.Id() << " - " << last.Id()); 00571 } 00572 } 00573 } 00574 if (!reported) { 00575 PTB_INFO("No dependency cycles found."); 00576 } 00577 } 00578 00579 int CProjBulderApp::Run(void) 00580 { 00581 // Set error posting and tracing on maximum. 00582 // SetDiagTrace(eDT_Enable); 00583 SetDiagPostAllFlags(eDPF_All & ~eDPF_DateTime); 00584 SetDiagPostLevel(eDiag_Info); 00585 LOG_POST(Info << "Started at " + CTime(CTime::eCurrent).AsString()); 00586 LOG_POST(Info << "Project tree builder version " + GetVersion().Print()); 00587 00588 CStopWatch sw; 00589 sw.Start(); 00590 00591 // Get and check arguments 00592 ParseArguments(); 00593 LOG_POST(Info << "Project tags filter: " + m_ProjTags); 00594 if (m_InteractiveCfg && !Gui_ConfirmConfiguration()) 00595 { 00596 LOG_POST(Info << "Cancelled by request."); 00597 return 1; 00598 } 00599 else if (m_ConfirmCfg && !ConfirmConfiguration()) 00600 { 00601 LOG_POST(Info << "Cancelled by request."); 00602 return 1; 00603 } 00604 VerifyArguments(); 00605 m_CustomConfiguration.Save(m_CustomConfFile); 00606 00607 // Configure 00608 CMsvcConfigure configure; 00609 configure.Configure(const_cast<CMsvcSite&>(GetSite()), 00610 GetRegSettings().m_ConfigInfo, 00611 m_IncDir); 00612 m_AllDllBuild = GetSite().IsProvided("DLL_BUILD"); 00613 00614 // Build projects tree 00615 #ifndef _DEBUG 00616 { 00617 bool b = m_ScanWholeTree; 00618 m_ScanWholeTree = true; 00619 GetWholeTree(); 00620 m_ScanWholeTree = b; 00621 } 00622 #endif 00623 CProjectItemsTree projects_tree(GetProjectTreeInfo().m_Src); 00624 CProjectTreeBuilder::BuildProjectTree(GetProjectTreeInfo().m_IProjectFilter.get(), 00625 GetProjectTreeInfo().m_Src, 00626 &projects_tree); 00627 if (m_ExitCode != 0) { 00628 LOG_POST(Info << "Cancelled by request."); 00629 return m_ExitCode; 00630 } 00631 configure.CreateConfH(const_cast<CMsvcSite&>(GetSite()), 00632 GetRegSettings().m_ConfigInfo, 00633 m_IncDir); 00634 00635 // MSVC specific part: 00636 PTB_INFO("Checking project requirements..."); 00637 // Exclude some projects from build: 00638 #ifdef COMBINED_EXCLUDE 00639 {{ 00640 // Implicit/Exclicit exclude by msvc Makefiles.in.msvc 00641 // and project .msvc makefiles. 00642 PIsExcludedMakefileIn p_make_in(GetProjectTreeInfo().m_Src); 00643 PIsExcludedByProjectMakefile p_project_makefile; 00644 CCombine<PIsExcludedMakefileIn, 00645 PIsExcludedByProjectMakefile, 00646 CProjectItemsTree::TProjects::value_type> 00647 logical_combine(p_make_in, p_project_makefile); 00648 EraseIf(projects_tree.m_Projects, logical_combine); 00649 }} 00650 #else 00651 {{ 00652 // Implicit/Exclicit exclude by msvc Makefiles.in.msvc 00653 PIsExcludedByProjectMakefile p_project_makefile; 00654 EraseIf(projects_tree.m_Projects, p_project_makefile); 00655 }} 00656 00657 #endif 00658 {{ 00659 // Project requires are not provided 00660 EraseIf(projects_tree.m_Projects, PIsExcludedByRequires()); 00661 }} 00662 00663 CProjectItemsTree dll_projects_tree; 00664 bool dll = (GetBuildType().GetType() == CBuildType::eDll); 00665 if (dll) { 00666 PTB_INFO("Assembling DLLs..."); 00667 // AnalyzeDllData(projects_tree); 00668 CreateDllBuildTree(projects_tree, &dll_projects_tree); 00669 } 00670 CProjectItemsTree& prj_tree = dll ? dll_projects_tree : projects_tree; 00671 prj_tree.VerifyExternalDepends(); 00672 {{ 00673 // Erase obsolete external projects 00674 EraseIf(prj_tree.m_Projects, PIsExcludedByDisuse()); 00675 }} 00676 prj_tree.VerifyDataspecProj(); 00677 00678 PTB_INFO("Checking project inter-dependencies..."); 00679 CCyclicDepends::TDependsCycles cycles; 00680 CCyclicDepends::FindCyclesNew(prj_tree.m_Projects, &cycles); 00681 s_ReportDependenciesStatus(cycles,projects_tree.m_Projects); 00682 00683 if (!m_SuspiciousProj.empty()) { 00684 ITERATE( set<CProjKey>, key, m_SuspiciousProj) { 00685 if (prj_tree.m_Projects.find(*key) != prj_tree.m_Projects.end()) { 00686 PTB_ERROR(prj_tree.m_Projects.find(*key)->second.GetPath(), 00687 "More than one target with this name"); 00688 m_ExitCode = 1; 00689 } 00690 } 00691 } 00692 if (m_ExitCode != 0) { 00693 string subtree = CDirEntry::ConcatPath(m_ProjectTreeInfo->m_Root, m_Subtree); 00694 if (CDirEntry(subtree).IsFile()) { 00695 return m_ExitCode; 00696 } 00697 m_ExitCode = 0; 00698 } 00699 PTB_INFO("Creating projects..."); 00700 if (CMsvc7RegSettings::GetMsvcPlatform() < CMsvc7RegSettings::eUnix) { 00701 GenerateMsvcProjects(prj_tree); 00702 } 00703 else if (CMsvc7RegSettings::GetMsvcPlatform() == CMsvc7RegSettings::eUnix) { 00704 GenerateUnixProjects(prj_tree); 00705 } 00706 else { 00707 GenerateMacProjects(prj_tree); 00708 } 00709 ReportGeneratedFiles(); 00710 ReportProjectWatchers(); 00711 // 00712 PTB_INFO("Done. Elapsed time = " << sw.Elapsed() << " seconds"); 00713 return m_ExitCode; 00714 } 00715 00716 void CProjBulderApp::GenerateMsvcProjects(CProjectItemsTree& projects_tree) 00717 { 00718 #if NCBI_COMPILER_MSVC 00719 PTB_INFO("Generating MSBuild projects..."); 00720 00721 bool dll = (GetBuildType().GetType() == CBuildType::eDll); 00722 list<SConfigInfo> dll_configs; 00723 const list<SConfigInfo>* configurations = 0; 00724 bool skip_config = !GetEnvironment().Get(s_ptb_skipconfig).empty(); 00725 string str_config; 00726 00727 if (dll) { 00728 _TRACE("DLL build"); 00729 GetBuildConfigs(&dll_configs); 00730 configurations = &dll_configs; 00731 } else { 00732 _TRACE("Static build"); 00733 configurations = &GetRegSettings().m_ConfigInfo; 00734 } 00735 {{ 00736 ITERATE(list<SConfigInfo>, p , *configurations) { 00737 str_config += p->GetConfigFullName() + " "; 00738 } 00739 PTB_INFO("Building configurations: " << str_config); 00740 }} 00741 00742 m_CurrentBuildTree = &projects_tree; 00743 if ( m_AddMissingLibs ) { 00744 m_IncompleteBuildTree = &projects_tree; 00745 } 00746 // Projects 00747 CMsvcProjectGenerator prj_gen(*configurations); 00748 NON_CONST_ITERATE(CProjectItemsTree::TProjects, p, projects_tree.m_Projects) { 00749 prj_gen.Generate(p->second); 00750 } 00751 00752 //Utility projects dir 00753 string utility_projects_dir = GetApp().GetUtilityProjectsDir(); 00754 00755 // MasterProject 00756 CMsvcMasterProjectGenerator master_prj_gen(projects_tree, 00757 *configurations, 00758 utility_projects_dir); 00759 if (!skip_config) { 00760 master_prj_gen.SaveProject(); 00761 } 00762 00763 // ConfigureProject 00764 string output_dir = GetProjectTreeInfo().m_Compilers; 00765 output_dir = CDirEntry::ConcatPath(output_dir, 00766 GetRegSettings().m_CompilersSubdir); 00767 output_dir = CDirEntry::ConcatPath(output_dir, 00768 (m_BuildPtb && dll) ? "static" : GetBuildType().GetTypeStr()); 00769 output_dir = CDirEntry::ConcatPath(output_dir, "bin"); 00770 output_dir = CDirEntry::AddTrailingPathSeparator(output_dir); 00771 CMsvcConfigureProjectGenerator configure_generator( 00772 output_dir, 00773 *configurations, 00774 dll, 00775 utility_projects_dir, 00776 GetProjectTreeInfo().m_Root, 00777 m_Subtree, 00778 m_Solution, 00779 m_BuildPtb); 00780 if (!skip_config) { 00781 configure_generator.SaveProject(false, &prj_gen); 00782 configure_generator.SaveProject(true, &prj_gen); 00783 } 00784 00785 // INDEX dummy project 00786 string index_prj_path = CDirEntry::ConcatPath(utility_projects_dir, "_INDEX_"); 00787 index_prj_path += CMsvc7RegSettings::GetVcprojExt(); 00788 string index_prj_guid, index_prj_name; 00789 if (CMsvc7RegSettings::GetMsvcVersion() < CMsvc7RegSettings::eMsvc1000) { 00790 CVisualStudioProject xmlprj; 00791 CreateUtilityProject(" INDEX, see here: ", *configurations, &xmlprj); 00792 if (!skip_config) { 00793 SaveIfNewer(index_prj_path, xmlprj); 00794 index_prj_guid = xmlprj.GetAttlist().GetProjectGUID(); 00795 index_prj_name = xmlprj.GetAttlist().GetName(); 00796 } 00797 } 00798 00799 string utils[] = {"_DATASPEC_ALL_", "-DATASPEC-ALL-", 00800 "_LIBS_ALL_", "-LIBS-ALL-", 00801 "_BUILD_ALL_","-BUILD-ALL-"}; 00802 vector<string> utils_id; 00803 int i = 0, num_util = 3; 00804 00805 for (i = 0; i < num_util; ++i) { 00806 string prj_path = CDirEntry::ConcatPath(utility_projects_dir, utils[i*2]); 00807 prj_path += CMsvc7RegSettings::GetVcprojExt(); 00808 utils_id.push_back(prj_path); 00809 if (CMsvc7RegSettings::GetMsvcVersion() < CMsvc7RegSettings::eMsvc1000) { 00810 CVisualStudioProject xmlprj; 00811 CreateUtilityProject(utils[i*2+1], *configurations, &xmlprj); 00812 SaveIfNewer(prj_path, xmlprj); 00813 utils_id.push_back(xmlprj.GetAttlist().GetProjectGUID()); 00814 utils_id.push_back(xmlprj.GetAttlist().GetName()); 00815 } else { 00816 string prj_dir = GetApp().GetUtilityProjectsSrcDir(); 00817 CProjItem prj_item( CreateUtilityProjectItem(prj_dir, utils[i*2+1])); 00818 prj_gen.Generate(prj_item); 00819 utils_id.push_back(prj_item.m_GUID); 00820 utils_id.push_back(prj_item.m_Name); 00821 } 00822 } 00823 if (m_ProjTags == "*") { 00824 for (map<string,string>::const_iterator composite = m_CompositeProjectTags.begin(); 00825 composite != m_CompositeProjectTags.end(); ++composite) { 00826 string composite_name = "_TAG_" + composite->first; 00827 string composite_filter = composite->second; 00828 00829 00830 string prj_path = CDirEntry::ConcatPath(utility_projects_dir, composite_name); 00831 prj_path += CMsvc7RegSettings::GetVcprojExt(); 00832 utils_id.push_back(prj_path); 00833 if (CMsvc7RegSettings::GetMsvcVersion() < CMsvc7RegSettings::eMsvc1000) { 00834 CVisualStudioProject xmlprj; 00835 CreateUtilityProject(composite_name, *configurations, &xmlprj); 00836 SaveIfNewer(prj_path, xmlprj); 00837 utils_id.push_back(xmlprj.GetAttlist().GetProjectGUID()); 00838 utils_id.push_back(xmlprj.GetAttlist().GetName()); 00839 } else { 00840 string prj_dir = GetApp().GetUtilityProjectsSrcDir(); 00841 CProjItem prj_item( CreateUtilityProjectItem(prj_dir, composite_name)); 00842 prj_gen.Generate(prj_item); 00843 utils_id.push_back(prj_item.m_GUID); 00844 utils_id.push_back(prj_item.m_Name); 00845 } 00846 utils_id.push_back(composite_filter); 00847 ++num_util; 00848 } 00849 } 00850 00851 // Solution 00852 CMsvcSolutionGenerator sln_gen(*configurations); 00853 ITERATE(CProjectItemsTree::TProjects, p, projects_tree.m_Projects) { 00854 sln_gen.AddProject(p->second); 00855 } 00856 if (!skip_config) { 00857 00858 if (CMsvc7RegSettings::GetMsvcVersion() < CMsvc7RegSettings::eMsvc1000) { 00859 sln_gen.AddUtilityProject( master_prj_gen.GetPath(), 00860 master_prj_gen.GetVisualStudioProject().GetAttlist().GetProjectGUID(), 00861 master_prj_gen.GetVisualStudioProject().GetAttlist().GetName()); 00862 00863 sln_gen.AddUtilityProject( index_prj_path, index_prj_guid, index_prj_name); 00864 } 00865 00866 string cfg_path, cfg_guid, cfg_name; 00867 configure_generator.GetVisualStudioProject(cfg_path, cfg_guid, cfg_name, false); 00868 sln_gen.AddConfigureProject( cfg_path, cfg_guid, cfg_name); 00869 00870 configure_generator.GetVisualStudioProject(cfg_path, cfg_guid, cfg_name, true); 00871 sln_gen.AddConfigureProject( cfg_path, cfg_guid, cfg_name); 00872 } 00873 00874 int u = 0; 00875 for (i = 0; i < num_util; ++i) { 00876 switch (i) { 00877 case 0: 00878 sln_gen.AddAsnAllProject( utils_id[u], utils_id[u+1], utils_id[u+2]); 00879 u += 3; 00880 break; 00881 case 1: 00882 sln_gen.AddLibsAllProject( utils_id[u], utils_id[u+1], utils_id[u+2]); 00883 u += 3; 00884 break; 00885 case 2: 00886 sln_gen.AddBuildAllProject( utils_id[u], utils_id[u+1], utils_id[u+2]); 00887 u += 3; 00888 break; 00889 default: 00890 sln_gen.AddTagProject( utils_id[u], utils_id[u+1], utils_id[u+2], utils_id[u+3]); 00891 u += 4; 00892 break; 00893 } 00894 } 00895 00896 sln_gen.SaveSolution(m_Solution); 00897 00898 CreateCheckList(configurations, projects_tree); 00899 list<string> enabled, disabled; 00900 CreateFeaturesAndPackagesFiles(configurations, enabled, disabled); 00901 GenerateSummary(*configurations, enabled, disabled); 00902 #endif //NCBI_COMPILER_MSVC 00903 } 00904 00905 void CProjBulderApp::GenerateMacProjects(CProjectItemsTree& projects_tree) 00906 { 00907 #if defined(NCBI_XCODE_BUILD) || defined(PSEUDO_XCODE) 00908 PTB_INFO("Generating XCode projects..."); 00909 00910 bool dll = (GetBuildType().GetType() == CBuildType::eDll); 00911 list<SConfigInfo> dll_configs; 00912 const list<SConfigInfo>* configurations = 0; 00913 // bool skip_config = !GetEnvironment().Get(s_ptb_skipconfig).empty(); 00914 string str_config; 00915 00916 if (dll) { 00917 _TRACE("DLL build"); 00918 GetBuildConfigs(&dll_configs); 00919 configurations = &dll_configs; 00920 } else { 00921 _TRACE("Static build"); 00922 configurations = &GetRegSettings().m_ConfigInfo; 00923 } 00924 {{ 00925 ITERATE(list<SConfigInfo>, p , *configurations) { 00926 str_config += p->GetConfigFullName() + " "; 00927 } 00928 PTB_INFO("Building configurations: " << str_config); 00929 }} 00930 00931 m_CurrentBuildTree = &projects_tree; 00932 if ( m_AddMissingLibs ) { 00933 m_IncompleteBuildTree = &projects_tree; 00934 } 00935 // Projects 00936 CMacProjectGenerator prj_gen(*configurations, projects_tree); 00937 prj_gen.Generate(m_Solution); 00938 00939 CreateCheckList(configurations, projects_tree); 00940 list<string> enabled, disabled; 00941 CreateFeaturesAndPackagesFiles(configurations, enabled, disabled); 00942 GenerateSummary(*configurations, enabled, disabled); 00943 #endif 00944 } 00945 void CProjBulderApp::CollectLibToLibDependencies( 00946 CProjectItemsTree& projects_tree, 00947 set<string>& dep, set<string>& visited, 00948 CProjectItemsTree::TProjects::const_iterator& lib, 00949 CProjectItemsTree::TProjects::const_iterator& lib_dep) 00950 { 00951 string lib_name(CreateProjectName(lib->first)); 00952 string lib_dep_name(CreateProjectName(lib_dep->first)); 00953 if (m_AllDllBuild) { 00954 dep.insert(lib_dep_name); 00955 // return; 00956 } 00957 if (visited.find(lib_dep_name) != visited.end() || 00958 lib_dep_name == lib_name) { 00959 return; 00960 } 00961 visited.insert(lib_dep_name); 00962 if (!lib_dep->second.m_DatatoolSources.empty() || 00963 !lib_dep->second.m_ExportHeaders.empty() || 00964 lib->second.m_UnconditionalDepends.find(lib_dep->first) != 00965 lib->second.m_UnconditionalDepends.end()) { 00966 dep.insert(lib_dep_name); 00967 } 00968 ITERATE(list<CProjKey>, p, lib_dep->second.m_Depends) { 00969 if (p->Type() == CProjKey::eLib) { 00970 CProjectItemsTree::TProjects::const_iterator n = 00971 projects_tree.m_Projects.find(*p); 00972 if (n != projects_tree.m_Projects.end()) { 00973 CollectLibToLibDependencies(projects_tree, dep, visited, lib, n); 00974 } 00975 } 00976 } 00977 } 00978 00979 void CProjBulderApp::GenerateUnixProjects(CProjectItemsTree& projects_tree) 00980 { 00981 map< string, list< string > > path_to_target; 00982 CNcbiOfstream ofs(m_Solution.c_str(), IOS_BASE::out | IOS_BASE::trunc); 00983 if (!ofs.is_open()) { 00984 NCBI_THROW(CProjBulderAppException, eFileOpen, m_Solution); 00985 return; 00986 } 00987 GetApp().RegisterGeneratedFile( m_Solution ); 00988 ofs << "# This file was generated by PROJECT_TREE_BUILDER v" 00989 << GetVersion().Print() << endl; 00990 ofs << "# on " << CTime(CTime::eCurrent).AsString() << endl << endl; 00991 00992 // see CXX-950 00993 #if 0 00994 ofs << "# This is tricky part; it might work incorrectly on some platforms" << endl; 00995 // ofs << "MARK=$(shell date +%Y%m%d%H%M%S)" << endl; 00996 ofs << "MARK=$(if $(MARK2),,$(eval MARK2=$(shell date +%Y%m%d%H%M%S)))$(MARK2)" << endl; 00997 ofs << "MARK:sh =date +%Y%m%d%H%M%S" << endl; 00998 ofs << endl; 00999 ofs << "prefix=.ncbi.signal." << endl; 01000 ofs << "s=$(prefix)$(MARK)" << endl; 01001 ofs << "sign=rm -f $(prefix)*.$@; touch $(s).$@" << endl; 01002 ofs << endl; 01003 #endif 01004 01005 ofs << "MINPUT=" << CDirEntry(m_Solution).GetName() << endl << endl; 01006 ofs << "# Use empty MTARGET to build a project;" << endl; 01007 ofs << "# MTARGET=clean - to clean, or MTARGET=purge - to purge" << endl; 01008 ofs << "MTARGET =" << endl << endl; 01009 01010 if (m_ExtSrcRoot.empty()) { 01011 ofs << "top_srcdir=" << m_Root << endl; 01012 } else { 01013 ofs << "top_srcdir=" << m_ExtSrcRoot << endl; 01014 } 01015 ofs << "# Non-redundant flags (will be overridden for GNU Make to avoid" << endl; 01016 ofs << "# --jobserver-fds=* proliferation)" << endl; 01017 ofs << "MFLAGS_NR = $(MFLAGS)" << endl; 01018 ofs << "SKIP_PRELIMINARIES= sources= configurables=configurables.null" << endl; 01019 01020 // all dirs ----------------------------------------------------------------- 01021 list<string> all_dirs; 01022 ITERATE(CProjectItemsTree::TProjects, p, projects_tree.m_Projects) { 01023 if (p->first.Type() == CProjKey::eDataSpec) { 01024 continue; 01025 } 01026 all_dirs.push_back( 01027 CDirEntry::DeleteTrailingPathSeparator( CDirEntry::CreateRelativePath( 01028 GetProjectTreeInfo().m_Src,p->second.m_SourcesBaseDir))); 01029 } 01030 all_dirs.sort(); 01031 all_dirs.unique(); 01032 ofs << "all_dirs ="; 01033 ITERATE(list<string>, p, all_dirs) { 01034 ofs << " \\" <<endl << " " << *p; 01035 } 01036 ofs << endl << endl; 01037 01038 ofs << "include $(top_srcdir)/src/build-system/Makefile.is_gmake" << endl; 01039 ofs << "include $(top_srcdir)/src/build-system/Makefile.meta.$(is_gmake)" << endl; 01040 ofs << endl; 01041 01042 string dotreal(".real"); 01043 string dotfiles(".files"); 01044 01045 // all projects ------------------------------------------------------------- 01046 ofs << "all_projects ="; 01047 ITERATE(CProjectItemsTree::TProjects, p, projects_tree.m_Projects) { 01048 if (p->second.m_MakeType == eMakeType_Excluded || 01049 p->second.m_MakeType == eMakeType_ExcludedByReq) { 01050 LOG_POST(Info << "For reference only: " << CreateProjectName(p->first)); 01051 continue; 01052 } 01053 if (p->first.Type() == CProjKey::eDataSpec) { 01054 continue; 01055 } 01056 ofs << " \\" <<endl << " " << CreateProjectName(p->first); 01057 } 01058 ofs << endl << endl; 01059 01060 ofs << "ptb_all :" << endl 01061 << "\t$(MAKE) $(MFLAGS_NR) -f $(MINPUT) ptb_all" << dotreal 01062 << " MTARGET=$(MTARGET)"; 01063 ofs << endl << endl; 01064 ofs << "ptb_all" << dotreal << " :" << " $(all_projects:%=%" << dotreal << ")"; 01065 ofs << endl << endl; 01066 01067 // all libs ----------------------------------------------------------------- 01068 ofs << "all_libraries ="; 01069 ITERATE(CProjectItemsTree::TProjects, p, projects_tree.m_Projects) { 01070 if (p->second.m_MakeType == eMakeType_Excluded || 01071 p->second.m_MakeType == eMakeType_ExcludedByReq) { 01072 continue; 01073 } 01074 if (p->first.Type() == CProjKey::eLib || 01075 p->first.Type() == CProjKey::eDll) { 01076 ofs << " \\" <<endl << " " << CreateProjectName(p->first); 01077 } 01078 } 01079 ofs << endl << endl; 01080 01081 ofs << "all_libs :" << endl 01082 << "\t$(MAKE) $(MFLAGS_NR) -f $(MINPUT) all_libs" << dotreal 01083 << " MTARGET=$(MTARGET)"; 01084 ofs << endl << endl; 01085 ofs << "all_libs" << dotreal << " :" << " $(all_libraries:%=%" << dotreal << ")"; 01086 ofs << endl << endl; 01087 01088 // all sources -------------------------------------------------------------- 01089 ofs << "all_dataspec ="; 01090 ITERATE(CProjectItemsTree::TProjects, p, projects_tree.m_Projects) { 01091 if (p->second.m_MakeType == eMakeType_Excluded || 01092 p->second.m_MakeType == eMakeType_ExcludedByReq) { 01093 continue; 01094 } 01095 if (p->first.Type() == CProjKey::eDataSpec) { 01096 continue; 01097 } 01098 if (p->second.m_DatatoolSources.empty()) { 01099 continue; 01100 } 01101 ofs << " \\" <<endl << " " << CreateProjectName(p->first) << dotfiles; 01102 } 01103 ofs << endl << endl; 01104 01105 ofs << "all_files :" << endl 01106 << "\t$(MAKE) $(MFLAGS_NR) -f $(MINPUT) all_files" << dotreal; 01107 ofs << endl << endl; 01108 ofs << "all_files" << dotreal << " :" << " $(all_dataspec:%=%" << dotreal << ")"; 01109 ofs << endl << endl; 01110 01111 // all apps ----------------------------------------------------------------- 01112 ofs << "all_apps ="; 01113 ITERATE(CProjectItemsTree::TProjects, p, projects_tree.m_Projects) { 01114 if (p->second.m_MakeType == eMakeType_Excluded || 01115 p->second.m_MakeType == eMakeType_ExcludedByReq) { 01116 continue; 01117 } 01118 if (p->first.Type() == CProjKey::eApp) { 01119 ofs << " \\" <<endl << " " << CreateProjectName(p->first); 01120 } 01121 } 01122 ofs << endl << endl; 01123 01124 // all Unix ------------------------------------------------------------- 01125 ofs << "all_unix ="; 01126 ITERATE(CProjectItemsTree::TProjects, p, projects_tree.m_Projects) { 01127 if (p->second.m_MakeType == eMakeType_Excluded || 01128 p->second.m_MakeType == eMakeType_ExcludedByReq) { 01129 continue; 01130 } 01131 if (p->first.Type() == CProjKey::eMsvc) { 01132 ofs << " \\" <<endl << " " << CreateProjectName(p->first); 01133 } 01134 } 01135 ofs << endl << endl; 01136 01137 // all excluded ------------------------------------------------------------- 01138 ofs << "all_excluded ="; 01139 ITERATE(CProjectItemsTree::TProjects, p, projects_tree.m_Projects) { 01140 if (p->first.Type() == CProjKey::eDataSpec) { 01141 continue; 01142 } 01143 if (p->second.m_MakeType == eMakeType_Excluded || 01144 p->second.m_MakeType == eMakeType_ExcludedByReq) { 01145 ofs << " \\" <<endl << " " << CreateProjectName(p->first); 01146 } 01147 } 01148 ofs << endl << endl; 01149 01150 // CompositeProjectTags ----------------------------------------------------- 01151 // (add always) 01152 vector<string> existing_composite_names; 01153 ITERATE(set<string>, r, m_RegisteredProjectTags) { 01154 m_CompositeProjectTags[*r] = *r; 01155 } 01156 /*if (m_ProjTags == "*")*/ { 01157 for (map<string,string>::const_iterator composite = m_CompositeProjectTags.begin(); 01158 composite != m_CompositeProjectTags.end(); ++composite) { 01159 string composite_name = "TAG_" + composite->first; 01160 string composite_filter = composite->second; 01161 vector<string> matching; 01162 01163 ITERATE(CProjectItemsTree::TProjects, p, projects_tree.m_Projects) { 01164 if (p->second.m_MakeType == eMakeType_Excluded || 01165 p->second.m_MakeType == eMakeType_ExcludedByReq) { 01166 continue; 01167 } 01168 if (p->first.Type() == CProjKey::eDataSpec) { 01169 continue; 01170 } 01171 if (IsAllowedProjectTag(p->second, &composite_filter)) { 01172 matching.push_back( CreateProjectName(p->first)); 01173 } 01174 } 01175 if (!matching.empty()) { 01176 existing_composite_names.push_back(composite_name); 01177 ofs << composite_name << "_projects ="; 01178 ITERATE(vector<string>, c, matching) { 01179 ofs << " \\" <<endl << " " << *c; 01180 } 01181 ofs << endl << endl; 01182 01183 ofs << composite_name << " :" << endl 01184 << "\t$(MAKE) $(MFLAGS_NR) -f $(MINPUT) " << composite_name << dotreal 01185 << " MTARGET=$(MTARGET)"; 01186 ofs << endl << endl; 01187 ofs << composite_name << dotreal << " :" << " $(" 01188 << composite_name << "_projects" << ":%=%" << dotreal << ")"; 01189 ofs << endl << endl; 01190 01191 } 01192 } 01193 } 01194 01195 01196 // help and list targets ---------------------------------------------------- 01197 ofs << "help :" 01198 << endl << "\t@echo Build all projects" 01199 << endl << "\t@echo \" make -f $(MINPUT) -j 12 ptb_all\"" 01200 << endl << "\t@echo Build a project, for example, xncbi.lib" 01201 << endl << "\t@echo \" make -f $(MINPUT) -j 12 xncbi.lib\"" 01202 << endl << "\t@echo Clean project intermediate files" 01203 << endl << "\t@echo \" make -f $(MINPUT) -j 12 xncbi.lib MTARGET=clean\"" 01204 << endl << "\t@echo Clean project intermediate and output files" 01205 << endl << "\t@echo \" make -f $(MINPUT) -j 12 xncbi.lib MTARGET=purge\"" 01206 << endl << "\t@echo Target lists: " 01207 << endl << "\t@echo \" list-all - list all targets\"" 01208 << endl << "\t@echo \" list-apps - list all applications\"" 01209 << endl << "\t@echo \" list-libs - list all libraries\"" 01210 << endl << "\t@echo \" list-unix - list all native Unix projects\"" 01211 << endl << "\t@echo \" list-excluded - list 'excluded' targets\"" 01212 << endl << "\t@echo \" list-tags - list composite targets\"" 01213 << endl << "\t@echo \" list-tag-TagName - list all targets in a composite target TagName\""; 01214 ofs << endl << endl; 01215 01216 ofs << "list-all :" 01217 << endl << "\t@echo" 01218 << endl << "\t@echo" 01219 << endl << "\t@echo --------------------------------------" 01220 << endl << "\t@echo APPLICATIONS" 01221 << endl << "\t@echo" 01222 << endl << "\t@for i in $(all_apps); do echo $$i; done" 01223 << endl << "\t@echo" 01224 << endl << "\t@echo" 01225 << endl << "\t@echo --------------------------------------" 01226 << endl << "\t@echo LIBRARIES" 01227 << endl << "\t@echo" 01228 << endl << "\t@for i in $(all_libraries); do echo $$i; done"; 01229 01230 if (!existing_composite_names.empty()) { 01231 ofs 01232 << endl << "\t@echo" 01233 << endl << "\t@echo" 01234 << endl << "\t@echo --------------------------------------" 01235 << endl << "\t@echo COMPOSITE TARGETS" 01236 << endl << "\t@echo"; 01237 ITERATE(vector<string>, c, existing_composite_names) { 01238 ofs << endl << "\t@echo " << *c; 01239 } 01240 } 01241 ofs 01242 << endl << "\t@echo" 01243 << endl << "\t@echo" 01244 << endl << "\t@echo --------------------------------------" 01245 << endl << "\t@echo DIRECTORIES" 01246 << endl << "\t@echo" 01247 << endl << "\t@for i in $(all_dirs); do echo $$i/; done"; 01248 ofs << endl << endl; 01249 ofs << "list-apps :" 01250 << endl << "\t@for i in $(all_apps); do echo $$i; done"; 01251 ofs << endl << endl; 01252 ofs << "list-libs :" 01253 << endl << "\t@for i in $(all_libraries); do echo $$i; done"; 01254 ofs << endl << endl; 01255 ofs << "list-unix :" 01256 << endl << "\t@for i in $(all_unix); do echo $$i; done"; 01257 ofs << endl << endl; 01258 ofs << "list-excluded :" 01259 << endl << "\t@for i in $(all_excluded); do echo $$i; done"; 01260 ofs << endl << endl; 01261 01262 ofs << "list-tags :"; 01263 if (!existing_composite_names.empty()) { 01264 ITERATE(vector<string>, c, existing_composite_names) { 01265 ofs << endl << "\t@echo " << *c; 01266 } 01267 } 01268 ofs << endl << endl; 01269 ITERATE(vector<string>, c, existing_composite_names) { 01270 ofs << "list-tag-" << *c << " :" 01271 << endl << "\t@for i in $(" << *c << "_projects); do echo $$i; done"; 01272 ofs << endl << endl; 01273 } 01274 01275 // -------------------------------------------------------------------------- 01276 string datatool_key; 01277 string datatool( GetDatatoolId() ); 01278 set<string> dataspec_dirs; 01279 if (!datatool.empty()) { 01280 CProjKey t(CProjKey::eApp, datatool); 01281 if (projects_tree.m_Projects.find(t) != projects_tree.m_Projects.end()) { 01282 datatool_key = CreateProjectName(t); 01283 } 01284 } 01285 01286 ITERATE(CProjectItemsTree::TProjects, p, projects_tree.m_Projects) { 01287 01288 if (p->first.Type() == CProjKey::eDataSpec) { 01289 continue; 01290 } 01291 01292 bool isLibrary = p->first.Type() == CProjKey::eLib; 01293 bool hasDataspec = !p->second.m_DatatoolSources.empty(); 01294 string target, target_app, target_lib, target_user; 01295 list<string> dependencies; 01296 CProjectItemsTree::TProjects::const_iterator n; 01297 01298 target = CreateProjectName(p->first); 01299 target_app = target_lib = target_user = "\"\""; 01300 if (p->first.Type() == CProjKey::eApp) { 01301 target_app = p->second.m_Name; 01302 } else if (p->first.Type() == CProjKey::eMsvc) { 01303 target_user = p->second.m_Name; 01304 } else if (p->first.Type() == CProjKey::eLib) { 01305 target_lib = p->second.m_Name; 01306 } else { 01307 target_lib = p->second.m_Name; 01308 } 01309 string rel_path = CDirEntry::CreateRelativePath( 01310 GetProjectTreeInfo().m_Src,p->second.m_SourcesBaseDir); 01311 01312 // check for missing dependencies ------------------------------------------- 01313 string error; 01314 if (p->second.m_MakeType != eMakeType_Expendable && m_BuildRoot.empty()) { 01315 ITERATE(set<CProjKey>, u, p->second.m_UnconditionalDepends) { 01316 CProjKey proj_key = *u; 01317 if (projects_tree.m_Projects.find(proj_key) == 01318 projects_tree.m_Projects.end()) { 01319 bool depfound = false; 01320 string dll(GetDllHost(projects_tree, proj_key.Id())); 01321 if (!dll.empty()) { 01322 CProjKey id_alt(CProjKey::eDll,dll); 01323 depfound = (projects_tree.m_Projects.find(id_alt) != 01324 projects_tree.m_Projects.end()); 01325 } 01326 if (!depfound && 01327 !SMakeProjectT::IsConfigurableDefine(proj_key.Id())) { 01328 error = "@echo ERROR: this project depends on missing " + 01329 CreateProjectName(proj_key); 01330 } 01331 } 01332 } 01333 } 01334 01335 // collect dependencies ----------------------------------------------------- 01336 set<string> lib_guid, visited; 01337 ITERATE(list<CProjKey>, i, p->second.m_Depends) { 01338 01339 const CProjKey& id = *i; 01340 // exclude 3rd party libs 01341 if ( GetSite().IsLibWithChoice(id.Id()) ) { 01342 if ( GetSite().GetChoiceForLib(id.Id()) == CMsvcSite::e3PartyLib ) { 01343 continue; 01344 } 01345 } 01346 // exclude missing projects 01347 n = projects_tree.m_Projects.find(id); 01348 if (n == projects_tree.m_Projects.end()) { 01349 /* 01350 CProjKey id_alt(CProjKey::eDll,GetDllsInfo().GetDllHost(id.Id())); 01351 n = projects_tree.m_Projects.find(id_alt); 01352 if (n == projects_tree.m_Projects.end()) 01353 */ 01354 { 01355 if (!SMakeProjectT::IsConfigurableDefine(id.Id())) { 01356 LOG_POST(Warning << "Project " + p->first.Id() + 01357 " depends on missing project " + id.Id()); 01358 } 01359 continue; 01360 } 01361 } 01362 if (isLibrary && id.Type() == CProjKey::eLib) { 01363 CollectLibToLibDependencies(projects_tree, lib_guid, visited, p, n); 01364 continue; 01365 } 01366 dependencies.push_back(CreateProjectName(n->first)); 01367 } 01368 copy(lib_guid.begin(), lib_guid.end(), back_inserter(dependencies)); 01369 dependencies.sort(); 01370 dependencies.unique(); 01371 CProjectTreeBuilder::VerifyBuildOrder( p->second, dependencies, projects_tree); 01372 01373 if (isLibrary && !m_AllDllBuild) { 01374 list<string> new_dependencies; 01375 // new_dependencies.push_back( target + dotfiles); 01376 ITERATE(list<string>, d, dependencies) { 01377 if (*d == datatool_key) { 01378 continue; 01379 } 01380 n = projects_tree.m_Projects.find(CreateProjKey(*d)); 01381 if (n != projects_tree.m_Projects.end() && 01382 !n->second.m_DatatoolSources.empty()) { 01383 new_dependencies.push_back(*d + dotfiles); 01384 continue; 01385 } 01386 new_dependencies.push_back(*d); 01387 } 01388 dependencies = new_dependencies; 01389 } 01390 01391 // collect paths ------------------------------------------------------------ 01392 if (p->first.Type() != CProjKey::eDataSpec) { 01393 01394 path_to_target[rel_path].push_back(target); 01395 if (p->second.m_MakeType != eMakeType_Excluded && 01396 p->second.m_MakeType != eMakeType_ExcludedByReq) { 01397 string stop_path(CDirEntry::AddTrailingPathSeparator(".")); 01398 string parent_path, prev_parent(rel_path); 01399 for (;;) { 01400 parent_path = ParentDir(prev_parent); 01401 // see CXX-950 01402 #if 0 01403 path_to_target[parent_path].push_back(prev_parent + ".real"); 01404 #else 01405 path_to_target[parent_path].push_back(prev_parent); 01406 #endif 01407 if (parent_path == stop_path) { 01408 break; 01409 } 01410 prev_parent = parent_path; 01411 } 01412 } 01413 } 01414 01415 #if NCBI_COMPILER_MSVC 01416 rel_path = NStr::Replace(rel_path,"\\","/"); 01417 #endif //NCBI_COMPILER_MSVC 01418 01419 // see CXX-950 01420 #if 0 01421 ofs << target << " : " << rel_path << "$(s)." << target << ".real"; 01422 ofs << endl << endl; 01423 ofs << rel_path << "$(s)." << target << ".real" << " :" << endl 01424 << "\t$(MAKE) $(MFLAGS_NR) -f $(MINPUT) " << target << ".real" 01425 << " MTARGET=$(MTARGET) MARK=$(MARK)"; 01426 ofs << endl << endl; 01427 ofs << target << ".real" << " :"; 01428 ITERATE(list<string>, d, dependencies) { 01429 ofs << " " << *d; 01430 } 01431 ofs << endl << "\t"; 01432 if (!error.empty()) { 01433 ofs << error << endl << "\t@exit 1" << endl << "\t"; 01434 } 01435 ofs << "+"; 01436 if (p->second.m_MakeType == eMakeType_Expendable) { 01437 ofs << "-"; 01438 } 01439 ofs << "cd " << rel_path << "; $(MAKE) $(MFLAGS_NR)" 01440 << " APP_PROJ=" << target_app 01441 << " LIB_PROJ=" << target_lib 01442 << " $(MTARGET)" << endl 01443 << "\t@" << "cd " << rel_path << "; $(sign)"; 01444 ofs << endl << endl; 01445 #else 01446 ofs << target << " :" << endl 01447 << "\t$(MAKE) $(MFLAGS) -f $(MINPUT) " << target << dotreal 01448 << " MTARGET=$(MTARGET)"; 01449 ofs << endl << endl; 01450 ofs << target << dotreal << " :"; 01451 01452 if (hasDataspec) { 01453 dataspec_dirs.insert(rel_path); 01454 } 01455 ITERATE(list<string>, d, dependencies) { 01456 if (*d == datatool_key) { 01457 dataspec_dirs.insert(rel_path); 01458 } else { 01459 ofs << " " << *d << dotreal; 01460 } 01461 } 01462 ofs << " " << rel_path << dotfiles << dotreal; 01463 01464 01465 ofs << endl << "\t"; 01466 if (!error.empty()) { 01467 ofs << error << endl << "\t@exit 1" << endl << "\t"; 01468 } 01469 ofs << "+"; 01470 if (p->second.m_MakeType >= eMakeType_Expendable) { 01471 ofs << "-"; 01472 } 01473 ofs << "cd " << rel_path << " && "; 01474 if (p->second.m_MakeType == eMakeType_Expendable) { 01475 ofs << " NCBI_BUT_EXPENDABLE=' (but expendable)'"; 01476 } 01477 ofs << " $(MAKE) $(MFLAGS)" 01478 << " APP_PROJ=" << target_app 01479 << " LIB_PROJ=" << target_lib 01480 << " UNIX_PROJ=" << target_user 01481 << " $(MTARGET) $(SKIP_PRELIMINARIES)" << endl << endl; 01482 #endif 01483 if (hasDataspec) { 01484 ofs << target << dotfiles << " :" << endl 01485 << "\t$(MAKE) $(MFLAGS) -f $(MINPUT) $(SKIP_PRELIMINARIES) " 01486 << target << dotfiles << dotreal; 01487 ofs << endl << endl; 01488 ofs << target << dotfiles << dotreal << " :"; 01489 ofs << " " << rel_path << dotfiles << dotreal; 01490 ofs << endl << endl; 01491 } 01492 } 01493 01494 // folder targets ----------------------------------------------------------- 01495 map< string, list< string > >::const_iterator pt; 01496 for ( pt = path_to_target.begin(); pt != path_to_target.end(); ++pt) { 01497 string target(pt->first); 01498 ofs << ".PHONY : " << target << endl << endl; 01499 ofs << target << " :" << endl 01500 << "\t$(MAKE) $(MFLAGS_NR) -f $(MINPUT) " << target << dotreal 01501 << " MTARGET=$(MTARGET)"; 01502 ofs << endl << endl; 01503 ofs << target << dotreal << " :"; 01504 if (!pt->second.empty()) { 01505 list< string > tt(pt->second); 01506 tt.sort(); 01507 tt.unique(); 01508 // see CXX-950 01509 #if 0 01510 ofs << " " << NStr::Join( tt, " "); 01511 #else 01512 ofs << " " << NStr::Join( tt, dotreal + " ") << dotreal; 01513 #endif 01514 ofs << endl << endl; 01515 } 01516 01517 ofs << target << dotfiles << " :" << endl 01518 << "\t$(MAKE) $(MFLAGS_NR) -f $(MINPUT) " << target << dotfiles << dotreal 01519 << " MTARGET=$(MTARGET)"; 01520 ofs << endl << endl; 01521 ofs << target << dotfiles << dotreal << " :"; 01522 if (m_Dtdep && !datatool_key.empty() && 01523 dataspec_dirs.find(target) != dataspec_dirs.end()) { 01524 ofs << " " << datatool_key << dotreal; 01525 } 01526 ofs << endl << "\t"; 01527 ofs << "-"; 01528 ofs << "cd " << target << " && $(MAKE) $(MFLAGS) sources"; 01529 ofs << endl << endl; 01530 } 01531 } 01532 01533 01534 void CProjBulderApp::CreateFeaturesAndPackagesFiles( 01535 const list<SConfigInfo>* configs, 01536 list<string>& list_enabled, list<string>& list_disabled) 01537 { 01538 PTB_INFO("Generating Features_And_Packages files..."); 01539 // Create makefile path 01540 string base_path = GetProjectTreeInfo().m_Compilers; 01541 base_path = CDirEntry::ConcatPath(base_path, 01542 GetRegSettings().m_CompilersSubdir); 01543 01544 base_path = CDirEntry::ConcatPath(base_path, GetBuildType().GetTypeStr()); 01545 ITERATE(list<SConfigInfo>, c , *configs) { 01546 string file_path = CDirEntry::ConcatPath(base_path, c->GetConfigFullName()); 01547 CDir(file_path).CreatePath(); 01548 string enabled = CDirEntry::ConcatPath(file_path, 01549 "features_and_packages.txt"); 01550 string disabled = CDirEntry::ConcatPath(file_path, 01551 "features_and_packages_disabled.txt"); 01552 file_path = CDirEntry::ConcatPath(file_path, 01553 "features_and_packages.txt"); 01554 CNcbiOfstream ofs(enabled.c_str(), IOS_BASE::out | IOS_BASE::trunc ); 01555 if ( !ofs ) 01556 NCBI_THROW(CProjBulderAppException, eFileCreation, enabled); 01557 GetApp().RegisterGeneratedFile( enabled ); 01558 01559 CNcbiOfstream ofsd(disabled.c_str(), IOS_BASE::out | IOS_BASE::trunc ); 01560 if ( !ofsd ) 01561 NCBI_THROW(CProjBulderAppException, eFileCreation, disabled); 01562 GetApp().RegisterGeneratedFile( disabled ); 01563 01564 if (c->m_rtType == SConfigInfo::rtMultiThreaded) { 01565 ofs << "MT" << endl; 01566 } else if (c->m_rtType == SConfigInfo::rtMultiThreadedDebug) { 01567 ofs << "MT" << endl << "Debug" << endl; 01568 } else if (c->m_rtType == SConfigInfo::rtMultiThreadedDLL) { 01569 ofs << "MT" << endl; 01570 } else if (c->m_rtType == SConfigInfo::rtMultiThreadedDebugDLL) { 01571 ofs << "MT" << endl << "Debug" << endl; 01572 } else if (c->m_rtType == SConfigInfo::rtSingleThreaded) { 01573 } else if (c->m_rtType == SConfigInfo::rtSingleThreadedDebug) { 01574 ofs << "Debug" << endl; 01575 } 01576 if (GetBuildType().GetType() == CBuildType::eDll) { 01577 ofs << "DLL" << endl; 01578 } 01579 const set<string>& epackages = 01580 CMsvcPrjProjectContext::GetEnabledPackages(c->GetConfigFullName()); 01581 ITERATE(set<string>, e, epackages) { 01582 ofs << *e << endl; 01583 list_enabled.push_back(*e); 01584 } 01585 01586 list<string> std_features; 01587 GetSite().GetStandardFeatures(std_features); 01588 ITERATE(list<string>, s, std_features) { 01589 ofs << *s << endl; 01590 list_enabled.push_back(*s); 01591 } 01592 01593 const set<string>& dpackages = 01594 CMsvcPrjProjectContext::GetDisabledPackages(c->GetConfigFullName()); 01595 ITERATE(set<string>, d, dpackages) { 01596 ofsd << *d << endl; 01597 list_disabled.push_back(*d); 01598 } 01599 } 01600 list_enabled.sort(); 01601 list_enabled.unique(); 01602 list_disabled.sort(); 01603 list_disabled.unique(); 01604 } 01605 01606 void CProjBulderApp::GenerateSummary(const list<SConfigInfo> configs, 01607 const list<string>& enabled, const list<string>& disabled) 01608 { 01609 if (!m_ConfSrc.empty() && !m_ConfDest.empty()) { 01610 string orig_ext = CDirEntry( CDirEntry(m_ConfSrc).GetBase() ).GetExt(); 01611 ITERATE(list<SConfigInfo>, p , configs) { 01612 const SConfigInfo& cfg_info = *p; 01613 string file_dst_path; 01614 file_dst_path = m_ConfDest + "." + 01615 ConfigurableFileSuffix(cfg_info.GetConfigFullName())+ 01616 orig_ext; 01617 CreateConfigurableFile(m_ConfSrc, file_dst_path, 01618 cfg_info.GetConfigFullName()); 01619 } 01620 } 01621 01622 string str_config; 01623 // summary 01624 SetDiagPostAllFlags(eDPF_Log); 01625 PTB_INFO("==========================================================="); 01626 PTB_INFO("SOLUTION: " << m_Solution); 01627 PTB_INFO("PROJECTS: " << CDirEntry::ConcatPath(m_ProjectTreeInfo->m_Root, m_Subtree)); 01628 PTB_INFO("CONFIGURATIONS: " << str_config); 01629 PTB_INFO("FEATURES AND PACKAGES: "); 01630 string str_pkg = " enabled: "; 01631 ITERATE( list<string>, p, enabled) { 01632 if (str_pkg.length() > 70) { 01633 PTB_INFO(str_pkg); 01634 str_pkg = " "; 01635 } 01636 str_pkg += " "; 01637 str_pkg += *p; 01638 } 01639 if (!str_pkg.empty()) { 01640 PTB_INFO(str_pkg); 01641 } 01642 str_pkg = " disabled: "; 01643 ITERATE( list<string>, p, disabled) { 01644 if (str_pkg.length() > 70) { 01645 PTB_INFO(str_pkg); 01646 str_pkg = " "; 01647 } 01648 str_pkg += " "; 01649 str_pkg += *p; 01650 } 01651 if (!str_pkg.empty()) { 01652 PTB_INFO(str_pkg); 01653 } 01654 string str_path = GetProjectTreeInfo().m_Compilers; 01655 str_path = CDirEntry::ConcatPath(str_path, 01656 GetRegSettings().m_CompilersSubdir); 01657 str_path = CDirEntry::ConcatPath(str_path, GetBuildType().GetTypeStr()); 01658 01659 PTB_INFO(" "); 01660 PTB_INFO(" If a package is present in both lists,"); 01661 PTB_INFO(" it is disabled in SOME configurations only"); 01662 PTB_INFO(" For details see 'features_and_packages' files in"); 01663 PTB_INFO(" " << str_path << "/%ConfigurationName%"); 01664 PTB_INFO("==========================================================="); 01665 } 01666 01667 void CProjBulderApp::CreateCheckList(const list<SConfigInfo>* configs, 01668 CProjectItemsTree& projects_tree) 01669 { 01670 PTB_INFO("Generating check.sh.list files..."); 01671 string output_dir(m_Solution); 01672 if (CMsvc7RegSettings::GetMsvcPlatform() < CMsvc7RegSettings::eUnix) { 01673 string::size_type n = output_dir.find_last_of('.'); 01674 if (n != string::npos) { 01675 output_dir = output_dir.substr(0,n); 01676 } 01677 } 01678 output_dir += ".check"; 01679 ITERATE(list<SConfigInfo>, c , *configs) { 01680 string cfg(c->GetConfigFullName()); 01681 string file_path = CDirEntry::ConcatPath(output_dir, cfg); 01682 CDir dir(file_path); 01683 if (!dir.Exists()) { 01684 dir.CreatePath(); 01685 } 01686 file_path = CDirEntry::ConcatPath(file_path, "check.sh.list"); 01687 CNcbiOfstream ofs(file_path.c_str(), IOS_BASE::out | IOS_BASE::trunc ); 01688 if ( !ofs ) 01689 NCBI_THROW(CProjBulderAppException, eFileCreation, file_path); 01690 GetApp().RegisterGeneratedFile( file_path ); 01691 list<string> all_cmd; 01692 ITERATE(CProjectItemsTree::TProjects, p, projects_tree.m_Projects) { 01693 const CProjItem& project = p->second; 01694 if (project.m_MakeType == eMakeType_Excluded || 01695 project.m_MakeType == eMakeType_ExcludedByReq) { 01696 continue; 01697 } 01698 if (project.m_CheckConfigs.find(cfg) != project.m_CheckConfigs.end()) { 01699 ITERATE( list<string>, cmd, project.m_CheckInfo) { 01700 all_cmd.push_back(*cmd); 01701 } 01702 } else if (!project.m_CheckInfo.empty()) { 01703 PTB_INFO("Project: " << p->first.Id() << ": CHECK_CMD disabled in " << cfg); 01704 } 01705 } 01706 all_cmd.sort(); 01707 all_cmd.unique(); 01708 ITERATE(list<string>, cmd, all_cmd) { 01709 ofs << *cmd << endl; 01710 } 01711 } 01712 } 01713 01714 void CProjBulderApp::ReportGeneratedFiles(void) 01715 { 01716 m_GeneratedFiles.sort(); 01717 string file_path( m_Solution + "_generated_files.txt"); 01718 string sep; 01719 sep += CDirEntry::GetPathSeparator(); 01720 string root(m_Root); 01721 if (!CDirEntry::IsAbsolutePath(root)) { 01722 root = CDirEntry::ConcatPath(CDir::GetCwd(), root); 01723 } 01724 CNcbiOfstream ofs(file_path.c_str(), IOS_BASE::out | IOS_BASE::trunc ); 01725 if (ofs.is_open()) { 01726 ITERATE( list<string>, f, m_GeneratedFiles) { 01727 string path(*f); 01728 if (!CDirEntry::IsAbsolutePath(path)) { 01729 path = CDirEntry::ConcatPath(CDir::GetCwd(), path); 01730 } 01731 path = CDirEntry::CreateRelativePath(root, path); 01732 ofs << NStr::ReplaceInPlace( path, sep, "/") << endl; 01733 } 01734 } 01735 } 01736 01737 void CProjBulderApp::ReportProjectWatchers(void) 01738 { 01739 m_ProjWatchers.sort(); 01740 string file_path( m_Solution + "_watchers.txt"); 01741 CNcbiOfstream ofs(file_path.c_str(), IOS_BASE::out | IOS_BASE::trunc ); 01742 if (ofs.is_open()) { 01743 ITERATE( list<string>, f, m_ProjWatchers) { 01744 ofs << *f << endl; 01745 } 01746 } 01747 } 01748 01749 void CProjBulderApp::Exit(void) 01750 { 01751 } 01752 01753 01754 void CProjBulderApp::ParseArguments(void) 01755 { 01756 const CArgs& args = GetArgs(); 01757 string root; 01758 bool extroot = false; 01759 bool argfile = false; 01760 string argsfile; 01761 01762 if ( args["args"] ) { 01763 argsfile = args["args"].AsString(); 01764 if (CDirEntry(argsfile).Exists()) { 01765 argfile = true; 01766 m_CustomConfiguration.LoadFrom(argsfile,&m_CustomConfiguration); 01767 } else { 01768 NCBI_THROW(CProjBulderAppException, eFileOpen, 01769 argsfile + " not found"); 01770 } 01771 } 01772 01773 root = args["root"].AsString(); 01774 if (root == "\"\"") { 01775 root = ""; 01776 } 01777 if (argfile && root.empty()) { 01778 m_CustomConfiguration.GetPathValue("__arg_root", root); 01779 } 01780 m_Root = CDirEntry::IsAbsolutePath(root) ? 01781 root : CDirEntry::ConcatPath( CDir::GetCwd(), root); 01782 m_Root = CDirEntry::AddTrailingPathSeparator(m_Root); 01783 m_Root = CDirEntry::NormalizePath(m_Root); 01784 m_Root = CDirEntry::AddTrailingPathSeparator(m_Root); 01785 01786 m_Subtree = args["subtree"].AsString(); 01787 if (m_Subtree == "\"\"") { 01788 m_Subtree = ""; 01789 } 01790 if (CDirEntry::IsAbsolutePath(m_Subtree)) { 01791 m_Subtree = CDirEntry::NormalizePath( 01792 CDirEntry::CreateRelativePath(m_Root, m_Subtree)); 01793 } 01794 m_Solution = CDirEntry::NormalizePath(args["solution"].AsString()); 01795 if (m_Solution == "\"\"") { 01796 m_Solution = ""; 01797 } 01798 if (!m_Solution.empty() && !CDirEntry::IsAbsolutePath(m_Solution)) { 01799 m_Solution = CDirEntry::ConcatPath( CDir::GetCwd(), m_Solution); 01800 } 01801 01802 if (argfile) { 01803 string v; 01804 if (GetConfigPath().empty() && 01805 m_CustomConfiguration.GetPathValue("__arg_conffile", v)) { 01806 if (!CDirEntry::IsAbsolutePath(v)) { 01807 v = CDirEntry::ConcatPath(m_Root,v); 01808 } 01809 LoadConfig(GetConfig(),&v); 01810 } 01811 string subtree; 01812 m_CustomConfiguration.GetPathValue("__arg_subtree", subtree); 01813 if (m_Subtree.empty()) { 01814 m_Subtree = subtree; 01815 } else if (m_Subtree != subtree) { 01816 m_CustomConfiguration.RemoveDefinition("__AllowedProjects"); 01817 } 01818 if (m_Solution.empty()) { 01819 m_CustomConfiguration.GetPathValue("__arg_solution", m_Solution); 01820 if (!CDirEntry::IsAbsolutePath(m_Solution)) { 01821 m_Solution = CDirEntry::ConcatPath(m_Root,m_Solution); 01822 } 01823 } 01824 01825 if (m_CustomConfiguration.GetValue("__arg_dll", v)) { 01826 m_Dll = NStr::StringToBool(v); 01827 } 01828 if (m_CustomConfiguration.GetValue("__arg_nobuildptb", v)) { 01829 m_BuildPtb = !NStr::StringToBool(v); 01830 } 01831 01832 if (m_CustomConfiguration.GetValue("__arg_ext", v)) { 01833 m_AddMissingLibs = NStr::StringToBool(v); 01834 } 01835 if (m_CustomConfiguration.GetValue("__arg_nws", v)) { 01836 m_ScanWholeTree = !NStr::StringToBool(v); 01837 } 01838 extroot = m_CustomConfiguration.GetPathValue("__arg_extroot", m_BuildRoot); 01839 m_CustomConfiguration.GetValue("__arg_projtag", m_ProjTags); 01840 01841 #if defined(NCBI_COMPILER_MSVC) || defined(NCBI_XCODE_BUILD) || defined(PSEUDO_XCODE) 01842 if (m_CustomConfiguration.GetValue("__arg_ide", v)) { 01843 m_Ide = NStr::StringToInt(v); 01844 } 01845 m_CustomConfiguration.GetValue("__arg_arch", m_Arch); 01846 #endif 01847 } else { 01848 m_Dll = (bool)args["dll"]; 01849 m_BuildPtb = !((bool)args["nobuildptb"]); 01850 m_AddMissingLibs = (bool)args["ext"]; 01851 m_ScanWholeTree = !((bool)args["nws"]); 01852 extroot = (bool)args["extroot"]; 01853 if (extroot) { 01854 m_BuildRoot = args["extroot"].AsString(); 01855 } 01856 if ( const CArgValue& t = args["projtag"] ) { 01857 m_ProjTags = t.AsString(); 01858 m_ProjTagCmnd = true; 01859 } else { 01860 m_ProjTags = CProjectsLstFileFilter::GetAllowedTagsInfo( 01861 CDirEntry::ConcatPath(m_Root, m_Subtree)); 01862 m_ProjTagCmnd = false; 01863 } 01864 #if defined(NCBI_COMPILER_MSVC) || defined(NCBI_XCODE_BUILD) || defined(PSEUDO_XCODE) 01865 const CArgValue& ide = args["ide"]; 01866 if ((bool)ide) { 01867 m_Ide = ide.AsInteger(); 01868 } 01869 const CArgValue& arch = args["arch"]; 01870 if ((bool)arch) { 01871 m_Arch = arch.AsString(); 01872 } 01873 #endif 01874 } 01875 01876 CMsvc7RegSettings::IdentifyPlatform(); 01877 01878 string entry[] = {"","",""}; 01879 if (CMsvc7RegSettings::GetMsvcPlatform() < CMsvc7RegSettings::eUnix) { 01880 entry[0] = "ThirdPartyBasePath"; 01881 entry[1] = "ThirdParty_C_ncbi"; 01882 } 01883 else if (CMsvc7RegSettings::GetMsvcPlatform() == CMsvc7RegSettings::eXCode) { 01884 entry[0] = "XCode_ThirdPartyBasePath"; 01885 entry[1] = "XCode_ThirdParty_C_ncbi"; 01886 } 01887 if (argfile) { 01888 // this replaces path separators in entry[j] with a native one 01889 string v; 01890 for (int j=0; !entry[j].empty(); ++j) { 01891 if (m_CustomConfiguration.GetPathValue(entry[j], v)) { 01892 m_CustomConfiguration.AddDefinition(entry[j], v); 01893 } 01894 } 01895 } 01896 01897 m_ConfirmCfg = false; 01898 #if defined(NCBI_COMPILER_MSVC) 01899 m_ConfirmCfg = (bool)args["cfg"]; 01900 #endif 01901 m_InteractiveCfg = (bool)args["i"]; 01902 m_Dtdep = (bool)args["dtdep"]; 01903 01904 // Solution 01905 PTB_INFO("Solution: " << m_Solution); 01906 m_StatusDir = 01907 CDirEntry::NormalizePath( CDirEntry::ConcatPath( CDirEntry::ConcatPath( 01908 CDirEntry(m_Solution).GetDir(),".."),"status")); 01909 // m_BuildPtb = m_BuildPtb && 01910 // CMsvc7RegSettings::GetMsvcVersion() == CMsvc7RegSettings::eMsvc710; 01911 01912 if ( extroot ) { 01913 if (CDirEntry(m_BuildRoot).Exists()) { 01914 // verify status dir 01915 if (!CDirEntry(m_StatusDir).Exists() && !m_BuildRoot.empty()) { 01916 m_StatusDir = CDirEntry::NormalizePath( 01917 CDirEntry::ConcatPath( CDirEntry::ConcatPath( 01918 m_BuildRoot,".."),"status")); 01919 } 01920 01921 string t, try_dir; 01922 string src = GetConfig().Get("ProjectTree", "src"); 01923 for ( t = try_dir = m_BuildRoot; ; try_dir = t) { 01924 if (CDirEntry( 01925 CDirEntry::ConcatPath(try_dir, src)).Exists()) { 01926 m_ExtSrcRoot = try_dir; 01927 break; 01928 } 01929 t = CDirEntry(try_dir).GetDir(); 01930 if (t == try_dir) { 01931 break; 01932 } 01933 } 01934 } 01935 } 01936 if (m_ProjTags.empty() || m_ProjTags == "\"\"" || m_ProjTags == "#") { 01937 m_ProjTags = "*"; 01938 } 01939 01940 string tmp(GetConfig().Get("ProjectTree", "CustomConfiguration")); 01941 if (!tmp.empty()) { 01942 m_CustomConfFile = CDirEntry::ConcatPath( CDirEntry(m_Solution).GetDir(), tmp); 01943 } 01944 CDir sln_dir(CDirEntry(m_Solution).GetDir()); 01945 if ( !sln_dir.Exists() ) { 01946 sln_dir.CreatePath(); 01947 } 01948 if (!argfile) { 01949 if (CFile(m_CustomConfFile).Exists()) { 01950 m_CustomConfiguration.LoadFrom(m_CustomConfFile,&m_CustomConfiguration); 01951 01952 string subtree; 01953 m_CustomConfiguration.GetPathValue("__arg_subtree", subtree); 01954 if (m_Subtree.empty()) { 01955 m_Subtree = subtree; 01956 } else if (m_Subtree != subtree) { 01957 m_CustomConfiguration.RemoveDefinition("__AllowedProjects"); 01958 } 01959 } else { 01960 if (CMsvc7RegSettings::GetMsvcPlatform() != CMsvc7RegSettings::eUnix) { 01961 for (int j=0; !entry[j].empty(); ++j) { 01962 m_CustomConfiguration.AddDefinition(entry[j], GetSite().GetConfigureEntry(entry[j])); 01963 } 01964 } 01965 if (CMsvc7RegSettings::GetMsvcPlatform() < CMsvc7RegSettings::eUnix) { 01966 m_CustomConfiguration.AddDefinition("__TweakVTuneR", "no"); 01967 m_CustomConfiguration.AddDefinition("__TweakVTuneD", "no"); 01968 } 01969 } 01970 01971 string v; 01972 v = GetConfigPath(); 01973 if (CDirEntry::IsAbsolutePath(v)) { 01974 try { 01975 v = CDirEntry::CreateRelativePath(m_Root, v); 01976 } catch (CFileException&) { 01977 } 01978 } 01979 m_CustomConfiguration.AddDefinition("__arg_conffile", v); 01980 01981 m_CustomConfiguration.AddDefinition("__arg_root", root); 01982 m_CustomConfiguration.AddDefinition("__arg_subtree", m_Subtree); 01983 v = m_Solution; 01984 if (CDirEntry::IsAbsolutePath(v)) { 01985 try { 01986 v = CDirEntry::CreateRelativePath(m_Root, v); 01987 } catch (CFileException&) { 01988 } 01989 } 01990 m_CustomConfiguration.AddDefinition("__arg_solution", v); 01991 01992 m_CustomConfiguration.AddDefinition("__arg_dll", m_Dll ? "yes" : "no"); 01993 m_CustomConfiguration.AddDefinition("__arg_nobuildptb", m_BuildPtb ? "no" : "yes"); 01994 m_CustomConfiguration.AddDefinition("__arg_ext", m_AddMissingLibs ? "yes" : "no"); 01995 m_CustomConfiguration.AddDefinition("__arg_nws", m_ScanWholeTree ? "no" : "yes"); 01996 m_CustomConfiguration.AddDefinition("__arg_extroot", m_BuildRoot); 01997 m_CustomConfiguration.AddDefinition("__arg_projtag", m_ProjTags); 01998 01999 #if defined(NCBI_COMPILER_MSVC) || defined(NCBI_XCODE_BUILD) || defined(PSEUDO_XCODE) 02000 m_CustomConfiguration.AddDefinition("__arg_ide", NStr::IntToString(m_Ide)); 02001 m_CustomConfiguration.AddDefinition("__arg_arch", m_Arch); 02002 #endif 02003 // this replaces path separators in entry[j] with a native one 02004 for (int j=0; !entry[j].empty(); ++j) { 02005 if (m_CustomConfiguration.GetPathValue(entry[j], v)) { 02006 m_CustomConfiguration.AddDefinition(entry[j], v); 02007 } 02008 } 02009 } 02010 if (CMsvc7RegSettings::GetMsvcPlatform() < CMsvc7RegSettings::eUnix) { 02011 string v; 02012 if (m_CustomConfiguration.GetValue("__TweakVTuneR", v)) { 02013 m_TweakVTuneR = NStr::StringToBool(v); 02014 } 02015 if (m_CustomConfiguration.GetValue("__TweakVTuneD", v)) { 02016 m_TweakVTuneD = NStr::StringToBool(v); 02017 } 02018 m_AddUnicode = GetSite().IsProvided("Ncbi-Unicode", false); 02019 } 02020 tmp = GetConfig().Get("Configure", "UserRequests"); 02021 if (!tmp.empty()) { 02022 m_CustomConfiguration.AddDefinition("__UserRequests", tmp); 02023 } else { 02024 m_CustomConfiguration.RemoveDefinition("__UserRequests"); 02025 } 02026 if ( m_MsvcRegSettings.get() ) { 02027 GetBuildConfigs(&m_MsvcRegSettings->m_ConfigInfo); 02028 } 02029 m_AbsDirs.clear(); 02030 for (int j=0; !entry[j].empty(); ++j) { 02031 string v; 02032 if (m_CustomConfiguration.GetPathValue(entry[j], v)) { 02033 m_AbsDirs.push_back(v); 02034 } 02035 } 02036 } 02037 02038 void CProjBulderApp::VerifyArguments(void) 02039 { 02040 m_Root = CDirEntry::AddTrailingPathSeparator(m_Root); 02041 if (CMsvc7RegSettings::GetMsvcPlatform() < CMsvc7RegSettings::eUnix) { 02042 NStr::ToLower(m_Root); 02043 } 02044 02045 m_IncDir = GetProjectTreeInfo().m_Compilers; 02046 if (CMsvc7RegSettings::GetMsvcPlatform() == CMsvc7RegSettings::eUnix) { 02047 m_IncDir = CDirEntry(m_Solution).GetDir(); 02048 m_IncDir = CDirEntry::ConcatPath(m_IncDir,".."); 02049 } else { 02050 m_IncDir = CDirEntry::ConcatPath(m_IncDir,GetRegSettings().m_CompilersSubdir); 02051 m_IncDir = CDirEntry::ConcatPath(m_IncDir, GetBuildType().GetTypeStr()); 02052 } 02053 m_IncDir = CDirEntry::ConcatPath(m_IncDir, "inc"); 02054 m_IncDir = CDirEntry::ConcatPath(m_IncDir, CMsvc7RegSettings::GetConfigNameKeyword()); 02055 } 02056 02057 02058 int CProjBulderApp::EnumOpt(const string& enum_name, 02059 const string& enum_val) const 02060 { 02061 int opt = GetConfig().GetInt(enum_name, enum_val, -1); 02062 if (opt == -1) { 02063 NCBI_THROW(CProjBulderAppException, eEnumValue, 02064 enum_name + "::" + enum_val); 02065 } 02066 return opt; 02067 } 02068 02069 02070 void CProjBulderApp::DumpFiles(const TFiles& files, 02071 const string& filename) const 02072 { 02073 CNcbiOfstream ofs(filename.c_str(), IOS_BASE::out | IOS_BASE::trunc); 02074 if ( !ofs ) { 02075 NCBI_THROW(CProjBulderAppException, eFileCreation, filename); 02076 } 02077 02078 ITERATE(TFiles, p, files) { 02079 ofs << "+++++++++++++++++++++++++\n"; 02080 ofs << p->first << endl; 02081 p->second.Dump(ofs); 02082 ofs << "-------------------------\n"; 02083 } 02084 } 02085 02086 bool CProjBulderApp::UseAbsolutePath(const string& path) const 02087 { 02088 ITERATE(list<string>, p, m_AbsDirs) { 02089 if (NStr::strncasecmp(path.c_str(), p->c_str(), p->length()) == 0) { 02090 return true; 02091 } 02092 } 02093 return false; 02094 } 02095 02096 void CProjBulderApp::AddCustomMetaData(const string& file) 02097 { 02098 string s( CDirEntry::CreateRelativePath(GetProjectTreeInfo().m_Src, file)); 02099 if ( find(m_CustomMetaData.begin(), m_CustomMetaData.end(), s) == 02100 m_CustomMetaData.end()) { 02101 m_CustomMetaData.push_back( s ); 02102 } 02103 } 02104 02105 void CProjBulderApp::GetMetaDataFiles(list<string>* files) const 02106 { 02107 *files = m_CustomMetaData; 02108 NStr::Split(GetConfig().Get("ProjectTree", "MetaData"), LIST_SEPARATOR, 02109 *files); 02110 } 02111 02112 void CProjBulderApp::AddCustomConfH(const string& file) 02113 { 02114 m_CustomConfH.push_back(file); 02115 } 02116 02117 void CProjBulderApp::GetCustomConfH(list<string>* files) const 02118 { 02119 *files = m_CustomConfH; 02120 } 02121 02122 02123 void CProjBulderApp::GetBuildConfigs(list<SConfigInfo>* configs) 02124 { 02125 configs->clear(); 02126 string name = m_Dll ? "DllConfigurations" : "Configurations"; 02127 const string& config_str 02128 = GetConfig().Get(CMsvc7RegSettings::GetMsvcSection(), name); 02129 list<string> configs_list; 02130 NStr::Split(config_str, LIST_SEPARATOR, configs_list); 02131 LoadConfigInfoByNames(GetConfig(), configs_list, configs); 02132 } 02133 02134 02135 const CMsvc7RegSettings& CProjBulderApp::GetRegSettings(void) 02136 { 02137 if ( !m_MsvcRegSettings.get() ) { 02138 m_MsvcRegSettings.reset(new CMsvc7RegSettings()); 02139 02140 string section(CMsvc7RegSettings::GetMsvcRegSection()); 02141 02142 m_MsvcRegSettings->m_MakefilesExt = 02143 GetConfig().GetString(section, "MakefilesExt", "msvc"); 02144 02145 m_MsvcRegSettings->m_ProjectsSubdir = 02146 GetConfig().GetString(section, "Projects", "build"); 02147 02148 m_MsvcRegSettings->m_MetaMakefile = CDirEntry::ConvertToOSPath( 02149 GetConfig().Get(section, "MetaMakefile")); 02150 02151 m_MsvcRegSettings->m_DllInfo = 02152 GetConfig().Get(section, "DllInfo"); 02153 02154 m_MsvcRegSettings->m_Version = 02155 GetConfig().Get(CMsvc7RegSettings::GetMsvcSection(), "Version"); 02156 02157 m_MsvcRegSettings->m_CompilersSubdir = 02158 GetConfig().Get(CMsvc7RegSettings::GetMsvcSection(), "msvc_prj"); 02159 02160 GetBuildConfigs(&m_MsvcRegSettings->m_ConfigInfo); 02161 } 02162 return *m_MsvcRegSettings; 02163 } 02164 02165 02166 const CMsvcSite& CProjBulderApp::GetSite(void) 02167 { 02168 if ( !m_MsvcSite.get() ) { 02169 m_MsvcSite.reset(new CMsvcSite(GetConfigPath())); 02170 } 02171 02172 return *m_MsvcSite; 02173 } 02174 02175 02176 const CMsvcMetaMakefile& CProjBulderApp::GetMetaMakefile(void) 02177 { 02178 if ( !m_MsvcMetaMakefile.get() ) { 02179 //Metamakefile must be in RootSrc directory 02180 m_MsvcMetaMakefile.reset(new CMsvcMetaMakefile 02181 (CDirEntry::ConcatPath(GetProjectTreeInfo().m_Src, 02182 GetRegSettings().m_MetaMakefile))); 02183 02184 //Metamakefile must present and must not be empty 02185 if ( m_MsvcMetaMakefile->IsEmpty() ) 02186 NCBI_THROW(CProjBulderAppException, 02187 eMetaMakefile, GetRegSettings().m_MetaMakefile); 02188 } 02189 02190 return *m_MsvcMetaMakefile; 02191 } 02192 02193 02194 const SProjectTreeInfo& CProjBulderApp::GetProjectTreeInfo(void) 02195 { 02196 if ( m_ProjectTreeInfo.get() ) 02197 return *m_ProjectTreeInfo; 02198 02199 m_ProjectTreeInfo.reset(new SProjectTreeInfo); 02200 02201 // Root, etc. 02202 m_ProjectTreeInfo->m_Root = m_Root; 02203 PTB_INFO("Project tree root: " << m_Root); 02204 02205 // all possible project tags 02206 const string& tagsfile = CDirEntry::ConvertToOSPath( 02207 GetConfig().Get("ProjectTree", "ProjectTags")); 02208 if (!tagsfile.empty()) { 02209 string fileloc(CDirEntry::ConcatPath(m_ProjectTreeInfo->m_Root, tagsfile)); 02210 if (!CDirEntry(fileloc).Exists() && !m_ExtSrcRoot.empty()) { 02211 fileloc = CDirEntry::ConcatPath(m_ExtSrcRoot,tagsfile); 02212 } 02213 LoadProjectTags(fileloc); 02214 } 02215 02216 /// <include> branch of tree 02217 const string& include = GetConfig().Get("ProjectTree", "include"); 02218 m_ProjectTreeInfo->m_Include = 02219 CDirEntry::ConcatPath(m_ProjectTreeInfo->m_Root, 02220 include); 02221 m_ProjectTreeInfo->m_Include = 02222 CDirEntry::AddTrailingPathSeparator(m_ProjectTreeInfo->m_Include); 02223 02224 02225 /// <src> branch of tree 02226 const string& src = GetConfig().Get("ProjectTree", "src"); 02227 m_ProjectTreeInfo->m_Src = 02228 CDirEntry::ConcatPath(m_ProjectTreeInfo->m_Root, 02229 src); 02230 m_ProjectTreeInfo->m_Src = 02231 CDirEntry::AddTrailingPathSeparator(m_ProjectTreeInfo->m_Src); 02232 02233 // Subtree to build - projects filter 02234 string subtree = CDirEntry::ConcatPath(m_ProjectTreeInfo->m_Root, m_Subtree); 02235 LOG_POST(Info << "Project list or subtree: " << subtree); 02236 if (!CDirEntry(subtree).Exists()) { 02237 LOG_POST(Info << "WARNING: " << subtree << " does not exist"); 02238 } 02239 m_ProjectTreeInfo->m_IProjectFilter.reset( 02240 new CProjectsLstFileFilter(m_ProjectTreeInfo->m_Src, subtree)); 02241 02242 /// <compilers> branch of tree 02243 const string& compilers = GetConfig().Get("ProjectTree", "compilers"); 02244 m_ProjectTreeInfo->m_Compilers = 02245 CDirEntry::ConcatPath(m_ProjectTreeInfo->m_Root, 02246 compilers); 02247 m_ProjectTreeInfo->m_Compilers = 02248 CDirEntry::AddTrailingPathSeparator 02249 (m_ProjectTreeInfo->m_Compilers); 02250 02251 /// ImplicitExcludedBranches - all subdirs will be excluded by default 02252 const string& implicit_exclude_str 02253 = GetConfig().Get("ProjectTree", "ImplicitExclude"); 02254 list<string> implicit_exclude_list; 02255 NStr::Split(implicit_exclude_str, 02256 LIST_SEPARATOR, 02257 implicit_exclude_list); 02258 ITERATE(list<string>, p, implicit_exclude_list) { 02259 const string& subdir = *p; 02260 string dir = CDirEntry::ConcatPath(m_ProjectTreeInfo->m_Src, 02261 subdir); 02262 dir = CDirEntry::AddTrailingPathSeparator(dir); 02263 m_ProjectTreeInfo->m_ImplicitExcludedAbsDirs.push_back(dir); 02264 } 02265 02266 /// <projects> branch of tree (scripts\projects) 02267 const string& projects = CDirEntry::ConvertToOSPath( 02268 GetConfig().Get("ProjectTree", "projects")); 02269 m_ProjectTreeInfo->m_Projects = 02270 CDirEntry::ConcatPath(m_ProjectTreeInfo->m_Root, 02271 projects); 02272 m_ProjectTreeInfo->m_Projects = 02273 CDirEntry::AddTrailingPathSeparator 02274 (m_ProjectTreeInfo->m_Compilers); 02275 02276 /// impl part if include project node 02277 m_ProjectTreeInfo->m_Impl = 02278 GetConfig().Get("ProjectTree", "impl"); 02279 02280 /// Makefile in tree node 02281 m_ProjectTreeInfo->m_TreeNode = 02282 GetConfig().Get("ProjectTree", "TreeNode"); 02283 02284 m_ProjectTreeInfo->m_CustomMetaData = 02285 GetConfig().Get("ProjectTree", "CustomMetaData"); 02286 m_ProjectTreeInfo->m_CustomConfH = 02287 GetConfig().Get("ProjectTree", "CustomConfH"); 02288 02289 return *m_ProjectTreeInfo; 02290 } 02291 02292 02293 const CBuildType& CProjBulderApp::GetBuildType(void) 02294 { 02295 if ( !m_BuildType.get() ) { 02296 m_BuildType.reset(new CBuildType(m_Dll)); 02297 } 02298 return *m_BuildType; 02299 } 02300 02301 const CProjectItemsTree& CProjBulderApp::GetWholeTree(void) 02302 { 02303 if ( !m_WholeTree.get() ) { 02304 m_WholeTree.reset(new CProjectItemsTree); 02305 if (m_ScanWholeTree) { 02306 m_ScanningWholeTree = true; 02307 CProjectsLstFileFilter pass_all_filter(m_ProjectTreeInfo->m_Src, m_ProjectTreeInfo->m_Src); 02308 // pass_all_filter.SetExcludePotential(false); 02309 CProjectTreeBuilder::BuildProjectTree(&pass_all_filter, 02310 GetProjectTreeInfo().m_Src, 02311 m_WholeTree.get()); 02312 m_ScanningWholeTree = false; 02313 } 02314 } 02315 return *m_WholeTree; 02316 } 02317 02318 02319 CDllSrcFilesDistr& CProjBulderApp::GetDllFilesDistr(void) 02320 { 02321 if (m_DllSrcFilesDistr.get()) 02322 return *m_DllSrcFilesDistr; 02323 02324 m_DllSrcFilesDistr.reset ( new CDllSrcFilesDistr() ); 02325 return *m_DllSrcFilesDistr; 02326 } 02327 02328 string CProjBulderApp::GetDataspecProjId(void) const 02329 { 02330 return "_generate_all_objects"; 02331 } 02332 02333 string CProjBulderApp::GetDatatoolId(void) const 02334 { 02335 return GetConfig().GetString("Datatool", "datatool", 02336 CMsvc7RegSettings::GetMsvcPlatform() >= CMsvc7RegSettings::eUnix ? "datatool" : ""); 02337 } 02338 02339 02340 string CProjBulderApp::GetDatatoolPathForApp(void) const 02341 { 02342 if (CMsvc7RegSettings::GetMsvcPlatform() == CMsvc7RegSettings::eXCode) { 02343 return GetConfig().GetString("Datatool", "Location.xcode", "datatool"); 02344 } 02345 return GetConfig().GetString("Datatool", "Location.App", "datatool.exe"); 02346 } 02347 02348 02349 string CProjBulderApp::GetDatatoolPathForLib(void) const 02350 { 02351 if (CMsvc7RegSettings::GetMsvcPlatform() == CMsvc7RegSettings::eXCode) { 02352 return GetConfig().GetString("Datatool", "Location.xcode", "datatool"); 02353 } 02354 return GetConfig().GetString("Datatool", "Location.Lib", "datatool.exe"); 02355 } 02356 02357 02358 string CProjBulderApp::GetDatatoolCommandLine(void) const 02359 { 02360 if (CMsvc7RegSettings::GetMsvcPlatform() == CMsvc7RegSettings::eXCode) { 02361 return GetConfig().GetString("Datatool", "CommandLine.xcode", ""); 02362 } 02363 return GetConfig().Get("Datatool", "CommandLine"); 02364 } 02365 02366 string CProjBulderApp::GetProjectTreeRoot(void) const 02367 { 02368 string path = CDirEntry::ConcatPath( 02369 m_ProjectTreeInfo->m_Compilers, 02370 m_MsvcRegSettings->m_CompilersSubdir); 02371 return CDirEntry::AddTrailingPathSeparator(path); 02372 } 02373 02374 bool CProjBulderApp::IsAllowedProjectTag( 02375 const CProjItem& project, const string* filter /*= NULL*/) const 02376 { 02377 // verify that all project tags are registered 02378 list<string>::const_iterator i; 02379 for (i = project.m_ProjTags.begin(); i != project.m_ProjTags.end(); ++i) { 02380 if (m_RegisteredProjectTags.find(*i) == m_RegisteredProjectTags.end()) { 02381 NCBI_THROW(CProjBulderAppException, eUnknownProjectTag, 02382 project.GetPath() + ": Unregistered project tag: " + *i); 02383 return false; 02384 } 02385 } 02386 02387 if (filter == NULL) { 02388 filter = &m_ProjTags; 02389 } 02390 // no filter - everything is allowed 02391 if (filter->empty() || *filter == "*") { 02392 return true; 02393 } 02394 02395 CExprParser parser; 02396 ITERATE( set<string>, p, m_RegisteredProjectTags) { 02397 parser.AddSymbol(p->c_str(), 02398 find( project.m_ProjTags.begin(), project.m_ProjTags.end(), *p) != project.m_ProjTags.end()); 02399 } 02400 parser.Parse(filter->c_str()); 02401 return parser.GetResult().GetBool(); 02402 } 02403 02404 void CProjBulderApp::LoadProjectTags(const string& filename) 02405 { 02406 CNcbiIfstream ifs(filename.c_str(), IOS_BASE::in | IOS_BASE::binary); 02407 if ( ifs.is_open() ) { 02408 string line; 02409 while ( NcbiGetlineEOL(ifs, line) ) { 02410 if (line.empty() || line[0] == '#') { 02411 continue; 02412 } 02413 list<string> values; 02414 if (line.find('=') != string::npos) { 02415 NStr::Split(line, "=", values); 02416 if (values.size() > 1) { 02417 string first = NStr::TruncateSpaces(values.front()); 02418 string second = NStr::TruncateSpaces(values.back()); 02419 m_CompositeProjectTags[first] = second; 02420 02421 } 02422 continue; 02423 } 02424 NStr::Split(line, LIST_SEPARATOR, values); 02425 ITERATE(list<string>,v,values) { 02426 m_RegisteredProjectTags.insert(*v); 02427 } 02428 } 02429 } 02430 m_RegisteredProjectTags.insert("exe"); 02431 m_RegisteredProjectTags.insert("lib"); 02432 m_RegisteredProjectTags.insert("dll"); 02433 m_RegisteredProjectTags.insert("public"); 02434 m_RegisteredProjectTags.insert("internal"); 02435 } 02436 02437 string CProjBulderApp::ProcessLocationMacros(string raw_data) 02438 { 02439 string data(raw_data), raw_macro, macro, definition; 02440 string::size_type start, end, done = 0; 02441 while ((start = data.find("$(", done)) != string::npos) { 02442 end = data.find(")", start); 02443 if (end == string::npos) { 02444 LOG_POST(Warning << "Possibly incorrect MACRO definition in: " + raw_data); 02445 return data; 02446 } 02447 raw_macro = data.substr(start,end-start+1); 02448 if (CSymResolver::IsDefine(raw_macro)) { 02449 macro = CSymResolver::StripDefine(raw_macro); 02450 definition.erase(); 02451 definition = GetConfig().GetString(CMsvc7RegSettings::GetMsvcSection(), macro, ""); 02452 if (!definition.empty()) { 02453 definition = CDirEntry::ConcatPath( 02454 m_ProjectTreeInfo->m_Compilers, definition); 02455 data = NStr::Replace(data, raw_macro, definition); 02456 } else { 02457 done = end; 02458 } 02459 } 02460 } 02461 return data; 02462 } 02463 02464 void CProjBulderApp::RegisterSuspiciousProject(const CProjKey& proj) 02465 { 02466 m_SuspiciousProj.insert(proj); 02467 } 02468 02469 void CProjBulderApp::RegisterGeneratedFile( const string& file) 02470 { 02471 m_GeneratedFiles.push_back(file); 02472 } 02473 02474 void CProjBulderApp::RegisterProjectWatcher( 02475 const string& project, const string& dir, const string& watcher) 02476 { 02477 if (watcher.empty()) { 02478 return; 02479 } 02480 string sep; 02481 sep += CDirEntry::GetPathSeparator(); 02482 string root(GetProjectTreeInfo().m_Src); 02483 if (!CDirEntry::IsAbsolutePath(root)) { 02484 root = CDirEntry::ConcatPath(CDir::GetCwd(), root); 02485 } 02486 string path(dir); 02487 if (!CDirEntry::IsAbsolutePath(path)) { 02488 path = CDirEntry::ConcatPath(CDir::GetCwd(), path); 02489 } 02490 path = CDirEntry::DeleteTrailingPathSeparator( 02491 CDirEntry::CreateRelativePath(root, path)); 02492 NStr::ReplaceInPlace( path, sep, "/"); 02493 m_ProjWatchers.push_back( project + ", " + path + ", " + watcher ); 02494 } 02495 02496 void CProjBulderApp::ExcludeProjectsByTag(CProjectItemsTree& tree) const 02497 { 02498 EraseIf(tree.m_Projects, PIsExcludedByTag()); 02499 if (!m_ProjTags.empty() && m_ProjTags != "*") { 02500 NON_CONST_ITERATE(CProjectItemsTree::TProjects, p, tree.m_Projects) { 02501 if (p->second.m_ProjType == CProjKey::eDll) { 02502 p->second.m_External = false; 02503 } 02504 } 02505 } 02506 } 02507 02508 void CProjBulderApp::ExcludeUnrequestedProjects(CProjectItemsTree& tree) const 02509 { 02510 EraseIf(tree.m_Projects, PIsExcludedByUser()); 02511 } 02512 02513 string CProjBulderApp::GetUtilityProjectsDir(void) const 02514 { 02515 string utility_projects_dir = CDirEntry(m_Solution).GetDir(); 02516 utility_projects_dir = 02517 CDirEntry::ConcatPath(utility_projects_dir, "UtilityProjects"); 02518 utility_projects_dir = 02519 CDirEntry::AddTrailingPathSeparator(utility_projects_dir); 02520 return utility_projects_dir; 02521 } 02522 02523 string CProjBulderApp::GetUtilityProjectsSrcDir(void) 02524 { 02525 string prj = GetProjectTreeInfo().m_Compilers; 02526 prj = CDirEntry::ConcatPath(prj, GetRegSettings().m_CompilersSubdir); 02527 prj = CDirEntry::ConcatPath(prj, GetBuildType().GetTypeStr()); 02528 prj = CDirEntry::ConcatPath(prj, GetRegSettings().m_ProjectsSubdir); 02529 02530 string sln = CDirEntry(m_Solution).GetDir(); 02531 prj = CDirEntry::CreateRelativePath( prj, sln); 02532 prj = CDirEntry::ConcatPath(GetProjectTreeInfo().m_Src, prj); 02533 prj = CDirEntry::ConcatPath(prj, "UtilityProjects"); 02534 prj = CDirEntry::AddTrailingPathSeparator(prj); 02535 return prj; 02536 } 02537 02538 void CProjBulderApp::SetConfFileData(const string& src, const string& dest) 02539 { 02540 m_ConfSrc = src; 02541 m_ConfDest= dest; 02542 } 02543 02544 CProjBulderApp& GetApp(void) 02545 { 02546 static CProjBulderApp theApp; 02547 return theApp; 02548 } 02549 02550 END_NCBI_SCOPE 02551 02552 02553 USING_NCBI_SCOPE; 02554 02555 int NcbiSys_main(int argc, TXChar* argv[]) 02556 { 02557 // Execute main application function 02558 CDiagContext::SetLogTruncate(true); 02559 GetDiagContext().SetLogRate_Limit(CDiagContext::eLogRate_Err, (unsigned int)-1); 02560 return GetApp().AppMain(argc, argv, 0, eDS_Default); 02561 }
1.7.5.1
Modified on Wed May 23 13:13:17 2012 by modify_doxy.py rev. 337098