cmBorlandMakefileGenerator.cpp 26 KB

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