1 /* $Id: msvc_masterproject_generator.cpp 195671 2010-06-24 17:25:11Z gouriano $
2  * ===========================================================================
3  *
4  *                            PUBLIC DOMAIN NOTICE
5  *               National Center for Biotechnology Information
6  *
7  *  This software/database is a "United States Government Work" under the
8  *  terms of the United States Copyright Act.  It was written as part of
9  *  the author's official duties as a United States Government employee and
10  *  thus cannot be copyrighted.  This software/database is freely available
11  *  to the public for use. The National Library of Medicine and the U.S.
12  *  Government have not placed any restriction on its use or reproduction.
13  *
14  *  Although all reasonable efforts have been taken to ensure the accuracy
15  *  and reliability of the software and data, the NLM and the U.S.
16  *  Government do not and cannot warrant the performance or results that
17  *  may be obtained by using this software or data. The NLM and the U.S.
18  *  Government disclaim all warranties, express or implied, including
19  *  warranties of performance, merchantability or fitness for any particular
20  *  purpose.
21  *
22  *  Please cite the author in any work or product based on this material.
23  *
24  * ===========================================================================
25  *
26  * Author:  Viatcheslav Gorelenkov
27  *
28  */
29 
30 #include <ncbi_pch.hpp>
31 #include "msvc_prj_generator.hpp"
32 #include "msvc_masterproject_generator.hpp"
33 
34 
35 #include "msvc_prj_utils.hpp"
36 #include "proj_builder_app.hpp"
37 #include "msvc_prj_defines.hpp"
38 #include "ptb_err_codes.hpp"
39 
40 
41 BEGIN_NCBI_SCOPE
42 
43 #if NCBI_COMPILER_MSVC
44 
45 static void
46 s_RegisterCreatedFilter(CRef<CFilter>& filter, CSerialObject* parent);
47 
48 
49 //-----------------------------------------------------------------------------
CMsvcMasterProjectGenerator(const CProjectItemsTree & tree,const list<SConfigInfo> & configs,const string & project_dir)50 CMsvcMasterProjectGenerator::CMsvcMasterProjectGenerator
51     ( const CProjectItemsTree& tree,
52       const list<SConfigInfo>& configs,
53       const string&            project_dir)
54     :m_Tree          (tree),
55      m_Configs       (configs),
56 	 m_Name          ("-HIERARCHICAL-VIEW-"), //_MasterProject
57      m_ProjectDir    (project_dir),
58      m_ProjectItemExt("._"),
59      m_FilesSubdir   ("UtilityProjectsFiles")
60 {
61     m_CustomBuildCommand  = "@echo on\n";
62     if (CMsvc7RegSettings::GetMsvcVersion() == CMsvc7RegSettings::eMsvc710) {
63         m_CustomBuildCommand += "devenv "\
64                                 "/build $(ConfigurationName) "\
65                                 "/project $(InputName) "\
66                                 "\"$(SolutionPath)\"";
67     } else {
68         m_CustomBuildCommand += "msbuild \"$(SolutionPath)\" /t:\"$(InputName)\" /p:Configuration=$(ConfigurationName)";
69         if (CMsvc7RegSettings::GetMsvcVersion() >= CMsvc7RegSettings::eMsvc900) {
70             m_CustomBuildCommand += " /maxcpucount";
71         }
72     }
73     m_CustomBuildCommand  += "\n@echo off";
74     CreateUtilityProject(m_Name, m_Configs, &m_Xmlprj);
75 }
76 
77 
~CMsvcMasterProjectGenerator(void)78 CMsvcMasterProjectGenerator::~CMsvcMasterProjectGenerator(void)
79 {
80 }
81 
82 
83 void
SaveProject()84 CMsvcMasterProjectGenerator::SaveProject()
85 {
86     {{
87         CProjectTreeFolders folders(m_Tree);
88         ProcessTreeFolder(folders.m_RootParent, &m_Xmlprj.SetFiles());
89     }}
90     SaveIfNewer(GetPath(), m_Xmlprj);
91 }
92 
93 
GetPath() const94 string CMsvcMasterProjectGenerator::GetPath() const
95 {
96     string project_path =
97         CDirEntry::ConcatPath(m_ProjectDir, "_HIERARCHICAL_VIEW_");
98     project_path += CMsvc7RegSettings::GetVcprojExt();
99     return project_path;
100 }
101 
102 
ProcessTreeFolder(const SProjectTreeFolder & folder,CSerialObject * parent)103 void CMsvcMasterProjectGenerator::ProcessTreeFolder
104                                         (const SProjectTreeFolder&  folder,
105                                          CSerialObject*             parent)
106 {
107     if ( folder.IsRoot() ) {
108 
109         ITERATE(SProjectTreeFolder::TSiblings, p, folder.m_Siblings) {
110 
111             ProcessTreeFolder(*(p->second), parent);
112         }
113     } else {
114 
115         CRef<CFilter> filter(new CFilter());
116         filter->SetAttlist().SetName(folder.m_Name);
117         filter->SetAttlist().SetFilter("");
118         s_RegisterCreatedFilter(filter, parent);
119 
120         ITERATE(SProjectTreeFolder::TProjects, p, folder.m_Projects) {
121 
122             const CProjKey& project_id = *p;
123             AddProjectToFilter(filter, project_id);
124         }
125         ITERATE(SProjectTreeFolder::TSiblings, p, folder.m_Siblings) {
126 
127             ProcessTreeFolder(*(p->second), filter);
128         }
129     }
130 }
131 
132 
133 static void
s_RegisterCreatedFilter(CRef<CFilter> & filter,CSerialObject * parent)134 s_RegisterCreatedFilter(CRef<CFilter>& filter, CSerialObject* parent)
135 {
136     {{
137         // Files section?
138         CFiles* files_parent = dynamic_cast< CFiles* >(parent);
139         if (files_parent != NULL) {
140             // Parent is <Files> section of MSVC project
141             files_parent->SetFilter().push_back(filter);
142             return;
143         }
144     }}
145     {{
146         // Another folder?
147         CFilter* filter_parent = dynamic_cast< CFilter* >(parent);
148         if (filter_parent != NULL) {
149             // Parent is another Filter (folder)
150             CRef< CFilter_Base::C_FF::C_E > ce(new CFilter_Base::C_FF::C_E());
151             ce->SetFilter(*filter);
152             filter_parent->SetFF().SetFF().push_back(ce);
153             return;
154         }
155     }}
156 }
157 
158 void
AddProjectToFilter(CRef<CFilter> & filter,const CProjKey & project_id)159 CMsvcMasterProjectGenerator::AddProjectToFilter(CRef<CFilter>&   filter,
160                                                 const CProjKey&  project_id)
161 {
162     CProjectItemsTree::TProjects::const_iterator p =
163         m_Tree.m_Projects.find(project_id);
164 
165     if (p != m_Tree.m_Projects.end()) {
166         // Add project to this filter (folder)
167 //        const CProjItem& project = p->second;
168         CreateProjectFileItem(project_id);
169 
170         SCustomBuildInfo build_info;
171         string project_name = CreateProjectName(project_id);
172         if (CMsvc7RegSettings::GetMsvcVersion() > CMsvc7RegSettings::eMsvc710) {
173             project_name = NStr::Replace( project_name, ".", "_");
174         }
175         string source_file_path_abs =
176             CDirEntry::ConcatPath(m_ProjectDir,
177                                   project_name + m_ProjectItemExt);
178         source_file_path_abs = CDirEntry::NormalizePath(source_file_path_abs);
179 
180         build_info.m_SourceFile  = source_file_path_abs;
181         build_info.m_Description = "Building project : $(InputName)";
182         build_info.m_CommandLine = m_CustomBuildCommand;
183         build_info.m_Outputs     = "$(InputPath).aanofile.out";
184 
185         AddCustomBuildFileToFilter(filter,
186                                    m_Configs,
187                                    m_ProjectDir,
188                                    build_info);
189 
190     } else {
191         PTB_WARNING_EX(project_id.Id(), ePTB_ProjectNotFound,
192                        "Project not found: " << project_id.Id());
193     }
194 }
195 
196 
197 void
CreateProjectFileItem(const CProjKey & project_id)198 CMsvcMasterProjectGenerator::CreateProjectFileItem(const CProjKey& project_id)
199 {
200     string project_name = CreateProjectName(project_id);
201     if (CMsvc7RegSettings::GetMsvcVersion() > CMsvc7RegSettings::eMsvc710) {
202         project_name = NStr::Replace( project_name, ".", "_");
203     }
204     string file_path =
205         CDirEntry::ConcatPath(m_ProjectDir, project_name);
206 
207     file_path += m_ProjectItemExt;
208 
209     // Create dir if no such dir...
210     string dir;
211     CDirEntry::SplitPath(file_path, &dir);
212     CDir project_dir(dir);
213     if ( !project_dir.Exists() ) {
214         CDir(dir).CreatePath();
215     }
216 
217     CNcbiOfstream  ofs(file_path.c_str(), IOS_BASE::out | IOS_BASE::trunc);
218     if ( !ofs )
219         NCBI_THROW(CProjBulderAppException, eFileCreation, file_path);
220 }
221 
222 #endif //NCBI_COMPILER_MSVC
223 
224 END_NCBI_SCOPE
225