cmDSPWriter.cxx 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829
  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 "cmDSPWriter.h"
  14. #include "cmStandardIncludes.h"
  15. #include "cmSystemTools.h"
  16. #include "cmRegularExpression.h"
  17. cmDSPWriter::~cmDSPWriter()
  18. {
  19. }
  20. cmDSPWriter::cmDSPWriter(cmMakefile*mf)
  21. {
  22. m_Makefile = mf;
  23. }
  24. void cmDSPWriter::OutputDSPFile()
  25. {
  26. // If not an in source build, then create the output directory
  27. if(strcmp(m_Makefile->GetStartOutputDirectory(),
  28. m_Makefile->GetHomeDirectory()) != 0)
  29. {
  30. if(!cmSystemTools::MakeDirectory(m_Makefile->GetStartOutputDirectory()))
  31. {
  32. cmSystemTools::Error("Error creating directory ",
  33. m_Makefile->GetStartOutputDirectory());
  34. }
  35. }
  36. // Setup /I and /LIBPATH options for the resulting DSP file
  37. std::vector<std::string>& includes = m_Makefile->GetIncludeDirectories();
  38. std::vector<std::string>::iterator i;
  39. for(i = includes.begin(); i != includes.end(); ++i)
  40. {
  41. m_IncludeOptions += " /I ";
  42. std::string tmp = cmSystemTools::ConvertToOutputPath(i->c_str());
  43. // quote if not already quoted
  44. if (tmp[0] != '"')
  45. {
  46. m_IncludeOptions += "\"";
  47. m_IncludeOptions += tmp;
  48. m_IncludeOptions += "\"";
  49. }
  50. else
  51. {
  52. m_IncludeOptions += tmp;
  53. }
  54. }
  55. // Create the DSP or set of DSP's for libraries and executables
  56. // clear project names
  57. m_CreatedProjectNames.clear();
  58. // build any targets
  59. cmTargets &tgts = m_Makefile->GetTargets();
  60. for(cmTargets::iterator l = tgts.begin();
  61. l != tgts.end(); l++)
  62. {
  63. switch(l->second.GetType())
  64. {
  65. case cmTarget::STATIC_LIBRARY:
  66. this->SetBuildType(STATIC_LIBRARY, l->first.c_str());
  67. break;
  68. case cmTarget::SHARED_LIBRARY:
  69. this->SetBuildType(DLL, l->first.c_str());
  70. break;
  71. case cmTarget::EXECUTABLE:
  72. this->SetBuildType(EXECUTABLE,l->first.c_str());
  73. break;
  74. case cmTarget::WIN32_EXECUTABLE:
  75. this->SetBuildType(WIN32_EXECUTABLE,l->first.c_str());
  76. break;
  77. case cmTarget::UTILITY:
  78. this->SetBuildType(UTILITY, l->first.c_str());
  79. break;
  80. case cmTarget::INSTALL_FILES:
  81. break;
  82. case cmTarget::INSTALL_PROGRAMS:
  83. break;
  84. default:
  85. cmSystemTools::Error("Bad target type", l->first.c_str());
  86. break;
  87. }
  88. // INCLUDE_EXTERNAL_MSPROJECT command only affects the workspace
  89. // so don't build a projectfile for it
  90. if ((l->second.GetType() != cmTarget::INSTALL_FILES)
  91. && (l->second.GetType() != cmTarget::INSTALL_PROGRAMS)
  92. && (strncmp(l->first.c_str(), "INCLUDE_EXTERNAL_MSPROJECT", 26) != 0))
  93. {
  94. this->CreateSingleDSP(l->first.c_str(),l->second);
  95. }
  96. }
  97. }
  98. void cmDSPWriter::CreateSingleDSP(const char *lname, cmTarget &target)
  99. {
  100. // add to the list of projects
  101. std::string pname = lname;
  102. m_CreatedProjectNames.push_back(pname);
  103. // create the dsp.cmake file
  104. std::string fname;
  105. fname = m_Makefile->GetStartOutputDirectory();
  106. fname += "/";
  107. fname += lname;
  108. fname += ".dsp";
  109. // save the name of the real dsp file
  110. std::string realDSP = fname;
  111. fname += ".cmake";
  112. std::ofstream fout(fname.c_str());
  113. if(!fout)
  114. {
  115. cmSystemTools::Error("Error Writing ", fname.c_str());
  116. }
  117. this->WriteDSPFile(fout,lname,target);
  118. fout.close();
  119. // if the dsp file has changed, then write it.
  120. cmSystemTools::CopyFileIfDifferent(fname.c_str(), realDSP.c_str());
  121. }
  122. void cmDSPWriter::AddDSPBuildRule(cmSourceGroup& sourceGroup)
  123. {
  124. std::string dspname = *(m_CreatedProjectNames.end()-1);
  125. if(dspname == "ALL_BUILD")
  126. {
  127. return;
  128. }
  129. dspname += ".dsp.cmake";
  130. std::string makefileIn = m_Makefile->GetStartDirectory();
  131. makefileIn += "/";
  132. makefileIn += "CMakeLists.txt";
  133. makefileIn = cmSystemTools::ConvertToOutputPath(makefileIn.c_str());
  134. std::string dsprule = "${CMAKE_COMMAND}";
  135. m_Makefile->ExpandVariablesInString(dsprule);
  136. dsprule = cmSystemTools::ConvertToOutputPath(dsprule.c_str());
  137. std::string args = makefileIn;
  138. args += " -H";
  139. args +=
  140. cmSystemTools::ConvertToOutputPath(m_Makefile->GetHomeDirectory());
  141. args += " -S";
  142. args +=
  143. cmSystemTools::ConvertToOutputPath(m_Makefile->GetStartDirectory());
  144. args += " -O";
  145. args +=
  146. cmSystemTools::ConvertToOutputPath(m_Makefile->GetStartOutputDirectory());
  147. args += " -B";
  148. args +=
  149. cmSystemTools::ConvertToOutputPath(m_Makefile->GetHomeOutputDirectory());
  150. m_Makefile->ExpandVariablesInString(args);
  151. std::string configFile =
  152. m_Makefile->GetDefinition("CMAKE_ROOT");
  153. configFile += "/Templates/CMakeWindowsSystemConfig.cmake";
  154. std::vector<std::string> listFiles = m_Makefile->GetListFiles();
  155. bool found = false;
  156. for(std::vector<std::string>::iterator i = listFiles.begin();
  157. i != listFiles.end(); ++i)
  158. {
  159. if(*i == configFile)
  160. {
  161. found = true;
  162. }
  163. }
  164. if(!found)
  165. {
  166. listFiles.push_back(configFile);
  167. }
  168. std::vector<std::string> outputs;
  169. outputs.push_back(dspname);
  170. cmCustomCommand cc(makefileIn.c_str(), dsprule.c_str(),
  171. args.c_str(),
  172. listFiles,
  173. outputs);
  174. sourceGroup.AddCustomCommand(cc);
  175. }
  176. void cmDSPWriter::WriteDSPFile(std::ostream& fout,
  177. const char *libName,
  178. cmTarget &target)
  179. {
  180. // We may be modifying the source groups temporarily, so make a copy.
  181. std::vector<cmSourceGroup> sourceGroups = m_Makefile->GetSourceGroups();
  182. // get the classes from the source lists then add them to the groups
  183. std::vector<cmSourceFile> classes = target.GetSourceFiles();
  184. for(std::vector<cmSourceFile>::iterator i = classes.begin();
  185. i != classes.end(); i++)
  186. {
  187. // Add the file to the list of sources.
  188. std::string source = i->GetFullPath();
  189. cmSourceGroup& sourceGroup = m_Makefile->FindSourceGroup(source.c_str(),
  190. sourceGroups);
  191. sourceGroup.AddSource(source.c_str(), &(*i));
  192. }
  193. // add any custom rules to the source groups
  194. for (std::vector<cmCustomCommand>::const_iterator cr =
  195. target.GetCustomCommands().begin();
  196. cr != target.GetCustomCommands().end(); ++cr)
  197. {
  198. cmSourceGroup& sourceGroup =
  199. m_Makefile->FindSourceGroup(cr->GetSourceName().c_str(),
  200. sourceGroups);
  201. cmCustomCommand cc(*cr);
  202. cc.ExpandVariables(*m_Makefile);
  203. sourceGroup.AddCustomCommand(cc);
  204. }
  205. // Write the DSP file's header.
  206. this->WriteDSPHeader(fout, libName, target, sourceGroups);
  207. // Find the group in which the CMakeLists.txt source belongs, and add
  208. // the rule to generate this DSP file.
  209. for(std::vector<cmSourceGroup>::reverse_iterator sg = sourceGroups.rbegin();
  210. sg != sourceGroups.rend(); ++sg)
  211. {
  212. if(sg->Matches("CMakeLists.txt"))
  213. {
  214. this->AddDSPBuildRule(*sg);
  215. break;
  216. }
  217. }
  218. // Loop through every source group.
  219. for(std::vector<cmSourceGroup>::const_iterator sg = sourceGroups.begin();
  220. sg != sourceGroups.end(); ++sg)
  221. {
  222. const cmSourceGroup::BuildRules& buildRules = sg->GetBuildRules();
  223. // If the group is empty, don't write it at all.
  224. if(buildRules.empty())
  225. { continue; }
  226. // If the group has a name, write the header.
  227. std::string name = sg->GetName();
  228. if(name != "")
  229. {
  230. this->WriteDSPBeginGroup(fout, name.c_str(), "");
  231. }
  232. // Loop through each build rule in the source group.
  233. for(cmSourceGroup::BuildRules::const_iterator cc =
  234. buildRules.begin(); cc != buildRules.end(); ++ cc)
  235. {
  236. std::string source = cc->first;
  237. const cmSourceGroup::Commands& commands = cc->second.m_Commands;
  238. const char* compileFlags = 0;
  239. if(cc->second.m_SourceFile)
  240. {
  241. compileFlags = cc->second.m_SourceFile->GetCompileFlags();
  242. }
  243. if (source != libName || target.GetType() == cmTarget::UTILITY)
  244. {
  245. fout << "# Begin Source File\n\n";
  246. // Tell MS-Dev what the source is. If the compiler knows how to
  247. // build it, then it will.
  248. fout << "SOURCE=" <<
  249. cmSystemTools::ConvertToOutputPath(source.c_str()) << "\n\n";
  250. if (!commands.empty())
  251. {
  252. cmSourceGroup::CommandFiles totalCommand;
  253. std::string totalCommandStr;
  254. totalCommandStr = this->CombineCommands(commands, totalCommand,
  255. source.c_str());
  256. this->WriteCustomRule(fout, source.c_str(), totalCommandStr.c_str(),
  257. totalCommand.m_Depends,
  258. totalCommand.m_Outputs, compileFlags);
  259. }
  260. else if(compileFlags)
  261. {
  262. for(std::vector<std::string>::iterator i
  263. = m_Configurations.begin(); i != m_Configurations.end(); ++i)
  264. {
  265. if (i == m_Configurations.begin())
  266. {
  267. fout << "!IF \"$(CFG)\" == " << i->c_str() << std::endl;
  268. }
  269. else
  270. {
  271. fout << "!ELSEIF \"$(CFG)\" == " << i->c_str() << std::endl;
  272. }
  273. fout << "\n# ADD CPP " << compileFlags << "\n\n";
  274. }
  275. fout << "!ENDIF\n\n";
  276. }
  277. fout << "# End Source File\n";
  278. }
  279. }
  280. // If the group has a name, write the footer.
  281. if(name != "")
  282. {
  283. this->WriteDSPEndGroup(fout);
  284. }
  285. }
  286. // Write the DSP file's footer.
  287. this->WriteDSPFooter(fout);
  288. }
  289. void cmDSPWriter::WriteCustomRule(std::ostream& fout,
  290. const char* source,
  291. const char* command,
  292. const std::set<std::string>& depends,
  293. const std::set<std::string>& outputs,
  294. const char* flags
  295. )
  296. {
  297. std::vector<std::string>::iterator i;
  298. for(i = m_Configurations.begin(); i != m_Configurations.end(); ++i)
  299. {
  300. if (i == m_Configurations.begin())
  301. {
  302. fout << "!IF \"$(CFG)\" == " << i->c_str() << std::endl;
  303. }
  304. else
  305. {
  306. fout << "!ELSEIF \"$(CFG)\" == " << i->c_str() << std::endl;
  307. }
  308. if(flags)
  309. {
  310. fout << "\n# ADD CPP " << flags << "\n\n";
  311. }
  312. // Write out the dependencies for the rule.
  313. fout << "USERDEP__HACK=";
  314. for(std::set<std::string>::const_iterator d = depends.begin();
  315. d != depends.end(); ++d)
  316. {
  317. fout << "\\\n\t" <<
  318. cmSystemTools::ConvertToOutputPath(d->c_str());
  319. }
  320. fout << "\n";
  321. fout << "# PROP Ignore_Default_Tool 1\n";
  322. fout << "# Begin Custom Build\n\n";
  323. if(outputs.size() == 0)
  324. {
  325. fout << source << "_force : \"$(SOURCE)\" \"$(INTDIR)\" \"$(OUTDIR)\"";
  326. fout << command << "\n\n";
  327. }
  328. // Write a rule for every output generated by this command.
  329. for(std::set<std::string>::const_iterator output = outputs.begin();
  330. output != outputs.end(); ++output)
  331. {
  332. fout << "\"" << output->c_str()
  333. << "\" : \"$(SOURCE)\" \"$(INTDIR)\" \"$(OUTDIR)\"";
  334. fout << command << "\n\n";
  335. }
  336. fout << "# End Custom Build\n\n";
  337. }
  338. fout << "!ENDIF\n\n";
  339. }
  340. void cmDSPWriter::WriteDSPBeginGroup(std::ostream& fout,
  341. const char* group,
  342. const char* filter)
  343. {
  344. fout << "# Begin Group \"" << group << "\"\n"
  345. "# PROP Default_Filter \"" << filter << "\"\n";
  346. }
  347. void cmDSPWriter::WriteDSPEndGroup(std::ostream& fout)
  348. {
  349. fout << "# End Group\n";
  350. }
  351. void cmDSPWriter::SetBuildType(BuildType b, const char *libName)
  352. {
  353. std::string root= m_Makefile->GetDefinition("CMAKE_ROOT");
  354. const char *def= m_Makefile->GetDefinition( "MSPROJECT_TEMPLATE_DIRECTORY");
  355. if( def)
  356. {
  357. root = def;
  358. }
  359. else
  360. {
  361. root += "/Templates";
  362. }
  363. switch(b)
  364. {
  365. case STATIC_LIBRARY:
  366. m_DSPHeaderTemplate = root;
  367. m_DSPHeaderTemplate += "/staticLibHeader.dsptemplate";
  368. m_DSPFooterTemplate = root;
  369. m_DSPFooterTemplate += "/staticLibFooter.dsptemplate";
  370. break;
  371. case DLL:
  372. m_DSPHeaderTemplate = root;
  373. m_DSPHeaderTemplate += "/DLLHeader.dsptemplate";
  374. m_DSPFooterTemplate = root;
  375. m_DSPFooterTemplate += "/DLLFooter.dsptemplate";
  376. break;
  377. case EXECUTABLE:
  378. m_DSPHeaderTemplate = root;
  379. m_DSPHeaderTemplate += "/EXEHeader.dsptemplate";
  380. m_DSPFooterTemplate = root;
  381. m_DSPFooterTemplate += "/EXEFooter.dsptemplate";
  382. break;
  383. case WIN32_EXECUTABLE:
  384. m_DSPHeaderTemplate = root;
  385. m_DSPHeaderTemplate += "/EXEWinHeader.dsptemplate";
  386. m_DSPFooterTemplate = root;
  387. m_DSPFooterTemplate += "/EXEFooter.dsptemplate";
  388. break;
  389. case UTILITY:
  390. m_DSPHeaderTemplate = root;
  391. m_DSPHeaderTemplate += "/UtilityHeader.dsptemplate";
  392. m_DSPFooterTemplate = root;
  393. m_DSPFooterTemplate += "/UtilityFooter.dsptemplate";
  394. break;
  395. }
  396. // once the build type is set, determine what configurations are
  397. // possible
  398. std::ifstream fin(m_DSPHeaderTemplate.c_str());
  399. cmRegularExpression reg("# Name ");
  400. if(!fin)
  401. {
  402. cmSystemTools::Error("Error Reading ", m_DSPHeaderTemplate.c_str());
  403. }
  404. // reset m_Configurations
  405. m_Configurations.erase(m_Configurations.begin(), m_Configurations.end());
  406. // now add all the configurations possible
  407. char buffer[2048];
  408. while(fin)
  409. {
  410. fin.getline(buffer, 2048);
  411. std::string line = buffer;
  412. cmSystemTools::ReplaceString(line, "OUTPUT_LIBNAME",libName);
  413. if (reg.find(line))
  414. {
  415. m_Configurations.push_back(line.substr(reg.end()));
  416. }
  417. }
  418. }
  419. std::string
  420. cmDSPWriter::CombineCommands(const cmSourceGroup::Commands &commands,
  421. cmSourceGroup::CommandFiles &totalCommand,
  422. const char *source)
  423. {
  424. // Loop through every custom command generating code from the
  425. // current source.
  426. // build up the depends and outputs and commands
  427. std::string totalCommandStr = "";
  428. std::string temp;
  429. for(cmSourceGroup::Commands::const_iterator c = commands.begin();
  430. c != commands.end(); ++c)
  431. {
  432. totalCommandStr += "\n\t";
  433. temp= c->second.m_Command;
  434. temp = cmSystemTools::ConvertToOutputPath(temp.c_str());
  435. totalCommandStr += temp;
  436. totalCommandStr += " ";
  437. totalCommandStr += c->second.m_Arguments;
  438. totalCommand.Merge(c->second);
  439. }
  440. // Create a dummy file with the name of the source if it does
  441. // not exist
  442. if(totalCommand.m_Outputs.empty())
  443. {
  444. std::string dummyFile = m_Makefile->GetStartOutputDirectory();
  445. dummyFile += "/";
  446. dummyFile += source;
  447. if(!cmSystemTools::FileExists(dummyFile.c_str()))
  448. {
  449. std::ofstream fout(dummyFile.c_str());
  450. fout << "Dummy file created by cmake as unused source for utility command.\n";
  451. }
  452. }
  453. return totalCommandStr;
  454. }
  455. // look for custom rules on a target and collect them together
  456. std::string
  457. cmDSPWriter::CreateTargetRules(const cmTarget &target,
  458. const char *libName)
  459. {
  460. std::string customRuleCode = "";
  461. if (target.GetType() >= cmTarget::UTILITY)
  462. {
  463. return customRuleCode;
  464. }
  465. // Find the group in which the lix exe custom rules belong
  466. bool init = false;
  467. for (std::vector<cmCustomCommand>::const_iterator cr =
  468. target.GetCustomCommands().begin();
  469. cr != target.GetCustomCommands().end(); ++cr)
  470. {
  471. cmCustomCommand cc(*cr);
  472. cc.ExpandVariables(*m_Makefile);
  473. if (cc.GetSourceName() == libName)
  474. {
  475. if (!init)
  476. {
  477. // header stuff
  478. customRuleCode = "# Begin Special Build Tool\nPostBuild_Cmds=";
  479. init = true;
  480. }
  481. else
  482. {
  483. customRuleCode += "\t";
  484. }
  485. customRuleCode += cc.GetCommand() + " " + cc.GetArguments();
  486. }
  487. }
  488. if (init)
  489. {
  490. customRuleCode += "\n# End Special Build Tool\n";
  491. }
  492. return customRuleCode;
  493. }
  494. inline std::string removeQuotes(const std::string& s)
  495. {
  496. if(s[0] == '\"' && s[s.size()-1] == '\"')
  497. {
  498. return s.substr(1, s.size()-2);
  499. }
  500. return s;
  501. }
  502. void cmDSPWriter::WriteDSPHeader(std::ostream& fout, const char *libName,
  503. const cmTarget &target,
  504. std::vector<cmSourceGroup> &)
  505. {
  506. std::set<std::string> pathEmitted;
  507. // determine the link directories
  508. std::string libOptions;
  509. std::string libDebugOptions;
  510. std::string libOptimizedOptions;
  511. std::string libMultiLineOptions;
  512. std::string libMultiLineDebugOptions;
  513. std::string libMultiLineOptimizedOptions;
  514. // suppoirt override in output directory
  515. std::string libPath = "";
  516. if (m_Makefile->GetDefinition("LIBRARY_OUTPUT_PATH"))
  517. {
  518. libPath = m_Makefile->GetDefinition("LIBRARY_OUTPUT_PATH");
  519. }
  520. std::string exePath = "";
  521. if (m_Makefile->GetDefinition("EXECUTABLE_OUTPUT_PATH"))
  522. {
  523. exePath = m_Makefile->GetDefinition("EXECUTABLE_OUTPUT_PATH");
  524. }
  525. if(libPath.size())
  526. {
  527. // make sure there is a trailing slash
  528. if(libPath[libPath.size()-1] != '/')
  529. {
  530. libPath += "/";
  531. }
  532. std::string lpath =
  533. cmSystemTools::ConvertToOutputPath(libPath.c_str());
  534. std::string lpathIntDir = libPath + "$(INTDIR)";
  535. lpathIntDir = cmSystemTools::ConvertToOutputPath(lpathIntDir.c_str());
  536. if(pathEmitted.insert(lpath).second)
  537. {
  538. libOptions += " /LIBPATH:";
  539. libOptions += lpathIntDir;
  540. libOptions += " ";
  541. libOptions += " /LIBPATH:";
  542. libOptions += lpath;
  543. libOptions += " ";
  544. libMultiLineOptions += "# ADD LINK32 /LIBPATH:";
  545. libMultiLineOptions += lpathIntDir;
  546. libMultiLineOptions += " ";
  547. libMultiLineOptions += " /LIBPATH:";
  548. libMultiLineOptions += lpath;
  549. libMultiLineOptions += " \n";
  550. }
  551. }
  552. if(exePath.size())
  553. {
  554. // make sure there is a trailing slash
  555. if(exePath[exePath.size()-1] != '/')
  556. {
  557. exePath += "/";
  558. }
  559. std::string lpath =
  560. cmSystemTools::ConvertToOutputPath(exePath.c_str());
  561. std::string lpathIntDir = exePath + "$(INTDIR)";
  562. lpathIntDir = cmSystemTools::ConvertToOutputPath(lpathIntDir.c_str());
  563. if(pathEmitted.insert(lpath).second)
  564. {
  565. libOptions += " /LIBPATH:";
  566. libOptions += lpathIntDir;
  567. libOptions += " ";
  568. libOptions += " /LIBPATH:";
  569. libOptions += lpath;
  570. libOptions += " ";
  571. libMultiLineOptions += "# ADD LINK32 /LIBPATH:";
  572. libMultiLineOptions += lpathIntDir;
  573. libMultiLineOptions += " ";
  574. libMultiLineOptions += " /LIBPATH:";
  575. libMultiLineOptions += lpath;
  576. libMultiLineOptions += " \n";
  577. }
  578. }
  579. std::vector<std::string>::iterator i;
  580. std::vector<std::string>& libdirs = m_Makefile->GetLinkDirectories();
  581. for(i = libdirs.begin(); i != libdirs.end(); ++i)
  582. {
  583. std::string path = *i;
  584. if(path[path.size()-1] != '/')
  585. {
  586. path += "/";
  587. }
  588. std::string lpath =
  589. cmSystemTools::ConvertToOutputPath(path.c_str());
  590. std::string lpathIntDir = path + "$(INTDIR)";
  591. lpathIntDir = cmSystemTools::ConvertToOutputPath(lpathIntDir.c_str());
  592. if(pathEmitted.insert(lpath).second)
  593. {
  594. libOptions += " /LIBPATH:";
  595. libOptions += lpathIntDir;
  596. libOptions += " ";
  597. libOptions += " /LIBPATH:";
  598. libOptions += lpath;
  599. libOptions += " ";
  600. libMultiLineOptions += "# ADD LINK32 /LIBPATH:";
  601. libMultiLineOptions += lpathIntDir;
  602. libMultiLineOptions += " ";
  603. libMultiLineOptions += " /LIBPATH:";
  604. libMultiLineOptions += lpath;
  605. libMultiLineOptions += " \n";
  606. }
  607. }
  608. // find link libraries
  609. const cmTarget::LinkLibraries& libs = target.GetLinkLibraries();
  610. cmTarget::LinkLibraries::const_iterator j;
  611. for(j = libs.begin(); j != libs.end(); ++j)
  612. {
  613. // add libraries to executables and dlls (but never include
  614. // a library in a library, bad recursion)
  615. if ((target.GetType() != cmTarget::SHARED_LIBRARY
  616. && target.GetType() != cmTarget::STATIC_LIBRARY) ||
  617. (target.GetType() == cmTarget::SHARED_LIBRARY && libName != j->first))
  618. {
  619. std::string lib = j->first;
  620. if(j->first.find(".lib") == std::string::npos)
  621. {
  622. lib += ".lib";
  623. }
  624. lib = cmSystemTools::ConvertToOutputPath(lib.c_str());
  625. if (j->second == cmTarget::GENERAL)
  626. {
  627. libOptions += " ";
  628. libOptions += lib;
  629. libMultiLineOptions += "# ADD LINK32 ";
  630. libMultiLineOptions += lib;
  631. libMultiLineOptions += "\n";
  632. }
  633. if (j->second == cmTarget::DEBUG)
  634. {
  635. libDebugOptions += " ";
  636. libDebugOptions += lib;
  637. libMultiLineDebugOptions += "# ADD LINK32 ";
  638. libMultiLineDebugOptions += lib;
  639. libMultiLineDebugOptions += "\n";
  640. }
  641. if (j->second == cmTarget::OPTIMIZED)
  642. {
  643. libOptimizedOptions += " ";
  644. libOptimizedOptions += lib;
  645. libMultiLineOptimizedOptions += "# ADD LINK32 ";
  646. libMultiLineOptimizedOptions += lib;
  647. libMultiLineOptimizedOptions += "\n";
  648. }
  649. }
  650. }
  651. std::string extraLinkOptions =
  652. m_Makefile->GetDefinition("CMAKE_EXTRA_LINK_FLAGS");
  653. if(extraLinkOptions.size())
  654. {
  655. libOptions += " ";
  656. libOptions += extraLinkOptions;
  657. libOptions += " ";
  658. libMultiLineOptions += "# ADD LINK32 ";
  659. libMultiLineOptions += extraLinkOptions;
  660. libMultiLineOptions += " \n";
  661. }
  662. // are there any custom rules on the target itself
  663. // only if the target is a lib or exe
  664. std::string customRuleCode = this->CreateTargetRules(target, libName);
  665. std::ifstream fin(m_DSPHeaderTemplate.c_str());
  666. if(!fin)
  667. {
  668. cmSystemTools::Error("Error Reading ", m_DSPHeaderTemplate.c_str());
  669. }
  670. char buffer[2048];
  671. while(fin)
  672. {
  673. fin.getline(buffer, 2048);
  674. std::string line = buffer;
  675. const char* mfcFlag = m_Makefile->GetDefinition("CMAKE_MFC_FLAG");
  676. if(!mfcFlag)
  677. {
  678. mfcFlag = "0";
  679. }
  680. cmSystemTools::ReplaceString(line, "CMAKE_CUSTOM_RULE_CODE",
  681. customRuleCode.c_str());
  682. cmSystemTools::ReplaceString(line, "CMAKE_MFC_FLAG",
  683. mfcFlag);
  684. cmSystemTools::ReplaceString(line, "CM_LIBRARIES",
  685. libOptions.c_str());
  686. cmSystemTools::ReplaceString(line, "CM_DEBUG_LIBRARIES",
  687. libDebugOptions.c_str());
  688. cmSystemTools::ReplaceString(line, "CM_OPTIMIZED_LIBRARIES",
  689. libOptimizedOptions.c_str());
  690. cmSystemTools::ReplaceString(line, "CM_MULTILINE_LIBRARIES",
  691. libMultiLineOptions.c_str());
  692. cmSystemTools::ReplaceString(line, "CM_MULTILINE_DEBUG_LIBRARIES",
  693. libMultiLineDebugOptions.c_str());
  694. cmSystemTools::ReplaceString(line, "CM_MULTILINE_OPTIMIZED_LIBRARIES",
  695. libMultiLineOptimizedOptions.c_str());
  696. cmSystemTools::ReplaceString(line, "BUILD_INCLUDES",
  697. m_IncludeOptions.c_str());
  698. cmSystemTools::ReplaceString(line, "OUTPUT_LIBNAME",libName);
  699. // because LIBRARY_OUTPUT_PATH and EXECUTABLE_OUTPUT_PATH
  700. // are already quoted in the template file,
  701. // we need to remove the quotes here, we still need
  702. // to convert to output path for unix to win32 conversion
  703. cmSystemTools::ReplaceString(line, "LIBRARY_OUTPUT_PATH",
  704. removeQuotes(
  705. cmSystemTools::ConvertToOutputPath(libPath.c_str())).c_str());
  706. cmSystemTools::ReplaceString(line, "EXECUTABLE_OUTPUT_PATH",
  707. removeQuotes(
  708. cmSystemTools::ConvertToOutputPath(exePath.c_str())).c_str());
  709. cmSystemTools::ReplaceString(line,
  710. "EXTRA_DEFINES",
  711. m_Makefile->GetDefineFlags());
  712. cmSystemTools::ReplaceString(line,
  713. "CMAKE_CXX_FLAGS_RELEASE",
  714. m_Makefile->
  715. GetDefinition("CMAKE_CXX_FLAGS_RELEASE"));
  716. cmSystemTools::ReplaceString(line,
  717. "CMAKE_CXX_FLAGS_MINSIZEREL",
  718. m_Makefile->
  719. GetDefinition("CMAKE_CXX_FLAGS_MINSIZEREL")
  720. );
  721. cmSystemTools::ReplaceString(line,
  722. "CMAKE_CXX_FLAGS_DEBUG",
  723. m_Makefile->
  724. GetDefinition("CMAKE_CXX_FLAGS_DEBUG"));
  725. cmSystemTools::ReplaceString(line,
  726. "CMAKE_CXX_FLAGS_RELWITHDEBINFO",
  727. m_Makefile->
  728. GetDefinition("CMAKE_CXX_FLAGS_RELWITHDEBINFO"));
  729. cmSystemTools::ReplaceString(line,
  730. "CMAKE_CXX_FLAGS",
  731. m_Makefile->
  732. GetDefinition("CMAKE_CXX_FLAGS"));
  733. fout << line.c_str() << std::endl;
  734. }
  735. }
  736. void cmDSPWriter::WriteDSPFooter(std::ostream& fout)
  737. {
  738. std::ifstream fin(m_DSPFooterTemplate.c_str());
  739. if(!fin)
  740. {
  741. cmSystemTools::Error("Error Reading ",
  742. m_DSPFooterTemplate.c_str());
  743. }
  744. char buffer[2048];
  745. while(fin)
  746. {
  747. fin.getline(buffer, 2048);
  748. fout << buffer << std::endl;
  749. }
  750. }