cmLocalGenerator.cxx 62 KB

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