cmBorlandMakefileGenerator.cpp 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769
  1. #include "cmBorlandMakefileGenerator.h"
  2. #include "cmMakefile.h"
  3. #include "cmStandardIncludes.h"
  4. #include "cmSystemTools.h"
  5. #include "cmSourceFile.h"
  6. #include "cmMakeDepend.h"
  7. #include "cmCacheManager.h"
  8. //---------------------------------------------------------------------------
  9. cmBorlandMakefileGenerator::cmBorlandMakefileGenerator()
  10. {
  11. m_CacheOnly = false;
  12. m_Recurse = false;
  13. }
  14. //---------------------------------------------------------------------------
  15. void cmBorlandMakefileGenerator::GenerateMakefile()
  16. {
  17. // suppoirt override in output directories
  18. if (m_Makefile->GetDefinition("LIBRARY_OUTPUT_PATH"))
  19. {
  20. m_LibraryOutputPath = m_Makefile->GetDefinition("LIBRARY_OUTPUT_PATH");
  21. if(m_LibraryOutputPath.size())
  22. {
  23. std::string tempLibraryOutputPath = m_LibraryOutputPath;
  24. if(tempLibraryOutputPath[tempLibraryOutputPath.size() -1] != '/')
  25. {
  26. tempLibraryOutputPath += "/";
  27. }
  28. if(!cmSystemTools::MakeDirectory(tempLibraryOutputPath.c_str()))
  29. {
  30. cmSystemTools::Error("Error failed create "
  31. "LIBRARY_OUTPUT_PATH directory:",
  32. tempLibraryOutputPath.c_str());
  33. }
  34. m_Makefile->AddLinkDirectory(m_LibraryOutputPath.c_str());
  35. }
  36. }
  37. if (m_Makefile->GetDefinition("EXECUTABLE_OUTPUT_PATH"))
  38. {
  39. m_ExecutableOutputPath =
  40. m_Makefile->GetDefinition("EXECUTABLE_OUTPUT_PATH");
  41. if(m_ExecutableOutputPath.size())
  42. {
  43. std::string tempExecutableOutputPath = m_ExecutableOutputPath;
  44. if(tempExecutableOutputPath[tempExecutableOutputPath.size() -1] != '/')
  45. {
  46. tempExecutableOutputPath += "/";
  47. }
  48. if(!cmSystemTools::MakeDirectory(tempExecutableOutputPath.c_str()))
  49. {
  50. cmSystemTools::Error("Error failed to create "
  51. "EXECUTABLE_OUTPUT_PATH directory:",
  52. tempExecutableOutputPath.c_str());
  53. }
  54. m_Makefile->AddLinkDirectory(m_ExecutableOutputPath.c_str());
  55. }
  56. }
  57. if(m_ExecutableOutputPath.size() == 0)
  58. {
  59. m_ExecutableOutputPath = ".";
  60. }
  61. if(m_LibraryOutputPath.size() == 0)
  62. {
  63. m_LibraryOutputPath = ".";
  64. }
  65. if (m_CacheOnly)
  66. {
  67. // Generate the cache only stuff
  68. this->GenerateCacheOnly();
  69. // if recurse then generate for all sub- makefiles
  70. if (m_Recurse)
  71. {
  72. this->RecursiveGenerateCacheOnly();
  73. }
  74. }
  75. }
  76. //---------------------------------------------------------------------------
  77. void cmBorlandMakefileGenerator::GenerateCacheOnly()
  78. {
  79. cmSystemTools::MakeDirectory(m_Makefile->GetStartOutputDirectory());
  80. std::string dest = m_Makefile->GetStartOutputDirectory();
  81. dest += "/makefile.mak";
  82. this->OutputMakefile(dest.c_str());
  83. }
  84. //---------------------------------------------------------------------------
  85. void cmBorlandMakefileGenerator::RecursiveGenerateCacheOnly()
  86. {
  87. std::vector<cmMakefile*> makefiles;
  88. m_Makefile->FindSubDirectoryCMakeListsFiles(makefiles);
  89. for (std::vector<cmMakefile*>::iterator i=makefiles.begin();
  90. i!=makefiles.end(); ++i)
  91. {
  92. cmMakefile* mf = *i;
  93. cmBorlandMakefileGenerator* gen = new cmBorlandMakefileGenerator;
  94. gen->SetCacheOnlyOn();
  95. gen->SetRecurseOff();
  96. mf->SetMakefileGenerator(gen);
  97. mf->GenerateMakefile();
  98. }
  99. // CLEAN up the makefiles created
  100. for (unsigned int i=0; i<makefiles.size(); ++i)
  101. {
  102. delete makefiles[i];
  103. }
  104. }
  105. //---------------------------------------------------------------------------
  106. void cmBorlandMakefileGenerator::OutputMakefile(const char* file)
  107. {
  108. //
  109. // Create sub directories for aux source directories
  110. //
  111. std::vector<std::string>& auxSourceDirs =
  112. m_Makefile->GetAuxSourceDirectories();
  113. if ( auxSourceDirs.size() )
  114. {
  115. // For the case when this is running as a remote build
  116. // on unix, make the directory
  117. for (std::vector<std::string>::iterator i=auxSourceDirs.begin();
  118. i!=auxSourceDirs.end(); ++i)
  119. {
  120. cmSystemTools::MakeDirectory(i->c_str());
  121. }
  122. }
  123. //
  124. std::ofstream fout(file);
  125. //
  126. // Begin writing to makefile.mak
  127. //
  128. fout << "# CMAKE Borland (win32) makefile : Edit with Caution \n\n";
  129. //
  130. // Turn on Autodependency checking
  131. //
  132. fout << ".autodepend \n\n";
  133. //
  134. // Define all our compile and make flags/variables
  135. //
  136. std::string replace;
  137. // Careful with these directory paths....\ vs /
  138. replace = "BCBBINPATH = @BCB_BIN_PATH@ \n";
  139. fout << m_Makefile->ExpandVariablesInString(replace);
  140. replace = "BCB = $(BCBBINPATH)/.. \n";
  141. fout << m_Makefile->ExpandVariablesInString(replace);
  142. // replace = "OUTDIRLIB = @LIBRARY_OUTPUT_PATH@ \n";
  143. // fout << cmSystemTools::ConvertToWindowsSlashes(m_Makefile->ExpandVariablesInString(replace));
  144. // replace = "OUTDIREXE = @EXECUTABLE_OUTPUT_PATH@ \n";
  145. // fout << m_Makefile->ExpandVariablesInString(replace);
  146. replace = "OUTDIRLIB = ";
  147. replace += m_LibraryOutputPath;
  148. replace += "\n";
  149. fout << cmSystemTools::ConvertToWindowsSlashes(replace);
  150. replace = "OUTDIREXE = ";
  151. replace += m_ExecutableOutputPath;
  152. replace += "\n";
  153. fout << cmSystemTools::ConvertToWindowsSlashes(replace);
  154. replace = "USERDEFINES = @DEFS_USER@ \n";
  155. fout << m_Makefile->ExpandVariablesInString(replace);
  156. replace = "SYSDEFINES = @DEFS_SYS@ \n";
  157. fout << m_Makefile->ExpandVariablesInString(replace);
  158. replace = "CMAKE_COMMAND = ${CMAKE_COMMAND} \n";
  159. fout << m_Makefile->ExpandVariablesInString(replace);
  160. replace = "CPP = \"$(BCBBINPATH)/BCC32.exe\" +CPP_PROJ.CFG \n";
  161. fout << m_Makefile->ExpandVariablesInString(replace);
  162. replace =
  163. "CPPFLAGS_DEBUG = @FLAGS_CPP_DEBUG@ \n"
  164. "CPPFLAGS_RELEASE = @FLAGS_CPP_RELEASE@ \n"
  165. "CPPFLAGS_WARNING = @FLAGS_CPP_WARNING@ \n"
  166. "LINKFLAGS_DLL = @FLAGS_LINK_DLL@ \n"
  167. "LINKFLAGS_BPL = @FLAGS_LINK_BPL@ \n"
  168. "LINKFLAGS_EXE = @FLAGS_LINK_EXE@ \n"
  169. "LINKFLAGS_DEBUG = @FLAGS_LINK_DEBUG@ \n";
  170. fout << m_Makefile->ExpandVariablesInString(replace);
  171. replace = "LINKFLAGS_STATIC = @FLAGS_LINK_STATIC@ \n";
  172. fout << m_Makefile->ExpandVariablesInString(replace);
  173. fout << "CMAKE_CURRENT_SOURCE = " << m_Makefile->GetStartDirectory() << "\n";
  174. fout << "CMAKE_CURRENT_BINARY = " << m_Makefile->GetStartOutputDirectory() << "\n";
  175. fout << "OBJDIR = " << m_Makefile->GetStartOutputDirectory() << "\n";
  176. fout << "CMAKEDEFINES = " << m_Makefile->GetDefineFlags() << "\n";
  177. fout << "LINK_LIB = \\ \n";
  178. fout << " import32.lib \\ \n";
  179. fout << " cw32mti.lib \n\n";
  180. //
  181. // create a make variable with all of the sources for this makefile for depend purposes.
  182. //
  183. std::vector<std::string> lfiles = m_Makefile->GetListFiles();
  184. // sort the array
  185. std::sort(lfiles.begin(), lfiles.end(), std::less<std::string>());
  186. // remove duplicates
  187. std::vector<std::string>::iterator new_end =
  188. std::unique(lfiles.begin(), lfiles.end());
  189. lfiles.erase(new_end, lfiles.end());
  190. fout << "CMAKE_MAKEFILE_SOURCES = \\ \n";
  191. std::string dir;
  192. for (std::vector<std::string>::const_iterator i=lfiles.begin();
  193. i!=lfiles.end(); ++i)
  194. {
  195. dir = *i;
  196. // cmSystemTools::ConvertToWindowsSlashes(dir);
  197. fout << " " << dir << " \\\n";
  198. }
  199. dir = m_Makefile->GetHomeOutputDirectory();
  200. dir += "/CMakeCache.txt";
  201. // cmSystemTools::ConvertToWindowsSlashes(dir);
  202. fout << " " << dir << "\n\n";
  203. //
  204. // Output Include paths
  205. //
  206. std::vector<std::string>& includes = m_Makefile->GetIncludeDirectories();
  207. fout << "INCLUDEPATH =";
  208. for (std::vector<std::string>::iterator i=includes.begin();
  209. i!=includes.end(); ++i)
  210. {
  211. std::string include = *i;
  212. fout << "-I" << cmSystemTools::EscapeSpaces(i->c_str()) << "; \\\n ";
  213. }
  214. fout << "-I" <<
  215. cmSystemTools::EscapeSpaces(m_Makefile->GetStartDirectory()) << "\n\n";
  216. //
  217. // for each target add to the list of targets
  218. //
  219. fout << "TARGETS = ";
  220. const cmTargets &tgts = m_Makefile->GetTargets();
  221. // list libraries first
  222. for (cmTargets::const_iterator l=tgts.begin();
  223. l!=tgts.end(); ++l)
  224. {
  225. if ((l->second.GetType() == cmTarget::STATIC_LIBRARY)
  226. && l->second.IsInAll())
  227. {
  228. fout << " \\\n $(OUTDIRLIB)\\" << l->first.c_str() << ".lib";
  229. }
  230. if ((l->second.GetType() == cmTarget::SHARED_LIBRARY) && l->second.IsInAll())
  231. {
  232. fout << " \\\n $(OUTDIRLIB)\\" << l->first.c_str() << ".dll";
  233. }
  234. if ((l->second.GetType() == cmTarget::MODULE_LIBRARY) && l->second.IsInAll())
  235. {
  236. fout << " \\\n $(OUTDIRLIB)\\" << l->first.c_str() << ".bpl";
  237. }
  238. }
  239. // executables
  240. for (cmTargets::const_iterator l=tgts.begin(); l!=tgts.end(); l++)
  241. {
  242. if ((l->second.GetType() == cmTarget::EXECUTABLE
  243. || l->second.GetType() == cmTarget::WIN32_EXECUTABLE) && l->second.IsInAll())
  244. {
  245. fout << " \\\n " << l->first.c_str() << ".exe";
  246. }
  247. }
  248. // list utilities last
  249. for (cmTargets::const_iterator l=tgts.begin(); l!=tgts.end(); l++)
  250. {
  251. if (l->second.GetType() == cmTarget::UTILITY && l->second.IsInAll())
  252. {
  253. fout << " \\\n " << l->first.c_str();
  254. }
  255. }
  256. fout << "\n\n";
  257. //
  258. // Now create the source file groups for each target
  259. //
  260. for (cmTargets::const_iterator l=tgts.begin(); l!=tgts.end(); l++)
  261. {
  262. std::vector<cmSourceFile> classes = l->second.GetSourceFiles();
  263. if (classes.begin() != classes.end())
  264. {
  265. fout << l->first << "_SRC_OBJS = ";
  266. for (std::vector<cmSourceFile>::iterator i=classes.begin(); i!=classes.end(); i++)
  267. {
  268. std::string ext = i->GetSourceExtension();
  269. if (!i->IsAHeaderFileOnly() && (ext!="def" && ext!="rc"))
  270. {
  271. std::string sourceName = i->GetSourceName();
  272. cmSystemTools::ConvertToWindowsSlashes(sourceName);
  273. fout << " \\\n " <<
  274. sourceName
  275. << ".obj ";
  276. }
  277. }
  278. fout << "\n\n";
  279. }
  280. }
  281. //
  282. // Create the link lib list for each target
  283. //
  284. // do .lib files
  285. std::string libname;
  286. for (cmTargets::const_iterator t=tgts.begin(); t!=tgts.end(); t++)
  287. {
  288. cmTarget::LinkLibraries const& libs = t->second.GetLinkLibraries();
  289. if ((t->second.GetType() == cmTarget::STATIC_LIBRARY) ||
  290. (t->second.GetType() == cmTarget::SHARED_LIBRARY) ||
  291. (t->second.GetType() == cmTarget::MODULE_LIBRARY) ||
  292. (t->second.GetType() == cmTarget::EXECUTABLE) ||
  293. (t->second.GetType() == cmTarget::WIN32_EXECUTABLE))
  294. {
  295. fout << t->first << "_LINK_LIB = ";
  296. for (cmTarget::LinkLibraries::const_iterator l=libs.begin();
  297. l!=libs.end(); l++)
  298. {
  299. if ((t->first!=l->first) &&
  300. (t->second.GetType()!=cmTarget::INSTALL_FILES
  301. || t->second.GetType()!=cmTarget::INSTALL_PROGRAMS))
  302. {
  303. // if this lib is not a target then don't add OUTDIRLIB to it
  304. if (tgts.find(l->first)==tgts.end())
  305. libname = l->first;
  306. else
  307. libname = "$(OUTDIRLIB)/" + l->first;
  308. if (libname.find(".bpi")!=std::string::npos) continue;
  309. cmSystemTools::ReplaceString(libname, ".lib", "");
  310. libname += ".lib";
  311. fout << " \\\n " << cmSystemTools::EscapeSpaces(libname.c_str());
  312. }
  313. }
  314. fout << "\n\n";
  315. }
  316. }
  317. // do .bpi package files
  318. for (cmTargets::const_iterator t=tgts.begin(); t!=tgts.end(); t++)
  319. {
  320. cmTarget::LinkLibraries const& libs = t->second.GetLinkLibraries();
  321. if ((t->second.GetType() == cmTarget::STATIC_LIBRARY) ||
  322. (t->second.GetType() == cmTarget::SHARED_LIBRARY) ||
  323. (t->second.GetType() == cmTarget::MODULE_LIBRARY) ||
  324. (t->second.GetType() == cmTarget::EXECUTABLE) ||
  325. (t->second.GetType() == cmTarget::WIN32_EXECUTABLE))
  326. {
  327. fout << t->first << "_LINK_BPI = ";
  328. for (cmTarget::LinkLibraries::const_iterator l=libs.begin();
  329. l!=libs.end(); l++)
  330. {
  331. if ((t->first!=l->first) &&
  332. (t->second.GetType()!=cmTarget::INSTALL_FILES
  333. || t->second.GetType()!=cmTarget::INSTALL_PROGRAMS))
  334. {
  335. // if this lib is not a target then don't add OUTDIRLIB to it
  336. if (tgts.find(l->first)==tgts.end())
  337. libname = l->first;
  338. else
  339. libname = "$(OUTDIRLIB)/" + l->first;
  340. if (libname.find(".bpi")==std::string::npos) continue;
  341. fout << " \\\n " << cmSystemTools::EscapeSpaces(libname.c_str());
  342. }
  343. }
  344. fout << "\n\n";
  345. }
  346. }
  347. //
  348. // Create the link dir list - use same for all targets
  349. //
  350. std::vector<std::string> dirs = m_Makefile->GetLinkDirectories();
  351. fout << "LINK_DIR =";
  352. for (std::vector<std::string>::const_iterator d=dirs.begin(); d!=dirs.end(); d++)
  353. {
  354. std::string temp = cmSystemTools::EscapeSpaces(d->c_str());
  355. fout << temp << ";";
  356. }
  357. fout << "\n\n";
  358. //
  359. // The project rule - Build All targets
  360. //
  361. fout << "DEFAULT : \n";
  362. fout << " @$(MAKE) makefile.mak \n";
  363. fout << " @$(MAKE) ALL \n\n";
  364. //
  365. // Create a rule to allow us to setup the compiler and output dir
  366. //
  367. fout << "PREPARE : \n";
  368. fout << " @if not exist \"$(OBJDIR)/.\" md \"$(OBJDIR)\" \n";
  369. fout << " @copy &&| \n";
  370. fout << " $(SYSDEFINES) $(CMAKEDEFINES) $(USERDEFINES)\n";
  371. fout << " $(CPPFLAGS_DEBUG) $(CPPFLAGS_WARNING) \n";
  372. fout << " $(INCLUDEPATH) \n";
  373. fout << " -I\"$(BCB)/include\";\"$(BCB)/include/rw\";\"$(BCB)/include/vcl\"; \n";
  374. fout << "| CPP_PROJ.CFG \n\n";
  375. //
  376. this->OutputDependencies(fout);
  377. this->OutputTargets(fout);
  378. this->OutputSubDirectoryRules(fout);
  379. //
  380. this->OutputCustomRules(fout);
  381. this->OutputMakeRules(fout);
  382. //
  383. // We'll omit current dir in path where possible
  384. std::string fullname, outpath = m_Makefile->GetStartOutputDirectory();
  385. outpath += "/";
  386. //
  387. for (cmTargets::const_iterator l=tgts.begin(); l!=tgts.end(); l++)
  388. {
  389. std::vector<cmSourceFile> classes = l->second.GetSourceFiles();
  390. if (classes.begin() != classes.end())
  391. {
  392. for (std::vector<cmSourceFile>::iterator i=classes.begin(); i!=classes.end(); i++)
  393. {
  394. if (!i->IsAHeaderFileOnly())
  395. {
  396. fullname = i->GetFullPath();
  397. cmSystemTools::ReplaceString(fullname, outpath.c_str(), "");
  398. std::string sourceName = i->GetSourceName();
  399. cmSystemTools::ConvertToWindowsSlashes(sourceName);
  400. fout << ""
  401. << sourceName
  402. << ".obj : " << fullname << "\n";
  403. }
  404. }
  405. }
  406. }
  407. //
  408. //
  409. fout << "\n# End of File\n";
  410. }
  411. //---------------------------------------------------------------------------
  412. // output the list of libraries that the executables in this makefile will depend on.
  413. void cmBorlandMakefileGenerator::OutputDependencies(std::ostream& fout)
  414. {
  415. // not required under win32
  416. }
  417. void cmBorlandMakefileGenerator::OutputTargets(std::ostream& fout)
  418. {
  419. // Do Libraries first as executables may depend on them
  420. const cmTargets &tgts = m_Makefile->GetTargets();
  421. for (cmTargets::const_iterator l=tgts.begin(); l!=tgts.end(); l++)
  422. {
  423. if (l->second.GetType() == cmTarget::STATIC_LIBRARY)
  424. {
  425. //
  426. // WARNING. TLIB fails with Unix style Forward slashes - use $(OUTDIRLIB)\\
  427. //
  428. fout << "# this should be a static library \n";
  429. fout << "$(OUTDIRLIB)\\" << l->first << ".lib : ${" << l->first << "_SRC_OBJS} \n";
  430. std::string Libname = "$(OUTDIRLIB)\\" + l->first + ".lib";
  431. fout << " TLib.exe $(LINKFLAGS_STATIC) /u " << Libname.c_str() << " @&&| \n";
  432. fout << " $? \n";
  433. fout << "| \n\n";
  434. }
  435. if (l->second.GetType() == cmTarget::SHARED_LIBRARY)
  436. {
  437. fout << "# this should be a shared (DLL) library \n";
  438. fout << "$(OUTDIRLIB)/" << l->first << ".dll : ${" << l->first << "_SRC_OBJS} \n";
  439. fout << " @ilink32.exe @&&| \n";
  440. fout << " -L\"$(BCB)/lib\" -L$(LINK_DIR) $(LINKFLAGS_DLL) $(LINKFLAGS_DEBUG) \"$(BCB)/lib/c0d32.obj\" ";
  441. fout << "$(" << l->first << "_SRC_OBJS) ";
  442. fout << "$(" << l->first << "_LINK_BPI) , $<, $*, ";
  443. fout << "$(" << l->first << "_LINK_LIB) $(LINK_LIB) \n";
  444. fout << "| \n";
  445. fout << " @implib -w " << "$(OUTDIRLIB)/" << l->first << ".lib " << "$(OUTDIRLIB)/" << l->first << ".dll \n\n";
  446. }
  447. if (l->second.GetType() == cmTarget::MODULE_LIBRARY)
  448. {
  449. fout << "# this should be a Borland Package library \n";
  450. fout << "$(OUTDIRLIB)/" << l->first << ".bpl : ${" << l->first << "_SRC_OBJS} \n";
  451. fout << " @ilink32.exe @&&| \n";
  452. fout << " -L\"$(BCB)/lib\" -L$(LINK_DIR) $(LINKFLAGS_BPL) $(LINKFLAGS_DEBUG) \"$(BCB)/lib/c0pkg32.obj\" ";
  453. fout << "$(" << l->first << "_SRC_OBJS) ";
  454. fout << "$(" << l->first << "_LINK_BPI) , $<, $*, ";
  455. fout << "$(" << l->first << "_LINK_LIB) $(LINK_LIB) \n";
  456. fout << "| \n";
  457. }
  458. }
  459. // Do Executables
  460. for (cmTargets::const_iterator l=tgts.begin(); l!=tgts.end(); l++)
  461. {
  462. if (l->second.GetType()==cmTarget::WIN32_EXECUTABLE)
  463. {
  464. fout << l->first << ".exe : ${" << l->first << "_SRC_OBJS} \n";
  465. fout << " @ilink32.exe @&&| \n";
  466. fout << " -L\"$(BCB)/lib\" -L$(LINK_DIR) $(LINKFLAGS_EXE) $(LINKFLAGS_DEBUG) \"$(BCB)/lib/c0w32.obj\" ";
  467. fout << "$(" << l->first << "_SRC_OBJS) ";
  468. fout << "$(" << l->first << "_LINK_BPI) , $<, $*, ";
  469. fout << "$(" << l->first << "_LINK_LIB) $(LINK_LIB) \n";
  470. fout << "| \n\n";
  471. }
  472. else if (l->second.GetType()==cmTarget::EXECUTABLE)
  473. {
  474. fout << l->first << ".exe : ${" << l->first << "_SRC_OBJS} \n";
  475. fout << " @ilink32.exe @&&| \n";
  476. fout << " -L\"$(BCB)/lib\" -L$(LINK_DIR) $(LINKFLAGS_EXE) $(LINKFLAGS_DEBUG) \"$(BCB)/lib/c0x32.obj\" ";
  477. fout << "$(" << l->first << "_SRC_OBJS) , $<, $*, ";
  478. fout << "$(" << l->first << "_LINK_LIB) $(LINK_LIB) \n";
  479. fout << "| \n\n";
  480. }
  481. }
  482. }
  483. //---------------------------------------------------------------------------
  484. void cmBorlandMakefileGenerator::OutputSubDirectoryRules(std::ostream& fout)
  485. {
  486. // output rules for decending into sub directories
  487. const std::vector<std::string>& SubDirectories = m_Makefile->GetSubDirectories();
  488. //
  489. if ( SubDirectories.size() == 0)
  490. {
  491. return;
  492. }
  493. //
  494. this->OutputSubDirectoryVars(fout, "SUBDIR_BUILD", "build",
  495. 0,
  496. 0,
  497. SubDirectories);
  498. }
  499. //---------------------------------------------------------------------------
  500. // fix up names of directories so they can be used
  501. // as targets in makefiles.
  502. inline std::string FixDirectoryName(const char* dir)
  503. {
  504. std::string s = dir;
  505. // replace ../ with 3 under bars
  506. size_t pos = s.find("../");
  507. if (pos != std::string::npos)
  508. {
  509. s.replace(pos, 3, "___");
  510. }
  511. // replace / directory separators with a single under bar
  512. pos = s.find("/");
  513. while(pos != std::string::npos)
  514. {
  515. s.replace(pos, 1, "_");
  516. pos = s.find("/");
  517. }
  518. return s;
  519. }
  520. void cmBorlandMakefileGenerator::OutputSubDirectoryVars(std::ostream& fout,
  521. const char* var,
  522. const char* target,
  523. const char* target1,
  524. const char* target2,
  525. const std::vector<std::string>& SubDirectories)
  526. {
  527. if (!SubDirectories.size()) return;
  528. //
  529. fout << "# Variable for making " << target << " in subdirectories.\n";
  530. fout << var << " = \\\n";
  531. unsigned int i;
  532. for (i =0; i < SubDirectories.size(); i++)
  533. {
  534. std::string subdir = FixDirectoryName(SubDirectories[i].c_str());
  535. fout << " " << target << "_" << subdir.c_str();
  536. if (i == SubDirectories.size()-1)
  537. {
  538. fout << " \n\n";
  539. }
  540. else
  541. {
  542. fout << " \\\n";
  543. }
  544. }
  545. //
  546. fout << "# Targets for making " << target << " in subdirectories.\n";
  547. for (unsigned int i=0; i<SubDirectories.size(); i++)
  548. {
  549. std::string subdir = FixDirectoryName(SubDirectories[i].c_str());
  550. fout << target << "_" << subdir.c_str() << ":\n";
  551. fout << " cd " << m_Makefile->GetStartOutputDirectory() << "/" << SubDirectories[i] << " \n";
  552. fout << " make makefile.mak\n";
  553. fout << " make \n\n";
  554. }
  555. }
  556. // Output each custom rule in the following format:
  557. // output: source depends...
  558. // (tab) command...
  559. // This routine is copied direct from unix makefile generator
  560. void cmBorlandMakefileGenerator::OutputCustomRules(std::ostream& fout)
  561. {
  562. // We may be modifying the source groups temporarily, so make a copy.
  563. std::vector<cmSourceGroup> sourceGroups = m_Makefile->GetSourceGroups();
  564. const cmTargets &tgts = m_Makefile->GetTargets();
  565. for(cmTargets::const_iterator tgt = tgts.begin();
  566. tgt != tgts.end(); ++tgt)
  567. {
  568. // add any custom rules to the source groups
  569. for (std::vector<cmCustomCommand>::const_iterator cr =
  570. tgt->second.GetCustomCommands().begin();
  571. cr != tgt->second.GetCustomCommands().end(); ++cr)
  572. {
  573. cmSourceGroup& sourceGroup =
  574. m_Makefile->FindSourceGroup(cr->GetSourceName().c_str(),
  575. sourceGroups);
  576. cmCustomCommand cc(*cr);
  577. cc.ExpandVariables(*m_Makefile);
  578. sourceGroup.AddCustomCommand(cc);
  579. }
  580. }
  581. // Loop through every source group.
  582. for(std::vector<cmSourceGroup>::const_iterator sg =
  583. sourceGroups.begin(); sg != sourceGroups.end(); ++sg)
  584. {
  585. const cmSourceGroup::BuildRules& buildRules = sg->GetBuildRules();
  586. if(buildRules.empty())
  587. {
  588. continue;
  589. }
  590. std::string name = sg->GetName();
  591. if(name != "")
  592. {
  593. fout << "# Start of source group \"" << name.c_str() << "\"\n";
  594. }
  595. // Loop through each source in the source group.
  596. for(cmSourceGroup::BuildRules::const_iterator cc =
  597. buildRules.begin(); cc != buildRules.end(); ++ cc)
  598. {
  599. std::string source = cc->first;
  600. const cmSourceGroup::Commands& commands = cc->second;
  601. // Loop through every command generating code from the current source.
  602. for(cmSourceGroup::Commands::const_iterator c = commands.begin();
  603. c != commands.end(); ++c)
  604. {
  605. std::string command = c->first;
  606. const cmSourceGroup::CommandFiles& commandFiles = c->second;
  607. // if the command has no outputs, then it is a utility command
  608. // with no outputs
  609. if(commandFiles.m_Outputs.size() == 0)
  610. {
  611. fout << source.c_str() << ": ";
  612. // Write out all the dependencies for this rule.
  613. for(std::set<std::string>::const_iterator d =
  614. commandFiles.m_Depends.begin();
  615. d != commandFiles.m_Depends.end(); ++d)
  616. {
  617. std::string dep = cmSystemTools::EscapeSpaces(d->c_str());
  618. fout << " " << dep.c_str();
  619. }
  620. fout << "\n\t" << command.c_str() << "\n\n";
  621. }
  622. // Write a rule for every output generated by this command.
  623. for(std::set<std::string>::const_iterator output =
  624. commandFiles.m_Outputs.begin();
  625. output != commandFiles.m_Outputs.end(); ++output)
  626. {
  627. std::string src = cmSystemTools::EscapeSpaces(source.c_str());
  628. fout << output->c_str() << ": " << src.c_str();
  629. // Write out all the dependencies for this rule.
  630. for(std::set<std::string>::const_iterator d =
  631. commandFiles.m_Depends.begin();
  632. d != commandFiles.m_Depends.end(); ++d)
  633. {
  634. std::string dep = cmSystemTools::EscapeSpaces(d->c_str());
  635. fout << " " << dep.c_str();
  636. }
  637. fout << "\n\t" << command.c_str() << "\n\n";
  638. }
  639. }
  640. }
  641. if(name != "")
  642. {
  643. fout << "# End of source group \"" << name.c_str() << "\"\n\n";
  644. }
  645. }
  646. fout << "# End Custom Rules \n";
  647. }
  648. void cmBorlandMakefileGenerator::OutputMakeRules(std::ostream& fout)
  649. {
  650. this->OutputMakeRule(fout,
  651. "Rule to build c file(s)",
  652. ".c.obj",
  653. 0,
  654. "$(CPP) -n$(OBJDIR) {$< }");
  655. this->OutputMakeRule(fout,
  656. "Rule to build cpp file(s)",
  657. ".cpp.obj",
  658. 0,
  659. "$(CPP) -n$(OBJDIR) {$< }");
  660. this->OutputMakeRule(fout,
  661. "Rule to build cxx file(s)",
  662. ".cxx.obj",
  663. 0,
  664. "$(CPP) -Pcxx -n$(OBJDIR) {$< }");
  665. this->OutputMakeRule(fout,
  666. "The project ALL rule",
  667. "ALL",
  668. "PREPARE ${TARGETS} ${SUBDIR_BUILD} ${CMAKE_COMMAND}",
  669. 0);
  670. this->OutputMakeRule(fout,
  671. "Rule to build the makefile",
  672. "makefile.mak",
  673. "${CMAKE_COMMAND} ${CMAKE_MAKEFILE_SOURCES} ",
  674. "${CMAKE_COMMAND} "
  675. "-H${CMAKE_SOURCE_DIR} -B${CMAKE_BINARY_DIR}");
  676. this->OutputMakeRule(fout,
  677. "Rebuild the cache",
  678. "${CMAKE_BINARY_DIR}/CMakeCache.txt",
  679. 0,
  680. "${CMAKE_COMMAND} "
  681. "-H${CMAKE_SOURCE_DIR} -B${CMAKE_BINARY_DIR}");
  682. this->OutputMakeRule(fout,
  683. "Rebuild cmake dummy rule",
  684. "${CMAKE_COMMAND}",
  685. 0,
  686. "echo \"cmake might be out of date\"");
  687. }
  688. void cmBorlandMakefileGenerator::OutputMakeRule(std::ostream& fout,
  689. const char* comment,
  690. const char* target,
  691. const char* depends,
  692. const char* command)
  693. {
  694. std::string replace;
  695. if (comment)
  696. {
  697. replace = comment;
  698. m_Makefile->ExpandVariablesInString(replace);
  699. fout << "# " << comment << " \n";
  700. }
  701. //
  702. replace = target;
  703. m_Makefile->ExpandVariablesInString(replace);
  704. fout << replace.c_str() << ": ";
  705. if (depends)
  706. {
  707. replace = depends;
  708. m_Makefile->ExpandVariablesInString(replace);
  709. fout << replace.c_str();
  710. }
  711. fout << "\n";
  712. //
  713. if (command)
  714. {
  715. replace = command;
  716. m_Makefile->ExpandVariablesInString(replace);
  717. fout << " " << replace.c_str() << " \n";
  718. }
  719. fout << "\n";
  720. }
  721. void cmBorlandMakefileGenerator::SetLocal (bool local)
  722. {
  723. if (local)
  724. {
  725. m_CacheOnly = false;
  726. m_Recurse = false;
  727. }
  728. else
  729. {
  730. m_CacheOnly = true;
  731. m_Recurse = true;
  732. }
  733. }
  734. void cmBorlandMakefileGenerator::ComputeSystemInfo()
  735. {
  736. // now load the settings
  737. if (!m_Makefile->GetDefinition("CMAKE_ROOT"))
  738. {
  739. cmSystemTools::Error("CMAKE_ROOT has not been defined, bad GUI or driver program");
  740. return;
  741. }
  742. std::string fpath = m_Makefile->GetDefinition("CMAKE_ROOT");
  743. fpath += "/Templates/CMakeWindowsBorlandConfig.cmake";
  744. m_Makefile->ReadListFile(NULL,fpath.c_str());
  745. }