cmMSDotNETGenerator.cxx 41 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287
  1. /*=========================================================================
  2. Program: Insight Segmentation & Registration Toolkit
  3. Module: $RCSfile$
  4. Language: C++
  5. Date: $Date$
  6. Version: $Revision$
  7. Copyright (c) 2002 Insight Consortium. All rights reserved.
  8. See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.
  9. This software is distributed WITHOUT ANY WARRANTY; without even
  10. the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  11. PURPOSE. See the above copyright notices for more information.
  12. =========================================================================*/
  13. #include "cmMSDotNETGenerator.h"
  14. #include "cmStandardIncludes.h"
  15. #include "cmMakefile.h"
  16. #include "cmCacheManager.h"
  17. #include "windows.h"
  18. #include "cmSystemTools.h"
  19. #include "cmRegularExpression.h"
  20. #include "cmSourceGroup.h"
  21. cmMSDotNETGenerator::cmMSDotNETGenerator()
  22. {
  23. // default to building a sln project file
  24. BuildProjOn();
  25. }
  26. void cmMSDotNETGenerator::GenerateMakefile()
  27. {
  28. std::string configTypes = m_Makefile->GetDefinition("CMAKE_CONFIGURATION_TYPES");
  29. std::string::size_type start = 0;
  30. std::string::size_type endpos = 0;
  31. while(endpos != std::string::npos)
  32. {
  33. endpos = configTypes.find(' ', start);
  34. if(endpos != std::string::npos)
  35. {
  36. std::string config = configTypes.substr(start, endpos - start);
  37. if(config == "Debug" || config == "Release" ||
  38. config == "MinSizeRel" || config == "RelWithDebInfo")
  39. {
  40. m_Configurations.push_back(config);
  41. }
  42. else
  43. {
  44. cmSystemTools::Error("Invalid configuration type in CMAKE_CONFIGURATION_TYPES: ",
  45. config.c_str(),
  46. " (Valid types are Debug,Release,MinSizeRel,RelWithDebInfo)");
  47. }
  48. }
  49. start = endpos+1;
  50. }
  51. if(m_Configurations.size() == 0)
  52. {
  53. m_Configurations.push_back("Debug");
  54. m_Configurations.push_back("Release");
  55. }
  56. if(m_BuildSLN)
  57. {
  58. this->OutputSLNFile();
  59. }
  60. else
  61. {
  62. this->OutputVCProjFile();
  63. }
  64. }
  65. cmMSDotNETGenerator::~cmMSDotNETGenerator()
  66. {
  67. }
  68. void cmMSDotNETGenerator::SetLocal(bool local)
  69. {
  70. m_BuildSLN = !local;
  71. }
  72. void cmMSDotNETGenerator::ComputeSystemInfo()
  73. {
  74. // now load the settings
  75. if(!m_Makefile->GetDefinition("CMAKE_ROOT"))
  76. {
  77. cmSystemTools::Error(
  78. "CMAKE_ROOT has not been defined, bad GUI or driver program");
  79. return;
  80. }
  81. std::string fpath =
  82. m_Makefile->GetDefinition("CMAKE_ROOT");
  83. fpath += "/Templates/CMakeDotNetSystemConfig.cmake";
  84. m_Makefile->ReadListFile(NULL,fpath.c_str());
  85. }
  86. // output the SLN file
  87. void cmMSDotNETGenerator::OutputSLNFile()
  88. {
  89. // if this is an out of source build, create the output directory
  90. if(strcmp(m_Makefile->GetStartOutputDirectory(),
  91. m_Makefile->GetHomeDirectory()) != 0)
  92. {
  93. if(!cmSystemTools::MakeDirectory(m_Makefile->GetStartOutputDirectory()))
  94. {
  95. cmSystemTools::Error("Error creating output directory for SLN file",
  96. m_Makefile->GetStartOutputDirectory());
  97. }
  98. }
  99. // create the dsw file name
  100. std::string fname;
  101. fname = m_Makefile->GetStartOutputDirectory();
  102. fname += "/";
  103. if(strlen(m_Makefile->GetProjectName()) == 0)
  104. {
  105. m_Makefile->SetProjectName("Project");
  106. }
  107. fname += m_Makefile->GetProjectName();
  108. fname += ".sln";
  109. std::ofstream fout(fname.c_str());
  110. if(!fout)
  111. {
  112. cmSystemTools::Error("Error can not open SLN file for write: "
  113. ,fname.c_str());
  114. return;
  115. }
  116. this->WriteSLNFile(fout);
  117. }
  118. // Write a SLN file to the stream
  119. void cmMSDotNETGenerator::WriteSLNFile(std::ostream& fout)
  120. {
  121. // Write out the header for a SLN file
  122. this->WriteSLNHeader(fout);
  123. // Create a list of cmMakefile created from all the
  124. // CMakeLists.txt files that are in sub directories of
  125. // this one.
  126. std::vector<cmMakefile*> allListFiles;
  127. // add this makefile to the list
  128. allListFiles.push_back(m_Makefile);
  129. // add a special target that depends on ALL projects for easy build
  130. // of Debug only
  131. m_Makefile->AddUtilityCommand("ALL_BUILD", "echo", "\"Build all projects\"",
  132. false);
  133. std::string ctest = m_Makefile->GetDefinition("CMAKE_COMMAND");
  134. ctest = cmSystemTools::GetFilenamePath(ctest.c_str());
  135. ctest += "/";
  136. ctest += "ctest";
  137. ctest += cmSystemTools::GetExecutableExtension();
  138. if(!cmSystemTools::FileExists(ctest.c_str()))
  139. {
  140. ctest = m_Makefile->GetDefinition("CMAKE_COMMAND");
  141. ctest = cmSystemTools::GetFilenamePath(ctest.c_str());
  142. ctest += "/Debug/";
  143. ctest += "ctest";
  144. ctest += cmSystemTools::GetExecutableExtension();
  145. }
  146. if(!cmSystemTools::FileExists(ctest.c_str()))
  147. {
  148. ctest = m_Makefile->GetDefinition("CMAKE_COMMAND");
  149. ctest = cmSystemTools::GetFilenamePath(ctest.c_str());
  150. ctest += "/Release/";
  151. ctest += "ctest";
  152. ctest += cmSystemTools::GetExecutableExtension();
  153. }
  154. m_Makefile->AddUtilityCommand("RUN_TESTS", ctest.c_str(), "-D $(IntDir)",
  155. false);
  156. m_Makefile->FindSubDirectoryCMakeListsFiles(allListFiles);
  157. // For each cmMakefile, create a VCProj for it, and
  158. // add it to this SLN file
  159. std::vector<cmMakefile*>::iterator k;
  160. for(k = allListFiles.begin();
  161. k != allListFiles.end(); ++k)
  162. {
  163. cmMakefile* mf = *k;
  164. cmMSDotNETGenerator* pg = 0;
  165. // if not this makefile, then create a new generator
  166. if(m_Makefile != mf)
  167. {
  168. // Create an MS generator with SLN off, so it only creates dsp files
  169. pg = new cmMSDotNETGenerator;
  170. }
  171. else
  172. {
  173. pg = static_cast<cmMSDotNETGenerator*>(m_Makefile->GetMakefileGenerator());
  174. }
  175. // make sure the generator is building dsp files
  176. pg->BuildSLNOff();
  177. mf->SetMakefileGenerator(pg);
  178. mf->GenerateMakefile();
  179. // Get the source directory from the makefile
  180. std::string dir = mf->GetStartDirectory();
  181. // Get the home directory with the trailing slash
  182. std::string homedir = m_Makefile->GetHomeDirectory();
  183. homedir += "/";
  184. // remove the home directory and / from the source directory
  185. // this gives a relative path
  186. cmSystemTools::ReplaceString(dir, homedir.c_str(), "");
  187. // Get the list of create dsp files names from the cmVCProjWriter, more
  188. // than one dsp could have been created per input CMakeLists.txt file
  189. // for each target
  190. std::vector<std::string> dspnames =
  191. pg->GetCreatedProjectNames();
  192. cmTargets &tgts = pg->GetMakefile()->GetTargets();
  193. cmTargets::iterator l = tgts.begin();
  194. for(std::vector<std::string>::iterator si = dspnames.begin();
  195. l != tgts.end(); ++l)
  196. {
  197. // special handling for the current makefile
  198. if(mf == m_Makefile)
  199. {
  200. dir = "."; // no subdirectory for project generated
  201. // if this is the special ALL_BUILD utility, then
  202. // make it depend on every other non UTILITY project.
  203. // This is done by adding the names to the GetUtilities
  204. // vector on the makefile
  205. if(l->first == "ALL_BUILD")
  206. {
  207. for(std::vector<cmMakefile*>::iterator a = allListFiles.begin();
  208. a != allListFiles.end(); ++a)
  209. {
  210. const cmTargets &atgts = (*a)->GetTargets();
  211. for(cmTargets::const_iterator al = atgts.begin();
  212. al != atgts.end(); ++al)
  213. {
  214. if (al->second.IsInAll())
  215. {
  216. if (al->second.GetType() == cmTarget::UTILITY)
  217. {
  218. l->second.AddUtility(al->first.c_str());
  219. }
  220. else
  221. {
  222. l->second.GetLinkLibraries().push_back(
  223. cmTarget::LinkLibraries::value_type(al->first,
  224. cmTarget::GENERAL));
  225. }
  226. }
  227. }
  228. }
  229. }
  230. }
  231. // Write the project into the SLN file
  232. if (strncmp(l->first.c_str(), "INCLUDE_EXTERNAL_MSPROJECT", 26) == 0)
  233. {
  234. cmCustomCommand cc = l->second.GetCustomCommands()[0];
  235. // dodgy use of the cmCustomCommand's members to store the
  236. // arguments from the INCLUDE_EXTERNAL_MSPROJECT command
  237. std::vector<std::string> stuff = cc.GetDepends();
  238. std::vector<std::string> depends = cc.GetOutputs();
  239. this->WriteExternalProject(fout, stuff[0].c_str(), stuff[1].c_str(), depends);
  240. ++si;
  241. }
  242. else if ((l->second.GetType() != cmTarget::INSTALL_FILES)
  243. && (l->second.GetType() != cmTarget::INSTALL_PROGRAMS))
  244. {
  245. this->WriteProject(fout, si->c_str(), dir.c_str(),
  246. pg,l->second);
  247. ++si;
  248. }
  249. }
  250. }
  251. fout << "Global\n"
  252. << "\tGlobalSection(SolutionConfiguration) = preSolution\n";
  253. int c = 0;
  254. for(std::vector<std::string>::iterator i = m_Configurations.begin();
  255. i != m_Configurations.end(); ++i)
  256. {
  257. fout << "\t\tConfigName." << c << " = " << *i << "\n";
  258. c++;
  259. }
  260. fout << "\tEndGlobalSection\n"
  261. << "\tGlobalSection(ProjectDependencies) = postSolution\n";
  262. // loop over again and compute the depends
  263. for(k = allListFiles.begin(); k != allListFiles.end(); ++k)
  264. {
  265. cmMakefile* mf = *k;
  266. cmMSDotNETGenerator* pg =
  267. static_cast<cmMSDotNETGenerator*>(mf->GetMakefileGenerator());
  268. // Get the list of create dsp files names from the cmVCProjWriter, more
  269. // than one dsp could have been created per input CMakeLists.txt file
  270. // for each target
  271. std::vector<std::string> dspnames =
  272. pg->GetCreatedProjectNames();
  273. cmTargets &tgts = pg->GetMakefile()->GetTargets();
  274. cmTargets::iterator l = tgts.begin();
  275. std::string dir = mf->GetStartDirectory();
  276. for(std::vector<std::string>::iterator si = dspnames.begin();
  277. l != tgts.end(); ++l)
  278. {
  279. if ((l->second.GetType() != cmTarget::INSTALL_FILES)
  280. && (l->second.GetType() != cmTarget::INSTALL_PROGRAMS))
  281. {
  282. this->WriteProjectDepends(fout, si->c_str(), dir.c_str(),
  283. pg,l->second);
  284. ++si;
  285. }
  286. }
  287. }
  288. fout << "\tEndGlobalSection\n";
  289. fout << "\tGlobalSection(ProjectConfiguration) = postSolution\n";
  290. // loop over again and compute the depends
  291. for(k = allListFiles.begin(); k != allListFiles.end(); ++k)
  292. {
  293. cmMakefile* mf = *k;
  294. cmMSDotNETGenerator* pg =
  295. static_cast<cmMSDotNETGenerator*>(mf->GetMakefileGenerator());
  296. // Get the list of create dsp files names from the cmVCProjWriter, more
  297. // than one dsp could have been created per input CMakeLists.txt file
  298. // for each target
  299. std::vector<std::string> dspnames =
  300. pg->GetCreatedProjectNames();
  301. cmTargets &tgts = pg->GetMakefile()->GetTargets();
  302. cmTargets::iterator l = tgts.begin();
  303. std::string dir = mf->GetStartDirectory();
  304. for(std::vector<std::string>::iterator si = dspnames.begin();
  305. l != tgts.end(); ++l)
  306. {
  307. if ((l->second.GetType() != cmTarget::INSTALL_FILES)
  308. && (l->second.GetType() != cmTarget::INSTALL_PROGRAMS))
  309. {
  310. this->WriteProjectConfigurations(fout, si->c_str());
  311. ++si;
  312. }
  313. }
  314. // delete the cmMakefile which also deletes the cmMSProjectGenerator
  315. if(mf != m_Makefile)
  316. {
  317. delete mf;
  318. }
  319. }
  320. fout << "\tEndGlobalSection\n";
  321. // Write the footer for the SLN file
  322. this->WriteSLNFooter(fout);
  323. }
  324. // Write a dsp file into the SLN file,
  325. // Note, that dependencies from executables to
  326. // the libraries it uses are also done here
  327. void cmMSDotNETGenerator::WriteProject(std::ostream& fout,
  328. const char* dspname,
  329. const char* dir,
  330. cmMSDotNETGenerator*,
  331. const cmTarget& target
  332. )
  333. {
  334. std::string d = cmSystemTools::ConvertToOutputPath(dir);
  335. fout << "Project(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\" = \""
  336. << dspname << "\", \""
  337. << d << "\\" << dspname << ".vcproj\", \"{"
  338. << this->CreateGUID(dspname) << "}\"\nEndProject\n";
  339. }
  340. // Write a dsp file into the SLN file,
  341. // Note, that dependencies from executables to
  342. // the libraries it uses are also done here
  343. void cmMSDotNETGenerator::WriteProjectDepends(std::ostream& fout,
  344. const char* dspname,
  345. const char* dir,
  346. cmMSDotNETGenerator*,
  347. const cmTarget& target
  348. )
  349. {
  350. int depcount = 0;
  351. // insert Begin Project Dependency Project_Dep_Name project stuff here
  352. if (target.GetType() != cmTarget::STATIC_LIBRARY)
  353. {
  354. cmTarget::LinkLibraries::const_iterator j, jend;
  355. j = target.GetLinkLibraries().begin();
  356. jend = target.GetLinkLibraries().end();
  357. for(;j!= jend; ++j)
  358. {
  359. if(j->first != dspname)
  360. {
  361. // is the library part of this SLN ? If so add dependency
  362. const char* cacheValue
  363. = m_Makefile->GetDefinition(j->first.c_str());
  364. if(cacheValue)
  365. {
  366. fout << "\t\t{" << this->CreateGUID(dspname) << "}." << depcount << " = {"
  367. << this->CreateGUID(j->first.c_str()) << "}\n";
  368. depcount++;
  369. }
  370. }
  371. }
  372. }
  373. std::set<std::string>::const_iterator i, end;
  374. // write utility dependencies.
  375. i = target.GetUtilities().begin();
  376. end = target.GetUtilities().end();
  377. for(;i!= end; ++i)
  378. {
  379. if(*i != dspname)
  380. {
  381. fout << "\t\t{" << this->CreateGUID(dspname) << "}." << depcount << " = {"
  382. << this->CreateGUID(i->c_str()) << "}\n";
  383. depcount++;
  384. }
  385. }
  386. }
  387. // Write a dsp file into the SLN file,
  388. // Note, that dependencies from executables to
  389. // the libraries it uses are also done here
  390. void cmMSDotNETGenerator::WriteProjectConfigurations(std::ostream& fout, const char* name)
  391. {
  392. std::string guid = this->CreateGUID(name);
  393. for(std::vector<std::string>::iterator i = m_Configurations.begin();
  394. i != m_Configurations.end(); ++i)
  395. {
  396. fout << "\t\t{" << guid << "}." << *i << ".ActiveCfg = " << *i << "|Win32\n"
  397. << "\t\t{" << guid << "}." << *i << ".Build.0 = " << *i << "|Win32\n";
  398. }
  399. }
  400. // Write a dsp file into the SLN file,
  401. // Note, that dependencies from executables to
  402. // the libraries it uses are also done here
  403. void cmMSDotNETGenerator::WriteExternalProject(std::ostream& fout,
  404. const char* name,
  405. const char* location,
  406. const std::vector<std::string>& dependencies)
  407. {
  408. cmSystemTools::Error("WriteExternalProject not implemented");
  409. // fout << "#########################################################"
  410. // "######################\n\n";
  411. // fout << "Project: \"" << name << "\"="
  412. // << location << " - Package Owner=<4>\n\n";
  413. // fout << "Package=<5>\n{{{\n}}}\n\n";
  414. // fout << "Package=<4>\n";
  415. // fout << "{{{\n";
  416. // std::vector<std::string>::const_iterator i, end;
  417. // // write dependencies.
  418. // i = dependencies.begin();
  419. // end = dependencies.end();
  420. // for(;i!= end; ++i)
  421. // {
  422. // fout << "Begin Project Dependency\n";
  423. // fout << "Project_Dep_Name " << *i << "\n";
  424. // fout << "End Project Dependency\n";
  425. // }
  426. // fout << "}}}\n\n";
  427. }
  428. // Standard end of dsw file
  429. void cmMSDotNETGenerator::WriteSLNFooter(std::ostream& fout)
  430. {
  431. fout << "\tGlobalSection(ExtensibilityGlobals) = postSolution\n"
  432. << "\tEndGlobalSection\n"
  433. << "\tGlobalSection(ExtensibilityAddIns) = postSolution\n"
  434. << "\tEndGlobalSection\n"
  435. << "EndGlobal\n";
  436. }
  437. // ouput standard header for dsw file
  438. void cmMSDotNETGenerator::WriteSLNHeader(std::ostream& fout)
  439. {
  440. fout << "Microsoft Visual Studio Solution File, Format Version 7.00\n";
  441. }
  442. std::string cmMSDotNETGenerator::CreateGUID(const char* name)
  443. {
  444. std::map<cmStdString, cmStdString>::iterator i = m_GUIDMap.find(name);
  445. if(i != m_GUIDMap.end())
  446. {
  447. return i->second;
  448. }
  449. std::string ret;
  450. UUID uid;
  451. unsigned char *uidstr;
  452. UuidCreate(&uid);
  453. UuidToString(&uid,&uidstr);
  454. ret = reinterpret_cast<char*>(uidstr);
  455. RpcStringFree(&uidstr);
  456. ret = cmSystemTools::UpperCase(ret);
  457. m_GUIDMap[name] = ret;
  458. return ret;
  459. }
  460. // TODO
  461. // for CommandLine= need to repleace quotes with &quot
  462. // write out configurations
  463. void cmMSDotNETGenerator::OutputVCProjFile()
  464. {
  465. // If not an in source build, then create the output directory
  466. if(strcmp(m_Makefile->GetStartOutputDirectory(),
  467. m_Makefile->GetHomeDirectory()) != 0)
  468. {
  469. if(!cmSystemTools::MakeDirectory(m_Makefile->GetStartOutputDirectory()))
  470. {
  471. cmSystemTools::Error("Error creating directory ",
  472. m_Makefile->GetStartOutputDirectory());
  473. }
  474. }
  475. m_LibraryOutputPath = "";
  476. if (m_Makefile->GetDefinition("LIBRARY_OUTPUT_PATH"))
  477. {
  478. m_LibraryOutputPath = m_Makefile->GetDefinition("LIBRARY_OUTPUT_PATH");
  479. }
  480. if(m_LibraryOutputPath.size())
  481. {
  482. // make sure there is a trailing slash
  483. if(m_LibraryOutputPath[m_LibraryOutputPath.size()-1] != '/')
  484. {
  485. m_LibraryOutputPath += "/";
  486. }
  487. }
  488. m_ExecutableOutputPath = "";
  489. if (m_Makefile->GetDefinition("EXECUTABLE_OUTPUT_PATH"))
  490. {
  491. m_ExecutableOutputPath = m_Makefile->GetDefinition("EXECUTABLE_OUTPUT_PATH");
  492. }
  493. if(m_ExecutableOutputPath.size())
  494. {
  495. // make sure there is a trailing slash
  496. if(m_ExecutableOutputPath[m_ExecutableOutputPath.size()-1] != '/')
  497. {
  498. m_ExecutableOutputPath += "/";
  499. }
  500. }
  501. // Create the VCProj or set of VCProj's for libraries and executables
  502. // clear project names
  503. m_CreatedProjectNames.clear();
  504. // build any targets
  505. cmTargets &tgts = m_Makefile->GetTargets();
  506. for(cmTargets::iterator l = tgts.begin();
  507. l != tgts.end(); l++)
  508. {
  509. // INCLUDE_EXTERNAL_MSPROJECT command only affects the workspace
  510. // so don't build a projectfile for it
  511. if ((l->second.GetType() != cmTarget::INSTALL_FILES)
  512. && (l->second.GetType() != cmTarget::INSTALL_PROGRAMS)
  513. && (strncmp(l->first.c_str(), "INCLUDE_EXTERNAL_MSPROJECT", 26) != 0))
  514. {
  515. this->CreateSingleVCProj(l->first.c_str(),l->second);
  516. }
  517. }
  518. }
  519. void cmMSDotNETGenerator::CreateSingleVCProj(const char *lname, cmTarget &target)
  520. {
  521. // add to the list of projects
  522. std::string pname = lname;
  523. m_CreatedProjectNames.push_back(pname);
  524. // create the dsp.cmake file
  525. std::string fname;
  526. fname = m_Makefile->GetStartOutputDirectory();
  527. fname += "/";
  528. fname += lname;
  529. fname += ".vcproj";
  530. // save the name of the real dsp file
  531. std::string realVCProj = fname;
  532. fname += ".cmake";
  533. std::ofstream fout(fname.c_str());
  534. if(!fout)
  535. {
  536. cmSystemTools::Error("Error Writing ", fname.c_str());
  537. }
  538. this->WriteVCProjFile(fout,lname,target);
  539. fout.close();
  540. // if the dsp file has changed, then write it.
  541. cmSystemTools::CopyFileIfDifferent(fname.c_str(), realVCProj.c_str());
  542. }
  543. void cmMSDotNETGenerator::AddVCProjBuildRule(cmSourceGroup& sourceGroup)
  544. {
  545. std::string dspname = *(m_CreatedProjectNames.end()-1);
  546. if(dspname == "ALL_BUILD")
  547. {
  548. return;
  549. }
  550. dspname += ".vcproj.cmake";
  551. std::string makefileIn = m_Makefile->GetStartDirectory();
  552. makefileIn += "/";
  553. makefileIn += "CMakeLists.txt";
  554. makefileIn = cmSystemTools::ConvertToOutputPath(makefileIn.c_str());
  555. std::string dsprule = "${CMAKE_COMMAND}";
  556. m_Makefile->ExpandVariablesInString(dsprule);
  557. dsprule = cmSystemTools::ConvertToOutputPath(dsprule.c_str());
  558. std::string args = makefileIn;
  559. args += " -H\"";
  560. args +=
  561. cmSystemTools::ConvertToOutputPath(m_Makefile->GetHomeDirectory());
  562. args += "\" -S\"";
  563. args +=
  564. cmSystemTools::ConvertToOutputPath(m_Makefile->GetStartDirectory());
  565. args += "\" -O\"";
  566. args +=
  567. cmSystemTools::ConvertToOutputPath(m_Makefile->GetStartOutputDirectory());
  568. args += "\" -B\"";
  569. args +=
  570. cmSystemTools::ConvertToOutputPath(m_Makefile->GetHomeOutputDirectory());
  571. args += "\"";
  572. m_Makefile->ExpandVariablesInString(args);
  573. std::string configFile =
  574. m_Makefile->GetDefinition("CMAKE_ROOT");
  575. configFile += "/Templates/CMakeWindowsSystemConfig.cmake";
  576. std::vector<std::string> listFiles = m_Makefile->GetListFiles();
  577. bool found = false;
  578. for(std::vector<std::string>::iterator i = listFiles.begin();
  579. i != listFiles.end(); ++i)
  580. {
  581. if(*i == configFile)
  582. {
  583. found = true;
  584. }
  585. }
  586. if(!found)
  587. {
  588. listFiles.push_back(configFile);
  589. }
  590. std::vector<std::string> outputs;
  591. outputs.push_back(dspname);
  592. cmCustomCommand cc(makefileIn.c_str(), dsprule.c_str(),
  593. args.c_str(),
  594. listFiles,
  595. outputs);
  596. sourceGroup.AddCustomCommand(cc);
  597. }
  598. void cmMSDotNETGenerator::WriteConfigurations(std::ostream& fout,
  599. const char *libName,
  600. const cmTarget &target)
  601. {
  602. fout << "\t<Configurations>\n";
  603. for( std::vector<std::string>::iterator i = m_Configurations.begin();
  604. i != m_Configurations.end(); ++i)
  605. {
  606. this->WriteConfiguration(fout, i->c_str(), libName, target);
  607. }
  608. fout << "\t</Configurations>\n";
  609. }
  610. void cmMSDotNETGenerator::WriteConfiguration(std::ostream& fout,
  611. const char* configName,
  612. const char *libName,
  613. const cmTarget &target)
  614. {
  615. const char* mfcFlag = m_Makefile->GetDefinition("CMAKE_MFC_FLAG");
  616. if(!mfcFlag)
  617. {
  618. mfcFlag = "0";
  619. }
  620. fout << "\t\t<Configuration\n"
  621. << "\t\t\tName=\"" << configName << "|Win32\"\n"
  622. << "\t\t\tOutputDirectory=\"" << configName << "\"\n";
  623. // This is an internal type to Visual Studio, it seems that:
  624. // 4 == static library
  625. // 2 == dll
  626. // 1 == executable
  627. // 10 == utility
  628. const char* configType = "10";
  629. switch(target.GetType())
  630. {
  631. case cmTarget::STATIC_LIBRARY:
  632. configType = "4";
  633. break;
  634. case cmTarget::SHARED_LIBRARY:
  635. case cmTarget::MODULE_LIBRARY:
  636. configType = "2";
  637. break;
  638. case cmTarget::EXECUTABLE:
  639. case cmTarget::WIN32_EXECUTABLE:
  640. configType = "1";
  641. break;
  642. case cmTarget::UTILITY:
  643. configType = "10";
  644. default:
  645. break;
  646. }
  647. fout << "\t\t\tIntermediateDirectory=\".\\" << configName << "\"\n"
  648. << "\t\t\tConfigurationType=\"" << configType << "\"\n"
  649. << "\t\t\tUseOfMFC=\"" << mfcFlag << "\"\n"
  650. << "\t\t\tATLMinimizesCRunTimeLibraryUsage=\"FALSE\"\n"
  651. << "\t\t\tCharacterSet=\"2\">\n";
  652. fout << "\t\t\t<Tool\n"
  653. << "\t\t\t\tName=\"VCCLCompilerTool\"\n"
  654. << "\t\t\t\tAdditionalOptions=\"" <<
  655. m_Makefile->GetDefinition("CMAKE_CXX_FLAGS") << "\"\n";
  656. fout << "\t\t\t\tAdditionalIncludeDirectories=\"";
  657. std::vector<std::string>& includes = m_Makefile->GetIncludeDirectories();
  658. std::vector<std::string>::iterator i = includes.begin();
  659. for(;i != includes.end(); ++i)
  660. {
  661. std::string ipath = this->ConvertToXMLOutputPath(i->c_str());
  662. fout << ipath << ";";
  663. }
  664. fout << "\"\n";
  665. // Optimization = 0 None Debug /O0
  666. // Optimization = 1 MinSize /O1
  667. // Optimization = 2 MaxSpeed /O2
  668. // Optimization = 3 Max Optimization /O3
  669. // RuntimeLibrary = 0 /MT multithread
  670. // RuntimeLibrary = 1 /MTd multithread debug
  671. // RuntimeLibrary = 2 /MD multithread dll
  672. // RuntimeLibrary = 3 /MDd multithread dll debug
  673. // RuntimeLibrary = 4 /ML single thread
  674. // RuntimeLibrary = 5 /MLd single thread debug
  675. // InlineFunctionExpansion = 0 none
  676. // InlineFunctionExpansion = 1 when inline keyword
  677. // InlineFunctionExpansion = 2 any time you can
  678. if(strcmp(configName, "Debug") == 0)
  679. {
  680. fout << "\t\t\t\tOptimization=\"0\"\n"
  681. << "\t\t\t\tRuntimeLibrary=\"3\"\n"
  682. << "\t\t\t\tInlineFunctionExpansion=\"0\"\n"
  683. << "\t\t\t\tPreprocessorDefinitions=\"WIN32,_DEBUG,_WINDOWS";
  684. }
  685. else if(strcmp(configName, "Release") == 0)
  686. {
  687. fout << "\t\t\t\tOptimization=\"2\"\n"
  688. << "\t\t\t\tRuntimeLibrary=\"2\"\n"
  689. << "\t\t\t\tInlineFunctionExpansion=\"1\"\n"
  690. << "\t\t\t\tPreprocessorDefinitions=\"WIN32,NDEBUG,_WINDOWS";
  691. }
  692. else if(strcmp(configName, "MinSizeRel") == 0)
  693. {
  694. fout << "\t\t\t\tOptimization=\"1\"\n"
  695. << "\t\t\t\tRuntimeLibrary=\"2\"\n"
  696. << "\t\t\t\tInlineFunctionExpansion=\"1\"\n"
  697. << "\t\t\t\tPreprocessorDefinitions=\"WIN32,NDEBUG,_WINDOWS";
  698. }
  699. else if(strcmp(configName, "RelWithDebInfo") == 0)
  700. {
  701. fout << "\t\t\t\tOptimization=\"2\"\n"
  702. << "\t\t\t\tRuntimeLibrary=\"2\"\n"
  703. << "\t\t\t\tInlineFunctionExpansion=\"1\"\n"
  704. << "\t\t\t\tPreprocessorDefinitions=\"WIN32,NDEBUG,_WINDOWS";
  705. }
  706. if(target.GetType() == cmTarget::SHARED_LIBRARY
  707. || target.GetType() == cmTarget::MODULE_LIBRARY)
  708. {
  709. fout << "," << libName << "_EXPORTS";
  710. }
  711. this->OutputDefineFlags(fout);
  712. fout << "\"\n";
  713. if(m_Makefile->IsOn("CMAKE_CXX_USE_RTTI"))
  714. {
  715. fout << "\t\t\t\tRuntimeTypeInfo=\"TRUE\"\n";
  716. }
  717. fout << "\t\t\t\tAssemblerListingLocation=\"" << configName << "\"\n";
  718. fout << "\t\t\t\tObjectFile=\"" << configName << "\\\"\n";
  719. fout << "\t\t\t\tWarningLevel=\"" << m_Makefile->GetDefinition("CMAKE_CXX_WARNING_LEVEL") << "\"\n";
  720. fout << "\t\t\t\tDetect64BitPortabilityProblems=\"TRUE\"\n"
  721. << "\t\t\t\tDebugInformationFormat=\"3\"";
  722. fout << "/>\n"; // end of <Tool Name=VCCLCompilerTool
  723. fout << "\t\t\t<Tool\n\t\t\t\tName=\"VCCustomBuildTool\"/>\n";
  724. fout << "\t\t\t<Tool\n\t\t\t\tName=\"VCMIDLTool\"/>\n";
  725. fout << "\t\t\t<Tool\n\t\t\t\tName=\"VCPostBuildEventTool\"";
  726. this->OutputTargetRules(fout, target, libName);
  727. fout << "/>\n";
  728. fout << "\t\t\t<Tool\n\t\t\t\tName=\"VCPreBuildEventTool\"/>\n";
  729. this->OutputBuildTool(fout, configName, libName, target);
  730. fout << "\t\t</Configuration>\n";
  731. }
  732. void cmMSDotNETGenerator::OutputBuildTool(std::ostream& fout,
  733. const char* configName,
  734. const char *libName,
  735. const cmTarget &target)
  736. {
  737. switch(target.GetType())
  738. {
  739. case cmTarget::STATIC_LIBRARY:
  740. {
  741. std::string libpath = m_LibraryOutputPath +
  742. "$(OutDir)/" + libName + ".lib";
  743. fout << "\t\t\t<Tool\n"
  744. << "\t\t\t\tName=\"VCLibrarianTool\"\n"
  745. << "\t\t\t\t\tOutputFile=\""
  746. << this->ConvertToXMLOutputPath(libpath.c_str()) << ".\"/>\n";
  747. break;
  748. }
  749. case cmTarget::SHARED_LIBRARY:
  750. case cmTarget::MODULE_LIBRARY:
  751. fout << "\t\t\t<Tool\n"
  752. << "\t\t\t\tName=\"VCLinkerTool\"\n"
  753. << "\t\t\t\tAdditionalOptions=\"/MACHINE:I386\"\n"
  754. << "\t\t\t\tAdditionalDependencies=\" odbc32.lib odbccp32.lib ";
  755. this->OutputLibraries(fout, configName, libName, target);
  756. fout << "\"\n";
  757. fout << "\t\t\t\tOutputFile=\""
  758. << m_ExecutableOutputPath << configName << "/"
  759. << libName << ".dll\"\n";
  760. fout << "\t\t\t\tLinkIncremental=\"1\"\n";
  761. fout << "\t\t\t\tSuppressStartupBanner=\"TRUE\"\n";
  762. fout << "\t\t\t\tAdditionalLibraryDirectories=\"";
  763. this->OutputLibraryDirectories(fout, configName, libName, target);
  764. fout << "\"\n";
  765. fout << "\t\t\t\tProgramDatabaseFile=\"" << m_LibraryOutputPath
  766. << "$(OutDir)\\" << libName << ".pdb\"\n";
  767. if(strcmp(configName, "Debug") == 0)
  768. {
  769. fout << "\t\t\t\tGenerateDebugInformation=\"TRUE\"\n";
  770. }
  771. fout << "\t\t\t\tStackReserveSize=\""
  772. << m_Makefile->GetDefinition("CMAKE_CXX_STACK_SIZE") << "\"\n";
  773. fout << "\t\t\t\tImportLibrary=\""
  774. << m_ExecutableOutputPath << configName << "/"
  775. << libName << ".lib\"/>\n";
  776. break;
  777. case cmTarget::EXECUTABLE:
  778. case cmTarget::WIN32_EXECUTABLE:
  779. fout << "\t\t\t<Tool\n"
  780. << "\t\t\t\tName=\"VCLinkerTool\"\n"
  781. << "\t\t\t\tAdditionalOptions=\"/MACHINE:I386\"\n"
  782. << "\t\t\t\tAdditionalDependencies=\" odbc32.lib odbccp32.lib ";
  783. this->OutputLibraries(fout, configName, libName, target);
  784. fout << "\"\n";
  785. fout << "\t\t\t\tOutputFile=\""
  786. << m_ExecutableOutputPath << configName << "/" << libName << ".exe\"\n";
  787. fout << "\t\t\t\tLinkIncremental=\"1\"\n";
  788. fout << "\t\t\t\tSuppressStartupBanner=\"TRUE\"\n";
  789. fout << "\t\t\t\tAdditionalLibraryDirectories=\"";
  790. this->OutputLibraryDirectories(fout, configName, libName, target);
  791. fout << "\"\n";
  792. fout << "\t\t\t\tProgramDatabaseFile=\"" << m_LibraryOutputPath
  793. << "$(OutDir)\\" << libName << ".pdb\"\n";
  794. if(strcmp(configName, "Debug") == 0)
  795. {
  796. fout << "\t\t\t\tGenerateDebugInformation=\"TRUE\"\n";
  797. }
  798. if( target.GetType() == cmTarget::EXECUTABLE)
  799. {
  800. fout << "\t\t\t\tSubSystem=\"1\"\n";
  801. }
  802. else
  803. {
  804. fout << "\t\t\t\tSubSystem=\"2\"\n";
  805. }
  806. fout << "\t\t\t\tStackReserveSize=\""
  807. << m_Makefile->GetDefinition("CMAKE_CXX_STACK_SIZE") << "\"/>\n";
  808. break;
  809. case cmTarget::UTILITY:
  810. break;
  811. }
  812. }
  813. void cmMSDotNETGenerator::OutputLibraryDirectories(std::ostream& fout,
  814. const char* configName,
  815. const char* libName,
  816. const cmTarget &target)
  817. {
  818. bool hasone = false;
  819. if(m_LibraryOutputPath.size())
  820. {
  821. hasone = true;
  822. fout << m_LibraryOutputPath << "$(INTDIR)," << m_LibraryOutputPath;
  823. }
  824. if(m_ExecutableOutputPath.size())
  825. {
  826. hasone = true;
  827. fout << m_ExecutableOutputPath << "$(INTDIR)," << m_ExecutableOutputPath;
  828. }
  829. std::set<std::string> pathEmitted;
  830. std::vector<std::string>::iterator i;
  831. std::vector<std::string>& libdirs = m_Makefile->GetLinkDirectories();
  832. for(i = libdirs.begin(); i != libdirs.end(); ++i)
  833. {
  834. std::string lpath = *i;
  835. if(lpath[lpath.size()-1] != '/')
  836. {
  837. lpath += "/";
  838. }
  839. if(pathEmitted.insert(lpath).second)
  840. {
  841. if(hasone)
  842. {
  843. fout << ",";
  844. }
  845. std::string lpathi = lpath + "$(INTDIR)";
  846. fout << this->ConvertToXMLOutputPath(lpathi.c_str()) << "," << lpath;
  847. hasone = true;
  848. }
  849. }
  850. }
  851. void cmMSDotNETGenerator::OutputLibraries(std::ostream& fout,
  852. const char* configName,
  853. const char* libName,
  854. const cmTarget &target)
  855. {
  856. const cmTarget::LinkLibraries& libs = target.GetLinkLibraries();
  857. cmTarget::LinkLibraries::const_iterator j;
  858. for(j = libs.begin(); j != libs.end(); ++j)
  859. {
  860. std::string lib = j->first;
  861. if(j->first.find(".lib") == std::string::npos)
  862. {
  863. lib += ".lib";
  864. }
  865. lib = this->ConvertToXMLOutputPath(lib.c_str());
  866. if (j->second == cmTarget::GENERAL
  867. || (j->second == cmTarget::DEBUG && strcmp(configName, "DEBUG") == 0)
  868. || (j->second == cmTarget::OPTIMIZED && strcmp(configName, "DEBUG") != 0))
  869. {
  870. fout << lib << " ";
  871. }
  872. }
  873. }
  874. void cmMSDotNETGenerator::OutputDefineFlags(std::ostream& fout)
  875. {
  876. std::string defs = m_Makefile->GetDefineFlags();
  877. std::string::size_type pos = defs.find("-D");
  878. bool done = pos == std::string::npos;
  879. if(!done)
  880. {
  881. fout << ",";
  882. }
  883. while(!done)
  884. {
  885. std::string::size_type nextpos = defs.find("-D", pos+2);
  886. std::string define;
  887. if(nextpos != std::string::npos)
  888. {
  889. define = defs.substr(pos+2, nextpos - pos -3);
  890. }
  891. else
  892. {
  893. define = defs.substr(pos+2);
  894. done = true;
  895. }
  896. fout << define << ",";
  897. if(!done)
  898. {
  899. pos = defs.find("-D", nextpos);
  900. }
  901. }
  902. }
  903. void cmMSDotNETGenerator::WriteVCProjFile(std::ostream& fout,
  904. const char *libName,
  905. cmTarget &target)
  906. {
  907. // We may be modifying the source groups temporarily, so make a copy.
  908. std::vector<cmSourceGroup> sourceGroups = m_Makefile->GetSourceGroups();
  909. // get the classes from the source lists then add them to the groups
  910. std::vector<cmSourceFile> classes = target.GetSourceFiles();
  911. for(std::vector<cmSourceFile>::iterator i = classes.begin();
  912. i != classes.end(); i++)
  913. {
  914. // Add the file to the list of sources.
  915. std::string source = i->GetFullPath();
  916. cmSourceGroup& sourceGroup = m_Makefile->FindSourceGroup(source.c_str(),
  917. sourceGroups);
  918. sourceGroup.AddSource(source.c_str(), &(*i));
  919. }
  920. // add any custom rules to the source groups
  921. for (std::vector<cmCustomCommand>::const_iterator cr =
  922. target.GetCustomCommands().begin();
  923. cr != target.GetCustomCommands().end(); ++cr)
  924. {
  925. cmSourceGroup& sourceGroup =
  926. m_Makefile->FindSourceGroup(cr->GetSourceName().c_str(),
  927. sourceGroups);
  928. cmCustomCommand cc(*cr);
  929. cc.ExpandVariables(*m_Makefile);
  930. sourceGroup.AddCustomCommand(cc);
  931. }
  932. // open the project
  933. this->WriteProjectStart(fout, libName, target, sourceGroups);
  934. // write the configuration information
  935. this->WriteConfigurations(fout, libName, target);
  936. fout << "\t<Files>\n";
  937. // Find the group in which the CMakeLists.txt source belongs, and add
  938. // the rule to generate this VCProj file.
  939. for(std::vector<cmSourceGroup>::reverse_iterator sg = sourceGroups.rbegin();
  940. sg != sourceGroups.rend(); ++sg)
  941. {
  942. if(sg->Matches("CMakeLists.txt"))
  943. {
  944. this->AddVCProjBuildRule(*sg);
  945. break;
  946. }
  947. }
  948. // Loop through every source group.
  949. for(std::vector<cmSourceGroup>::const_iterator sg = sourceGroups.begin();
  950. sg != sourceGroups.end(); ++sg)
  951. {
  952. const cmSourceGroup::BuildRules& buildRules = sg->GetBuildRules();
  953. // If the group is empty, don't write it at all.
  954. if(buildRules.empty())
  955. { continue; }
  956. // If the group has a name, write the header.
  957. std::string name = sg->GetName();
  958. if(name != "")
  959. {
  960. this->WriteVCProjBeginGroup(fout, name.c_str(), "");
  961. }
  962. // Loop through each build rule in the source group.
  963. for(cmSourceGroup::BuildRules::const_iterator cc =
  964. buildRules.begin(); cc != buildRules.end(); ++ cc)
  965. {
  966. std::string source = cc->first;
  967. const cmSourceGroup::Commands& commands = cc->second.m_Commands;
  968. const char* compileFlags = 0;
  969. if(cc->second.m_SourceFile)
  970. {
  971. compileFlags = cc->second.m_SourceFile->GetCompileFlags();
  972. }
  973. if (source != libName || target.GetType() == cmTarget::UTILITY)
  974. {
  975. fout << "\t\t\t<File\n";
  976. std::string d = this->ConvertToXMLOutputPath(source.c_str());
  977. // Tell MS-Dev what the source is. If the compiler knows how to
  978. // build it, then it will.
  979. fout << "\t\t\t\tRelativePath=\"" << d << "\">\n";
  980. if (!commands.empty())
  981. {
  982. cmSourceGroup::CommandFiles totalCommand;
  983. std::string totalCommandStr;
  984. totalCommandStr = this->CombineCommands(commands, totalCommand,
  985. source.c_str());
  986. this->WriteCustomRule(fout, source.c_str(), totalCommandStr.c_str(),
  987. totalCommand.m_Depends,
  988. totalCommand.m_Outputs, compileFlags);
  989. }
  990. else if(compileFlags)
  991. {
  992. for(std::vector<std::string>::iterator i
  993. = m_Configurations.begin(); i != m_Configurations.end(); ++i)
  994. {
  995. fout << "\t\t\t\t<FileConfiguration\n"
  996. << "\t\t\t\t\tName=\"" << *i << "|Win32\">\n"
  997. << "\t\t\t\t\t<Tool\n"
  998. << "\t\t\t\t\tName=\"VCCLCompilerTool\"\n"
  999. << "\t\t\t\t\tAdditionalOptions=\""
  1000. << compileFlags << "\"/>\n"
  1001. << "\t\t\t\t</FileConfiguration>\n";
  1002. }
  1003. }
  1004. fout << "\t\t\t</File>\n";
  1005. }
  1006. }
  1007. // If the group has a name, write the footer.
  1008. if(name != "")
  1009. {
  1010. this->WriteVCProjEndGroup(fout);
  1011. }
  1012. }
  1013. fout << "\t</Files>\n";
  1014. // Write the VCProj file's footer.
  1015. this->WriteVCProjFooter(fout);
  1016. }
  1017. void cmMSDotNETGenerator::WriteCustomRule(std::ostream& fout,
  1018. const char* source,
  1019. const char* command,
  1020. const std::set<std::string>& depends,
  1021. const std::set<std::string>& outputs,
  1022. const char* compileFlags)
  1023. {
  1024. std::string cmd = command;
  1025. cmSystemTools::ReplaceString(cmd, "\"", "&quot;");
  1026. std::vector<std::string>::iterator i;
  1027. for(i = m_Configurations.begin(); i != m_Configurations.end(); ++i)
  1028. {
  1029. fout << "\t\t\t\t<FileConfiguration\n";
  1030. fout << "\t\t\t\t\tName=\"" << *i << "|Win32\">\n";
  1031. if(compileFlags)
  1032. {
  1033. fout << "\t\t\t\t\t<Tool\n"
  1034. << "\t\t\t\t\tName=\"VCCLCompilerTool\"\n"
  1035. << "\t\t\t\t\tAdditionalOptions=\""
  1036. << compileFlags << "\"/>\n";
  1037. }
  1038. fout << "\t\t\t\t\t<Tool\n"
  1039. << "\t\t\t\t\tName=\"VCCustomBuildTool\"\n"
  1040. << "\t\t\t\t\tCommandLine=\"" << cmd << "\n\"\n"
  1041. << "\t\t\t\t\tAdditionalDependencies=\"";
  1042. // Write out the dependencies for the rule.
  1043. std::string temp;
  1044. for(std::set<std::string>::const_iterator d = depends.begin();
  1045. d != depends.end(); ++d)
  1046. {
  1047. fout << this->ConvertToXMLOutputPath(d->c_str())
  1048. << ";";
  1049. }
  1050. fout << "\"\n";
  1051. fout << "\t\t\t\t\tOutputs=\"";
  1052. if(outputs.size() == 0)
  1053. {
  1054. fout << source << "_force";
  1055. }
  1056. bool first = true;
  1057. // Write a rule for every output generated by this command.
  1058. for(std::set<std::string>::const_iterator output = outputs.begin();
  1059. output != outputs.end(); ++output)
  1060. {
  1061. if(!first)
  1062. {
  1063. fout << ";";
  1064. }
  1065. else
  1066. {
  1067. first = true;
  1068. }
  1069. fout << output->c_str();
  1070. }
  1071. fout << "\"/>\n";
  1072. fout << "\t\t\t\t</FileConfiguration>\n";
  1073. }
  1074. }
  1075. void cmMSDotNETGenerator::WriteVCProjBeginGroup(std::ostream& fout,
  1076. const char* group,
  1077. const char* filter)
  1078. {
  1079. fout << "\t\t<Filter\n"
  1080. << "\t\t\tName=\"" << group << "\"\n"
  1081. << "\t\t\tFilter=\"\">\n";
  1082. }
  1083. void cmMSDotNETGenerator::WriteVCProjEndGroup(std::ostream& fout)
  1084. {
  1085. fout << "\t\t</Filter>\n";
  1086. }
  1087. std::string
  1088. cmMSDotNETGenerator::CombineCommands(const cmSourceGroup::Commands &commands,
  1089. cmSourceGroup::CommandFiles &totalCommand,
  1090. const char *source)
  1091. {
  1092. // Loop through every custom command generating code from the
  1093. // current source.
  1094. // build up the depends and outputs and commands
  1095. std::string totalCommandStr = "";
  1096. std::string temp;
  1097. for(cmSourceGroup::Commands::const_iterator c = commands.begin();
  1098. c != commands.end(); ++c)
  1099. {
  1100. temp=
  1101. cmSystemTools::ConvertToOutputPath(c->second.m_Command.c_str());
  1102. totalCommandStr += temp;
  1103. totalCommandStr += " ";
  1104. totalCommandStr += c->second.m_Arguments;
  1105. totalCommand.Merge(c->second);
  1106. }
  1107. // Create a dummy file with the name of the source if it does
  1108. // not exist
  1109. if(totalCommand.m_Outputs.empty())
  1110. {
  1111. std::string dummyFile = m_Makefile->GetStartOutputDirectory();
  1112. dummyFile += "/";
  1113. dummyFile += source;
  1114. if(!cmSystemTools::FileExists(dummyFile.c_str()))
  1115. {
  1116. std::ofstream fout(dummyFile.c_str());
  1117. fout << "Dummy file created by cmake as unused source for utility command.\n";
  1118. }
  1119. }
  1120. return totalCommandStr;
  1121. }
  1122. // look for custom rules on a target and collect them together
  1123. void cmMSDotNETGenerator::OutputTargetRules(std::ostream& fout,
  1124. const cmTarget &target,
  1125. const char *libName)
  1126. {
  1127. if (target.GetType() >= cmTarget::UTILITY)
  1128. {
  1129. return;
  1130. }
  1131. // Find the group in which the lix exe custom rules belong
  1132. bool init = false;
  1133. for (std::vector<cmCustomCommand>::const_iterator cr =
  1134. target.GetCustomCommands().begin();
  1135. cr != target.GetCustomCommands().end(); ++cr)
  1136. {
  1137. cmCustomCommand cc(*cr);
  1138. cc.ExpandVariables(*m_Makefile);
  1139. if (cc.GetSourceName() == libName)
  1140. {
  1141. if(!init)
  1142. {
  1143. fout << "\nCommandLine=\"";
  1144. init = true;
  1145. }
  1146. fout << cc.GetCommand() << " " << cc.GetArguments() << "\n";
  1147. }
  1148. }
  1149. if (init)
  1150. {
  1151. fout << "\"";
  1152. }
  1153. }
  1154. void cmMSDotNETGenerator::WriteProjectStart(std::ostream& fout, const char *libName,
  1155. const cmTarget &target,
  1156. std::vector<cmSourceGroup> &)
  1157. {
  1158. fout << "<?xml version=\"1.0\" encoding = \"Windows-1252\"?>\n"
  1159. << "<VisualStudioProject\n"
  1160. << "\tProjectType=\"Visual C++\"\n"
  1161. << "\tVersion=\"7.00\"\n"
  1162. << "\tName=\"" << libName << "\"\n"
  1163. << "\tSccProjectName=\"\"\n"
  1164. << "\tSccLocalPath=\"\"\n"
  1165. << "\tKeyword=\"Win32Proj\">\n"
  1166. << "\t<Platforms>\n"
  1167. << "\t\t<Platform\n\t\t\tName=\"Win32\"/>\n"
  1168. << "\t</Platforms>\n";
  1169. }
  1170. void cmMSDotNETGenerator::WriteVCProjFooter(std::ostream& fout)
  1171. {
  1172. fout << "\t<Globals>\n"
  1173. << "\t</Globals>\n"
  1174. << "</VisualStudioProject>\n";
  1175. }
  1176. std::string cmMSDotNETGenerator::ConvertToXMLOutputPath(const char* path)
  1177. {
  1178. std::string ret = cmSystemTools::ConvertToOutputPath(path);
  1179. cmSystemTools::ReplaceString(ret, "\"", "&quot;");
  1180. return ret;
  1181. }