cmLocalGenerator.cxx 53 KB

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