1 /* $Id: msvc_configure.cpp 622157 2020-12-21 15:39:27Z ivanov $
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_configure.hpp"
32 #include "proj_builder_app.hpp"
33 #include "util/random_gen.hpp"
34
35 #include "ptb_err_codes.hpp"
36 #ifdef NCBI_XCODE_BUILD
37 #include <sys/utsname.h>
38 #include <unistd.h>
39 #endif
40
41 #include <corelib/ncbiexec.hpp>
42 #include <util/xregexp/regexp.hpp>
43
44
45 BEGIN_NCBI_SCOPE
46
47
CMsvcConfigure(void)48 CMsvcConfigure::CMsvcConfigure(void)
49 : m_HaveBuildVer(false)
50 {
51 }
52
53
~CMsvcConfigure(void)54 CMsvcConfigure::~CMsvcConfigure(void)
55 {
56 }
57
58
s_ResetLibInstallKey(const string & dir,const string & lib)59 void s_ResetLibInstallKey(const string& dir,
60 const string& lib)
61 {
62 string key_file_name(lib);
63 NStr::ToLower(key_file_name);
64 key_file_name += ".installed";
65 string key_file_path = CDirEntry::ConcatPath(dir, key_file_name);
66 if ( CDirEntry(key_file_path).Exists() ) {
67 CDirEntry(key_file_path).Remove();
68 }
69 }
70
71
s_CreateThirdPartyLibsInstallMakefile(CMsvcSite & site,const list<string> libs_to_install,const SConfigInfo & config,const CBuildType & build_type)72 static void s_CreateThirdPartyLibsInstallMakefile
73 (CMsvcSite& site,
74 const list<string> libs_to_install,
75 const SConfigInfo& config,
76 const CBuildType& build_type)
77 {
78 // Create makefile path
79 string makefile_path = GetApp().GetProjectTreeInfo().m_Compilers;
80 makefile_path =
81 CDirEntry::ConcatPath(makefile_path,
82 GetApp().GetRegSettings().m_CompilersSubdir);
83
84 makefile_path = CDirEntry::ConcatPath(makefile_path, build_type.GetTypeStr());
85 makefile_path = CDirEntry::ConcatPath(makefile_path, config.GetConfigFullName());
86 makefile_path = CDirEntry::ConcatPath(makefile_path,
87 "Makefile.third_party.mk");
88
89 // Create dir if no such dir...
90 string dir;
91 CDirEntry::SplitPath(makefile_path, &dir);
92 CDir makefile_dir(dir);
93 if ( !makefile_dir.Exists() ) {
94 CDir(dir).CreatePath();
95 }
96
97 CNcbiOfstream ofs(makefile_path.c_str(),
98 IOS_BASE::out | IOS_BASE::trunc );
99 if ( !ofs )
100 NCBI_THROW(CProjBulderAppException, eFileCreation, makefile_path);
101
102 GetApp().RegisterGeneratedFile( makefile_path );
103 ITERATE(list<string>, n, libs_to_install) {
104 const string& lib = *n;
105 SLibInfo lib_info;
106 site.GetLibInfo(lib, config, &lib_info);
107 if ( !lib_info.m_LibPath.empty() ) {
108 string bin_dir = lib_info.m_LibPath;
109 string bin_path = lib_info.m_BinPath;
110 if (bin_path.empty()) {
111 bin_path = site.GetThirdPartyLibsBinSubDir();
112 }
113 bin_dir =
114 CDirEntry::ConcatPath(bin_dir, bin_path);
115 bin_dir = CDirEntry::NormalizePath(bin_dir);
116 if ( CDirEntry(bin_dir).Exists() ) {
117 //
118 string key(lib);
119 NStr::ToUpper(key);
120 key += site.GetThirdPartyLibsBinPathSuffix();
121
122 ofs << key << " = " << bin_dir << "\n";
123
124 s_ResetLibInstallKey(dir, lib);
125 site.SetThirdPartyLibBin(lib, bin_dir);
126 } else {
127 PTB_WARNING_EX(bin_dir, ePTB_PathNotFound,
128 lib << "|" << config.GetConfigFullName()
129 << " disabled, path not found");
130 }
131 } else {
132 PTB_WARNING_EX(kEmptyStr, ePTB_PathNotFound,
133 lib << "|" << config.GetConfigFullName()
134 << ": no LIBPATH specified");
135 }
136 }
137 }
138
139
Configure(CMsvcSite & site,const list<SConfigInfo> & configs,const string & root_dir)140 void CMsvcConfigure::Configure(CMsvcSite& site,
141 const list<SConfigInfo>& configs,
142 const string& root_dir)
143 {
144 _TRACE("*** Analyzing 3rd party libraries availability ***");
145
146 site.InitializeLibChoices();
147 InitializeFrom(site);
148 site.ProcessMacros(configs);
149
150 if (CMsvc7RegSettings::GetMsvcPlatform() >= CMsvc7RegSettings::eUnix) {
151 return;
152 }
153 _TRACE("*** Creating Makefile.third_party.mk files ***");
154 // Write makefile uses to install 3-rd party dlls
155 list<string> third_party_to_install;
156 site.GetThirdPartyLibsToInstall(&third_party_to_install);
157 // For static buid
158 ITERATE(list<SConfigInfo>, p, configs) {
159 const SConfigInfo& config = *p;
160 s_CreateThirdPartyLibsInstallMakefile(site,
161 third_party_to_install,
162 config,
163 GetApp().GetBuildType());
164 }
165 }
166
CreateConfH(CMsvcSite & site,const list<SConfigInfo> & configs,const string & root_dir)167 void CMsvcConfigure::CreateConfH(
168 CMsvcSite& site,
169 const list<SConfigInfo>& configs,
170 const string& root_dir)
171 {
172 CMsvc7RegSettings::EMsvcPlatform platform = CMsvc7RegSettings::GetMsvcPlatform();
173
174 ITERATE(list<SConfigInfo>, p, configs) {
175 WriteExtraDefines(site, root_dir, *p);
176 // Windows and XCode only. On Unix build version header file is generated by configure, not PTB.
177 if (platform != CMsvc7RegSettings::eUnix) {
178 WriteBuildVer(site, root_dir, *p);
179 }
180 }
181 if (platform == CMsvc7RegSettings::eUnix) {
182 return;
183 }
184 _TRACE("*** Creating local ncbiconf headers ***");
185 const CBuildType& build_type(GetApp().GetBuildType());
186 ITERATE(list<SConfigInfo>, p, configs) {
187 /*if (!p->m_VTuneAddon && !p->m_Unicode)*/ {
188 AnalyzeDefines( site, root_dir, *p, build_type);
189 }
190 }
191 }
192
193
InitializeFrom(const CMsvcSite & site)194 void CMsvcConfigure::InitializeFrom(const CMsvcSite& site)
195 {
196 m_ConfigSite.clear();
197
198 m_ConfigureDefinesPath = site.GetConfigureDefinesPath();
199 if ( m_ConfigureDefinesPath.empty() ) {
200 NCBI_THROW(CProjBulderAppException,
201 eConfigureDefinesPath,
202 "Configure defines file name is not specified");
203 }
204
205 site.GetConfigureDefines(&m_ConfigureDefines);
206 if( m_ConfigureDefines.empty() ) {
207 PTB_ERROR(m_ConfigureDefinesPath,
208 "No configurable macro definitions specified.");
209 } else {
210 _TRACE("Configurable macro definitions: ");
211 ITERATE(list<string>, p, m_ConfigureDefines) {
212 _TRACE(*p);
213 }
214 }
215 }
216
217
ProcessDefine(const string & define,const CMsvcSite & site,const SConfigInfo & config) const218 bool CMsvcConfigure::ProcessDefine(const string& define,
219 const CMsvcSite& site,
220 const SConfigInfo& config) const
221 {
222 if ( !site.IsDescribed(define) ) {
223 PTB_ERROR_EX(kEmptyStr, ePTB_MacroUndefined,
224 define << ": Macro not defined");
225 return false;
226 }
227 list<string> components;
228 site.GetComponents(define, &components);
229 ITERATE(list<string>, p, components) {
230 const string& component = *p;
231 if (site.IsBanned(component)) {
232 PTB_WARNING_EX("", ePTB_ConfigurationError,
233 component << "|" << config.GetConfigFullName()
234 << ": " << define << " not provided, disabled");
235 return false;
236 }
237 if (site.IsProvided( component, false)) {
238 continue;
239 }
240 SLibInfo lib_info;
241 site.GetLibInfo(component, config, &lib_info);
242 if ( !site.IsLibOk(lib_info) ||
243 !site.IsLibEnabledInConfig(component, config)) {
244 if (!lib_info.IsEmpty()) {
245 PTB_WARNING_EX("", ePTB_ConfigurationError,
246 component << "|" << config.GetConfigFullName()
247 << ": " << define << " not satisfied, disabled");
248 }
249 return false;
250 }
251 }
252 return true;
253 }
254
255
WriteExtraDefines(CMsvcSite & site,const string & root_dir,const SConfigInfo & config)256 void CMsvcConfigure::WriteExtraDefines(CMsvcSite& site, const string& root_dir, const SConfigInfo& config)
257 {
258 string cfg = CMsvc7RegSettings::GetConfigNameKeyword();
259 string cfg_root_inc(root_dir);
260 if (!cfg.empty()) {
261 NStr::ReplaceInPlace(cfg_root_inc,cfg,config.GetConfigFullName());
262 }
263 string extra = site.GetConfigureEntry("ExtraDefines");
264 string filename = CDirEntry::ConcatPath(cfg_root_inc, extra);
265 int random_count = NStr::StringToInt(site.GetConfigureEntry("RandomValueCount"), NStr::fConvErr_NoThrow);
266
267 if (extra.empty() || random_count <= 0 || CFile(filename).Exists()) {
268 return;
269 }
270
271 string dir;
272 CDirEntry::SplitPath(filename, &dir);
273 CDir(dir).CreatePath();
274
275 CNcbiOfstream ofs(filename.c_str(), IOS_BASE::out | IOS_BASE::trunc);
276 if ( !ofs ) {
277 NCBI_THROW(CProjBulderAppException, eFileCreation, filename);
278 }
279 WriteNcbiconfHeader(ofs);
280
281 CRandom rnd(CRandom::eGetRand_Sys);
282 string prefix("#define NCBI_RANDOM_VALUE_");
283 ofs << prefix << "TYPE Uint4" << endl;
284 ofs << prefix << "MIN 0" << endl;
285 ofs << prefix << "MAX " << std::hex
286 << std::showbase << rnd.GetMax() << endl << endl;
287 for (int i = 0; i < random_count; ++i) {
288 ofs << prefix << std::noshowbase << i
289 << setw(16) << std::showbase << rnd.GetRand() << endl;
290 }
291 ofs << endl;
292 GetApp().RegisterGeneratedFile( filename );
293 }
294
295
296
WriteBuildVer(CMsvcSite & site,const string & root_dir,const SConfigInfo & config)297 void CMsvcConfigure::WriteBuildVer(CMsvcSite& site, const string& root_dir, const SConfigInfo& config)
298 {
299 static TXChar* filename_cache = NULL;
300
301 string cfg = CMsvc7RegSettings::GetConfigNameKeyword();
302 string cfg_root_inc(root_dir);
303 if (!cfg.empty()) {
304 NStr::ReplaceInPlace(cfg_root_inc, cfg, config.GetConfigFullName());
305 }
306 string extra = CDirEntry::ConvertToOSPath(site.GetConfigureEntry("BuildVerPath"));
307 string filename = CDirEntry::ConcatPath(cfg_root_inc, extra);
308
309 if (extra.empty()) {
310 return;
311 }
312
313 string dir;
314 CDirEntry::SplitPath(filename, &dir);
315 CDir(dir).CreatePath();
316
317 // Each file with build version information is the same for each configuration,
318 // so create it once and copy to each configuration on next calls.
319
320 if (filename_cache) {
321 CFile src(_T_STDSTRING(filename_cache));
322 CFile dst(filename);
323 if (!dst.Exists() || src.IsNewer(dst.GetPath(),0)) {
324 src.Copy(filename, CFile::fCF_Overwrite);
325 GetApp().RegisterGeneratedFile( filename );
326 }
327 return;
328 }
329
330 // get vars
331 string tc_ver = GetApp().GetEnvironment().Get("TEAMCITY_VERSION");
332 string tc_build = GetApp().GetEnvironment().Get("BUILD_NUMBER");
333 string tc_build_id;
334 string tc_prj = GetApp().GetEnvironment().Get("TEAMCITY_PROJECT_NAME");
335 string tc_conf = GetApp().GetEnvironment().Get("TEAMCITY_BUILDCONF_NAME");
336 string svn_rev = GetApp().GetEnvironment().Get("SVNREV");
337 string sc_ver = GetApp().GetEnvironment().Get("SCVER");
338
339 // Get content of the Teamcity property file, if any
340 string prop_file_name = GetApp().GetEnvironment().Get("TEAMCITY_BUILD_PROPERTIES_FILE");
341 string prop_file_info;
342 if (!prop_file_name.empty()) {
343 CNcbiIfstream is(prop_file_name.c_str(), IOS_BASE::in);
344 if (is.good()) {
345 NcbiStreamToString(&prop_file_info, is);
346 // teamcity.build.id
347 if (!prop_file_info.empty()) {
348 CRegexp re("teamcity.build.id=(\\d+)");
349 tc_build_id = re.GetMatch(prop_file_info, 0, 1);
350 }
351 }
352 }
353 string tree_root = GetApp().GetEnvironment().Get("TREE_ROOT");
354 if (tree_root.empty()) {
355 tree_root = GetApp().GetProjectTreeInfo().m_Root;
356 }
357 if (!tree_root.empty()) {
358 // Get SVN info
359 string tmp_file = CFile::GetTmpName();
360
361 string cmd = "svn info " + tree_root + " > " + tmp_file;
362 TExitCode ret = CExec::System(cmd.c_str());
363 if (ret == 0) {
364 // SVN client present, parse results
365 string info;
366 {
367 CNcbiIfstream is(tmp_file.c_str(), IOS_BASE::in);
368 NcbiStreamToString(&info, is);
369 CFile(tmp_file).Remove();
370 if (!info.empty()) {
371 CRegexp re("Revision: (\\d+)");
372 svn_rev = re.GetMatch(info, 0, 1);
373 }
374 }
375 cmd = "svn info " + CDir::ConcatPath(tree_root, "src/build-system") + " > " + tmp_file;
376 ret = CExec::System(cmd.c_str());
377 if (ret == 0) {
378 CNcbiIfstream is(tmp_file.c_str(), IOS_BASE::in);
379 NcbiStreamToString(&info, is);
380 CFile(tmp_file).Remove();
381 if (!info.empty()) {
382 CRegexp re("/production/components/[^/]*/(\\d+)");
383 sc_ver = re.GetMatch(info, 0, 1);
384 }
385 }
386 }
387 else {
388 // Fallback
389 if (sc_ver.empty()) {
390 sc_ver = GetApp().GetEnvironment().Get("NCBI_SC_VERSION");
391 }
392 // try to get revision bumber from teamcity property file
393 if (svn_rev.empty() && !prop_file_info.empty()) {
394 CRegexp re("build.vcs.number=(\\d+)");
395 svn_rev = re.GetMatch(prop_file_info, 0, 1);
396 }
397 }
398 }
399 if (tc_build.empty()) {tc_build = "0";}
400 if (sc_ver.empty()) {sc_ver = "0";}
401 if (svn_rev.empty()) {svn_rev = "0";}
402
403 map<string,string> build_vars;
404 build_vars["NCBI_TEAMCITY_BUILD_NUMBER"] = tc_build;
405 build_vars["NCBI_TEAMCITY_BUILD_ID"] = tc_build_id;
406 build_vars["NCBI_TEAMCITY_PROJECT_NAME"] = tc_prj;
407 build_vars["NCBI_TEAMCITY_BUILDCONF_NAME"] = tc_conf;
408 build_vars["NCBI_SUBVERSION_REVISION"] = svn_rev;
409 build_vars["NCBI_SC_VERSION"] = sc_ver;
410
411 auto converter = [](const string& file_in, const string& file_out, const map<string,string>& vocabulary) {
412 string candidate = file_out + ".candidate";
413 CNcbiOfstream ofs(candidate.c_str(), IOS_BASE::out | IOS_BASE::trunc);
414 if ( ofs.is_open() ) {
415
416 CNcbiIfstream ifs(file_in.c_str());
417 if (ifs.is_open()) {
418 string line;
419 while( getline(ifs, line) ) {
420 for (string::size_type from = line.find("@"); from != string::npos; from = line.find("@")) {
421 string::size_type to = line.find("@", from + 1);
422 if (to != string::npos) {
423 string key = line.substr(from+1, to-from-1);
424 if (vocabulary.find(key) != vocabulary.end()) {
425 line.replace(from, to-from+1, vocabulary.at(key));
426 } else {
427 line.replace(from, to-from+1, "");
428 }
429 }
430 }
431 ofs << line << endl;
432 }
433 ifs.close();
434 }
435 ofs.close();
436 PromoteIfDifferent(file_out, candidate);
437 }
438 };
439
440 string file_in = CDirEntry::ConvertToOSPath(CDirEntry::ConcatPath(GetApp().GetProjectTreeInfo().m_Include, "common/ncbi_build_ver.h.in"));
441 converter(file_in, filename, build_vars);
442 // Cache file name for the generated file
443 filename_cache = NcbiSys_strdup(_T_XCSTRING(filename));
444 m_HaveBuildVer = true;
445
446 filename = CDirEntry::ConvertToOSPath(CDirEntry::ConcatPath(GetApp().GetProjectTreeInfo().m_Include, "common/ncbi_revision.h"));
447 file_in = CDirEntry::ConvertToOSPath(CDirEntry::ConcatPath(GetApp().GetProjectTreeInfo().m_Include, "common/ncbi_revision.h.in"));
448 converter(file_in, filename, build_vars);
449 }
450
451
AnalyzeDefines(CMsvcSite & site,const string & root_dir,const SConfigInfo & config,const CBuildType & build_type)452 void CMsvcConfigure::AnalyzeDefines(
453 CMsvcSite& site, const string& root_dir,
454 const SConfigInfo& config, const CBuildType& build_type)
455 {
456 string cfg_root_inc = NStr::Replace(root_dir,
457 CMsvc7RegSettings::GetConfigNameKeyword(),config.GetConfigFullName());
458 string filename =
459 CDirEntry::ConcatPath(cfg_root_inc, m_ConfigureDefinesPath);
460 string dir;
461 CDirEntry::SplitPath(filename, &dir);
462
463 _TRACE("Configuration " << config.m_Name << ":");
464
465 m_ConfigSite.clear();
466
467 ITERATE(list<string>, p, m_ConfigureDefines) {
468 const string& define = *p;
469 if( ProcessDefine(define, site, config) ) {
470 _TRACE("Macro definition Ok " << define);
471 m_ConfigSite[define] = '1';
472 } else {
473 PTB_WARNING_EX(kEmptyStr, ePTB_MacroUndefined,
474 "Macro definition not satisfied: " << define);
475 m_ConfigSite[define] = '0';
476 }
477 }
478 if (m_HaveBuildVer) {
479 // Add define that we have build version info file
480 m_ConfigSite["HAVE_COMMON_NCBI_BUILD_VER_H"] = '1';
481 }
482
483 string signature;
484 if (CMsvc7RegSettings::GetMsvcPlatform() < CMsvc7RegSettings::eUnix) {
485 signature = "MSVC";
486 } else if (CMsvc7RegSettings::GetMsvcPlatform() > CMsvc7RegSettings::eUnix) {
487 signature = "XCODE";
488 } else {
489 signature = CMsvc7RegSettings::GetMsvcPlatformName();
490 }
491 signature += "_";
492 signature += CMsvc7RegSettings::GetMsvcVersionName();
493 signature += "-" + config.GetConfigFullName();
494 if (config.m_rtType == SConfigInfo::rtMultiThreadedDLL ||
495 config.m_rtType == SConfigInfo::rtMultiThreadedDebugDLL) {
496 signature += "MT";
497 }
498 #ifdef NCBI_XCODE_BUILD
499 string tmp = CMsvc7RegSettings::GetRequestedArchs();
500 NStr::ReplaceInPlace(tmp, " ", "_");
501 signature += "_" + tmp;
502 signature += "--";
503 struct utsname u;
504 if (uname(&u) == 0) {
505 // signature += string(u.machine) + string("-apple-") + string(u.sysname) + string(u.release);
506 signature +=
507 GetApp().GetSite().GetPlatformInfo( u.sysname, "arch", u.machine) +
508 string("-apple-") +
509 GetApp().GetSite().GetPlatformInfo( u.sysname, "os", u.sysname) +
510 string(u.release);
511 } else {
512 signature += HOST;
513 }
514 signature += "-";
515 {
516 char hostname[255];
517 string tmp1, tmp2;
518 if (0 == gethostname(hostname, 255))
519 NStr::SplitInTwo(hostname,".", tmp1, tmp2);
520 signature += tmp1;
521 }
522 #else
523 signature += "--";
524 if (CMsvc7RegSettings::GetMsvcPlatform() < CMsvc7RegSettings::eUnix) {
525 signature += "i386-pc-";
526 signature += CMsvc7RegSettings::GetRequestedArchs();
527 } else {
528 signature += HOST;
529 }
530 signature += "-";
531 if (CMsvc7RegSettings::GetMsvcPlatform() < CMsvc7RegSettings::eUnix) {
532 signature += GetApp().GetEnvironment().Get("COMPUTERNAME");
533 }
534 #endif
535
536 string candidate_path = filename + ".candidate";
537 CDirEntry::SplitPath(filename, &dir);
538 CDir(dir).CreatePath();
539 WriteNcbiconfMsvcSite(candidate_path, signature);
540 if (PromoteIfDifferent(filename, candidate_path)) {
541 PTB_WARNING_EX(filename, ePTB_FileModified,
542 "Configuration file modified");
543 } else {
544 PTB_INFO_EX(filename, ePTB_NoError,
545 "Configuration file unchanged");
546 }
547 }
548
WriteNcbiconfHeader(CNcbiOfstream & ofs) const549 CNcbiOfstream& CMsvcConfigure::WriteNcbiconfHeader(CNcbiOfstream& ofs) const
550 {
551 ofs <<"/* $" << "Id" << "$" << endl;
552 ofs <<"* ===========================================================================" << endl;
553 ofs <<"*" << endl;
554 ofs <<"* PUBLIC DOMAIN NOTICE" << endl;
555 ofs <<"* National Center for Biotechnology Information" << endl;
556 ofs <<"*" << endl;
557 ofs <<"* This software/database is a \"United States Government Work\" under the" << endl;
558 ofs <<"* terms of the United States Copyright Act. It was written as part of" << endl;
559 ofs <<"* the author's official duties as a United States Government employee and" << endl;
560 ofs <<"* thus cannot be copyrighted. This software/database is freely available" << endl;
561 ofs <<"* to the public for use. The National Library of Medicine and the U.S." << endl;
562 ofs <<"* Government have not placed any restriction on its use or reproduction." << endl;
563 ofs <<"*" << endl;
564 ofs <<"* Although all reasonable efforts have been taken to ensure the accuracy" << endl;
565 ofs <<"* and reliability of the software and data, the NLM and the U.S." << endl;
566 ofs <<"* Government do not and cannot warrant the performance or results that" << endl;
567 ofs <<"* may be obtained by using this software or data. The NLM and the U.S." << endl;
568 ofs <<"* Government disclaim all warranties, express or implied, including" << endl;
569 ofs <<"* warranties of performance, merchantability or fitness for any particular" << endl;
570 ofs <<"* purpose." << endl;
571 ofs <<"*" << endl;
572 ofs <<"* Please cite the author in any work or product based on this material." << endl;
573 ofs <<"*" << endl;
574 ofs <<"* ===========================================================================" << endl;
575 ofs <<"*" << endl;
576 ofs <<"* Author: ......." << endl;
577 ofs <<"*" << endl;
578 ofs <<"* File Description:" << endl;
579 ofs <<"* ......." << endl;
580 ofs <<"*" << endl;
581 ofs <<"* ATTENTION:" << endl;
582 ofs <<"* Do not edit or commit this file into SVN as this file will" << endl;
583 ofs <<"* be overwritten (by PROJECT_TREE_BUILDER) without warning!" << endl;
584 ofs <<"*/" << endl;
585 ofs << endl;
586 ofs << endl;
587 return ofs;
588 }
589
WriteNcbiconfMsvcSite(const string & full_path,const string & signature) const590 void CMsvcConfigure::WriteNcbiconfMsvcSite(
591 const string& full_path, const string& signature) const
592 {
593 CNcbiOfstream ofs(full_path.c_str(),
594 IOS_BASE::out | IOS_BASE::trunc );
595 if ( !ofs )
596 NCBI_THROW(CProjBulderAppException, eFileCreation, full_path);
597
598 WriteNcbiconfHeader(ofs);
599
600 ITERATE(TConfigSite, p, m_ConfigSite) {
601 if (p->second == '1') {
602 ofs << "#define " << p->first << " " << p->second << endl;
603 } else {
604 ofs << "/* #undef " << p->first << " */" << endl;
605 }
606 }
607 ofs << endl;
608 ofs << "#define NCBI_SIGNATURE \\" << endl << " \"" << signature << "\"" << endl;
609
610 list<string> customH;
611 GetApp().GetCustomConfH(&customH);
612 ITERATE(list<string>, c, customH) {
613 string file (CDirEntry::CreateRelativePath(GetApp().m_Root, *c));
614 NStr::ReplaceInPlace(file, "\\", "/");
615 ofs << endl << "/*"
616 << endl << "* ==========================================================================="
617 << endl << "* Included contents of " << file
618 << endl << "*/"
619 << endl;
620
621 CNcbiIfstream is(c->c_str(), IOS_BASE::in | IOS_BASE::binary);
622 if ( !is ) {
623 continue;
624 }
625 char buf[1024];
626 while ( is ) {
627 is.read(buf, sizeof(buf));
628 ofs.write(buf, is.gcount());
629 }
630 }
631 }
632
633
634 END_NCBI_SCOPE
635