cmLocalGenerator.cxx 48 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537
  1. /*=========================================================================
  2. Program: CMake - Cross-Platform Makefile Generator
  3. Module: $RCSfile$
  4. Language: C++
  5. Date: $Date$
  6. Version: $Revision$
  7. Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved.
  8. See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
  9. This software is distributed WITHOUT ANY WARRANTY; without even
  10. the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  11. PURPOSE. See the above copyright notices for more information.
  12. =========================================================================*/
  13. #include "cmLocalGenerator.h"
  14. #include "cmGlobalGenerator.h"
  15. #include "cmake.h"
  16. #include "cmMakefile.h"
  17. #include "cmGeneratedFileStream.h"
  18. #include "cmSourceFile.h"
  19. #include "cmOrderLinkDirectories.h"
  20. #include "cmTest.h"
  21. #include <ctype.h> // for isalpha
  22. cmLocalGenerator::cmLocalGenerator()
  23. {
  24. m_Makefile = new cmMakefile;
  25. m_Makefile->SetLocalGenerator(this);
  26. m_ExcludeFromAll = false;
  27. m_Parent = 0;
  28. m_WindowsShell = false;
  29. m_IgnoreLibPrefix = false;
  30. m_UseRelativePaths = false;
  31. this->Configured = false;
  32. }
  33. cmLocalGenerator::~cmLocalGenerator()
  34. {
  35. delete m_Makefile;
  36. }
  37. void cmLocalGenerator::Configure()
  38. {
  39. // find & read the list file
  40. std::string currentStart = m_Makefile->GetStartDirectory();
  41. currentStart += "/CMakeLists.txt";
  42. m_Makefile->ReadListFile(currentStart.c_str());
  43. // at the end of the ReadListFile handle any old style subdirs
  44. // first get all the subdirectories
  45. std::vector<cmLocalGenerator *> subdirs = this->GetChildren();
  46. // for each subdir recurse
  47. std::vector<cmLocalGenerator *>::iterator sdi = subdirs.begin();
  48. for (; sdi != subdirs.end(); ++sdi)
  49. {
  50. if (!(*sdi)->Configured)
  51. {
  52. m_Makefile->ConfigureSubDirectory(*sdi);
  53. }
  54. }
  55. // Setup the current output directory components for use by
  56. // Convert
  57. std::string outdir;
  58. outdir =
  59. cmSystemTools::CollapseFullPath(m_Makefile->GetHomeDirectory());
  60. cmSystemTools::SplitPath(outdir.c_str(), m_HomeDirectoryComponents);
  61. outdir =
  62. cmSystemTools::CollapseFullPath(m_Makefile->GetStartDirectory());
  63. cmSystemTools::SplitPath(outdir.c_str(), m_StartDirectoryComponents);
  64. outdir =
  65. cmSystemTools::CollapseFullPath(m_Makefile->GetHomeOutputDirectory());
  66. cmSystemTools::SplitPath(outdir.c_str(), m_HomeOutputDirectoryComponents);
  67. outdir =
  68. cmSystemTools::CollapseFullPath(m_Makefile->GetStartOutputDirectory());
  69. cmSystemTools::SplitPath(outdir.c_str(), m_StartOutputDirectoryComponents);
  70. // Check whether relative paths should be used for optionally
  71. // relative paths.
  72. m_UseRelativePaths = m_Makefile->IsOn("CMAKE_USE_RELATIVE_PATHS");
  73. this->Configured = true;
  74. }
  75. void cmLocalGenerator::SetGlobalGenerator(cmGlobalGenerator *gg)
  76. {
  77. m_GlobalGenerator = gg;
  78. // setup the home directories
  79. m_Makefile->SetHomeDirectory(
  80. gg->GetCMakeInstance()->GetHomeDirectory());
  81. m_Makefile->SetHomeOutputDirectory(
  82. gg->GetCMakeInstance()->GetHomeOutputDirectory());
  83. }
  84. void cmLocalGenerator::ConfigureFinalPass()
  85. {
  86. m_Makefile->ConfigureFinalPass();
  87. }
  88. void cmLocalGenerator::GenerateTestFiles()
  89. {
  90. if ( !m_Makefile->IsOn("CMAKE_TESTING_ENABLED") )
  91. {
  92. return;
  93. }
  94. std::string file = m_Makefile->GetStartOutputDirectory();
  95. file += "/";
  96. if ( m_Makefile->IsSet("CTEST_NEW_FORMAT") )
  97. {
  98. file += "CTestTestfile.cmake";
  99. }
  100. else
  101. {
  102. file += "DartTestfile.txt";
  103. }
  104. cmGeneratedFileStream fout(file.c_str());
  105. fout.SetCopyIfDifferent(true);
  106. fout << "# CMake generated Testfile for " << std::endl
  107. << "# Source directory: " << m_Makefile->GetStartDirectory() << std::endl
  108. << "# Build directory: " << m_Makefile->GetStartOutputDirectory() << std::endl
  109. << "# " << std::endl
  110. << "# This file replicates the SUBDIRS() and ADD_TEST() commands from the source" << std::endl
  111. << "# tree CMakeLists.txt file, skipping any SUBDIRS() or ADD_TEST() commands" << std::endl
  112. << "# that are excluded by CMake control structures, i.e. IF() commands." << std::endl
  113. << "#" << std::endl
  114. << "# The next line is critical for Dart to work" << std::endl
  115. << "# Duh :-)" << std::endl << std::endl;
  116. const char* testIncludeFile = m_Makefile->GetProperty("TEST_INCLUDE_FILE");
  117. if ( testIncludeFile )
  118. {
  119. fout << "INCLUDE(\"" << testIncludeFile << "\")" << std::endl;
  120. }
  121. const std::vector<cmTest*> *tests = m_Makefile->GetTests();
  122. std::vector<cmTest*>::const_iterator it;
  123. for ( it = tests->begin(); it != tests->end(); ++ it )
  124. {
  125. cmTest* test = *it;
  126. fout << "ADD_TEST(";
  127. fout << test->GetName() << " \"" << test->GetCommand() << "\"";
  128. std::vector<cmStdString>::iterator argit;
  129. for (argit = test->GetArguments().begin();
  130. argit != test->GetArguments().end(); ++argit)
  131. {
  132. // Just double-quote all arguments so they are re-parsed
  133. // correctly by the test system.
  134. fout << " \"";
  135. for(std::string::iterator c = argit->begin(); c != argit->end(); ++c)
  136. {
  137. // Escape quotes within arguments. We should escape
  138. // backslashes too but we cannot because it makes the result
  139. // inconsistent with previous behavior of this command.
  140. if((*c == '"'))
  141. {
  142. fout << '\\';
  143. }
  144. fout << *c;
  145. }
  146. fout << "\"";
  147. }
  148. fout << ")" << std::endl;
  149. }
  150. if ( this->Children.size())
  151. {
  152. fout << "SUBDIRS(";
  153. size_t i;
  154. std::string outDir = m_Makefile->GetStartOutputDirectory();
  155. outDir += "/";
  156. for(i = 0; i < this->Children.size(); ++i)
  157. {
  158. std::string binP = this->Children[i]->GetMakefile()->GetStartOutputDirectory();
  159. cmSystemTools::ReplaceString(binP, outDir.c_str(), "");
  160. if ( i > 0 )
  161. {
  162. fout << " ";
  163. }
  164. fout << binP.c_str();
  165. }
  166. fout << ")" << std::endl << std::endl;;
  167. }
  168. }
  169. void cmLocalGenerator::GenerateInstallRules()
  170. {
  171. cmTargets &tgts = m_Makefile->GetTargets();
  172. const char* prefix
  173. = m_Makefile->GetDefinition("CMAKE_INSTALL_PREFIX");
  174. #if defined(_WIN32) && !defined(__CYGWIN__)
  175. std::string prefix_win32;
  176. if(!prefix)
  177. {
  178. if(!cmSystemTools::GetEnv("SystemDrive", prefix_win32))
  179. {
  180. prefix_win32 = "C:";
  181. }
  182. const char* project_name = m_Makefile->GetDefinition("PROJECT_NAME");
  183. if(project_name && project_name[0])
  184. {
  185. prefix_win32 += "/Program Files/";
  186. prefix_win32 += project_name;
  187. }
  188. else
  189. {
  190. prefix_win32 += "/InstalledCMakeProject";
  191. }
  192. prefix = prefix_win32.c_str();
  193. }
  194. #else
  195. if (!prefix)
  196. {
  197. prefix = "/usr/local";
  198. }
  199. #endif
  200. std::string file = m_Makefile->GetStartOutputDirectory();
  201. std::string homedir = m_Makefile->GetHomeOutputDirectory();
  202. std::string currdir = m_Makefile->GetCurrentOutputDirectory();
  203. cmSystemTools::ConvertToUnixSlashes(file);
  204. cmSystemTools::ConvertToUnixSlashes(homedir);
  205. cmSystemTools::ConvertToUnixSlashes(currdir);
  206. int toplevel_install = 0;
  207. if ( currdir == homedir )
  208. {
  209. toplevel_install = 1;
  210. }
  211. file += "/cmake_install.cmake";
  212. cmGeneratedFileStream fout(file.c_str());
  213. fout.SetCopyIfDifferent(true);
  214. fout << "# Install script for directory: " << m_Makefile->GetCurrentDirectory()
  215. << std::endl << std::endl;
  216. const char* cmakeDebugPosfix = m_Makefile->GetDefinition("CMAKE_DEBUG_POSTFIX");
  217. if ( cmakeDebugPosfix )
  218. {
  219. fout << "SET(CMAKE_DEBUG_POSTFIX \"" << cmakeDebugPosfix << "\")"
  220. << std::endl << std::endl;
  221. }
  222. std::string libOutPath = "";
  223. if (m_Makefile->GetDefinition("LIBRARY_OUTPUT_PATH"))
  224. {
  225. libOutPath = m_Makefile->GetDefinition("LIBRARY_OUTPUT_PATH");
  226. if(libOutPath.size())
  227. {
  228. if(libOutPath[libOutPath.size() -1] != '/')
  229. {
  230. libOutPath += "/";
  231. }
  232. }
  233. }
  234. std::string exeOutPath = "";
  235. if (m_Makefile->GetDefinition("EXECUTABLE_OUTPUT_PATH"))
  236. {
  237. exeOutPath =
  238. m_Makefile->GetDefinition("EXECUTABLE_OUTPUT_PATH");
  239. if(exeOutPath.size())
  240. {
  241. if(exeOutPath[exeOutPath.size() -1] != '/')
  242. {
  243. exeOutPath += "/";
  244. }
  245. }
  246. }
  247. if ( libOutPath.size() == 0 )
  248. {
  249. // LIBRARY_OUTPUT_PATH not defined
  250. libOutPath = currdir + "/";
  251. }
  252. if ( exeOutPath.size() == 0 )
  253. {
  254. // EXECUTABLE_OUTPUT_PATH not defined
  255. exeOutPath = currdir + "/";
  256. }
  257. std::string destination;
  258. for(cmTargets::iterator l = tgts.begin();
  259. l != tgts.end(); l++)
  260. {
  261. const char* preinstall = l->second.GetProperty("PRE_INSTALL_SCRIPT");
  262. const char* postinstall = l->second.GetProperty("POST_INSTALL_SCRIPT");
  263. if ( preinstall )
  264. {
  265. fout << "INCLUDE(\"" << preinstall << "\")" << std::endl;
  266. }
  267. if (l->second.GetInstallPath() != "")
  268. {
  269. destination = prefix + l->second.GetInstallPath();
  270. cmSystemTools::ConvertToUnixSlashes(destination);
  271. const char* dest = destination.c_str();
  272. int type = l->second.GetType();
  273. std::string fname;
  274. const char* files;
  275. // now install the target
  276. switch (type)
  277. {
  278. case cmTarget::STATIC_LIBRARY:
  279. case cmTarget::MODULE_LIBRARY:
  280. fname = libOutPath;
  281. fname += l->second.GetFullName(m_Makefile);
  282. files = fname.c_str();
  283. this->AddInstallRule(fout, dest, type, files);
  284. break;
  285. case cmTarget::SHARED_LIBRARY:
  286. {
  287. // Special code to handle DLL
  288. fname = libOutPath;
  289. fname += l->second.GetFullName(m_Makefile);
  290. std::string ext = cmSystemTools::GetFilenameExtension(fname);
  291. ext = cmSystemTools::LowerCase(ext);
  292. if ( ext == ".dll" )
  293. {
  294. std::string libname = libOutPath;
  295. libname += cmSystemTools::GetFilenameWithoutExtension(fname);
  296. libname += ".lib";
  297. files = libname.c_str();
  298. this->AddInstallRule(fout, dest, cmTarget::STATIC_LIBRARY, files, true);
  299. std::string dlldest = prefix + l->second.GetRuntimeInstallPath();
  300. files = fname.c_str();
  301. this->AddInstallRule(fout, dlldest.c_str(), type, files);
  302. }
  303. else
  304. {
  305. files = fname.c_str();
  306. std::string properties;
  307. const char* lib_version = l->second.GetProperty("VERSION");
  308. const char* lib_soversion = l->second.GetProperty("SOVERSION");
  309. if(!m_Makefile->GetDefinition("CMAKE_SHARED_LIBRARY_SONAME_C_FLAG"))
  310. {
  311. // Versioning is supported only for shared libraries and modules,
  312. // and then only when the platform supports an soname flag.
  313. lib_version = 0;
  314. lib_soversion = 0;
  315. }
  316. if ( lib_version )
  317. {
  318. properties += " VERSION ";
  319. properties += lib_version;
  320. }
  321. if ( lib_soversion )
  322. {
  323. properties += " SOVERSION ";
  324. properties += lib_soversion;
  325. }
  326. this->AddInstallRule(fout, dest, type, files, false, properties.c_str());
  327. }
  328. }
  329. break;
  330. case cmTarget::EXECUTABLE:
  331. if(l->second.GetPropertyAsBool("MACOSX_BUNDLE"))
  332. {
  333. fname = exeOutPath;
  334. fname += l->second.GetFullName(m_Makefile);
  335. std::string plist = fname;
  336. plist += ".app/Contents/Info.plist";
  337. fname += ".app/Contents/MacOS/";
  338. fname += l->second.GetName();
  339. files = fname.c_str();
  340. std::string bdest = dest;
  341. bdest += "/";
  342. bdest += l->second.GetName();
  343. std::string pdest = bdest;
  344. pdest += ".app/Contents";
  345. bdest += ".app/Contents/MacOS";
  346. // first install the actual executable
  347. this->AddInstallRule(fout, bdest.c_str(), type, files);
  348. files = plist.c_str();
  349. // now install the Info.plist file
  350. this->AddInstallRule(fout, pdest.c_str(),
  351. cmTarget::INSTALL_FILES, files);
  352. }
  353. else
  354. {
  355. fname = exeOutPath;
  356. fname += l->second.GetFullName(m_Makefile);
  357. files = fname.c_str();
  358. this->AddInstallRule(fout, dest, type, files);
  359. }
  360. break;
  361. case cmTarget::INSTALL_FILES:
  362. {
  363. std::string sourcePath = m_Makefile->GetCurrentDirectory();
  364. std::string binaryPath = m_Makefile->GetCurrentOutputDirectory();
  365. sourcePath += "/";
  366. binaryPath += "/";
  367. const std::vector<std::string> &sf = l->second.GetSourceLists();
  368. std::vector<std::string>::const_iterator i;
  369. for (i = sf.begin(); i != sf.end(); ++i)
  370. {
  371. std::string f = *i;
  372. if(f.substr(0, sourcePath.length()) == sourcePath)
  373. {
  374. f = f.substr(sourcePath.length());
  375. }
  376. else if(f.substr(0, binaryPath.length()) == binaryPath)
  377. {
  378. f = f.substr(binaryPath.length());
  379. }
  380. files = i->c_str();
  381. this->AddInstallRule(fout, dest, type, files);
  382. }
  383. }
  384. break;
  385. case cmTarget::INSTALL_PROGRAMS:
  386. {
  387. std::string sourcePath = m_Makefile->GetCurrentDirectory();
  388. std::string binaryPath = m_Makefile->GetCurrentOutputDirectory();
  389. sourcePath += "/";
  390. binaryPath += "/";
  391. const std::vector<std::string> &sf = l->second.GetSourceLists();
  392. std::vector<std::string>::const_iterator i;
  393. for (i = sf.begin(); i != sf.end(); ++i)
  394. {
  395. std::string f = *i;
  396. if(f.substr(0, sourcePath.length()) == sourcePath)
  397. {
  398. f = f.substr(sourcePath.length());
  399. }
  400. else if(f.substr(0, binaryPath.length()) == binaryPath)
  401. {
  402. f = f.substr(binaryPath.length());
  403. }
  404. files = i->c_str();
  405. this->AddInstallRule(fout, dest, type, files);
  406. }
  407. }
  408. break;
  409. case cmTarget::UTILITY:
  410. default:
  411. break;
  412. }
  413. }
  414. if ( postinstall )
  415. {
  416. fout << "INCLUDE(\"" << postinstall << "\")" << std::endl;
  417. }
  418. }
  419. if ( this->Children.size())
  420. {
  421. std::vector<cmLocalGenerator*>::const_iterator i = this->Children.begin();
  422. for(; i != this->Children.end(); ++i)
  423. {
  424. std::string odir = (*i)->GetMakefile()->GetStartOutputDirectory();
  425. cmSystemTools::ConvertToUnixSlashes(odir);
  426. fout << "INCLUDE(\"" << odir.c_str()
  427. << "/cmake_install.cmake\")" << std::endl;
  428. }
  429. fout << std::endl;;
  430. }
  431. if ( toplevel_install )
  432. {
  433. fout << "FILE(WRITE \"" << homedir.c_str() << "/install_manifest.txt\" "
  434. << "\"\")" << std::endl;
  435. fout << "FOREACH(file ${CMAKE_INSTALL_MANIFEST_FILES})" << std::endl
  436. << " FILE(APPEND \"" << homedir.c_str() << "/install_manifest.txt\" "
  437. << "\"${file}\\n\")" << std::endl
  438. << "ENDFOREACH(file)" << std::endl;
  439. }
  440. }
  441. void cmLocalGenerator::AddInstallRule(std::ostream& fout, const char* dest,
  442. int type, const char* files, bool optional /* = false */, const char* properties /* = 0 */)
  443. {
  444. std::string sfiles = files;
  445. std::string destination = dest;
  446. std::string stype;
  447. switch ( type )
  448. {
  449. case cmTarget::INSTALL_PROGRAMS: stype = "PROGRAM"; break;
  450. case cmTarget::EXECUTABLE: stype = "EXECUTABLE"; break;
  451. case cmTarget::STATIC_LIBRARY: stype = "STATIC_LIBRARY"; break;
  452. case cmTarget::SHARED_LIBRARY: stype = "SHARED_LIBRARY"; break;
  453. case cmTarget::MODULE_LIBRARY: stype = "MODULE"; break;
  454. case cmTarget::INSTALL_FILES:
  455. default: stype = "FILE"; break;
  456. }
  457. std::string fname = cmSystemTools::GetFilenameName(sfiles.c_str());
  458. fout
  459. << "MESSAGE(STATUS \"Installing " << destination.c_str()
  460. << "/" << fname.c_str() << "\")\n"
  461. << "FILE(INSTALL DESTINATION \"" << destination.c_str()
  462. << "\" TYPE " << stype.c_str() << (optional?" OPTIONAL":"") ;
  463. if ( properties && *properties )
  464. {
  465. fout << " PROPERTIES" << properties;
  466. }
  467. fout
  468. << " FILES \"" << sfiles.c_str() << "\")\n";
  469. }
  470. void cmLocalGenerator::AddCustomCommandToCreateObject(const char* ofname,
  471. const char* lang,
  472. cmSourceFile& source,
  473. cmTarget& )
  474. {
  475. std::string objectFile = this->Convert(ofname,START_OUTPUT,SHELL);
  476. std::string sourceFile =
  477. this->Convert(source.GetFullPath().c_str(),START_OUTPUT,SHELL,true);
  478. std::string varString = "CMAKE_";
  479. varString += lang;
  480. varString += "_COMPILE_OBJECT";
  481. std::vector<std::string> rules;
  482. rules.push_back(m_Makefile->GetRequiredDefinition(varString.c_str()));
  483. varString = "CMAKE_";
  484. varString += lang;
  485. varString += "_FLAGS";
  486. std::string flags;
  487. flags += m_Makefile->GetSafeDefinition(varString.c_str());
  488. flags += " ";
  489. flags += this->GetIncludeFlags(lang);
  490. std::vector<std::string> commands;
  491. cmSystemTools::ExpandList(rules, commands);
  492. for(std::vector<std::string>::iterator i = commands.begin();
  493. i != commands.end(); ++i)
  494. {
  495. this->ExpandRuleVariables(*i,
  496. lang,
  497. 0, // no objects
  498. 0, // no target
  499. 0, // no link libs
  500. sourceFile.c_str(),
  501. objectFile.c_str(),
  502. flags.c_str());
  503. }
  504. std::vector<std::string> sourceAndDeps;
  505. sourceAndDeps.push_back(sourceFile);
  506. if(commands.size() > 1)
  507. {
  508. cmSystemTools::Error("Currently custom rules can only have one command sorry ");
  509. }
  510. // Check for extra object-file dependencies.
  511. std::vector<std::string> depends;
  512. const char* additionalDeps = source.GetProperty("OBJECT_DEPENDS");
  513. if(additionalDeps)
  514. {
  515. cmSystemTools::ExpandListArgument(additionalDeps, depends);
  516. for(std::vector<std::string>::iterator i = depends.begin();
  517. i != depends.end(); ++i)
  518. {
  519. sourceAndDeps.push_back(this->Convert(i->c_str(),START_OUTPUT,SHELL));
  520. }
  521. }
  522. #if 0
  523. std::string command;
  524. std::string args;
  525. cmSystemTools::SplitProgramFromArgs(commands[0].c_str(), command, args);
  526. std::vector<std::string> argsv;
  527. argsv.push_back(args);
  528. m_Makefile->AddCustomCommandToOutput(ofname,
  529. command.c_str(),
  530. argsv,
  531. source.GetFullPath().c_str(),
  532. sourceAndDeps,
  533. "build from source");
  534. #endif
  535. }
  536. void cmLocalGenerator::AddBuildTargetRule(const char* llang, cmTarget& target)
  537. {
  538. cmStdString objs;
  539. std::vector<std::string> objVector;
  540. // Add all the sources outputs to the depends of the target
  541. std::vector<cmSourceFile*>& classes = target.GetSourceFiles();
  542. for(std::vector<cmSourceFile*>::iterator i = classes.begin();
  543. i != classes.end(); ++i)
  544. {
  545. if(!(*i)->GetPropertyAsBool("HEADER_FILE_ONLY") &&
  546. !(*i)->GetCustomCommand())
  547. {
  548. std::string outExt =
  549. m_GlobalGenerator->GetLanguageOutputExtensionFromExtension(
  550. (*i)->GetSourceExtension().c_str());
  551. if(outExt.size() && !(*i)->GetPropertyAsBool("EXTERNAL_OBJECT") )
  552. {
  553. std::string ofname = m_Makefile->GetCurrentOutputDirectory();
  554. ofname += "/";
  555. ofname += (*i)->GetSourceName() + outExt;
  556. objVector.push_back(ofname);
  557. this->AddCustomCommandToCreateObject(ofname.c_str(), llang, *(*i), target);
  558. objs += this->Convert(ofname.c_str(),START_OUTPUT,MAKEFILE);
  559. objs += " ";
  560. }
  561. }
  562. }
  563. std::string createRule = "CMAKE_";
  564. createRule += llang;
  565. createRule += target.GetCreateRuleVariable();
  566. std::string targetName = target.GetFullName(m_Makefile);
  567. // Executable :
  568. // Shared Library:
  569. // Static Library:
  570. // Shared Module:
  571. std::string linkLibs; // should be set
  572. std::string flags; // should be set
  573. std::string linkFlags; // should be set
  574. this->GetTargetFlags(linkLibs, flags, linkFlags, target);
  575. std::string rule = m_Makefile->GetRequiredDefinition(createRule.c_str());
  576. this->ExpandRuleVariables(rule,
  577. llang, // language
  578. objs.c_str(), // objects
  579. targetName.c_str(), // target
  580. linkLibs.c_str(), // link libs
  581. 0, // source
  582. 0, // object
  583. flags.c_str(), // flags
  584. 0, // objects quoted
  585. 0, // target base name
  586. 0, // target so name,
  587. linkFlags.c_str() // link flags
  588. );
  589. #if 0
  590. std::string command;
  591. std::string args;
  592. cmSystemTools::SplitProgramFromArgs(rule.c_str(), command, args);
  593. // Just like ADD_CUSTOM_TARGET(foo ALL DEPENDS a.o b.o)
  594. // Add a custom command for generating each .o file
  595. cmCustomCommand cc(command.c_str(), args.c_str(), objVector,
  596. targetName.c_str(), 0);
  597. target.GetPostBuildCommands().push_back(cc);
  598. #endif
  599. }
  600. void cmLocalGenerator::CreateCustomTargetsAndCommands(std::set<cmStdString> const& lang)
  601. {
  602. cmTargets &tgts = m_Makefile->GetTargets();
  603. for(cmTargets::iterator l = tgts.begin();
  604. l != tgts.end(); l++)
  605. {
  606. cmTarget& target = l->second;
  607. switch(target.GetType())
  608. {
  609. case cmTarget::STATIC_LIBRARY:
  610. case cmTarget::SHARED_LIBRARY:
  611. case cmTarget::MODULE_LIBRARY:
  612. case cmTarget::EXECUTABLE:
  613. {
  614. const char* llang = target.GetLinkerLanguage(this->GetGlobalGenerator());
  615. if(!llang)
  616. {
  617. cmSystemTools::Error("CMake can not determine linker language for target:",
  618. target.GetName());
  619. return;
  620. }
  621. // if the language is not in the set lang then create custom
  622. // commands to build the target
  623. if(lang.count(llang) == 0)
  624. {
  625. this->AddBuildTargetRule(llang, target);
  626. }
  627. }
  628. break;
  629. case cmTarget::UTILITY:
  630. case cmTarget::INSTALL_FILES:
  631. case cmTarget::INSTALL_PROGRAMS:
  632. break;
  633. }
  634. }
  635. }
  636. // List of variables that are replaced when
  637. // rules are expanced. These variables are
  638. // replaced in the form <var> with GetSafeDefinition(var).
  639. // ${LANG} is replaced in the variable first with all enabled
  640. // languages.
  641. static const char* ruleReplaceVars[] =
  642. {
  643. "CMAKE_${LANG}_COMPILER",
  644. "CMAKE_SHARED_LIBRARY_CREATE_${LANG}_FLAGS",
  645. "CMAKE_SHARED_MODULE_CREATE_${LANG}_FLAGS",
  646. "CMAKE_SHARED_MODULE_${LANG}_FLAGS",
  647. "CMAKE_SHARED_LIBRARY_${LANG}_FLAGS",
  648. "CMAKE_${LANG}_LINK_FLAGS",
  649. "CMAKE_SHARED_LIBRARY_SONAME_${LANG}_FLAG",
  650. "CMAKE_${LANG}_ARCHIVE",
  651. "CMAKE_AR",
  652. "CMAKE_CURRENT_SOURCE_DIR",
  653. "CMAKE_CURRENT_BINARY_DIR",
  654. "CMAKE_RANLIB",
  655. 0
  656. };
  657. std::string
  658. cmLocalGenerator::ExpandRuleVariable(std::string const& variable,
  659. const char* lang,
  660. const char* objects,
  661. const char* target,
  662. const char* linkLibs,
  663. const char* source,
  664. const char* object,
  665. const char* flags,
  666. const char* objectsquoted,
  667. const char* targetBase,
  668. const char* targetSOName,
  669. const char* linkFlags)
  670. {
  671. if(linkFlags)
  672. {
  673. if(variable == "LINK_FLAGS")
  674. {
  675. return linkFlags;
  676. }
  677. }
  678. if(flags)
  679. {
  680. if(variable == "FLAGS")
  681. {
  682. return flags;
  683. }
  684. }
  685. if(source)
  686. {
  687. if(variable == "SOURCE")
  688. {
  689. return source;
  690. }
  691. }
  692. if(object)
  693. {
  694. if(variable == "OBJECT")
  695. {
  696. return object;
  697. }
  698. }
  699. if(objects)
  700. {
  701. if(variable == "OBJECTS")
  702. {
  703. return objects;
  704. }
  705. }
  706. if(objectsquoted)
  707. {
  708. if(variable == "OBJECTS_QUOTED")
  709. {
  710. return objectsquoted;
  711. }
  712. }
  713. if(target)
  714. {
  715. if(variable == "TARGET_QUOTED")
  716. {
  717. std::string targetQuoted = target;
  718. if(targetQuoted.size() && targetQuoted[0] != '\"')
  719. {
  720. targetQuoted = '\"';
  721. targetQuoted += target;
  722. targetQuoted += '\"';
  723. return targetQuoted;
  724. }
  725. }
  726. if(variable == "TARGET")
  727. {
  728. return target;
  729. }
  730. }
  731. if(targetBase)
  732. {
  733. if(variable == "TARGET_BASE.lib" || variable == "TARGET_BASE.dll")
  734. {
  735. // special case for quoted paths with spaces
  736. // if you see <TARGET_BASE>.lib then put the .lib inside
  737. // the quotes, same for .dll
  738. if((strlen(targetBase) > 1) && targetBase[0] == '\"')
  739. {
  740. std::string base = targetBase;
  741. base[base.size()-1] = '.';
  742. std::string baseLib = base + "lib\"";
  743. std::string baseDll = base + "dll\"";
  744. if(variable == "TARGET_BASE.lib" )
  745. {
  746. return baseLib;
  747. }
  748. if(variable == "TARGET_BASE.dll" )
  749. {
  750. return baseDll;
  751. }
  752. }
  753. }
  754. if(variable == "TARGET_BASE")
  755. {
  756. return targetBase;
  757. }
  758. }
  759. if(targetSOName)
  760. {
  761. if(variable == "TARGET_SONAME")
  762. {
  763. if(lang)
  764. {
  765. std::string name = "CMAKE_SHARED_LIBRARY_SONAME_";
  766. name += lang;
  767. name += "_FLAG";
  768. if(m_Makefile->GetDefinition(name.c_str()))
  769. {
  770. return targetSOName;
  771. }
  772. }
  773. return "";
  774. }
  775. }
  776. if(linkLibs)
  777. {
  778. if(variable == "LINK_LIBRARIES")
  779. {
  780. return linkLibs;
  781. }
  782. }
  783. std::vector<std::string> enabledLanguages;
  784. m_GlobalGenerator->GetEnabledLanguages(enabledLanguages);
  785. // loop over language specific replace variables
  786. int pos = 0;
  787. while(ruleReplaceVars[pos])
  788. {
  789. for(std::vector<std::string>::iterator i = enabledLanguages.begin();
  790. i != enabledLanguages.end(); ++i)
  791. {
  792. lang = i->c_str();
  793. std::string actualReplace = ruleReplaceVars[pos];
  794. // If this is the compiler then look for the extra variable
  795. // _COMPILER_ARG1 which must be the first argument to the compiler
  796. const char* compilerArg1 = 0;
  797. if(actualReplace == "CMAKE_${LANG}_COMPILER")
  798. {
  799. std::string arg1 = actualReplace + "_ARG1";
  800. cmSystemTools::ReplaceString(arg1, "${LANG}", lang);
  801. compilerArg1 = m_Makefile->GetDefinition(arg1.c_str());
  802. }
  803. if(actualReplace.find("${LANG}") != actualReplace.npos)
  804. {
  805. cmSystemTools::ReplaceString(actualReplace, "${LANG}", lang);
  806. }
  807. if(actualReplace == variable)
  808. {
  809. std::string replace = m_Makefile->GetSafeDefinition(variable.c_str());
  810. // if the variable is not a FLAG then treat it like a path
  811. if(variable.find("_FLAG") == variable.npos)
  812. {
  813. std::string ret = this->ConvertToOutputForExisting(replace.c_str());
  814. // if there is a required first argument to the compiler add it to the compiler string
  815. if(compilerArg1)
  816. {
  817. ret += " ";
  818. ret += compilerArg1;
  819. }
  820. return ret;
  821. }
  822. return replace;
  823. }
  824. }
  825. pos++;
  826. }
  827. return variable;
  828. }
  829. void
  830. cmLocalGenerator::ExpandRuleVariables(std::string& s,
  831. const char* lang,
  832. const char* objects,
  833. const char* target,
  834. const char* linkLibs,
  835. const char* source,
  836. const char* object,
  837. const char* flags,
  838. const char* objectsquoted,
  839. const char* targetBase,
  840. const char* targetSOName,
  841. const char* linkFlags)
  842. {
  843. std::vector<std::string> enabledLanguages;
  844. m_GlobalGenerator->GetEnabledLanguages(enabledLanguages);
  845. std::string::size_type start = s.find('<');
  846. // no variables to expand
  847. if(start == s.npos)
  848. {
  849. return;
  850. }
  851. std::string::size_type pos = 0;
  852. std::string expandedInput;
  853. while(start != s.npos && start < s.size()-2)
  854. {
  855. std::string::size_type end = s.find('>', start);
  856. // if we find a < with no > we are done
  857. if(end == s.npos)
  858. {
  859. return;
  860. }
  861. char c = s[start+1];
  862. // if the next char after the < is not A-Za-z then
  863. // skip it and try to find the next < in the string
  864. if(!isalpha(c))
  865. {
  866. start = s.find('<', start+1);
  867. }
  868. else
  869. {
  870. // extract the var
  871. std::string var = s.substr(start+1, end - start-1);
  872. std::string replace = this->ExpandRuleVariable(var, lang, objects,
  873. target, linkLibs,
  874. source, object, flags,
  875. objectsquoted,
  876. targetBase, targetSOName,
  877. linkFlags);
  878. expandedInput += s.substr(pos, start-pos);
  879. expandedInput += replace;
  880. // move to next one
  881. start = s.find('<', start+var.size()+2);
  882. pos = end+1;
  883. }
  884. }
  885. // add the rest of the input
  886. expandedInput += s.substr(pos, s.size()-pos);
  887. s = expandedInput;
  888. }
  889. std::string
  890. cmLocalGenerator::ConvertToOutputForExisting(const char* p)
  891. {
  892. std::string ret = this->Convert(p, START_OUTPUT, SHELL, true);
  893. // if there are spaces in the path, then get the short path version
  894. // if there is one
  895. if(ret.find(' ') != std::string::npos)
  896. {
  897. if(cmSystemTools::FileExists(p))
  898. {
  899. if(!cmSystemTools::GetShortPath(ret.c_str(), ret))
  900. {
  901. ret = this->Convert(p,START_OUTPUT,MAKEFILE,true);
  902. }
  903. }
  904. }
  905. return ret;
  906. }
  907. const char* cmLocalGenerator::GetIncludeFlags(const char* lang)
  908. {
  909. if(!lang)
  910. {
  911. return "";
  912. }
  913. if(m_LanguageToIncludeFlags.count(lang))
  914. {
  915. return m_LanguageToIncludeFlags[lang].c_str();
  916. }
  917. cmOStringStream includeFlags;
  918. std::vector<std::string> includes;
  919. this->GetIncludeDirectories(includes);
  920. std::vector<std::string>::iterator i;
  921. std::string flagVar = "CMAKE_INCLUDE_FLAG_";
  922. flagVar += lang;
  923. const char* includeFlag = m_Makefile->GetDefinition(flagVar.c_str());
  924. flagVar = "CMAKE_INCLUDE_FLAG_SEP_";
  925. flagVar += lang;
  926. const char* sep = m_Makefile->GetDefinition(flagVar.c_str());
  927. bool repeatFlag = true; // should the include flag be repeated like ie. -IA -IB
  928. if(!sep)
  929. {
  930. sep = " ";
  931. }
  932. else
  933. {
  934. // if there is a separator then the flag is not repeated but is only given once
  935. // i.e. -classpath a:b:c
  936. repeatFlag = false;
  937. }
  938. bool flagUsed = false;
  939. for(i = includes.begin(); i != includes.end(); ++i)
  940. {
  941. std::string include = *i;
  942. if(!flagUsed || repeatFlag)
  943. {
  944. includeFlags << includeFlag;
  945. flagUsed = true;
  946. }
  947. includeFlags << this->ConvertToOutputForExisting(i->c_str()) << sep;
  948. }
  949. std::string flags = includeFlags.str();
  950. // remove trailing separators
  951. if((sep[0] != ' ') && flags[flags.size()-1] == sep[0])
  952. {
  953. flags[flags.size()-1] = ' ';
  954. }
  955. flags += m_Makefile->GetDefineFlags();
  956. m_LanguageToIncludeFlags[lang] = flags;
  957. return m_LanguageToIncludeFlags[lang].c_str();
  958. }
  959. //----------------------------------------------------------------------------
  960. void cmLocalGenerator::GetIncludeDirectories(std::vector<std::string>& dirs)
  961. {
  962. // Output Include paths
  963. std::set<cmStdString> implicitIncludes;
  964. // CMake versions below 2.0 would add the source tree to the -I path
  965. // automatically. Preserve compatibility.
  966. bool includeSourceDir = false;
  967. const char* versionValue =
  968. m_Makefile->GetDefinition("CMAKE_BACKWARDS_COMPATIBILITY");
  969. if(versionValue)
  970. {
  971. int major = 0;
  972. int minor = 0;
  973. if(sscanf(versionValue, "%d.%d", &major, &minor) == 2 && major < 2)
  974. {
  975. includeSourceDir = true;
  976. }
  977. }
  978. const char* vtkSourceDir =
  979. m_Makefile->GetDefinition("VTK_SOURCE_DIR");
  980. if(vtkSourceDir)
  981. {
  982. // Special hack for VTK 4.0 - 4.4.
  983. const char* vtk_major = m_Makefile->GetDefinition("VTK_MAJOR_VERSION");
  984. const char* vtk_minor = m_Makefile->GetDefinition("VTK_MINOR_VERSION");
  985. vtk_major = vtk_major? vtk_major : "4";
  986. vtk_minor = vtk_minor? vtk_minor : "4";
  987. int major = 0;
  988. int minor = 0;
  989. if(sscanf(vtk_major, "%d", &major) && sscanf(vtk_minor, "%d", &minor) &&
  990. major == 4 && minor <= 4)
  991. {
  992. includeSourceDir = true;
  993. }
  994. }
  995. if(includeSourceDir)
  996. {
  997. dirs.push_back(m_Makefile->GetStartDirectory());
  998. }
  999. // Do not explicitly add the standard include path "/usr/include".
  1000. // This can cause problems with certain standard library
  1001. // implementations because the wrong headers may be found first.
  1002. implicitIncludes.insert("/usr/include");
  1003. if(m_Makefile->GetDefinition("CMAKE_PLATFORM_IMPLICIT_INCLUDE_DIRECTORIES"))
  1004. {
  1005. std::string arg = m_Makefile->GetDefinition("CMAKE_PLATFORM_IMPLICIT_INCLUDE_DIRECTORIES");
  1006. std::vector<std::string> implicitIncludeVec;
  1007. cmSystemTools::ExpandListArgument(arg, implicitIncludeVec);
  1008. for(unsigned int k =0; k < implicitIncludeVec.size(); k++)
  1009. {
  1010. implicitIncludes.insert(implicitIncludeVec[k]);
  1011. }
  1012. }
  1013. // Construct the ordered list.
  1014. std::vector<std::string>& includes = m_Makefile->GetIncludeDirectories();
  1015. for(std::vector<std::string>::iterator i = includes.begin();
  1016. i != includes.end(); ++i)
  1017. {
  1018. if(implicitIncludes.find(*i) == implicitIncludes.end())
  1019. {
  1020. dirs.push_back(*i);
  1021. }
  1022. }
  1023. }
  1024. void cmLocalGenerator::GetTargetFlags(std::string& linkLibs,
  1025. std::string& flags,
  1026. std::string& linkFlags,
  1027. cmTarget& target)
  1028. {
  1029. std::string buildType = m_Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE");
  1030. buildType = cmSystemTools::UpperCase(buildType);
  1031. const char* libraryLinkVariable = "CMAKE_SHARED_LINKER_FLAGS"; // default to shared library
  1032. switch(target.GetType())
  1033. {
  1034. case cmTarget::STATIC_LIBRARY:
  1035. {
  1036. const char* targetLinkFlags = target.GetProperty("STATIC_LIBRARY_FLAGS");
  1037. if(targetLinkFlags)
  1038. {
  1039. linkFlags += targetLinkFlags;
  1040. linkFlags += " ";
  1041. }
  1042. }
  1043. break;
  1044. case cmTarget::MODULE_LIBRARY:
  1045. libraryLinkVariable = "CMAKE_MODULE_LINKER_FLAGS";
  1046. case cmTarget::SHARED_LIBRARY:
  1047. {
  1048. linkFlags = m_Makefile->GetSafeDefinition(libraryLinkVariable);
  1049. linkFlags += " ";
  1050. if(buildType.size())
  1051. {
  1052. std::string build = libraryLinkVariable;
  1053. build += "_";
  1054. build += buildType;
  1055. linkFlags += m_Makefile->GetSafeDefinition(build.c_str());
  1056. linkFlags += " ";
  1057. }
  1058. if(m_Makefile->IsOn("WIN32") && !(m_Makefile->IsOn("CYGWIN") || m_Makefile->IsOn("MINGW")))
  1059. {
  1060. const std::vector<cmSourceFile*>& sources = target.GetSourceFiles();
  1061. for(std::vector<cmSourceFile*>::const_iterator i = sources.begin();
  1062. i != sources.end(); ++i)
  1063. {
  1064. if((*i)->GetSourceExtension() == "def")
  1065. {
  1066. linkFlags += m_Makefile->GetSafeDefinition("CMAKE_LINK_DEF_FILE_FLAG");
  1067. linkFlags += this->Convert((*i)->GetFullPath().c_str(),START_OUTPUT,MAKEFILE);
  1068. linkFlags += " ";
  1069. }
  1070. }
  1071. }
  1072. const char* targetLinkFlags = target.GetProperty("LINK_FLAGS");
  1073. if(targetLinkFlags)
  1074. {
  1075. linkFlags += targetLinkFlags;
  1076. linkFlags += " ";
  1077. }
  1078. cmOStringStream linklibsStr;
  1079. this->OutputLinkLibraries(linklibsStr, target.GetName(), target);
  1080. linkLibs = linklibsStr.str();
  1081. }
  1082. break;
  1083. case cmTarget::EXECUTABLE:
  1084. {
  1085. linkFlags += m_Makefile->GetSafeDefinition("CMAKE_EXE_LINKER_FLAGS");
  1086. linkFlags += " ";
  1087. if(buildType.size())
  1088. {
  1089. std::string build = "CMAKE_EXE_LINKER_FLAGS_";
  1090. build += buildType;
  1091. linkFlags += m_Makefile->GetSafeDefinition(build.c_str());
  1092. linkFlags += " ";
  1093. }
  1094. const char* linkLanguage = target.GetLinkerLanguage(this->GetGlobalGenerator());
  1095. if(!linkLanguage)
  1096. {
  1097. cmSystemTools::Error("CMake can not determine linker language for target:",
  1098. target.GetName());
  1099. return;
  1100. }
  1101. std::string langVar = "CMAKE_";
  1102. langVar += linkLanguage;
  1103. std::string flagsVar = langVar + "_FLAGS";
  1104. std::string sharedFlagsVar = "CMAKE_SHARED_LIBRARY_";
  1105. sharedFlagsVar += linkLanguage;
  1106. sharedFlagsVar += "_FLAGS";
  1107. flags += m_Makefile->GetSafeDefinition(flagsVar.c_str());
  1108. flags += " ";
  1109. flags += m_Makefile->GetSafeDefinition(sharedFlagsVar.c_str());
  1110. flags += " ";
  1111. cmOStringStream linklibs;
  1112. this->OutputLinkLibraries(linklibs, 0, target);
  1113. linkLibs = linklibs.str();
  1114. if(cmSystemTools::IsOn(m_Makefile->GetDefinition("BUILD_SHARED_LIBS")))
  1115. {
  1116. std::string sFlagVar = std::string("CMAKE_SHARED_BUILD_") + linkLanguage
  1117. + std::string("_FLAGS");
  1118. linkFlags += m_Makefile->GetSafeDefinition(sFlagVar.c_str());
  1119. linkFlags += " ";
  1120. }
  1121. if ( target.GetPropertyAsBool("WIN32_EXECUTABLE") )
  1122. {
  1123. linkFlags += m_Makefile->GetSafeDefinition("CMAKE_CREATE_WIN32_EXE");
  1124. linkFlags += " ";
  1125. }
  1126. else
  1127. {
  1128. linkFlags += m_Makefile->GetSafeDefinition("CMAKE_CREATE_CONSOLE_EXE");
  1129. linkFlags += " ";
  1130. }
  1131. const char* targetLinkFlags = target.GetProperty("LINK_FLAGS");
  1132. if(targetLinkFlags)
  1133. {
  1134. linkFlags += targetLinkFlags;
  1135. linkFlags += " ";
  1136. }
  1137. }
  1138. break;
  1139. case cmTarget::UTILITY:
  1140. case cmTarget::INSTALL_FILES:
  1141. case cmTarget::INSTALL_PROGRAMS:
  1142. break;
  1143. }
  1144. }
  1145. /**
  1146. * Output the linking rules on a command line. For executables,
  1147. * targetLibrary should be a NULL pointer. For libraries, it should point
  1148. * to the name of the library. This will not link a library against itself.
  1149. */
  1150. void cmLocalGenerator::OutputLinkLibraries(std::ostream& fout,
  1151. const char* targetLibrary,
  1152. cmTarget &tgt)
  1153. {
  1154. // Try to emit each search path once
  1155. std::set<cmStdString> emitted;
  1156. // Embed runtime search paths if possible and if required.
  1157. bool outputRuntime = true;
  1158. std::string runtimeFlag;
  1159. std::string runtimeSep;
  1160. std::vector<std::string> runtimeDirs;
  1161. std::string buildType = m_Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE");
  1162. buildType = cmSystemTools::UpperCase(buildType);
  1163. cmTarget::LinkLibraryType cmakeBuildType = cmTarget::GENERAL;
  1164. if(buildType == "DEBUG")
  1165. {
  1166. cmakeBuildType = cmTarget::DEBUG;
  1167. }
  1168. else if(buildType.size())
  1169. {
  1170. cmakeBuildType = cmTarget::OPTIMIZED;
  1171. }
  1172. const char* linkLanguage = tgt.GetLinkerLanguage(this->GetGlobalGenerator());
  1173. if(!linkLanguage)
  1174. {
  1175. cmSystemTools::
  1176. Error("CMake can not determine linker language for target:",
  1177. tgt.GetName());
  1178. return;
  1179. }
  1180. std::string runTimeFlagVar = "CMAKE_SHARED_LIBRARY_RUNTIME_";
  1181. runTimeFlagVar += linkLanguage;
  1182. runTimeFlagVar += "_FLAG";
  1183. std::string runTimeFlagSepVar = runTimeFlagVar + "_SEP";
  1184. runtimeFlag = m_Makefile->GetSafeDefinition(runTimeFlagVar.c_str());
  1185. runtimeSep = m_Makefile->GetSafeDefinition(runTimeFlagSepVar.c_str());
  1186. // concatenate all paths or no?
  1187. bool runtimeConcatenate = ( runtimeSep!="" );
  1188. if(runtimeFlag == "" || m_Makefile->IsOn("CMAKE_SKIP_RPATH") )
  1189. {
  1190. outputRuntime = false;
  1191. }
  1192. // Some search paths should never be emitted
  1193. emitted.insert("");
  1194. emitted.insert("/usr/lib");
  1195. std::string libPathFlag = m_Makefile->GetRequiredDefinition("CMAKE_LIBRARY_PATH_FLAG");
  1196. std::string libLinkFlag = m_Makefile->GetSafeDefinition("CMAKE_LINK_LIBRARY_FLAG");
  1197. // collect all the flags needed for linking libraries
  1198. std::string linkLibs;
  1199. // Flags to link an executable to shared libraries.
  1200. std::string linkFlagsVar = "CMAKE_SHARED_LIBRARY_LINK_";
  1201. linkFlagsVar += linkLanguage;
  1202. linkFlagsVar += "_FLAGS";
  1203. if( tgt.GetType() == cmTarget::EXECUTABLE )
  1204. {
  1205. linkLibs = m_Makefile->GetSafeDefinition(linkFlagsVar.c_str());
  1206. linkLibs += " ";
  1207. }
  1208. cmOrderLinkDirectories orderLibs;
  1209. std::string ext =
  1210. m_Makefile->GetSafeDefinition("CMAKE_STATIC_LIBRARY_SUFFIX");
  1211. if(ext.size())
  1212. {
  1213. orderLibs.AddLinkExtension(ext.c_str());
  1214. }
  1215. ext =
  1216. m_Makefile->GetSafeDefinition("CMAKE_SHARED_LIBRARY_SUFFIX");
  1217. if(ext.size())
  1218. {
  1219. orderLibs.AddLinkExtension(ext.c_str());
  1220. }
  1221. ext =
  1222. m_Makefile->GetSafeDefinition("CMAKE_LINK_LIBRARY_SUFFIX");
  1223. if(ext.size())
  1224. {
  1225. orderLibs.AddLinkExtension(ext.c_str());
  1226. }
  1227. // compute the correct order for -L paths
  1228. orderLibs.SetLinkInformation(tgt, cmakeBuildType, targetLibrary);
  1229. orderLibs.DetermineLibraryPathOrder();
  1230. std::vector<cmStdString> libdirs;
  1231. std::vector<cmStdString> linkItems;
  1232. orderLibs.GetLinkerInformation(libdirs, linkItems);
  1233. for(std::vector<cmStdString>::const_iterator libDir = libdirs.begin();
  1234. libDir != libdirs.end(); ++libDir)
  1235. {
  1236. std::string libpath = this->ConvertToOutputForExisting(libDir->c_str());
  1237. if(emitted.insert(libpath).second)
  1238. {
  1239. std::string fullLibPath;
  1240. if(!m_WindowsShell && m_UseRelativePaths)
  1241. {
  1242. fullLibPath = "\"`cd ";
  1243. }
  1244. fullLibPath += libpath;
  1245. if(!m_WindowsShell && m_UseRelativePaths)
  1246. {
  1247. fullLibPath += ";pwd`\"";
  1248. }
  1249. std::string::size_type pos = libDir->find(libPathFlag.c_str());
  1250. if((pos == std::string::npos || pos > 0)
  1251. && libDir->find("${") == std::string::npos)
  1252. {
  1253. linkLibs += libPathFlag;
  1254. if(outputRuntime)
  1255. {
  1256. runtimeDirs.push_back( fullLibPath );
  1257. }
  1258. }
  1259. linkLibs += fullLibPath;
  1260. linkLibs += " ";
  1261. }
  1262. }
  1263. std::string linkSuffix =
  1264. m_Makefile->GetSafeDefinition("CMAKE_LINK_LIBRARY_SUFFIX");
  1265. std::string regexp = ".*\\";
  1266. regexp += linkSuffix;
  1267. regexp += "$";
  1268. cmsys::RegularExpression hasSuffix(regexp.c_str());
  1269. std::string librariesLinked;
  1270. for(std::vector<cmStdString>::iterator lib = linkItems.begin();
  1271. lib != linkItems.end(); ++lib)
  1272. {
  1273. cmStdString& linkItem = *lib;
  1274. // check to see if the link item has a -l already
  1275. cmsys::RegularExpression reg("^([ \t]*\\-[lLWRB])|([ \t]*\\-framework)|(\\${)|([ \t]*\\-pthread)|([ \t]*`)");
  1276. if(!reg.find(linkItem))
  1277. {
  1278. librariesLinked += libLinkFlag;
  1279. }
  1280. librariesLinked += linkItem;
  1281. if(linkSuffix.size() && !hasSuffix.find(linkItem))
  1282. {
  1283. librariesLinked += linkSuffix;
  1284. }
  1285. librariesLinked += " ";
  1286. }
  1287. linkLibs += librariesLinked;
  1288. fout << linkLibs;
  1289. if(outputRuntime && runtimeDirs.size()>0)
  1290. {
  1291. // For the runtime search directories, do a "-Wl,-rpath,a:b:c" or
  1292. // a "-R a -R b -R c" type link line
  1293. fout << runtimeFlag;
  1294. std::vector<std::string>::iterator itr = runtimeDirs.begin();
  1295. fout << *itr;
  1296. ++itr;
  1297. for( ; itr != runtimeDirs.end(); ++itr )
  1298. {
  1299. if(runtimeConcatenate)
  1300. {
  1301. fout << runtimeSep << *itr;
  1302. }
  1303. else
  1304. {
  1305. fout << " " << runtimeFlag << *itr;
  1306. }
  1307. }
  1308. fout << " ";
  1309. }
  1310. if(m_Makefile->GetDefinition("CMAKE_STANDARD_LIBRARIES"))
  1311. {
  1312. fout << m_Makefile->GetDefinition("CMAKE_STANDARD_LIBRARIES") << " ";
  1313. }
  1314. }
  1315. //----------------------------------------------------------------------------
  1316. void cmLocalGenerator::AddLanguageFlags(std::string& flags,
  1317. const char* lang)
  1318. {
  1319. // Add language-specific flags.
  1320. std::string flagsVar = "CMAKE_";
  1321. flagsVar += lang;
  1322. flagsVar += "_FLAGS";
  1323. this->AddConfigVariableFlags(flags, flagsVar.c_str());
  1324. }
  1325. //----------------------------------------------------------------------------
  1326. void cmLocalGenerator::AddSharedFlags(std::string& flags,
  1327. const char* lang,
  1328. bool shared)
  1329. {
  1330. std::string flagsVar;
  1331. // Add flags for dealing with shared libraries for this language.
  1332. if(shared)
  1333. {
  1334. flagsVar = "CMAKE_SHARED_LIBRARY_";
  1335. flagsVar += lang;
  1336. flagsVar += "_FLAGS";
  1337. this->AppendFlags(flags, m_Makefile->GetDefinition(flagsVar.c_str()));
  1338. }
  1339. // Add flags specific to shared builds.
  1340. if(cmSystemTools::IsOn(m_Makefile->GetDefinition("BUILD_SHARED_LIBS")))
  1341. {
  1342. flagsVar = "CMAKE_SHARED_BUILD_";
  1343. flagsVar += lang;
  1344. flagsVar += "_FLAGS";
  1345. this->AppendFlags(flags, m_Makefile->GetDefinition(flagsVar.c_str()));
  1346. }
  1347. }
  1348. //----------------------------------------------------------------------------
  1349. void cmLocalGenerator::AddConfigVariableFlags(std::string& flags,
  1350. const char* var)
  1351. {
  1352. // Add the flags from the variable itself.
  1353. std::string flagsVar = var;
  1354. this->AppendFlags(flags, m_Makefile->GetDefinition(flagsVar.c_str()));
  1355. // Add the flags from the build-type specific variable.
  1356. const char* buildType = m_Makefile->GetDefinition("CMAKE_BUILD_TYPE");
  1357. if(buildType && *buildType)
  1358. {
  1359. flagsVar += "_";
  1360. flagsVar += cmSystemTools::UpperCase(buildType);
  1361. this->AppendFlags(flags, m_Makefile->GetDefinition(flagsVar.c_str()));
  1362. }
  1363. }
  1364. //----------------------------------------------------------------------------
  1365. void cmLocalGenerator::AppendFlags(std::string& flags,
  1366. const char* newFlags)
  1367. {
  1368. if(newFlags && *newFlags)
  1369. {
  1370. if(flags.size())
  1371. {
  1372. flags += " ";
  1373. }
  1374. flags += newFlags;
  1375. }
  1376. }
  1377. //----------------------------------------------------------------------------
  1378. std::string
  1379. cmLocalGenerator::ConstructScript(const cmCustomCommandLines& commandLines,
  1380. const char* newline)
  1381. {
  1382. // Store the script in a string.
  1383. std::string script;
  1384. // Write each command on a single line.
  1385. for(cmCustomCommandLines::const_iterator cl = commandLines.begin();
  1386. cl != commandLines.end(); ++cl)
  1387. {
  1388. // Start with the command name.
  1389. const cmCustomCommandLine& commandLine = *cl;
  1390. script += this->Convert(commandLine[0].c_str(),START_OUTPUT,SHELL);
  1391. // Add the arguments.
  1392. for(unsigned int j=1;j < commandLine.size(); ++j)
  1393. {
  1394. script += " ";
  1395. script += cmSystemTools::EscapeSpaces(commandLine[j].c_str());
  1396. }
  1397. // End the line.
  1398. script += newline;
  1399. }
  1400. return script;
  1401. }
  1402. //----------------------------------------------------------------------------
  1403. std::string
  1404. cmLocalGenerator::ConvertToOptionallyRelativeOutputPath(const char* remote)
  1405. {
  1406. return this->Convert(remote, START_OUTPUT, SHELL, true);
  1407. }
  1408. //----------------------------------------------------------------------------
  1409. std::string cmLocalGenerator::Convert(const char* source,
  1410. RelativeRoot relative,
  1411. OutputFormat output,
  1412. bool optional)
  1413. {
  1414. // Convert the path to a relative path.
  1415. std::string result = source;
  1416. if (!optional || m_UseRelativePaths)
  1417. {
  1418. switch (relative)
  1419. {
  1420. case HOME:
  1421. //result = cmSystemTools::CollapseFullPath(result.c_str());
  1422. result = m_GlobalGenerator->
  1423. ConvertToRelativePath(m_HomeDirectoryComponents, result.c_str());
  1424. break;
  1425. case START:
  1426. //result = cmSystemTools::CollapseFullPath(result.c_str());
  1427. result = m_GlobalGenerator->
  1428. ConvertToRelativePath(m_StartDirectoryComponents, result.c_str());
  1429. break;
  1430. case HOME_OUTPUT:
  1431. //result = cmSystemTools::CollapseFullPath(result.c_str());
  1432. result = m_GlobalGenerator->
  1433. ConvertToRelativePath(m_HomeOutputDirectoryComponents, result.c_str());
  1434. break;
  1435. case START_OUTPUT:
  1436. //result = cmSystemTools::CollapseFullPath(result.c_str());
  1437. result = m_GlobalGenerator->
  1438. ConvertToRelativePath(m_StartOutputDirectoryComponents, result.c_str());
  1439. break;
  1440. case FULL:
  1441. result = cmSystemTools::CollapseFullPath(result.c_str());
  1442. break;
  1443. case NONE:
  1444. break;
  1445. }
  1446. }
  1447. // Now convert it to an output path.
  1448. if (output == MAKEFILE || output == SHELL)
  1449. {
  1450. result = cmSystemTools::ConvertToOutputPath(result.c_str());
  1451. }
  1452. return result;
  1453. }