cmLocalGenerator.cxx 54 KB

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