cmLocalGenerator.cxx 59 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866
  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. // make sure the CMakeFiles dir is there
  40. std::string filesDir = m_Makefile->GetStartOutputDirectory();
  41. filesDir += "/CMakeFiles";
  42. cmSystemTools::MakeDirectory(filesDir.c_str());
  43. // find & read the list file
  44. std::string currentStart = m_Makefile->GetStartDirectory();
  45. currentStart += "/CMakeLists.txt";
  46. m_Makefile->ReadListFile(currentStart.c_str());
  47. // at the end of the ReadListFile handle any old style subdirs
  48. // first get all the subdirectories
  49. std::vector<cmLocalGenerator *> subdirs = this->GetChildren();
  50. // for each subdir recurse
  51. std::vector<cmLocalGenerator *>::iterator sdi = subdirs.begin();
  52. for (; sdi != subdirs.end(); ++sdi)
  53. {
  54. if (!(*sdi)->Configured)
  55. {
  56. m_Makefile->ConfigureSubDirectory(*sdi);
  57. }
  58. }
  59. this->SetupPathConversions();
  60. // Check whether relative paths should be used for optionally
  61. // relative paths.
  62. m_UseRelativePaths = m_Makefile->IsOn("CMAKE_USE_RELATIVE_PATHS");
  63. this->Configured = true;
  64. }
  65. void cmLocalGenerator::SetupPathConversions()
  66. {
  67. // Setup the current output directory components for use by
  68. // Convert
  69. std::string outdir;
  70. outdir =
  71. cmSystemTools::CollapseFullPath(m_Makefile->GetHomeDirectory());
  72. cmSystemTools::SplitPath(outdir.c_str(), m_HomeDirectoryComponents);
  73. outdir =
  74. cmSystemTools::CollapseFullPath(m_Makefile->GetStartDirectory());
  75. cmSystemTools::SplitPath(outdir.c_str(), m_StartDirectoryComponents);
  76. outdir =
  77. cmSystemTools::CollapseFullPath(m_Makefile->GetHomeOutputDirectory());
  78. cmSystemTools::SplitPath(outdir.c_str(), m_HomeOutputDirectoryComponents);
  79. outdir =
  80. cmSystemTools::CollapseFullPath(m_Makefile->GetStartOutputDirectory());
  81. cmSystemTools::SplitPath(outdir.c_str(), m_StartOutputDirectoryComponents);
  82. }
  83. void cmLocalGenerator::SetGlobalGenerator(cmGlobalGenerator *gg)
  84. {
  85. m_GlobalGenerator = gg;
  86. // setup the home directories
  87. m_Makefile->SetHomeDirectory(
  88. gg->GetCMakeInstance()->GetHomeDirectory());
  89. m_Makefile->SetHomeOutputDirectory(
  90. gg->GetCMakeInstance()->GetHomeOutputDirectory());
  91. }
  92. void cmLocalGenerator::ConfigureFinalPass()
  93. {
  94. m_Makefile->ConfigureFinalPass();
  95. }
  96. void cmLocalGenerator::GenerateTestFiles()
  97. {
  98. if ( !m_Makefile->IsOn("CMAKE_TESTING_ENABLED") )
  99. {
  100. return;
  101. }
  102. std::string file = m_Makefile->GetStartOutputDirectory();
  103. file += "/";
  104. if ( m_Makefile->IsSet("CTEST_NEW_FORMAT") )
  105. {
  106. file += "CTestTestfile.cmake";
  107. }
  108. else
  109. {
  110. file += "DartTestfile.txt";
  111. }
  112. cmGeneratedFileStream fout(file.c_str());
  113. fout.SetCopyIfDifferent(true);
  114. fout << "# CMake generated Testfile for " << std::endl
  115. << "# Source directory: " << m_Makefile->GetStartDirectory() << std::endl
  116. << "# Build directory: " << m_Makefile->GetStartOutputDirectory() << std::endl
  117. << "# " << std::endl
  118. << "# This file replicates the SUBDIRS() and ADD_TEST() commands from the source" << std::endl
  119. << "# tree CMakeLists.txt file, skipping any SUBDIRS() or ADD_TEST() commands" << std::endl
  120. << "# that are excluded by CMake control structures, i.e. IF() commands." << std::endl
  121. << "#" << std::endl
  122. << "# The next line is critical for Dart to work" << std::endl
  123. << "# Duh :-)" << std::endl << std::endl;
  124. const char* testIncludeFile = m_Makefile->GetProperty("TEST_INCLUDE_FILE");
  125. if ( testIncludeFile )
  126. {
  127. fout << "INCLUDE(\"" << testIncludeFile << "\")" << std::endl;
  128. }
  129. const std::vector<cmTest*> *tests = m_Makefile->GetTests();
  130. std::vector<cmTest*>::const_iterator it;
  131. for ( it = tests->begin(); it != tests->end(); ++ it )
  132. {
  133. cmTest* test = *it;
  134. fout << "ADD_TEST(";
  135. fout << test->GetName() << " \"" << test->GetCommand() << "\"";
  136. std::vector<cmStdString>::const_iterator argit;
  137. for (argit = test->GetArguments().begin();
  138. argit != test->GetArguments().end(); ++argit)
  139. {
  140. // Just double-quote all arguments so they are re-parsed
  141. // correctly by the test system.
  142. fout << " \"";
  143. for(std::string::const_iterator c = argit->begin(); c != argit->end(); ++c)
  144. {
  145. // Escape quotes within arguments. We should escape
  146. // backslashes too but we cannot because it makes the result
  147. // inconsistent with previous behavior of this command.
  148. if((*c == '"'))
  149. {
  150. fout << '\\';
  151. }
  152. fout << *c;
  153. }
  154. fout << "\"";
  155. }
  156. fout << ")" << std::endl;
  157. std::map<cmStdString,cmStdString>::const_iterator pit;
  158. const std::map<cmStdString,cmStdString>* mpit = &test->GetProperties();
  159. if ( mpit->size() )
  160. {
  161. fout << "SET_TESTS_PROPERTIES(" << test->GetName() << " PROPERTIES ";
  162. for ( pit = mpit->begin(); pit != mpit->end(); ++ pit )
  163. {
  164. fout << " " << pit->first.c_str() << " \"";
  165. const char* value = pit->second.c_str();
  166. for ( ; *value; ++ value )
  167. {
  168. switch ( *value )
  169. {
  170. case '\\':
  171. case '"':
  172. case ' ':
  173. case '#':
  174. case '(':
  175. case ')':
  176. case '$':
  177. case '^':
  178. fout << "\\" << *value;
  179. break;
  180. case '\t':
  181. fout << "\\t";
  182. break;
  183. case '\n':
  184. fout << "\\n";
  185. break;
  186. case '\r':
  187. fout << "\\r";
  188. break;
  189. default:
  190. fout << *value;
  191. }
  192. }
  193. fout << "\"";
  194. }
  195. fout << ")" << std::endl;
  196. }
  197. }
  198. if ( this->Children.size())
  199. {
  200. fout << "SUBDIRS(";
  201. size_t i;
  202. std::string outDir = m_Makefile->GetStartOutputDirectory();
  203. outDir += "/";
  204. for(i = 0; i < this->Children.size(); ++i)
  205. {
  206. std::string binP = this->Children[i]->GetMakefile()->GetStartOutputDirectory();
  207. cmSystemTools::ReplaceString(binP, outDir.c_str(), "");
  208. if ( i > 0 )
  209. {
  210. fout << " ";
  211. }
  212. fout << binP.c_str();
  213. }
  214. fout << ")" << std::endl << std::endl;;
  215. }
  216. }
  217. void cmLocalGenerator::GenerateInstallRules()
  218. {
  219. cmTargets &tgts = m_Makefile->GetTargets();
  220. const char* prefix
  221. = m_Makefile->GetDefinition("CMAKE_INSTALL_PREFIX");
  222. #if defined(_WIN32) && !defined(__CYGWIN__)
  223. std::string prefix_win32;
  224. if(!prefix)
  225. {
  226. if(!cmSystemTools::GetEnv("SystemDrive", prefix_win32))
  227. {
  228. prefix_win32 = "C:";
  229. }
  230. const char* project_name = m_Makefile->GetDefinition("PROJECT_NAME");
  231. if(project_name && project_name[0])
  232. {
  233. prefix_win32 += "/Program Files/";
  234. prefix_win32 += project_name;
  235. }
  236. else
  237. {
  238. prefix_win32 += "/InstalledCMakeProject";
  239. }
  240. prefix = prefix_win32.c_str();
  241. }
  242. #else
  243. if (!prefix)
  244. {
  245. prefix = "/usr/local";
  246. }
  247. #endif
  248. std::string file = m_Makefile->GetStartOutputDirectory();
  249. std::string homedir = m_Makefile->GetHomeOutputDirectory();
  250. std::string currdir = m_Makefile->GetCurrentOutputDirectory();
  251. cmSystemTools::ConvertToUnixSlashes(file);
  252. cmSystemTools::ConvertToUnixSlashes(homedir);
  253. cmSystemTools::ConvertToUnixSlashes(currdir);
  254. int toplevel_install = 0;
  255. if ( currdir == homedir )
  256. {
  257. toplevel_install = 1;
  258. }
  259. file += "/cmake_install.cmake";
  260. cmGeneratedFileStream fout(file.c_str());
  261. fout.SetCopyIfDifferent(true);
  262. fout << "# Install script for directory: " << m_Makefile->GetCurrentDirectory()
  263. << std::endl << std::endl;
  264. fout << "# Set the install prefix" << std::endl
  265. << "IF(NOT CMAKE_INSTALL_PREFIX)" << std::endl
  266. << " SET(CMAKE_INSTALL_PREFIX \"" << prefix << "\")" << std::endl
  267. << "ENDIF(NOT CMAKE_INSTALL_PREFIX)" << std::endl
  268. << std::endl;
  269. std::vector<std::string> configurationTypes;
  270. if(const char* types = m_Makefile->GetDefinition("CMAKE_CONFIGURATION_TYPES"))
  271. {
  272. cmSystemTools::ExpandListArgument(types, configurationTypes);
  273. }
  274. const char* config = 0;
  275. if(configurationTypes.empty())
  276. {
  277. config = m_Makefile->GetDefinition("CMAKE_BUILD_TYPE");
  278. }
  279. fout <<
  280. "# Set the install configuration name.\n"
  281. "IF(NOT CMAKE_INSTALL_CONFIG_NAME)\n"
  282. " IF(BUILD_TYPE)\n"
  283. " STRING(REGEX REPLACE \"^[^A-Za-z0-9_]+\" \"\"\n"
  284. " CMAKE_INSTALL_CONFIG_NAME \"${BUILD_TYPE}\")\n"
  285. " ELSE(BUILD_TYPE)\n"
  286. " SET(CMAKE_INSTALL_CONFIG_NAME Release)\n"
  287. " ENDIF(BUILD_TYPE)\n"
  288. " MESSAGE(STATUS \"Install configuration: \\\"${CMAKE_INSTALL_CONFIG_NAME}\\\"\")\n"
  289. "ENDIF(NOT CMAKE_INSTALL_CONFIG_NAME)\n"
  290. "\n";
  291. std::string libOutPath = "";
  292. if (m_Makefile->GetDefinition("LIBRARY_OUTPUT_PATH"))
  293. {
  294. libOutPath = m_Makefile->GetDefinition("LIBRARY_OUTPUT_PATH");
  295. if(libOutPath.size())
  296. {
  297. if(libOutPath[libOutPath.size() -1] != '/')
  298. {
  299. libOutPath += "/";
  300. }
  301. }
  302. }
  303. std::string exeOutPath = "";
  304. if (m_Makefile->GetDefinition("EXECUTABLE_OUTPUT_PATH"))
  305. {
  306. exeOutPath =
  307. m_Makefile->GetDefinition("EXECUTABLE_OUTPUT_PATH");
  308. if(exeOutPath.size())
  309. {
  310. if(exeOutPath[exeOutPath.size() -1] != '/')
  311. {
  312. exeOutPath += "/";
  313. }
  314. }
  315. }
  316. if ( libOutPath.size() == 0 )
  317. {
  318. // LIBRARY_OUTPUT_PATH not defined
  319. libOutPath = currdir + "/";
  320. }
  321. if ( exeOutPath.size() == 0 )
  322. {
  323. // EXECUTABLE_OUTPUT_PATH not defined
  324. exeOutPath = currdir + "/";
  325. }
  326. // Include user-specified install scripts.
  327. std::vector<std::string> const& installScripts =
  328. m_Makefile->GetInstallScripts();
  329. for(std::vector<std::string>::const_iterator s = installScripts.begin();
  330. s != installScripts.end(); ++s)
  331. {
  332. fout << "INCLUDE(\"" << s->c_str() << "\")" << std::endl;
  333. }
  334. std::string destination;
  335. for(cmTargets::iterator l = tgts.begin();
  336. l != tgts.end(); l++)
  337. {
  338. const char* preinstall = l->second.GetProperty("PRE_INSTALL_SCRIPT");
  339. const char* postinstall = l->second.GetProperty("POST_INSTALL_SCRIPT");
  340. if ( preinstall )
  341. {
  342. fout << "INCLUDE(\"" << preinstall << "\")" << std::endl;
  343. }
  344. if (l->second.GetInstallPath() != "")
  345. {
  346. destination = "${CMAKE_INSTALL_PREFIX}" + l->second.GetInstallPath();
  347. cmSystemTools::ConvertToUnixSlashes(destination);
  348. const char* dest = destination.c_str();
  349. int type = l->second.GetType();
  350. std::string fname;
  351. std::string props;
  352. const char* properties = 0;
  353. const char* files;
  354. this->PrepareInstallReference(fout, l->second, configurationTypes);
  355. // now install the target
  356. switch (type)
  357. {
  358. case cmTarget::SHARED_LIBRARY:
  359. {
  360. // Special code to handle DLL
  361. fname = l->second.GetFullName();
  362. std::string ext = cmSystemTools::GetFilenameLastExtension(fname);
  363. ext = cmSystemTools::LowerCase(ext);
  364. if ( ext == ".dll" )
  365. {
  366. // Install the .lib separately.
  367. std::string libname = libOutPath;
  368. libname += this->GetInstallReference(l->second, config,
  369. configurationTypes,
  370. true);
  371. files = libname.c_str();
  372. this->AddInstallRule(fout, dest, cmTarget::STATIC_LIBRARY, files, true);
  373. // Change the destination to the .dll destination.
  374. destination = "${CMAKE_INSTALL_PREFIX}" + l->second.GetRuntimeInstallPath();
  375. dest = destination.c_str();
  376. }
  377. else
  378. {
  379. // Add shared library installation properties.
  380. const char* lib_version = l->second.GetProperty("VERSION");
  381. const char* lib_soversion = l->second.GetProperty("SOVERSION");
  382. if(!m_Makefile->GetDefinition("CMAKE_SHARED_LIBRARY_SONAME_C_FLAG"))
  383. {
  384. // Versioning is supported only for shared libraries and modules,
  385. // and then only when the platform supports an soname flag.
  386. lib_version = 0;
  387. lib_soversion = 0;
  388. }
  389. if ( lib_version )
  390. {
  391. props += " VERSION ";
  392. props += lib_version;
  393. }
  394. if ( lib_soversion )
  395. {
  396. props += " SOVERSION ";
  397. props += lib_soversion;
  398. }
  399. properties = props.c_str();
  400. }
  401. }
  402. /* No "break;" because we want to install the library here. */
  403. case cmTarget::STATIC_LIBRARY:
  404. case cmTarget::MODULE_LIBRARY:
  405. {
  406. fname = libOutPath;
  407. fname += this->GetInstallReference(l->second, config,
  408. configurationTypes);
  409. files = fname.c_str();
  410. this->AddInstallRule(fout, dest, type, files, false, properties);
  411. }
  412. break;
  413. case cmTarget::EXECUTABLE:
  414. {
  415. #if defined(_WIN32) && !defined(__CYGWIN__)
  416. const char* exe_version = 0;
  417. #else
  418. const char* exe_version = l->second.GetProperty("VERSION");
  419. #endif
  420. if(exe_version)
  421. {
  422. props += " VERSION ";
  423. props += exe_version;
  424. properties = props.c_str();
  425. }
  426. std::string exeName =
  427. this->GetInstallReference(l->second, config, configurationTypes);
  428. fname = exeOutPath;
  429. fname += exeName;
  430. if(l->second.GetPropertyAsBool("MACOSX_BUNDLE"))
  431. {
  432. std::string plist = fname;
  433. plist += ".app/Contents/Info.plist";
  434. fname += ".app/Contents/MacOS/";
  435. fname += exeName;
  436. files = fname.c_str();
  437. std::string bdest = dest;
  438. bdest += "/";
  439. bdest += exeName;
  440. std::string pdest = bdest;
  441. pdest += ".app/Contents";
  442. bdest += ".app/Contents/MacOS";
  443. // first install the actual executable
  444. this->AddInstallRule(fout, bdest.c_str(), type, files,
  445. false, properties);
  446. files = plist.c_str();
  447. // now install the Info.plist file
  448. this->AddInstallRule(fout, pdest.c_str(),
  449. cmTarget::INSTALL_FILES, files);
  450. }
  451. else
  452. {
  453. files = fname.c_str();
  454. this->AddInstallRule(fout, dest, type, files, false,
  455. properties);
  456. }
  457. }
  458. break;
  459. case cmTarget::INSTALL_FILES:
  460. {
  461. std::string sourcePath = m_Makefile->GetCurrentDirectory();
  462. std::string binaryPath = m_Makefile->GetCurrentOutputDirectory();
  463. sourcePath += "/";
  464. binaryPath += "/";
  465. const std::vector<std::string> &sf = l->second.GetSourceLists();
  466. std::vector<std::string>::const_iterator i;
  467. for (i = sf.begin(); i != sf.end(); ++i)
  468. {
  469. std::string f = *i;
  470. if(f.substr(0, sourcePath.length()) == sourcePath)
  471. {
  472. f = f.substr(sourcePath.length());
  473. }
  474. else if(f.substr(0, binaryPath.length()) == binaryPath)
  475. {
  476. f = f.substr(binaryPath.length());
  477. }
  478. files = i->c_str();
  479. this->AddInstallRule(fout, dest, type, files);
  480. }
  481. }
  482. break;
  483. case cmTarget::INSTALL_PROGRAMS:
  484. {
  485. std::string sourcePath = m_Makefile->GetCurrentDirectory();
  486. std::string binaryPath = m_Makefile->GetCurrentOutputDirectory();
  487. sourcePath += "/";
  488. binaryPath += "/";
  489. const std::vector<std::string> &sf = l->second.GetSourceLists();
  490. std::vector<std::string>::const_iterator i;
  491. for (i = sf.begin(); i != sf.end(); ++i)
  492. {
  493. std::string f = *i;
  494. if(f.substr(0, sourcePath.length()) == sourcePath)
  495. {
  496. f = f.substr(sourcePath.length());
  497. }
  498. else if(f.substr(0, binaryPath.length()) == binaryPath)
  499. {
  500. f = f.substr(binaryPath.length());
  501. }
  502. files = i->c_str();
  503. this->AddInstallRule(fout, dest, type, files);
  504. }
  505. }
  506. break;
  507. case cmTarget::UTILITY:
  508. default:
  509. break;
  510. }
  511. }
  512. if ( postinstall )
  513. {
  514. fout << "INCLUDE(\"" << postinstall << "\")" << std::endl;
  515. }
  516. }
  517. if ( this->Children.size())
  518. {
  519. std::vector<cmLocalGenerator*>::const_iterator i = this->Children.begin();
  520. for(; i != this->Children.end(); ++i)
  521. {
  522. std::string odir = (*i)->GetMakefile()->GetStartOutputDirectory();
  523. cmSystemTools::ConvertToUnixSlashes(odir);
  524. fout << "INCLUDE(\"" << odir.c_str()
  525. << "/cmake_install.cmake\")" << std::endl;
  526. }
  527. fout << std::endl;;
  528. }
  529. if ( toplevel_install )
  530. {
  531. fout << "FILE(WRITE \"" << homedir.c_str() << "/install_manifest.txt\" "
  532. << "\"\")" << std::endl;
  533. fout << "FOREACH(file ${CMAKE_INSTALL_MANIFEST_FILES})" << std::endl
  534. << " FILE(APPEND \"" << homedir.c_str() << "/install_manifest.txt\" "
  535. << "\"${file}\\n\")" << std::endl
  536. << "ENDFOREACH(file)" << std::endl;
  537. }
  538. }
  539. void cmLocalGenerator::AddInstallRule(std::ostream& fout, const char* dest,
  540. int type, const char* files, bool optional /* = false */, const char* properties /* = 0 */)
  541. {
  542. std::string sfiles = files;
  543. std::string destination = dest;
  544. std::string stype;
  545. switch ( type )
  546. {
  547. case cmTarget::INSTALL_PROGRAMS: stype = "PROGRAM"; break;
  548. case cmTarget::EXECUTABLE: stype = "EXECUTABLE"; break;
  549. case cmTarget::STATIC_LIBRARY: stype = "STATIC_LIBRARY"; break;
  550. case cmTarget::SHARED_LIBRARY: stype = "SHARED_LIBRARY"; break;
  551. case cmTarget::MODULE_LIBRARY: stype = "MODULE"; break;
  552. case cmTarget::INSTALL_FILES:
  553. default: stype = "FILE"; break;
  554. }
  555. std::string fname = cmSystemTools::GetFilenameName(sfiles.c_str());
  556. fout
  557. << "MESSAGE(STATUS \"Installing " << destination.c_str()
  558. << "/" << fname.c_str() << "\")\n"
  559. << "FILE(INSTALL DESTINATION \"" << destination.c_str()
  560. << "\" TYPE " << stype.c_str() << (optional?" OPTIONAL":"") ;
  561. if ( properties && *properties )
  562. {
  563. fout << " PROPERTIES" << properties;
  564. }
  565. fout
  566. << " FILES \"" << sfiles.c_str() << "\")\n";
  567. }
  568. void cmLocalGenerator::AddCustomCommandToCreateObject(const char* ofname,
  569. const char* lang,
  570. cmSourceFile& source,
  571. cmTarget& )
  572. {
  573. std::string objectFile = this->Convert(ofname,START_OUTPUT,SHELL);
  574. std::string sourceFile =
  575. this->Convert(source.GetFullPath().c_str(),START_OUTPUT,SHELL,true);
  576. std::string varString = "CMAKE_";
  577. varString += lang;
  578. varString += "_COMPILE_OBJECT";
  579. std::vector<std::string> rules;
  580. rules.push_back(m_Makefile->GetRequiredDefinition(varString.c_str()));
  581. varString = "CMAKE_";
  582. varString += lang;
  583. varString += "_FLAGS";
  584. std::string flags;
  585. flags += m_Makefile->GetSafeDefinition(varString.c_str());
  586. flags += " ";
  587. flags += this->GetIncludeFlags(lang);
  588. std::vector<std::string> commands;
  589. cmSystemTools::ExpandList(rules, commands);
  590. for(std::vector<std::string>::iterator i = commands.begin();
  591. i != commands.end(); ++i)
  592. {
  593. this->ExpandRuleVariables(*i,
  594. lang,
  595. 0, // no objects
  596. 0, // no target
  597. 0, // no link libs
  598. sourceFile.c_str(),
  599. objectFile.c_str(),
  600. flags.c_str());
  601. }
  602. std::vector<std::string> sourceAndDeps;
  603. sourceAndDeps.push_back(sourceFile);
  604. if(commands.size() > 1)
  605. {
  606. cmSystemTools::Error("Currently custom rules can only have one command sorry ");
  607. }
  608. // Check for extra object-file dependencies.
  609. std::vector<std::string> depends;
  610. const char* additionalDeps = source.GetProperty("OBJECT_DEPENDS");
  611. if(additionalDeps)
  612. {
  613. cmSystemTools::ExpandListArgument(additionalDeps, depends);
  614. for(std::vector<std::string>::iterator i = depends.begin();
  615. i != depends.end(); ++i)
  616. {
  617. sourceAndDeps.push_back(this->Convert(i->c_str(),START_OUTPUT,SHELL));
  618. }
  619. }
  620. #if 0
  621. std::string command;
  622. std::string args;
  623. cmSystemTools::SplitProgramFromArgs(commands[0].c_str(), command, args);
  624. std::vector<std::string> argsv;
  625. argsv.push_back(args);
  626. m_Makefile->AddCustomCommandToOutput(ofname,
  627. command.c_str(),
  628. argsv,
  629. source.GetFullPath().c_str(),
  630. sourceAndDeps,
  631. "build from source");
  632. #endif
  633. }
  634. void cmLocalGenerator::AddBuildTargetRule(const char* llang, cmTarget& target)
  635. {
  636. cmStdString objs;
  637. std::vector<std::string> objVector;
  638. // Add all the sources outputs to the depends of the target
  639. std::vector<cmSourceFile*>& classes = target.GetSourceFiles();
  640. for(std::vector<cmSourceFile*>::iterator i = classes.begin();
  641. i != classes.end(); ++i)
  642. {
  643. if(!(*i)->GetPropertyAsBool("HEADER_FILE_ONLY") &&
  644. !(*i)->GetCustomCommand())
  645. {
  646. std::string outExt =
  647. m_GlobalGenerator->GetLanguageOutputExtensionFromExtension(
  648. (*i)->GetSourceExtension().c_str());
  649. if(outExt.size() && !(*i)->GetPropertyAsBool("EXTERNAL_OBJECT") )
  650. {
  651. std::string ofname = m_Makefile->GetCurrentOutputDirectory();
  652. ofname += "/";
  653. ofname += (*i)->GetSourceName() + outExt;
  654. objVector.push_back(ofname);
  655. this->AddCustomCommandToCreateObject(ofname.c_str(), llang, *(*i), target);
  656. objs += this->Convert(ofname.c_str(),START_OUTPUT,MAKEFILE);
  657. objs += " ";
  658. }
  659. }
  660. }
  661. std::string createRule = "CMAKE_";
  662. createRule += llang;
  663. createRule += target.GetCreateRuleVariable();
  664. std::string targetName = target.GetFullName();
  665. // Executable :
  666. // Shared Library:
  667. // Static Library:
  668. // Shared Module:
  669. std::string linkLibs; // should be set
  670. std::string flags; // should be set
  671. std::string linkFlags; // should be set
  672. this->GetTargetFlags(linkLibs, flags, linkFlags, target);
  673. std::string rule = m_Makefile->GetRequiredDefinition(createRule.c_str());
  674. this->ExpandRuleVariables(rule,
  675. llang, // language
  676. objs.c_str(), // objects
  677. targetName.c_str(), // target
  678. linkLibs.c_str(), // link libs
  679. 0, // source
  680. 0, // object
  681. flags.c_str(), // flags
  682. 0, // objects quoted
  683. 0, // target so name,
  684. linkFlags.c_str() // link flags
  685. );
  686. #if 0
  687. std::string command;
  688. std::string args;
  689. cmSystemTools::SplitProgramFromArgs(rule.c_str(), command, args);
  690. // Just like ADD_CUSTOM_TARGET(foo ALL DEPENDS a.o b.o)
  691. // Add a custom command for generating each .o file
  692. cmCustomCommand cc(command.c_str(), args.c_str(), objVector,
  693. targetName.c_str(), 0);
  694. target.GetPostBuildCommands().push_back(cc);
  695. #endif
  696. }
  697. void cmLocalGenerator::CreateCustomTargetsAndCommands(std::set<cmStdString> const& lang)
  698. {
  699. cmTargets &tgts = m_Makefile->GetTargets();
  700. for(cmTargets::iterator l = tgts.begin();
  701. l != tgts.end(); l++)
  702. {
  703. cmTarget& target = l->second;
  704. switch(target.GetType())
  705. {
  706. case cmTarget::STATIC_LIBRARY:
  707. case cmTarget::SHARED_LIBRARY:
  708. case cmTarget::MODULE_LIBRARY:
  709. case cmTarget::EXECUTABLE:
  710. {
  711. const char* llang = target.GetLinkerLanguage(this->GetGlobalGenerator());
  712. if(!llang)
  713. {
  714. cmSystemTools::Error("CMake can not determine linker language for target:",
  715. target.GetName());
  716. return;
  717. }
  718. // if the language is not in the set lang then create custom
  719. // commands to build the target
  720. if(lang.count(llang) == 0)
  721. {
  722. this->AddBuildTargetRule(llang, target);
  723. }
  724. }
  725. break;
  726. case cmTarget::UTILITY:
  727. case cmTarget::INSTALL_FILES:
  728. case cmTarget::INSTALL_PROGRAMS:
  729. break;
  730. }
  731. }
  732. }
  733. // List of variables that are replaced when
  734. // rules are expanced. These variables are
  735. // replaced in the form <var> with GetSafeDefinition(var).
  736. // ${LANG} is replaced in the variable first with all enabled
  737. // languages.
  738. static const char* ruleReplaceVars[] =
  739. {
  740. "CMAKE_${LANG}_COMPILER",
  741. "CMAKE_SHARED_LIBRARY_CREATE_${LANG}_FLAGS",
  742. "CMAKE_SHARED_MODULE_CREATE_${LANG}_FLAGS",
  743. "CMAKE_SHARED_MODULE_${LANG}_FLAGS",
  744. "CMAKE_SHARED_LIBRARY_${LANG}_FLAGS",
  745. "CMAKE_${LANG}_LINK_FLAGS",
  746. "CMAKE_SHARED_LIBRARY_SONAME_${LANG}_FLAG",
  747. "CMAKE_${LANG}_ARCHIVE",
  748. "CMAKE_AR",
  749. "CMAKE_CURRENT_SOURCE_DIR",
  750. "CMAKE_CURRENT_BINARY_DIR",
  751. "CMAKE_RANLIB",
  752. 0
  753. };
  754. std::string
  755. cmLocalGenerator::ExpandRuleVariable(std::string const& variable,
  756. const char* lang,
  757. const char* objects,
  758. const char* target,
  759. const char* linkLibs,
  760. const char* source,
  761. const char* object,
  762. const char* flags,
  763. const char* objectsquoted,
  764. const char* targetSOName,
  765. const char* linkFlags)
  766. {
  767. if(linkFlags)
  768. {
  769. if(variable == "LINK_FLAGS")
  770. {
  771. return linkFlags;
  772. }
  773. }
  774. if(flags)
  775. {
  776. if(variable == "FLAGS")
  777. {
  778. return flags;
  779. }
  780. }
  781. if(source)
  782. {
  783. if(variable == "SOURCE")
  784. {
  785. return source;
  786. }
  787. }
  788. if(object)
  789. {
  790. if(variable == "OBJECT")
  791. {
  792. return object;
  793. }
  794. }
  795. if(objects)
  796. {
  797. if(variable == "OBJECTS")
  798. {
  799. return objects;
  800. }
  801. }
  802. if(objectsquoted)
  803. {
  804. if(variable == "OBJECTS_QUOTED")
  805. {
  806. return objectsquoted;
  807. }
  808. }
  809. if(target)
  810. {
  811. if(variable == "TARGET_QUOTED")
  812. {
  813. std::string targetQuoted = target;
  814. if(targetQuoted.size() && targetQuoted[0] != '\"')
  815. {
  816. targetQuoted = '\"';
  817. targetQuoted += target;
  818. targetQuoted += '\"';
  819. return targetQuoted;
  820. }
  821. }
  822. if(variable == "TARGET")
  823. {
  824. return target;
  825. }
  826. if(variable == "TARGET_BASE")
  827. {
  828. // Strip the last extension off the target name.
  829. std::string targetBase = target;
  830. std::string::size_type pos = targetBase.rfind(".");
  831. if(pos != targetBase.npos)
  832. {
  833. return targetBase.substr(0, pos);
  834. }
  835. else
  836. {
  837. return targetBase;
  838. }
  839. }
  840. }
  841. if(targetSOName)
  842. {
  843. if(variable == "TARGET_SONAME")
  844. {
  845. if(lang)
  846. {
  847. std::string name = "CMAKE_SHARED_LIBRARY_SONAME_";
  848. name += lang;
  849. name += "_FLAG";
  850. if(m_Makefile->GetDefinition(name.c_str()))
  851. {
  852. return targetSOName;
  853. }
  854. }
  855. return "";
  856. }
  857. }
  858. if(linkLibs)
  859. {
  860. if(variable == "LINK_LIBRARIES")
  861. {
  862. return linkLibs;
  863. }
  864. }
  865. std::vector<std::string> enabledLanguages;
  866. m_GlobalGenerator->GetEnabledLanguages(enabledLanguages);
  867. // loop over language specific replace variables
  868. int pos = 0;
  869. while(ruleReplaceVars[pos])
  870. {
  871. for(std::vector<std::string>::iterator i = enabledLanguages.begin();
  872. i != enabledLanguages.end(); ++i)
  873. {
  874. lang = i->c_str();
  875. std::string actualReplace = ruleReplaceVars[pos];
  876. // If this is the compiler then look for the extra variable
  877. // _COMPILER_ARG1 which must be the first argument to the compiler
  878. const char* compilerArg1 = 0;
  879. if(actualReplace == "CMAKE_${LANG}_COMPILER")
  880. {
  881. std::string arg1 = actualReplace + "_ARG1";
  882. cmSystemTools::ReplaceString(arg1, "${LANG}", lang);
  883. compilerArg1 = m_Makefile->GetDefinition(arg1.c_str());
  884. }
  885. if(actualReplace.find("${LANG}") != actualReplace.npos)
  886. {
  887. cmSystemTools::ReplaceString(actualReplace, "${LANG}", lang);
  888. }
  889. if(actualReplace == variable)
  890. {
  891. std::string replace = m_Makefile->GetSafeDefinition(variable.c_str());
  892. // if the variable is not a FLAG then treat it like a path
  893. if(variable.find("_FLAG") == variable.npos)
  894. {
  895. std::string ret = this->ConvertToOutputForExisting(replace.c_str());
  896. // if there is a required first argument to the compiler add it to the compiler string
  897. if(compilerArg1)
  898. {
  899. ret += " ";
  900. ret += compilerArg1;
  901. }
  902. return ret;
  903. }
  904. return replace;
  905. }
  906. }
  907. pos++;
  908. }
  909. return variable;
  910. }
  911. void
  912. cmLocalGenerator::ExpandRuleVariables(std::string& s,
  913. const char* lang,
  914. const char* objects,
  915. const char* target,
  916. const char* linkLibs,
  917. const char* source,
  918. const char* object,
  919. const char* flags,
  920. const char* objectsquoted,
  921. const char* targetSOName,
  922. const char* linkFlags)
  923. {
  924. std::vector<std::string> enabledLanguages;
  925. m_GlobalGenerator->GetEnabledLanguages(enabledLanguages);
  926. std::string::size_type start = s.find('<');
  927. // no variables to expand
  928. if(start == s.npos)
  929. {
  930. return;
  931. }
  932. std::string::size_type pos = 0;
  933. std::string expandedInput;
  934. while(start != s.npos && start < s.size()-2)
  935. {
  936. std::string::size_type end = s.find('>', start);
  937. // if we find a < with no > we are done
  938. if(end == s.npos)
  939. {
  940. return;
  941. }
  942. char c = s[start+1];
  943. // if the next char after the < is not A-Za-z then
  944. // skip it and try to find the next < in the string
  945. if(!isalpha(c))
  946. {
  947. start = s.find('<', start+1);
  948. }
  949. else
  950. {
  951. // extract the var
  952. std::string var = s.substr(start+1, end - start-1);
  953. std::string replace = this->ExpandRuleVariable(var, lang, objects,
  954. target, linkLibs,
  955. source, object, flags,
  956. objectsquoted,
  957. targetSOName,
  958. linkFlags);
  959. expandedInput += s.substr(pos, start-pos);
  960. expandedInput += replace;
  961. // move to next one
  962. start = s.find('<', start+var.size()+2);
  963. pos = end+1;
  964. }
  965. }
  966. // add the rest of the input
  967. expandedInput += s.substr(pos, s.size()-pos);
  968. s = expandedInput;
  969. }
  970. std::string
  971. cmLocalGenerator::ConvertToOutputForExisting(const char* p)
  972. {
  973. std::string ret = this->Convert(p, START_OUTPUT, SHELL, true);
  974. // if there are spaces in the path, then get the short path version
  975. // if there is one
  976. if(ret.find(' ') != std::string::npos)
  977. {
  978. if(cmSystemTools::FileExists(p))
  979. {
  980. if(!cmSystemTools::GetShortPath(ret.c_str(), ret))
  981. {
  982. ret = this->Convert(p,START_OUTPUT,MAKEFILE,true);
  983. }
  984. }
  985. }
  986. return ret;
  987. }
  988. const char* cmLocalGenerator::GetIncludeFlags(const char* lang)
  989. {
  990. if(!lang)
  991. {
  992. return "";
  993. }
  994. if(m_LanguageToIncludeFlags.count(lang))
  995. {
  996. return m_LanguageToIncludeFlags[lang].c_str();
  997. }
  998. cmOStringStream includeFlags;
  999. std::vector<std::string> includes;
  1000. this->GetIncludeDirectories(includes);
  1001. std::vector<std::string>::iterator i;
  1002. std::string flagVar = "CMAKE_INCLUDE_FLAG_";
  1003. flagVar += lang;
  1004. const char* includeFlag = m_Makefile->GetDefinition(flagVar.c_str());
  1005. flagVar = "CMAKE_INCLUDE_FLAG_SEP_";
  1006. flagVar += lang;
  1007. const char* sep = m_Makefile->GetDefinition(flagVar.c_str());
  1008. bool quotePaths = false;
  1009. if(m_Makefile->GetDefinition("CMAKE_QUOTE_INCLUDE_PATHS"))
  1010. {
  1011. quotePaths = true;
  1012. }
  1013. bool repeatFlag = true; // should the include flag be repeated like ie. -IA -IB
  1014. if(!sep)
  1015. {
  1016. sep = " ";
  1017. }
  1018. else
  1019. {
  1020. // if there is a separator then the flag is not repeated but is only given once
  1021. // i.e. -classpath a:b:c
  1022. repeatFlag = false;
  1023. }
  1024. bool flagUsed = false;
  1025. std::set<cmStdString> emitted;
  1026. for(i = includes.begin(); i != includes.end(); ++i)
  1027. {
  1028. #ifdef __APPLE__
  1029. if(cmSystemTools::IsPathToFramework(i->c_str()))
  1030. {
  1031. std::string frameworkDir = *i;
  1032. frameworkDir += "/../";
  1033. frameworkDir = cmSystemTools::CollapseFullPath(frameworkDir.c_str());
  1034. if(emitted.insert(frameworkDir).second)
  1035. {
  1036. includeFlags << "-F" << this->ConvertToOutputForExisting(frameworkDir.c_str()) << " ";
  1037. }
  1038. continue;
  1039. }
  1040. #endif
  1041. std::string include = *i;
  1042. if(!flagUsed || repeatFlag)
  1043. {
  1044. includeFlags << includeFlag;
  1045. flagUsed = true;
  1046. }
  1047. std::string includePath = this->ConvertToOutputForExisting(i->c_str());
  1048. if(quotePaths && includePath.size() && includePath[0] != '\"')
  1049. {
  1050. includeFlags << "\"";
  1051. }
  1052. includeFlags << includePath;
  1053. if(quotePaths && includePath.size() && includePath[0] != '\"')
  1054. {
  1055. includeFlags << "\"";
  1056. }
  1057. includeFlags << sep;
  1058. }
  1059. std::string flags = includeFlags.str();
  1060. // remove trailing separators
  1061. if((sep[0] != ' ') && flags[flags.size()-1] == sep[0])
  1062. {
  1063. flags[flags.size()-1] = ' ';
  1064. }
  1065. flags += m_Makefile->GetDefineFlags();
  1066. m_LanguageToIncludeFlags[lang] = flags;
  1067. return m_LanguageToIncludeFlags[lang].c_str();
  1068. }
  1069. //----------------------------------------------------------------------------
  1070. void cmLocalGenerator::GetIncludeDirectories(std::vector<std::string>& dirs)
  1071. {
  1072. // Output Include paths
  1073. std::set<cmStdString> implicitIncludes;
  1074. // CMake versions below 2.0 would add the source tree to the -I path
  1075. // automatically. Preserve compatibility.
  1076. bool includeSourceDir = false;
  1077. const char* versionValue =
  1078. m_Makefile->GetDefinition("CMAKE_BACKWARDS_COMPATIBILITY");
  1079. if(versionValue)
  1080. {
  1081. int major = 0;
  1082. int minor = 0;
  1083. if(sscanf(versionValue, "%d.%d", &major, &minor) == 2 && major < 2)
  1084. {
  1085. includeSourceDir = true;
  1086. }
  1087. }
  1088. const char* vtkSourceDir =
  1089. m_Makefile->GetDefinition("VTK_SOURCE_DIR");
  1090. if(vtkSourceDir)
  1091. {
  1092. // Special hack for VTK 4.0 - 4.4.
  1093. const char* vtk_major = m_Makefile->GetDefinition("VTK_MAJOR_VERSION");
  1094. const char* vtk_minor = m_Makefile->GetDefinition("VTK_MINOR_VERSION");
  1095. vtk_major = vtk_major? vtk_major : "4";
  1096. vtk_minor = vtk_minor? vtk_minor : "4";
  1097. int major = 0;
  1098. int minor = 0;
  1099. if(sscanf(vtk_major, "%d", &major) && sscanf(vtk_minor, "%d", &minor) &&
  1100. major == 4 && minor <= 4)
  1101. {
  1102. includeSourceDir = true;
  1103. }
  1104. }
  1105. if(includeSourceDir)
  1106. {
  1107. dirs.push_back(m_Makefile->GetStartDirectory());
  1108. }
  1109. // Do not explicitly add the standard include path "/usr/include".
  1110. // This can cause problems with certain standard library
  1111. // implementations because the wrong headers may be found first.
  1112. implicitIncludes.insert("/usr/include");
  1113. if(m_Makefile->GetDefinition("CMAKE_PLATFORM_IMPLICIT_INCLUDE_DIRECTORIES"))
  1114. {
  1115. std::string arg = m_Makefile->GetDefinition("CMAKE_PLATFORM_IMPLICIT_INCLUDE_DIRECTORIES");
  1116. std::vector<std::string> implicitIncludeVec;
  1117. cmSystemTools::ExpandListArgument(arg, implicitIncludeVec);
  1118. for(unsigned int k =0; k < implicitIncludeVec.size(); k++)
  1119. {
  1120. implicitIncludes.insert(implicitIncludeVec[k]);
  1121. }
  1122. }
  1123. // Construct the ordered list.
  1124. std::vector<std::string>& includes = m_Makefile->GetIncludeDirectories();
  1125. for(std::vector<std::string>::iterator i = includes.begin();
  1126. i != includes.end(); ++i)
  1127. {
  1128. if(implicitIncludes.find(*i) == implicitIncludes.end())
  1129. {
  1130. dirs.push_back(*i);
  1131. }
  1132. }
  1133. }
  1134. void cmLocalGenerator::GetTargetFlags(std::string& linkLibs,
  1135. std::string& flags,
  1136. std::string& linkFlags,
  1137. cmTarget& target)
  1138. {
  1139. std::string buildType = m_Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE");
  1140. buildType = cmSystemTools::UpperCase(buildType);
  1141. const char* libraryLinkVariable = "CMAKE_SHARED_LINKER_FLAGS"; // default to shared library
  1142. switch(target.GetType())
  1143. {
  1144. case cmTarget::STATIC_LIBRARY:
  1145. {
  1146. const char* targetLinkFlags = target.GetProperty("STATIC_LIBRARY_FLAGS");
  1147. if(targetLinkFlags)
  1148. {
  1149. linkFlags += targetLinkFlags;
  1150. linkFlags += " ";
  1151. }
  1152. }
  1153. break;
  1154. case cmTarget::MODULE_LIBRARY:
  1155. libraryLinkVariable = "CMAKE_MODULE_LINKER_FLAGS";
  1156. case cmTarget::SHARED_LIBRARY:
  1157. {
  1158. linkFlags = m_Makefile->GetSafeDefinition(libraryLinkVariable);
  1159. linkFlags += " ";
  1160. if(buildType.size())
  1161. {
  1162. std::string build = libraryLinkVariable;
  1163. build += "_";
  1164. build += buildType;
  1165. linkFlags += m_Makefile->GetSafeDefinition(build.c_str());
  1166. linkFlags += " ";
  1167. }
  1168. if(m_Makefile->IsOn("WIN32") && !(m_Makefile->IsOn("CYGWIN") || m_Makefile->IsOn("MINGW")))
  1169. {
  1170. const std::vector<cmSourceFile*>& sources = target.GetSourceFiles();
  1171. for(std::vector<cmSourceFile*>::const_iterator i = sources.begin();
  1172. i != sources.end(); ++i)
  1173. {
  1174. if((*i)->GetSourceExtension() == "def")
  1175. {
  1176. linkFlags += m_Makefile->GetSafeDefinition("CMAKE_LINK_DEF_FILE_FLAG");
  1177. linkFlags += this->Convert((*i)->GetFullPath().c_str(),START_OUTPUT,MAKEFILE);
  1178. linkFlags += " ";
  1179. }
  1180. }
  1181. }
  1182. const char* targetLinkFlags = target.GetProperty("LINK_FLAGS");
  1183. if(targetLinkFlags)
  1184. {
  1185. linkFlags += targetLinkFlags;
  1186. linkFlags += " ";
  1187. }
  1188. cmOStringStream linklibsStr;
  1189. this->OutputLinkLibraries(linklibsStr, target);
  1190. linkLibs = linklibsStr.str();
  1191. }
  1192. break;
  1193. case cmTarget::EXECUTABLE:
  1194. {
  1195. linkFlags += m_Makefile->GetSafeDefinition("CMAKE_EXE_LINKER_FLAGS");
  1196. linkFlags += " ";
  1197. if(buildType.size())
  1198. {
  1199. std::string build = "CMAKE_EXE_LINKER_FLAGS_";
  1200. build += buildType;
  1201. linkFlags += m_Makefile->GetSafeDefinition(build.c_str());
  1202. linkFlags += " ";
  1203. }
  1204. const char* linkLanguage = target.GetLinkerLanguage(this->GetGlobalGenerator());
  1205. if(!linkLanguage)
  1206. {
  1207. cmSystemTools::Error("CMake can not determine linker language for target:",
  1208. target.GetName());
  1209. return;
  1210. }
  1211. std::string langVar = "CMAKE_";
  1212. langVar += linkLanguage;
  1213. std::string flagsVar = langVar + "_FLAGS";
  1214. std::string sharedFlagsVar = "CMAKE_SHARED_LIBRARY_";
  1215. sharedFlagsVar += linkLanguage;
  1216. sharedFlagsVar += "_FLAGS";
  1217. flags += m_Makefile->GetSafeDefinition(flagsVar.c_str());
  1218. flags += " ";
  1219. flags += m_Makefile->GetSafeDefinition(sharedFlagsVar.c_str());
  1220. flags += " ";
  1221. cmOStringStream linklibs;
  1222. this->OutputLinkLibraries(linklibs, target);
  1223. linkLibs = linklibs.str();
  1224. if(cmSystemTools::IsOn(m_Makefile->GetDefinition("BUILD_SHARED_LIBS")))
  1225. {
  1226. std::string sFlagVar = std::string("CMAKE_SHARED_BUILD_") + linkLanguage
  1227. + std::string("_FLAGS");
  1228. linkFlags += m_Makefile->GetSafeDefinition(sFlagVar.c_str());
  1229. linkFlags += " ";
  1230. }
  1231. if ( target.GetPropertyAsBool("WIN32_EXECUTABLE") )
  1232. {
  1233. linkFlags += m_Makefile->GetSafeDefinition("CMAKE_CREATE_WIN32_EXE");
  1234. linkFlags += " ";
  1235. }
  1236. else
  1237. {
  1238. linkFlags += m_Makefile->GetSafeDefinition("CMAKE_CREATE_CONSOLE_EXE");
  1239. linkFlags += " ";
  1240. }
  1241. const char* targetLinkFlags = target.GetProperty("LINK_FLAGS");
  1242. if(targetLinkFlags)
  1243. {
  1244. linkFlags += targetLinkFlags;
  1245. linkFlags += " ";
  1246. }
  1247. }
  1248. break;
  1249. case cmTarget::UTILITY:
  1250. case cmTarget::INSTALL_FILES:
  1251. case cmTarget::INSTALL_PROGRAMS:
  1252. break;
  1253. }
  1254. }
  1255. /**
  1256. * Output the linking rules on a command line. For executables,
  1257. * targetLibrary should be a NULL pointer. For libraries, it should point
  1258. * to the name of the library. This will not link a library against itself.
  1259. */
  1260. void cmLocalGenerator::OutputLinkLibraries(std::ostream& fout,
  1261. cmTarget &tgt)
  1262. {
  1263. // Try to emit each search path once
  1264. std::set<cmStdString> emitted;
  1265. // Embed runtime search paths if possible and if required.
  1266. bool outputRuntime = true;
  1267. std::string runtimeFlag;
  1268. std::string runtimeSep;
  1269. std::vector<std::string> runtimeDirs;
  1270. const char* config = m_Makefile->GetDefinition("CMAKE_BUILD_TYPE");
  1271. const char* linkLanguage = tgt.GetLinkerLanguage(this->GetGlobalGenerator());
  1272. if(!linkLanguage)
  1273. {
  1274. cmSystemTools::
  1275. Error("CMake can not determine linker language for target:",
  1276. tgt.GetName());
  1277. return;
  1278. }
  1279. std::string runTimeFlagVar = "CMAKE_SHARED_LIBRARY_RUNTIME_";
  1280. runTimeFlagVar += linkLanguage;
  1281. runTimeFlagVar += "_FLAG";
  1282. std::string runTimeFlagSepVar = runTimeFlagVar + "_SEP";
  1283. runtimeFlag = m_Makefile->GetSafeDefinition(runTimeFlagVar.c_str());
  1284. runtimeSep = m_Makefile->GetSafeDefinition(runTimeFlagSepVar.c_str());
  1285. // concatenate all paths or no?
  1286. bool runtimeConcatenate = ( runtimeSep!="" );
  1287. if(runtimeFlag == "" || m_Makefile->IsOn("CMAKE_SKIP_RPATH") )
  1288. {
  1289. outputRuntime = false;
  1290. }
  1291. // Some search paths should never be emitted
  1292. emitted.insert("");
  1293. emitted.insert("/usr/lib");
  1294. std::string libPathFlag = m_Makefile->GetRequiredDefinition("CMAKE_LIBRARY_PATH_FLAG");
  1295. std::string libLinkFlag = m_Makefile->GetSafeDefinition("CMAKE_LINK_LIBRARY_FLAG");
  1296. // collect all the flags needed for linking libraries
  1297. std::string linkLibs;
  1298. // Flags to link an executable to shared libraries.
  1299. std::string linkFlagsVar = "CMAKE_SHARED_LIBRARY_LINK_";
  1300. linkFlagsVar += linkLanguage;
  1301. linkFlagsVar += "_FLAGS";
  1302. if( tgt.GetType() == cmTarget::EXECUTABLE )
  1303. {
  1304. linkLibs = m_Makefile->GetSafeDefinition(linkFlagsVar.c_str());
  1305. linkLibs += " ";
  1306. }
  1307. // Compute the link library and directory information.
  1308. std::vector<cmStdString> libNames;
  1309. std::vector<cmStdString> libDirs;
  1310. this->ComputeLinkInformation(tgt, config, libNames, libDirs);
  1311. // Append the library search path flags.
  1312. for(std::vector<cmStdString>::const_iterator libDir = libDirs.begin();
  1313. libDir != libDirs.end(); ++libDir)
  1314. {
  1315. std::string libpath = this->ConvertToOutputForExisting(libDir->c_str());
  1316. if(emitted.insert(libpath).second)
  1317. {
  1318. std::string fullLibPath;
  1319. if(!m_WindowsShell && m_UseRelativePaths)
  1320. {
  1321. fullLibPath = "\"`cd ";
  1322. }
  1323. fullLibPath += libpath;
  1324. if(!m_WindowsShell && m_UseRelativePaths)
  1325. {
  1326. fullLibPath += ";pwd`\"";
  1327. }
  1328. std::string::size_type pos = libDir->find(libPathFlag.c_str());
  1329. if((pos == std::string::npos || pos > 0)
  1330. && libDir->find("${") == std::string::npos)
  1331. {
  1332. linkLibs += libPathFlag;
  1333. if(outputRuntime)
  1334. {
  1335. runtimeDirs.push_back( fullLibPath );
  1336. }
  1337. }
  1338. linkLibs += fullLibPath;
  1339. linkLibs += " ";
  1340. }
  1341. }
  1342. // Append the link libraries.
  1343. for(std::vector<cmStdString>::iterator lib = libNames.begin();
  1344. lib != libNames.end(); ++lib)
  1345. {
  1346. linkLibs += *lib;
  1347. linkLibs += " ";
  1348. }
  1349. fout << linkLibs;
  1350. if(outputRuntime && runtimeDirs.size()>0)
  1351. {
  1352. // For the runtime search directories, do a "-Wl,-rpath,a:b:c" or
  1353. // a "-R a -R b -R c" type link line
  1354. fout << runtimeFlag;
  1355. std::vector<std::string>::iterator itr = runtimeDirs.begin();
  1356. fout << *itr;
  1357. ++itr;
  1358. for( ; itr != runtimeDirs.end(); ++itr )
  1359. {
  1360. if(runtimeConcatenate)
  1361. {
  1362. fout << runtimeSep << *itr;
  1363. }
  1364. else
  1365. {
  1366. fout << " " << runtimeFlag << *itr;
  1367. }
  1368. }
  1369. fout << " ";
  1370. }
  1371. if(m_Makefile->GetDefinition("CMAKE_STANDARD_LIBRARIES"))
  1372. {
  1373. fout << m_Makefile->GetDefinition("CMAKE_STANDARD_LIBRARIES") << " ";
  1374. }
  1375. }
  1376. //----------------------------------------------------------------------------
  1377. void
  1378. cmLocalGenerator::ComputeLinkInformation(cmTarget& target,
  1379. const char* config,
  1380. std::vector<cmStdString>& outLibs,
  1381. std::vector<cmStdString>& outDirs,
  1382. std::vector<cmStdString>* fullPathLibs)
  1383. {
  1384. // Compute which library configuration to link.
  1385. cmTarget::LinkLibraryType linkType = cmTarget::OPTIMIZED;
  1386. if(config && cmSystemTools::UpperCase(config) == "DEBUG")
  1387. {
  1388. linkType = cmTarget::DEBUG;
  1389. }
  1390. // Get the list of libraries against which this target wants to link.
  1391. std::vector<std::string> linkLibraries;
  1392. const cmTarget::LinkLibraries& inLibs = target.GetLinkLibraries();
  1393. for(cmTarget::LinkLibraries::const_iterator j = inLibs.begin();
  1394. j != inLibs.end(); ++j)
  1395. {
  1396. // For backwards compatibility variables may have been expanded
  1397. // inside library names. Clean up the resulting name.
  1398. std::string lib = j->first;
  1399. std::string::size_type pos = lib.find_first_not_of(" \t\r\n");
  1400. if(pos != lib.npos)
  1401. {
  1402. lib = lib.substr(pos, lib.npos);
  1403. }
  1404. pos = lib.find_last_not_of(" \t\r\n");
  1405. if(pos != lib.npos)
  1406. {
  1407. lib = lib.substr(0, pos+1);
  1408. }
  1409. if(lib.empty())
  1410. {
  1411. continue;
  1412. }
  1413. // Link to a library if it is not the same target and is meant for
  1414. // this configuration type.
  1415. if((target.GetType() == cmTarget::EXECUTABLE ||
  1416. lib != target.GetName()) &&
  1417. (j->second == cmTarget::GENERAL || j->second == linkType))
  1418. {
  1419. // Compute the proper name to use to link this library.
  1420. cmTarget* tgt = m_GlobalGenerator->FindTarget(0, lib.c_str());
  1421. if(tgt)
  1422. {
  1423. // This is a CMake target. Ask the target for its real name.
  1424. linkLibraries.push_back(tgt->GetFullName(config));
  1425. if(fullPathLibs)
  1426. {
  1427. fullPathLibs->push_back(tgt->GetFullPath(config));
  1428. }
  1429. }
  1430. else
  1431. {
  1432. // This is not a CMake target. Use the name given.
  1433. linkLibraries.push_back(lib);
  1434. }
  1435. }
  1436. }
  1437. // Get the list of directories the target wants to search for libraries.
  1438. const std::vector<std::string>&
  1439. linkDirectories = target.GetLinkDirectories();
  1440. // Compute the link directory order needed to link the libraries.
  1441. cmOrderLinkDirectories orderLibs;
  1442. orderLibs.SetLinkPrefix(
  1443. m_Makefile->GetDefinition("CMAKE_STATIC_LIBRARY_PREFIX"));
  1444. orderLibs.AddLinkExtension(
  1445. m_Makefile->GetDefinition("CMAKE_STATIC_LIBRARY_SUFFIX"));
  1446. orderLibs.AddLinkExtension(
  1447. m_Makefile->GetDefinition("CMAKE_SHARED_LIBRARY_SUFFIX"));
  1448. orderLibs.AddLinkExtension(
  1449. m_Makefile->GetDefinition("CMAKE_LINK_LIBRARY_SUFFIX"));
  1450. orderLibs.SetLinkInformation(target.GetName(),
  1451. linkLibraries,
  1452. linkDirectories);
  1453. orderLibs.DetermineLibraryPathOrder();
  1454. std::vector<cmStdString> orderedLibs;
  1455. orderLibs.GetLinkerInformation(outDirs, orderedLibs);
  1456. if(fullPathLibs)
  1457. {
  1458. orderLibs.GetFullPathLibraries(*fullPathLibs);
  1459. }
  1460. // Make sure libraries are linked with the proper syntax.
  1461. std::string libLinkFlag =
  1462. m_Makefile->GetSafeDefinition("CMAKE_LINK_LIBRARY_FLAG");
  1463. std::string libLinkSuffix =
  1464. m_Makefile->GetSafeDefinition("CMAKE_LINK_LIBRARY_SUFFIX");
  1465. for(std::vector<cmStdString>::iterator l = orderedLibs.begin();
  1466. l != orderedLibs.end(); ++l)
  1467. {
  1468. std::string lib = *l;
  1469. if(lib[0] == '-' || lib[0] == '$' || lib[0] == '`')
  1470. {
  1471. // The library is linked with special syntax by the user.
  1472. outLibs.push_back(lib);
  1473. }
  1474. else
  1475. {
  1476. // Generate the proper link syntax.
  1477. lib = libLinkFlag;
  1478. lib += *l;
  1479. lib += libLinkSuffix;
  1480. outLibs.push_back(lib);
  1481. }
  1482. }
  1483. }
  1484. //----------------------------------------------------------------------------
  1485. std::string
  1486. cmLocalGenerator::GetInstallReference(cmTarget& target, const char* config,
  1487. std::vector<std::string> const& configs,
  1488. bool implib /* = false*/)
  1489. {
  1490. if(configs.empty())
  1491. {
  1492. std::string ref = target.GetFullName(config);
  1493. if(implib)
  1494. {
  1495. ref = cmSystemTools::GetFilenameWithoutLastExtension(ref);
  1496. ref += ".lib";
  1497. }
  1498. return ref;
  1499. }
  1500. else
  1501. {
  1502. std::string ref = "${";
  1503. ref += target.GetName();
  1504. if(implib)
  1505. {
  1506. ref += "_LIBNAME_";
  1507. }
  1508. else
  1509. {
  1510. ref += "_NAME_";
  1511. }
  1512. ref += "${CMAKE_INSTALL_CONFIG_NAME}}";
  1513. return ref;
  1514. }
  1515. }
  1516. //----------------------------------------------------------------------------
  1517. void
  1518. cmLocalGenerator
  1519. ::PrepareInstallReference(std::ostream& fout, cmTarget& target,
  1520. std::vector<std::string> const& configs)
  1521. {
  1522. // If the target name may vary with the configuration type then
  1523. // store all possible names ahead of time in variables.
  1524. cmTarget::TargetType type = target.GetType();
  1525. if(type == cmTarget::SHARED_LIBRARY ||
  1526. type == cmTarget::STATIC_LIBRARY ||
  1527. type == cmTarget::MODULE_LIBRARY ||
  1528. type == cmTarget::EXECUTABLE)
  1529. {
  1530. std::string fname;
  1531. for(std::vector<std::string>::const_iterator i = configs.begin();
  1532. i != configs.end(); ++i)
  1533. {
  1534. // Set a variable with the target name for this
  1535. // configuration.
  1536. fname = target.GetFullName(i->c_str());
  1537. fout << "SET(" << target.GetName() << "_NAME_" << *i
  1538. << " \"" << fname << "\")\n";
  1539. #ifdef _WIN32
  1540. // If the target is a .dll then add the corresponding .lib
  1541. // name in its own variable.
  1542. if(type == cmTarget::SHARED_LIBRARY)
  1543. {
  1544. fname = cmSystemTools::GetFilenameWithoutExtension(fname);
  1545. fname += ".lib";
  1546. fout << "SET(" << target.GetName() << "_LIBNAME_" << *i
  1547. << " \"" << fname << "\")\n";
  1548. }
  1549. #endif
  1550. }
  1551. }
  1552. }
  1553. //----------------------------------------------------------------------------
  1554. void cmLocalGenerator::AddLanguageFlags(std::string& flags,
  1555. const char* lang)
  1556. {
  1557. // Add language-specific flags.
  1558. std::string flagsVar = "CMAKE_";
  1559. flagsVar += lang;
  1560. flagsVar += "_FLAGS";
  1561. this->AddConfigVariableFlags(flags, flagsVar.c_str());
  1562. }
  1563. //----------------------------------------------------------------------------
  1564. std::string cmLocalGenerator::GetRealDependency(const char* inName,
  1565. const char* config)
  1566. {
  1567. // Older CMake code may specify the dependency using the target
  1568. // output file rather than the target name. Such code would have
  1569. // been written before there was support for target properties that
  1570. // modify the name so stripping down to just the file name should
  1571. // produce the target name in this case.
  1572. std::string name = cmSystemTools::GetFilenameName(inName);
  1573. if(cmSystemTools::GetFilenameLastExtension(name) == ".exe")
  1574. {
  1575. name = cmSystemTools::GetFilenameWithoutLastExtension(name);
  1576. }
  1577. // Look for a CMake target with the given name.
  1578. if(cmTarget* target = m_GlobalGenerator->FindTarget(0, name.c_str()))
  1579. {
  1580. switch (target->GetType())
  1581. {
  1582. case cmTarget::EXECUTABLE:
  1583. case cmTarget::STATIC_LIBRARY:
  1584. case cmTarget::SHARED_LIBRARY:
  1585. case cmTarget::MODULE_LIBRARY:
  1586. {
  1587. // Get the location of the target's output file and depend on it.
  1588. if(const char* location = target->GetLocation(config))
  1589. {
  1590. return location;
  1591. }
  1592. }
  1593. break;
  1594. case cmTarget::UTILITY:
  1595. // Depending on a utility target may not work but just trust
  1596. // the user to have given a valid name.
  1597. return inName;
  1598. case cmTarget::INSTALL_FILES:
  1599. case cmTarget::INSTALL_PROGRAMS:
  1600. break;
  1601. }
  1602. }
  1603. // The name was not that of a CMake target. It must name a file.
  1604. if(cmSystemTools::FileIsFullPath(inName))
  1605. {
  1606. // This is a full path. Return it as given.
  1607. return inName;
  1608. }
  1609. // Treat the name as relative to the source directory in which it
  1610. // was given.
  1611. name = m_Makefile->GetCurrentDirectory();
  1612. name += "/";
  1613. name += inName;
  1614. return name;
  1615. }
  1616. //----------------------------------------------------------------------------
  1617. void cmLocalGenerator::AddSharedFlags(std::string& flags,
  1618. const char* lang,
  1619. bool shared)
  1620. {
  1621. std::string flagsVar;
  1622. // Add flags for dealing with shared libraries for this language.
  1623. if(shared)
  1624. {
  1625. flagsVar = "CMAKE_SHARED_LIBRARY_";
  1626. flagsVar += lang;
  1627. flagsVar += "_FLAGS";
  1628. this->AppendFlags(flags, m_Makefile->GetDefinition(flagsVar.c_str()));
  1629. }
  1630. // Add flags specific to shared builds.
  1631. if(cmSystemTools::IsOn(m_Makefile->GetDefinition("BUILD_SHARED_LIBS")))
  1632. {
  1633. flagsVar = "CMAKE_SHARED_BUILD_";
  1634. flagsVar += lang;
  1635. flagsVar += "_FLAGS";
  1636. this->AppendFlags(flags, m_Makefile->GetDefinition(flagsVar.c_str()));
  1637. }
  1638. }
  1639. //----------------------------------------------------------------------------
  1640. void cmLocalGenerator::AddConfigVariableFlags(std::string& flags,
  1641. const char* var)
  1642. {
  1643. // Add the flags from the variable itself.
  1644. std::string flagsVar = var;
  1645. this->AppendFlags(flags, m_Makefile->GetDefinition(flagsVar.c_str()));
  1646. // Add the flags from the build-type specific variable.
  1647. const char* buildType = m_Makefile->GetDefinition("CMAKE_BUILD_TYPE");
  1648. if(buildType && *buildType)
  1649. {
  1650. flagsVar += "_";
  1651. flagsVar += cmSystemTools::UpperCase(buildType);
  1652. this->AppendFlags(flags, m_Makefile->GetDefinition(flagsVar.c_str()));
  1653. }
  1654. }
  1655. //----------------------------------------------------------------------------
  1656. void cmLocalGenerator::AppendFlags(std::string& flags,
  1657. const char* newFlags)
  1658. {
  1659. if(newFlags && *newFlags)
  1660. {
  1661. if(flags.size())
  1662. {
  1663. flags += " ";
  1664. }
  1665. flags += newFlags;
  1666. }
  1667. }
  1668. //----------------------------------------------------------------------------
  1669. std::string
  1670. cmLocalGenerator::ConstructScript(const cmCustomCommandLines& commandLines,
  1671. const char* workingDirectory,
  1672. const char* newline)
  1673. {
  1674. // Store the script in a string.
  1675. std::string script;
  1676. if(workingDirectory)
  1677. {
  1678. script += "cd ";
  1679. script += this->Convert(workingDirectory, START_OUTPUT, SHELL);
  1680. script += newline;
  1681. }
  1682. // Write each command on a single line.
  1683. for(cmCustomCommandLines::const_iterator cl = commandLines.begin();
  1684. cl != commandLines.end(); ++cl)
  1685. {
  1686. // Start with the command name.
  1687. const cmCustomCommandLine& commandLine = *cl;
  1688. script += this->Convert(commandLine[0].c_str(),START_OUTPUT,SHELL);
  1689. // Add the arguments.
  1690. for(unsigned int j=1;j < commandLine.size(); ++j)
  1691. {
  1692. script += " ";
  1693. script += cmSystemTools::EscapeSpaces(commandLine[j].c_str());
  1694. }
  1695. // End the line.
  1696. script += newline;
  1697. }
  1698. return script;
  1699. }
  1700. //----------------------------------------------------------------------------
  1701. std::string
  1702. cmLocalGenerator::ConvertToOptionallyRelativeOutputPath(const char* remote)
  1703. {
  1704. return this->Convert(remote, START_OUTPUT, SHELL, true);
  1705. }
  1706. //----------------------------------------------------------------------------
  1707. std::string cmLocalGenerator::Convert(const char* source,
  1708. RelativeRoot relative,
  1709. OutputFormat output,
  1710. bool optional)
  1711. {
  1712. // Convert the path to a relative path.
  1713. std::string result = source;
  1714. if (!optional || m_UseRelativePaths)
  1715. {
  1716. switch (relative)
  1717. {
  1718. case HOME:
  1719. //result = cmSystemTools::CollapseFullPath(result.c_str());
  1720. result = m_GlobalGenerator->
  1721. ConvertToRelativePath(m_HomeDirectoryComponents, result.c_str());
  1722. break;
  1723. case START:
  1724. //result = cmSystemTools::CollapseFullPath(result.c_str());
  1725. result = m_GlobalGenerator->
  1726. ConvertToRelativePath(m_StartDirectoryComponents, result.c_str());
  1727. break;
  1728. case HOME_OUTPUT:
  1729. //result = cmSystemTools::CollapseFullPath(result.c_str());
  1730. result = m_GlobalGenerator->
  1731. ConvertToRelativePath(m_HomeOutputDirectoryComponents, result.c_str());
  1732. break;
  1733. case START_OUTPUT:
  1734. //result = cmSystemTools::CollapseFullPath(result.c_str());
  1735. result = m_GlobalGenerator->
  1736. ConvertToRelativePath(m_StartOutputDirectoryComponents, result.c_str());
  1737. break;
  1738. case FULL:
  1739. result = cmSystemTools::CollapseFullPath(result.c_str());
  1740. break;
  1741. case NONE:
  1742. break;
  1743. }
  1744. }
  1745. // Now convert it to an output path.
  1746. if (output == MAKEFILE)
  1747. {
  1748. result = cmSystemTools::ConvertToOutputPath(result.c_str());
  1749. }
  1750. if( output == SHELL)
  1751. {
  1752. // for shell commands if force unix is on, but m_WindowsShell
  1753. // is true, then turn off force unix paths for the output path
  1754. // so that the path is windows style and will work with windows
  1755. // cmd.exe.
  1756. bool forceOn = cmSystemTools::GetForceUnixPaths();
  1757. if(forceOn && m_WindowsShell)
  1758. {
  1759. cmSystemTools::SetForceUnixPaths(false);
  1760. }
  1761. result = cmSystemTools::ConvertToOutputPath(result.c_str());
  1762. if(forceOn && m_WindowsShell)
  1763. {
  1764. cmSystemTools::SetForceUnixPaths(true);
  1765. }
  1766. }
  1767. return result;
  1768. }