cmBorlandMakefileGenerator.cpp 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826
  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())
  336. {
  337. libname = path;
  338. }
  339. else
  340. // if we can't find it - and it's not a target - and it has no path
  341. // already specified, it must be in OUTDIRLIB from another
  342. // makefile in the same project !
  343. {
  344. std::string path = cmSystemTools::GetFilenamePath(libname);
  345. if (path.size()==0)
  346. {
  347. libname = "$(OUTDIRLIB)\\" + libname;
  348. }
  349. // otherwise just leave it alone
  350. }
  351. }
  352. else
  353. {
  354. libname = "$(OUTDIRLIB)\\" + libname;
  355. }
  356. fout << " \\\n " << cmBorlandMakefileGenerator::EscapeSpaces(libname.c_str());
  357. }
  358. }
  359. fout << "\n\n";
  360. }
  361. }
  362. // Create the link bpi list for each target : see notes above for lib files
  363. for (cmTargets::const_iterator t=tgts.begin(); t!=tgts.end(); t++)
  364. {
  365. cmTarget::LinkLibraries const& libs = t->second.GetLinkLibraries();
  366. if ((t->second.GetType() == cmTarget::STATIC_LIBRARY) ||
  367. (t->second.GetType() == cmTarget::SHARED_LIBRARY) ||
  368. (t->second.GetType() == cmTarget::MODULE_LIBRARY) ||
  369. (t->second.GetType() == cmTarget::EXECUTABLE) ||
  370. (t->second.GetType() == cmTarget::WIN32_EXECUTABLE))
  371. {
  372. fout << t->first << "_LINK_BPI = ";
  373. for (cmTarget::LinkLibraries::const_iterator l=libs.begin();
  374. l!=libs.end(); l++)
  375. {
  376. if ((t->first!=l->first) &&
  377. (t->second.GetType()!=cmTarget::INSTALL_FILES
  378. || t->second.GetType()!=cmTarget::INSTALL_PROGRAMS))
  379. {
  380. // Get the lib name
  381. libname = l->first;
  382. // only allow bpi files
  383. if (l->first.find(".bpi")==std::string::npos) continue;
  384. // if this bpi is not a target then don't add OUTDIRLIB to it
  385. // but do try to find complete path
  386. if (tgts.find(l->first)==tgts.end())
  387. {
  388. std::string path = cmSystemTools::FindFile(libname.c_str(),linkdirs);
  389. if (path.size())
  390. {
  391. libname = path;
  392. }
  393. else
  394. // if we can't find it - and it's not a target - and it has no path
  395. // already specified, it must be in OUTDIRLIB from another
  396. // makefile in the same project !
  397. {
  398. std::string path = cmSystemTools::GetFilenamePath(libname);
  399. if (path.size()==0)
  400. {
  401. libname = "$(OUTDIRLIB)\\" + libname;
  402. }
  403. // otherwise just leave it alone
  404. }
  405. }
  406. else
  407. {
  408. libname = "$(OUTDIRLIB)\\" + libname;
  409. }
  410. fout << " \\\n " << cmBorlandMakefileGenerator::EscapeSpaces(libname.c_str());
  411. }
  412. }
  413. fout << "\n\n";
  414. }
  415. }
  416. //
  417. // The project rule - Build All targets
  418. //
  419. fout << "DEFAULT : \n";
  420. fout << " @$(MAKE) makefile.mak \n";
  421. fout << " @$(MAKE) ALL \n\n";
  422. //
  423. // Create a rule to allow us to setup the compiler and output dir
  424. //
  425. fout << "PREPARE : \n";
  426. fout << " @if not exist \"$(OBJDIR)/.\" md \"$(OBJDIR)\" \n";
  427. fout << " @copy &&| \n";
  428. fout << " $(SYSDEFINES) $(CMAKEDEFINES) $(USERDEFINES)\n";
  429. fout << " $(CPPFLAGS_DEBUG) $(CPPFLAGS_WARNING) \n";
  430. fout << " $(INCLUDEPATH) \n";
  431. fout << " -I\"$(BCB)/include\";\"$(BCB)/include/rw\";\"$(BCB)/include/vcl\"; \n";
  432. fout << "| CPP_PROJ.CFG \n\n";
  433. //
  434. this->OutputDependencies(fout);
  435. this->OutputTargets(fout);
  436. this->OutputSubDirectoryRules(fout);
  437. //
  438. this->OutputCustomRules(fout);
  439. this->OutputMakeRules(fout);
  440. //
  441. // We'll omit current dir in path where possible
  442. std::string fullname, outpath = m_Makefile->GetStartOutputDirectory();
  443. outpath += "/";
  444. //
  445. for (cmTargets::const_iterator l=tgts.begin(); l!=tgts.end(); l++)
  446. {
  447. std::vector<cmSourceFile> classes = l->second.GetSourceFiles();
  448. if (classes.begin() != classes.end())
  449. {
  450. for (std::vector<cmSourceFile>::iterator i=classes.begin(); i!=classes.end(); i++)
  451. {
  452. if (!i->IsAHeaderFileOnly())
  453. {
  454. fullname = i->GetFullPath();
  455. cmSystemTools::ReplaceString(fullname, outpath.c_str(), "");
  456. std::string sourceName = i->GetSourceName();
  457. cmSystemTools::ConvertToWindowsSlashes(sourceName);
  458. fout << ""
  459. << sourceName
  460. << ".obj : " << fullname << "\n";
  461. }
  462. }
  463. }
  464. }
  465. //
  466. //
  467. fout << "\n# End of File\n";
  468. }
  469. //---------------------------------------------------------------------------
  470. // output the list of libraries that the executables in this makefile will depend on.
  471. void cmBorlandMakefileGenerator::OutputDependencies(std::ostream& fout)
  472. {
  473. // not required with the Borland generator
  474. // .autodepend
  475. // is added to the start of the makefile to enable automatic dependency
  476. // checking of source files
  477. }
  478. void cmBorlandMakefileGenerator::OutputTargets(std::ostream& fout)
  479. {
  480. // Do Libraries first as executables may depend on them
  481. const cmTargets &tgts = m_Makefile->GetTargets();
  482. for (cmTargets::const_iterator l=tgts.begin(); l!=tgts.end(); l++)
  483. {
  484. if (l->second.GetType() == cmTarget::STATIC_LIBRARY)
  485. {
  486. //
  487. // WARNING. TLIB fails with Unix style Forward slashes - use $(OUTDIRLIB)\\
  488. //
  489. fout << "# this should be a static library \n";
  490. fout << "$(OUTDIRLIB)\\" << l->first << ".lib : ${" << l->first << "_SRC_OBJS} ${" << l->first << "_LINK_LIB} ${" << l->first << "_LINK_BPI} \n";
  491. std::string Libname = "$(OUTDIRLIB)\\" + l->first + ".lib";
  492. fout << " TLib.exe $(LINKFLAGS_STATIC) /u " << Libname.c_str() << " @&&| \n";
  493. fout << " $? \n";
  494. fout << "| \n\n";
  495. }
  496. if (l->second.GetType() == cmTarget::SHARED_LIBRARY)
  497. {
  498. fout << "# this should be a shared (DLL) library \n";
  499. fout << "$(OUTDIRLIB)\\" << l->first << ".dll : ${" << l->first << "_SRC_OBJS} ${" << l->first << "_LINK_LIB} ${" << l->first << "_LINK_BPI} \n";
  500. fout << " @ilink32.exe @&&| \n";
  501. fout << " -L$(LINK_DIR) $(LINKFLAGS_DLL) $(LINKFLAGS_DEBUG) \"$(BCB)/lib/c0d32.obj\" ";
  502. fout << "$(" << l->first << "_LINK_BPI) ";
  503. fout << "$(" << l->first << "_SRC_OBJS) , $<, $*, ";
  504. fout << "$(" << l->first << "_LINK_LIB) import32.lib cw32mti.lib \n";
  505. fout << "| \n";
  506. fout << " @implib -w " << "$(OUTDIRLIB)\\" << l->first << ".lib " << "$(OUTDIRLIB)\\" << l->first << ".dll \n\n";
  507. }
  508. if (l->second.GetType() == cmTarget::MODULE_LIBRARY)
  509. {
  510. fout << "# this should be a Borland Package library \n";
  511. fout << "$(OUTDIRLIB)\\" << l->first << ".bpl : ${" << l->first << "_SRC_OBJS} ${" << l->first << "_LINK_LIB} ${" << l->first << "_LINK_BPI} \n";
  512. fout << " @ilink32.exe @&&| \n";
  513. fout << " -L\"$(BCB)/lib\" -L$(LINK_DIR) $(LINKFLAGS_BPL) $(LINKFLAGS_DEBUG) \"$(BCB)/lib/c0pkg32.obj \" ";
  514. fout << "$(" << l->first << "_LINK_BPI) Memmgr.lib sysinit.obj ";
  515. fout << "$(" << l->first << "_SRC_OBJS) , $<, $*, ";
  516. fout << "$(" << l->first << "_LINK_LIB) import32.lib cp32mti.lib \n";
  517. fout << "| \n";
  518. }
  519. }
  520. // Do Executables
  521. for (cmTargets::const_iterator l=tgts.begin(); l!=tgts.end(); l++)
  522. {
  523. if (l->second.GetType()==cmTarget::WIN32_EXECUTABLE)
  524. {
  525. fout << l->first << ".exe : ${" << l->first << "_SRC_OBJS} ${" << l->first << "_LINK_LIB} ${" << l->first << "_LINK_BPI} \n";
  526. fout << " @ilink32.exe @&&| \n";
  527. fout << " -L\"$(BCB)/lib\" -L$(LINK_DIR) $(LINKFLAGS_EXE) $(LINKFLAGS_DEBUG) \"$(BCB)/lib/c0w32.obj\" ";
  528. fout << "$(" << l->first << "_LINK_BPI) Memmgr.lib sysinit.obj ";
  529. fout << "$(" << l->first << "_SRC_OBJS) , $<, $*, ";
  530. fout << "$(" << l->first << "_LINK_LIB) import32.lib cp32mti.lib \n";
  531. fout << "| \n\n";
  532. }
  533. else if (l->second.GetType()==cmTarget::EXECUTABLE)
  534. {
  535. fout << l->first << ".exe : ${" << l->first << "_SRC_OBJS} ${" << l->first << "_LINK_LIB} ${" << l->first << "_LINK_BPI} \n";
  536. fout << " @ilink32.exe @&&| \n";
  537. fout << " -L\"$(BCB)/lib\" -L$(LINK_DIR) $(LINKFLAGS_EXE) $(LINKFLAGS_DEBUG) \"$(BCB)/lib/c0x32.obj\" ";
  538. fout << "$(" << l->first << "_SRC_OBJS) , $<, $*, ";
  539. fout << "$(" << l->first << "_LINK_LIB) import32.lib cw32mti.lib \n";
  540. fout << "| \n\n";
  541. }
  542. }
  543. }
  544. //---------------------------------------------------------------------------
  545. void cmBorlandMakefileGenerator::OutputSubDirectoryRules(std::ostream& fout)
  546. {
  547. // output rules for decending into sub directories
  548. const std::vector<std::string>& SubDirectories = m_Makefile->GetSubDirectories();
  549. //
  550. if ( SubDirectories.size() == 0)
  551. {
  552. return;
  553. }
  554. //
  555. this->OutputSubDirectoryVars(fout, "SUBDIR_BUILD", "build",
  556. 0,
  557. 0,
  558. SubDirectories);
  559. }
  560. //---------------------------------------------------------------------------
  561. // fix up names of directories so they can be used
  562. // as targets in makefiles.
  563. inline std::string FixDirectoryName(const char* dir)
  564. {
  565. std::string s = dir;
  566. // replace ../ with 3 under bars
  567. size_t pos = s.find("../");
  568. if (pos != std::string::npos)
  569. {
  570. s.replace(pos, 3, "___");
  571. }
  572. // replace / directory separators with a single under bar
  573. pos = s.find("/");
  574. while(pos != std::string::npos)
  575. {
  576. s.replace(pos, 1, "_");
  577. pos = s.find("/");
  578. }
  579. return s;
  580. }
  581. void cmBorlandMakefileGenerator::OutputSubDirectoryVars(std::ostream& fout,
  582. const char* var,
  583. const char* target,
  584. const char* target1,
  585. const char* target2,
  586. const std::vector<std::string>& SubDirectories)
  587. {
  588. if (!SubDirectories.size()) return;
  589. //
  590. fout << "# Variable for making " << target << " in subdirectories.\n";
  591. fout << var << " = \\\n";
  592. unsigned int i;
  593. for (i =0; i < SubDirectories.size(); i++)
  594. {
  595. std::string subdir = FixDirectoryName(SubDirectories[i].c_str());
  596. fout << " " << target << "_" << subdir.c_str();
  597. if (i == SubDirectories.size()-1)
  598. {
  599. fout << " \n\n";
  600. }
  601. else
  602. {
  603. fout << " \\\n";
  604. }
  605. }
  606. //
  607. fout << "# Targets for making " << target << " in subdirectories.\n";
  608. for (unsigned int i=0; i<SubDirectories.size(); i++)
  609. {
  610. std::string subdir = FixDirectoryName(SubDirectories[i].c_str());
  611. fout << target << "_" << subdir.c_str() << ":\n";
  612. fout << " cd " << m_Makefile->GetStartOutputDirectory() << "/" << SubDirectories[i] << " \n";
  613. fout << " make makefile.mak\n";
  614. fout << " make \n\n";
  615. }
  616. }
  617. // Output each custom rule in the following format:
  618. // output: source depends...
  619. // (tab) command...
  620. // This routine is copied direct from unix makefile generator
  621. void cmBorlandMakefileGenerator::OutputCustomRules(std::ostream& fout)
  622. {
  623. // We may be modifying the source groups temporarily, so make a copy.
  624. std::vector<cmSourceGroup> sourceGroups = m_Makefile->GetSourceGroups();
  625. const cmTargets &tgts = m_Makefile->GetTargets();
  626. for(cmTargets::const_iterator tgt = tgts.begin();
  627. tgt != tgts.end(); ++tgt)
  628. {
  629. // add any custom rules to the source groups
  630. for (std::vector<cmCustomCommand>::const_iterator cr =
  631. tgt->second.GetCustomCommands().begin();
  632. cr != tgt->second.GetCustomCommands().end(); ++cr)
  633. {
  634. cmSourceGroup& sourceGroup =
  635. m_Makefile->FindSourceGroup(cr->GetSourceName().c_str(),
  636. sourceGroups);
  637. cmCustomCommand cc(*cr);
  638. cc.ExpandVariables(*m_Makefile);
  639. sourceGroup.AddCustomCommand(cc);
  640. }
  641. }
  642. // Loop through every source group.
  643. for(std::vector<cmSourceGroup>::const_iterator sg =
  644. sourceGroups.begin(); sg != sourceGroups.end(); ++sg)
  645. {
  646. const cmSourceGroup::BuildRules& buildRules = sg->GetBuildRules();
  647. if(buildRules.empty())
  648. {
  649. continue;
  650. }
  651. std::string name = sg->GetName();
  652. if(name != "")
  653. {
  654. fout << "# Start of source group \"" << name.c_str() << "\"\n";
  655. }
  656. // Loop through each source in the source group.
  657. for(cmSourceGroup::BuildRules::const_iterator cc =
  658. buildRules.begin(); cc != buildRules.end(); ++ cc)
  659. {
  660. std::string source = cc->first;
  661. const cmSourceGroup::Commands& commands = cc->second;
  662. // Loop through every command generating code from the current source.
  663. for(cmSourceGroup::Commands::const_iterator c = commands.begin();
  664. c != commands.end(); ++c)
  665. {
  666. std::string command = c->first;
  667. const cmSourceGroup::CommandFiles& commandFiles = c->second;
  668. // if the command has no outputs, then it is a utility command
  669. // with no outputs
  670. if(commandFiles.m_Outputs.size() == 0)
  671. {
  672. fout << source.c_str() << ": ";
  673. // Write out all the dependencies for this rule.
  674. for(std::set<std::string>::const_iterator d =
  675. commandFiles.m_Depends.begin();
  676. d != commandFiles.m_Depends.end(); ++d)
  677. {
  678. std::string dep = cmBorlandMakefileGenerator::EscapeSpaces(d->c_str());
  679. fout << " " << dep.c_str();
  680. }
  681. fout << "\n\t" << command.c_str() << "\n\n";
  682. }
  683. // Write a rule for every output generated by this command.
  684. for(std::set<std::string>::const_iterator output =
  685. commandFiles.m_Outputs.begin();
  686. output != commandFiles.m_Outputs.end(); ++output)
  687. {
  688. std::string src = cmBorlandMakefileGenerator::EscapeSpaces(source.c_str());
  689. fout << output->c_str() << ": " << src.c_str();
  690. // Write out all the dependencies for this rule.
  691. for(std::set<std::string>::const_iterator d =
  692. commandFiles.m_Depends.begin();
  693. d != commandFiles.m_Depends.end(); ++d)
  694. {
  695. std::string dep = cmBorlandMakefileGenerator::EscapeSpaces(d->c_str());
  696. fout << " " << dep.c_str();
  697. }
  698. fout << "\n\t" << command.c_str() << "\n\n";
  699. }
  700. }
  701. }
  702. if(name != "")
  703. {
  704. fout << "# End of source group \"" << name.c_str() << "\"\n\n";
  705. }
  706. }
  707. }
  708. void cmBorlandMakefileGenerator::OutputMakeRules(std::ostream& fout)
  709. {
  710. this->OutputMakeRule(fout,
  711. "Rule to build c file(s)",
  712. ".c.obj",
  713. 0,
  714. "$(CPP) -n$(OBJDIR) {$< }");
  715. this->OutputMakeRule(fout,
  716. "Rule to build cpp file(s)",
  717. ".cpp.obj",
  718. 0,
  719. "$(CPP) -n$(OBJDIR) {$< }");
  720. this->OutputMakeRule(fout,
  721. "Rule to build cxx file(s)",
  722. ".cxx.obj",
  723. 0,
  724. "$(CPP) -Pcxx -n$(OBJDIR) {$< }");
  725. this->OutputMakeRule(fout,
  726. "The project ALL rule",
  727. "ALL",
  728. "PREPARE ${TARGETS} ${SUBDIR_BUILD} ${CMAKE_COMMAND}",
  729. 0);
  730. this->OutputMakeRule(fout,
  731. "Rule to build the makefile",
  732. "makefile.mak",
  733. "${CMAKE_COMMAND} ${CMAKE_MAKEFILE_SOURCES} ",
  734. "${CMAKE_COMMAND} "
  735. "-H${CMAKE_SOURCE_DIR} -B${CMAKE_BINARY_DIR}");
  736. this->OutputMakeRule(fout,
  737. "Rebuild the cache",
  738. "${CMAKE_BINARY_DIR}/CMakeCache.txt",
  739. 0,
  740. "${CMAKE_COMMAND} "
  741. "-H${CMAKE_SOURCE_DIR} -B${CMAKE_BINARY_DIR}");
  742. this->OutputMakeRule(fout,
  743. "Rebuild cmake dummy rule",
  744. "${CMAKE_COMMAND}",
  745. 0,
  746. "echo \"cmake might be out of date\"");
  747. }
  748. void cmBorlandMakefileGenerator::OutputMakeRule(std::ostream& fout,
  749. const char* comment,
  750. const char* target,
  751. const char* depends,
  752. const char* command)
  753. {
  754. std::string replace;
  755. if (comment)
  756. {
  757. replace = comment;
  758. m_Makefile->ExpandVariablesInString(replace);
  759. fout << "# " << comment << " \n";
  760. }
  761. //
  762. replace = target;
  763. m_Makefile->ExpandVariablesInString(replace);
  764. fout << replace.c_str() << ": ";
  765. if (depends)
  766. {
  767. replace = depends;
  768. m_Makefile->ExpandVariablesInString(replace);
  769. fout << replace.c_str();
  770. }
  771. fout << "\n";
  772. //
  773. if (command)
  774. {
  775. replace = command;
  776. m_Makefile->ExpandVariablesInString(replace);
  777. fout << " " << replace.c_str() << " \n";
  778. }
  779. fout << "\n";
  780. }
  781. void cmBorlandMakefileGenerator::SetLocal (bool local)
  782. {
  783. if (local)
  784. {
  785. m_CacheOnly = false;
  786. m_Recurse = false;
  787. }
  788. else
  789. {
  790. m_CacheOnly = true;
  791. m_Recurse = true;
  792. }
  793. }
  794. void cmBorlandMakefileGenerator::ComputeSystemInfo()
  795. {
  796. // now load the settings
  797. if (!m_Makefile->GetDefinition("CMAKE_ROOT"))
  798. {
  799. cmSystemTools::Error("CMAKE_ROOT has not been defined, bad GUI or driver program");
  800. return;
  801. }
  802. std::string fpath = m_Makefile->GetDefinition("CMAKE_ROOT");
  803. fpath += "/Templates/CMakeWindowsBorlandConfig.cmake";
  804. m_Makefile->ReadListFile(NULL,fpath.c_str());
  805. }