cmBorlandMakefileGenerator.cpp 28 KB

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