cmInstallCommand.cxx 48 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366
  1. /*============================================================================
  2. CMake - Cross Platform Makefile Generator
  3. Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
  4. Distributed under the OSI-approved BSD License (the "License");
  5. see accompanying file Copyright.txt for details.
  6. This software is distributed WITHOUT ANY WARRANTY; without even the
  7. implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  8. See the License for more information.
  9. ============================================================================*/
  10. #include "cmInstallCommand.h"
  11. #include "cmExportSet.h"
  12. #include "cmInstallCommandArguments.h"
  13. #include "cmInstallDirectoryGenerator.h"
  14. #include "cmInstallExportGenerator.h"
  15. #include "cmInstallFilesGenerator.h"
  16. #include "cmInstallScriptGenerator.h"
  17. #include "cmInstallTargetGenerator.h"
  18. #include "cmTargetExport.h"
  19. #include <cmsys/Glob.hxx>
  20. static cmInstallTargetGenerator* CreateInstallTargetGenerator(
  21. cmTarget& target, const cmInstallCommandArguments& args, bool impLib,
  22. bool forceOpt = false)
  23. {
  24. cmInstallGenerator::MessageLevel message =
  25. cmInstallGenerator::SelectMessageLevel(target.GetMakefile());
  26. target.SetHaveInstallRule(true);
  27. return new cmInstallTargetGenerator(
  28. target.GetName(), args.GetDestination().c_str(), impLib,
  29. args.GetPermissions().c_str(), args.GetConfigurations(),
  30. args.GetComponent().c_str(), message, args.GetExcludeFromAll(),
  31. args.GetOptional() || forceOpt);
  32. }
  33. static cmInstallFilesGenerator* CreateInstallFilesGenerator(
  34. cmMakefile* mf, const std::vector<std::string>& absFiles,
  35. const cmInstallCommandArguments& args, bool programs)
  36. {
  37. cmInstallGenerator::MessageLevel message =
  38. cmInstallGenerator::SelectMessageLevel(mf);
  39. return new cmInstallFilesGenerator(
  40. absFiles, args.GetDestination().c_str(), programs,
  41. args.GetPermissions().c_str(), args.GetConfigurations(),
  42. args.GetComponent().c_str(), message, args.GetExcludeFromAll(),
  43. args.GetRename().c_str(), args.GetOptional());
  44. }
  45. // cmInstallCommand
  46. bool cmInstallCommand::InitialPass(std::vector<std::string> const& args,
  47. cmExecutionStatus&)
  48. {
  49. // Allow calling with no arguments so that arguments may be built up
  50. // using a variable that may be left empty.
  51. if (args.empty()) {
  52. return true;
  53. }
  54. // Enable the install target.
  55. this->Makefile->GetGlobalGenerator()->EnableInstallTarget();
  56. this->DefaultComponentName =
  57. this->Makefile->GetSafeDefinition("CMAKE_INSTALL_DEFAULT_COMPONENT_NAME");
  58. if (this->DefaultComponentName.empty()) {
  59. this->DefaultComponentName = "Unspecified";
  60. }
  61. // Switch among the command modes.
  62. if (args[0] == "SCRIPT") {
  63. return this->HandleScriptMode(args);
  64. }
  65. if (args[0] == "CODE") {
  66. return this->HandleScriptMode(args);
  67. }
  68. if (args[0] == "TARGETS") {
  69. return this->HandleTargetsMode(args);
  70. }
  71. if (args[0] == "FILES") {
  72. return this->HandleFilesMode(args);
  73. }
  74. if (args[0] == "PROGRAMS") {
  75. return this->HandleFilesMode(args);
  76. }
  77. if (args[0] == "DIRECTORY") {
  78. return this->HandleDirectoryMode(args);
  79. }
  80. if (args[0] == "EXPORT") {
  81. return this->HandleExportMode(args);
  82. }
  83. if (args[0] == "EXPORT_ANDROID_MK") {
  84. return this->HandleExportAndroidMKMode(args);
  85. }
  86. // Unknown mode.
  87. std::string e = "called with unknown mode ";
  88. e += args[0];
  89. this->SetError(e);
  90. return false;
  91. }
  92. bool cmInstallCommand::HandleScriptMode(std::vector<std::string> const& args)
  93. {
  94. std::string component = this->DefaultComponentName;
  95. int componentCount = 0;
  96. bool doing_script = false;
  97. bool doing_code = false;
  98. bool exclude_from_all = false;
  99. // Scan the args once for COMPONENT. Only allow one.
  100. //
  101. for (size_t i = 0; i < args.size(); ++i) {
  102. if (args[i] == "COMPONENT" && i + 1 < args.size()) {
  103. ++componentCount;
  104. ++i;
  105. component = args[i];
  106. }
  107. if (args[i] == "EXCLUDE_FROM_ALL") {
  108. exclude_from_all = true;
  109. }
  110. }
  111. if (componentCount > 1) {
  112. this->SetError("given more than one COMPONENT for the SCRIPT or CODE "
  113. "signature of the INSTALL command. "
  114. "Use multiple INSTALL commands with one COMPONENT each.");
  115. return false;
  116. }
  117. // Scan the args again, this time adding install generators each time we
  118. // encounter a SCRIPT or CODE arg:
  119. //
  120. for (size_t i = 0; i < args.size(); ++i) {
  121. if (args[i] == "SCRIPT") {
  122. doing_script = true;
  123. doing_code = false;
  124. } else if (args[i] == "CODE") {
  125. doing_script = false;
  126. doing_code = true;
  127. } else if (args[i] == "COMPONENT") {
  128. doing_script = false;
  129. doing_code = false;
  130. } else if (doing_script) {
  131. doing_script = false;
  132. std::string script = args[i];
  133. if (!cmSystemTools::FileIsFullPath(script.c_str())) {
  134. script = this->Makefile->GetCurrentSourceDirectory();
  135. script += "/";
  136. script += args[i];
  137. }
  138. if (cmSystemTools::FileIsDirectory(script)) {
  139. this->SetError("given a directory as value of SCRIPT argument.");
  140. return false;
  141. }
  142. this->Makefile->AddInstallGenerator(new cmInstallScriptGenerator(
  143. script.c_str(), false, component.c_str(), exclude_from_all));
  144. } else if (doing_code) {
  145. doing_code = false;
  146. std::string code = args[i];
  147. this->Makefile->AddInstallGenerator(new cmInstallScriptGenerator(
  148. code.c_str(), true, component.c_str(), exclude_from_all));
  149. }
  150. }
  151. if (doing_script) {
  152. this->SetError("given no value for SCRIPT argument.");
  153. return false;
  154. }
  155. if (doing_code) {
  156. this->SetError("given no value for CODE argument.");
  157. return false;
  158. }
  159. // Tell the global generator about any installation component names
  160. // specified.
  161. this->Makefile->GetGlobalGenerator()->AddInstallComponent(component.c_str());
  162. return true;
  163. }
  164. /*struct InstallPart
  165. {
  166. InstallPart(cmCommandArgumentsHelper* helper, const char* key,
  167. cmCommandArgumentGroup* group);
  168. cmCAStringVector argVector;
  169. cmInstallCommandArguments args;
  170. };*/
  171. bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
  172. {
  173. // This is the TARGETS mode.
  174. std::vector<cmTarget*> targets;
  175. cmCommandArgumentsHelper argHelper;
  176. cmCommandArgumentGroup group;
  177. cmCAStringVector genericArgVector(&argHelper, CM_NULLPTR);
  178. cmCAStringVector archiveArgVector(&argHelper, "ARCHIVE", &group);
  179. cmCAStringVector libraryArgVector(&argHelper, "LIBRARY", &group);
  180. cmCAStringVector runtimeArgVector(&argHelper, "RUNTIME", &group);
  181. cmCAStringVector frameworkArgVector(&argHelper, "FRAMEWORK", &group);
  182. cmCAStringVector bundleArgVector(&argHelper, "BUNDLE", &group);
  183. cmCAStringVector includesArgVector(&argHelper, "INCLUDES", &group);
  184. cmCAStringVector privateHeaderArgVector(&argHelper, "PRIVATE_HEADER",
  185. &group);
  186. cmCAStringVector publicHeaderArgVector(&argHelper, "PUBLIC_HEADER", &group);
  187. cmCAStringVector resourceArgVector(&argHelper, "RESOURCE", &group);
  188. genericArgVector.Follows(CM_NULLPTR);
  189. group.Follows(&genericArgVector);
  190. argHelper.Parse(&args, CM_NULLPTR);
  191. // now parse the generic args (i.e. the ones not specialized on LIBRARY/
  192. // ARCHIVE, RUNTIME etc. (see above)
  193. // These generic args also contain the targets and the export stuff
  194. std::vector<std::string> unknownArgs;
  195. cmInstallCommandArguments genericArgs(this->DefaultComponentName);
  196. cmCAStringVector targetList(&genericArgs.Parser, "TARGETS");
  197. cmCAString exports(&genericArgs.Parser, "EXPORT",
  198. &genericArgs.ArgumentGroup);
  199. targetList.Follows(CM_NULLPTR);
  200. genericArgs.ArgumentGroup.Follows(&targetList);
  201. genericArgs.Parse(&genericArgVector.GetVector(), &unknownArgs);
  202. bool success = genericArgs.Finalize();
  203. cmInstallCommandArguments archiveArgs(this->DefaultComponentName);
  204. cmInstallCommandArguments libraryArgs(this->DefaultComponentName);
  205. cmInstallCommandArguments runtimeArgs(this->DefaultComponentName);
  206. cmInstallCommandArguments frameworkArgs(this->DefaultComponentName);
  207. cmInstallCommandArguments bundleArgs(this->DefaultComponentName);
  208. cmInstallCommandArguments privateHeaderArgs(this->DefaultComponentName);
  209. cmInstallCommandArguments publicHeaderArgs(this->DefaultComponentName);
  210. cmInstallCommandArguments resourceArgs(this->DefaultComponentName);
  211. cmInstallCommandIncludesArgument includesArgs;
  212. // now parse the args for specific parts of the target (e.g. LIBRARY,
  213. // RUNTIME, ARCHIVE etc.
  214. archiveArgs.Parse(&archiveArgVector.GetVector(), &unknownArgs);
  215. libraryArgs.Parse(&libraryArgVector.GetVector(), &unknownArgs);
  216. runtimeArgs.Parse(&runtimeArgVector.GetVector(), &unknownArgs);
  217. frameworkArgs.Parse(&frameworkArgVector.GetVector(), &unknownArgs);
  218. bundleArgs.Parse(&bundleArgVector.GetVector(), &unknownArgs);
  219. privateHeaderArgs.Parse(&privateHeaderArgVector.GetVector(), &unknownArgs);
  220. publicHeaderArgs.Parse(&publicHeaderArgVector.GetVector(), &unknownArgs);
  221. resourceArgs.Parse(&resourceArgVector.GetVector(), &unknownArgs);
  222. includesArgs.Parse(&includesArgVector.GetVector(), &unknownArgs);
  223. if (!unknownArgs.empty()) {
  224. // Unknown argument.
  225. std::ostringstream e;
  226. e << "TARGETS given unknown argument \"" << unknownArgs[0] << "\".";
  227. this->SetError(e.str());
  228. return false;
  229. }
  230. // apply generic args
  231. archiveArgs.SetGenericArguments(&genericArgs);
  232. libraryArgs.SetGenericArguments(&genericArgs);
  233. runtimeArgs.SetGenericArguments(&genericArgs);
  234. frameworkArgs.SetGenericArguments(&genericArgs);
  235. bundleArgs.SetGenericArguments(&genericArgs);
  236. privateHeaderArgs.SetGenericArguments(&genericArgs);
  237. publicHeaderArgs.SetGenericArguments(&genericArgs);
  238. resourceArgs.SetGenericArguments(&genericArgs);
  239. success = success && archiveArgs.Finalize();
  240. success = success && libraryArgs.Finalize();
  241. success = success && runtimeArgs.Finalize();
  242. success = success && frameworkArgs.Finalize();
  243. success = success && bundleArgs.Finalize();
  244. success = success && privateHeaderArgs.Finalize();
  245. success = success && publicHeaderArgs.Finalize();
  246. success = success && resourceArgs.Finalize();
  247. if (!success) {
  248. return false;
  249. }
  250. // Enforce argument rules too complex to specify for the
  251. // general-purpose parser.
  252. if (archiveArgs.GetNamelinkOnly() || runtimeArgs.GetNamelinkOnly() ||
  253. frameworkArgs.GetNamelinkOnly() || bundleArgs.GetNamelinkOnly() ||
  254. privateHeaderArgs.GetNamelinkOnly() ||
  255. publicHeaderArgs.GetNamelinkOnly() || resourceArgs.GetNamelinkOnly()) {
  256. this->SetError(
  257. "TARGETS given NAMELINK_ONLY option not in LIBRARY group. "
  258. "The NAMELINK_ONLY option may be specified only following LIBRARY.");
  259. return false;
  260. }
  261. if (archiveArgs.GetNamelinkSkip() || runtimeArgs.GetNamelinkSkip() ||
  262. frameworkArgs.GetNamelinkSkip() || bundleArgs.GetNamelinkSkip() ||
  263. privateHeaderArgs.GetNamelinkSkip() ||
  264. publicHeaderArgs.GetNamelinkSkip() || resourceArgs.GetNamelinkSkip()) {
  265. this->SetError(
  266. "TARGETS given NAMELINK_SKIP option not in LIBRARY group. "
  267. "The NAMELINK_SKIP option may be specified only following LIBRARY.");
  268. return false;
  269. }
  270. if (libraryArgs.GetNamelinkOnly() && libraryArgs.GetNamelinkSkip()) {
  271. this->SetError("TARGETS given NAMELINK_ONLY and NAMELINK_SKIP. "
  272. "At most one of these two options may be specified.");
  273. return false;
  274. }
  275. // Select the mode for installing symlinks to versioned shared libraries.
  276. cmInstallTargetGenerator::NamelinkModeType namelinkMode =
  277. cmInstallTargetGenerator::NamelinkModeNone;
  278. if (libraryArgs.GetNamelinkOnly()) {
  279. namelinkMode = cmInstallTargetGenerator::NamelinkModeOnly;
  280. } else if (libraryArgs.GetNamelinkSkip()) {
  281. namelinkMode = cmInstallTargetGenerator::NamelinkModeSkip;
  282. }
  283. // Check if there is something to do.
  284. if (targetList.GetVector().empty()) {
  285. return true;
  286. }
  287. // Check whether this is a DLL platform.
  288. bool dll_platform =
  289. (this->Makefile->IsOn("WIN32") || this->Makefile->IsOn("CYGWIN") ||
  290. this->Makefile->IsOn("MINGW"));
  291. for (std::vector<std::string>::const_iterator targetIt =
  292. targetList.GetVector().begin();
  293. targetIt != targetList.GetVector().end(); ++targetIt) {
  294. if (this->Makefile->IsAlias(*targetIt)) {
  295. std::ostringstream e;
  296. e << "TARGETS given target \"" << (*targetIt) << "\" which is an alias.";
  297. this->SetError(e.str());
  298. return false;
  299. }
  300. // Lookup this target in the current directory.
  301. if (cmTarget* target =
  302. this->Makefile->FindLocalNonAliasTarget(*targetIt)) {
  303. // Found the target. Check its type.
  304. if (target->GetType() != cmState::EXECUTABLE &&
  305. target->GetType() != cmState::STATIC_LIBRARY &&
  306. target->GetType() != cmState::SHARED_LIBRARY &&
  307. target->GetType() != cmState::MODULE_LIBRARY &&
  308. target->GetType() != cmState::OBJECT_LIBRARY &&
  309. target->GetType() != cmState::INTERFACE_LIBRARY) {
  310. std::ostringstream e;
  311. e << "TARGETS given target \"" << (*targetIt)
  312. << "\" which is not an executable, library, or module.";
  313. this->SetError(e.str());
  314. return false;
  315. }
  316. if (target->GetType() == cmState::OBJECT_LIBRARY) {
  317. std::ostringstream e;
  318. e << "TARGETS given OBJECT library \"" << (*targetIt)
  319. << "\" which may not be installed.";
  320. this->SetError(e.str());
  321. return false;
  322. }
  323. // Store the target in the list to be installed.
  324. targets.push_back(target);
  325. } else {
  326. // Did not find the target.
  327. std::ostringstream e;
  328. e << "TARGETS given target \"" << (*targetIt)
  329. << "\" which does not exist in this directory.";
  330. this->SetError(e.str());
  331. return false;
  332. }
  333. }
  334. // Keep track of whether we will be performing an installation of
  335. // any files of the given type.
  336. bool installsArchive = false;
  337. bool installsLibrary = false;
  338. bool installsRuntime = false;
  339. bool installsFramework = false;
  340. bool installsBundle = false;
  341. bool installsPrivateHeader = false;
  342. bool installsPublicHeader = false;
  343. bool installsResource = false;
  344. // Generate install script code to install the given targets.
  345. for (std::vector<cmTarget*>::iterator ti = targets.begin();
  346. ti != targets.end(); ++ti) {
  347. // Handle each target type.
  348. cmTarget& target = *(*ti);
  349. cmInstallTargetGenerator* archiveGenerator = CM_NULLPTR;
  350. cmInstallTargetGenerator* libraryGenerator = CM_NULLPTR;
  351. cmInstallTargetGenerator* runtimeGenerator = CM_NULLPTR;
  352. cmInstallTargetGenerator* frameworkGenerator = CM_NULLPTR;
  353. cmInstallTargetGenerator* bundleGenerator = CM_NULLPTR;
  354. cmInstallFilesGenerator* privateHeaderGenerator = CM_NULLPTR;
  355. cmInstallFilesGenerator* publicHeaderGenerator = CM_NULLPTR;
  356. cmInstallFilesGenerator* resourceGenerator = CM_NULLPTR;
  357. // Track whether this is a namelink-only rule.
  358. bool namelinkOnly = false;
  359. switch (target.GetType()) {
  360. case cmState::SHARED_LIBRARY: {
  361. // Shared libraries are handled differently on DLL and non-DLL
  362. // platforms. All windows platforms are DLL platforms including
  363. // cygwin. Currently no other platform is a DLL platform.
  364. if (dll_platform) {
  365. // When in namelink only mode skip all libraries on Windows.
  366. if (namelinkMode == cmInstallTargetGenerator::NamelinkModeOnly) {
  367. continue;
  368. }
  369. // This is a DLL platform.
  370. if (!archiveArgs.GetDestination().empty()) {
  371. // The import library uses the ARCHIVE properties.
  372. archiveGenerator =
  373. CreateInstallTargetGenerator(target, archiveArgs, true);
  374. }
  375. if (!runtimeArgs.GetDestination().empty()) {
  376. // The DLL uses the RUNTIME properties.
  377. runtimeGenerator =
  378. CreateInstallTargetGenerator(target, runtimeArgs, false);
  379. }
  380. if ((archiveGenerator == CM_NULLPTR) &&
  381. (runtimeGenerator == CM_NULLPTR)) {
  382. this->SetError("Library TARGETS given no DESTINATION!");
  383. return false;
  384. }
  385. } else {
  386. // This is a non-DLL platform.
  387. // If it is marked with FRAMEWORK property use the FRAMEWORK set of
  388. // INSTALL properties. Otherwise, use the LIBRARY properties.
  389. if (target.IsFrameworkOnApple()) {
  390. // When in namelink only mode skip frameworks.
  391. if (namelinkMode == cmInstallTargetGenerator::NamelinkModeOnly) {
  392. continue;
  393. }
  394. // Use the FRAMEWORK properties.
  395. if (!frameworkArgs.GetDestination().empty()) {
  396. frameworkGenerator =
  397. CreateInstallTargetGenerator(target, frameworkArgs, false);
  398. } else {
  399. std::ostringstream e;
  400. e << "TARGETS given no FRAMEWORK DESTINATION for shared library "
  401. "FRAMEWORK target \""
  402. << target.GetName() << "\".";
  403. this->SetError(e.str());
  404. return false;
  405. }
  406. } else {
  407. // The shared library uses the LIBRARY properties.
  408. if (!libraryArgs.GetDestination().empty()) {
  409. libraryGenerator =
  410. CreateInstallTargetGenerator(target, libraryArgs, false);
  411. libraryGenerator->SetNamelinkMode(namelinkMode);
  412. namelinkOnly =
  413. (namelinkMode == cmInstallTargetGenerator::NamelinkModeOnly);
  414. } else {
  415. std::ostringstream e;
  416. e << "TARGETS given no LIBRARY DESTINATION for shared library "
  417. "target \""
  418. << target.GetName() << "\".";
  419. this->SetError(e.str());
  420. return false;
  421. }
  422. }
  423. }
  424. } break;
  425. case cmState::STATIC_LIBRARY: {
  426. // Static libraries use ARCHIVE properties.
  427. if (!archiveArgs.GetDestination().empty()) {
  428. archiveGenerator =
  429. CreateInstallTargetGenerator(target, archiveArgs, false);
  430. } else {
  431. std::ostringstream e;
  432. e << "TARGETS given no ARCHIVE DESTINATION for static library "
  433. "target \""
  434. << target.GetName() << "\".";
  435. this->SetError(e.str());
  436. return false;
  437. }
  438. } break;
  439. case cmState::MODULE_LIBRARY: {
  440. // Modules use LIBRARY properties.
  441. if (!libraryArgs.GetDestination().empty()) {
  442. libraryGenerator =
  443. CreateInstallTargetGenerator(target, libraryArgs, false);
  444. libraryGenerator->SetNamelinkMode(namelinkMode);
  445. namelinkOnly =
  446. (namelinkMode == cmInstallTargetGenerator::NamelinkModeOnly);
  447. } else {
  448. std::ostringstream e;
  449. e << "TARGETS given no LIBRARY DESTINATION for module target \""
  450. << target.GetName() << "\".";
  451. this->SetError(e.str());
  452. return false;
  453. }
  454. } break;
  455. case cmState::EXECUTABLE: {
  456. if (target.IsAppBundleOnApple()) {
  457. // Application bundles use the BUNDLE properties.
  458. if (!bundleArgs.GetDestination().empty()) {
  459. bundleGenerator =
  460. CreateInstallTargetGenerator(target, bundleArgs, false);
  461. } else if (!runtimeArgs.GetDestination().empty()) {
  462. bool failure = false;
  463. if (this->CheckCMP0006(failure)) {
  464. // For CMake 2.4 compatibility fallback to the RUNTIME
  465. // properties.
  466. bundleGenerator =
  467. CreateInstallTargetGenerator(target, runtimeArgs, false);
  468. } else if (failure) {
  469. return false;
  470. }
  471. }
  472. if (!bundleGenerator) {
  473. std::ostringstream e;
  474. e << "TARGETS given no BUNDLE DESTINATION for MACOSX_BUNDLE "
  475. "executable target \""
  476. << target.GetName() << "\".";
  477. this->SetError(e.str());
  478. return false;
  479. }
  480. } else {
  481. // Executables use the RUNTIME properties.
  482. if (!runtimeArgs.GetDestination().empty()) {
  483. runtimeGenerator =
  484. CreateInstallTargetGenerator(target, runtimeArgs, false);
  485. } else {
  486. std::ostringstream e;
  487. e << "TARGETS given no RUNTIME DESTINATION for executable "
  488. "target \""
  489. << target.GetName() << "\".";
  490. this->SetError(e.str());
  491. return false;
  492. }
  493. }
  494. // On DLL platforms an executable may also have an import
  495. // library. Install it to the archive destination if it
  496. // exists.
  497. if (dll_platform && !archiveArgs.GetDestination().empty() &&
  498. target.IsExecutableWithExports()) {
  499. // The import library uses the ARCHIVE properties.
  500. archiveGenerator =
  501. CreateInstallTargetGenerator(target, archiveArgs, true, true);
  502. }
  503. } break;
  504. case cmState::INTERFACE_LIBRARY:
  505. // Nothing to do. An INTERFACE_LIBRARY can be installed, but the
  506. // only effect of that is to make it exportable. It installs no
  507. // other files itself.
  508. break;
  509. default:
  510. // This should never happen due to the above type check.
  511. // Ignore the case.
  512. break;
  513. }
  514. // These well-known sets of files are installed *automatically* for
  515. // FRAMEWORK SHARED library targets on the Mac as part of installing the
  516. // FRAMEWORK. For other target types or on other platforms, they are not
  517. // installed automatically and so we need to create install files
  518. // generators for them.
  519. bool createInstallGeneratorsForTargetFileSets = true;
  520. if (target.IsFrameworkOnApple() ||
  521. target.GetType() == cmState::INTERFACE_LIBRARY) {
  522. createInstallGeneratorsForTargetFileSets = false;
  523. }
  524. if (createInstallGeneratorsForTargetFileSets && !namelinkOnly) {
  525. const char* files = target.GetProperty("PRIVATE_HEADER");
  526. if ((files) && (*files)) {
  527. std::vector<std::string> relFiles;
  528. cmSystemTools::ExpandListArgument(files, relFiles);
  529. std::vector<std::string> absFiles;
  530. if (!this->MakeFilesFullPath("PRIVATE_HEADER", relFiles, absFiles)) {
  531. return false;
  532. }
  533. // Create the files install generator.
  534. if (!privateHeaderArgs.GetDestination().empty()) {
  535. privateHeaderGenerator = CreateInstallFilesGenerator(
  536. this->Makefile, absFiles, privateHeaderArgs, false);
  537. } else {
  538. std::ostringstream e;
  539. e << "INSTALL TARGETS - target " << target.GetName() << " has "
  540. << "PRIVATE_HEADER files but no PRIVATE_HEADER DESTINATION.";
  541. cmSystemTools::Message(e.str().c_str(), "Warning");
  542. }
  543. }
  544. files = target.GetProperty("PUBLIC_HEADER");
  545. if ((files) && (*files)) {
  546. std::vector<std::string> relFiles;
  547. cmSystemTools::ExpandListArgument(files, relFiles);
  548. std::vector<std::string> absFiles;
  549. if (!this->MakeFilesFullPath("PUBLIC_HEADER", relFiles, absFiles)) {
  550. return false;
  551. }
  552. // Create the files install generator.
  553. if (!publicHeaderArgs.GetDestination().empty()) {
  554. publicHeaderGenerator = CreateInstallFilesGenerator(
  555. this->Makefile, absFiles, publicHeaderArgs, false);
  556. } else {
  557. std::ostringstream e;
  558. e << "INSTALL TARGETS - target " << target.GetName() << " has "
  559. << "PUBLIC_HEADER files but no PUBLIC_HEADER DESTINATION.";
  560. cmSystemTools::Message(e.str().c_str(), "Warning");
  561. }
  562. }
  563. files = target.GetProperty("RESOURCE");
  564. if ((files) && (*files)) {
  565. std::vector<std::string> relFiles;
  566. cmSystemTools::ExpandListArgument(files, relFiles);
  567. std::vector<std::string> absFiles;
  568. if (!this->MakeFilesFullPath("RESOURCE", relFiles, absFiles)) {
  569. return false;
  570. }
  571. // Create the files install generator.
  572. if (!resourceArgs.GetDestination().empty()) {
  573. resourceGenerator = CreateInstallFilesGenerator(
  574. this->Makefile, absFiles, resourceArgs, false);
  575. } else {
  576. std::ostringstream e;
  577. e << "INSTALL TARGETS - target " << target.GetName() << " has "
  578. << "RESOURCE files but no RESOURCE DESTINATION.";
  579. cmSystemTools::Message(e.str().c_str(), "Warning");
  580. }
  581. }
  582. }
  583. // Keep track of whether we're installing anything in each category
  584. installsArchive = installsArchive || archiveGenerator != CM_NULLPTR;
  585. installsLibrary = installsLibrary || libraryGenerator != CM_NULLPTR;
  586. installsRuntime = installsRuntime || runtimeGenerator != CM_NULLPTR;
  587. installsFramework = installsFramework || frameworkGenerator != CM_NULLPTR;
  588. installsBundle = installsBundle || bundleGenerator != CM_NULLPTR;
  589. installsPrivateHeader =
  590. installsPrivateHeader || privateHeaderGenerator != CM_NULLPTR;
  591. installsPublicHeader =
  592. installsPublicHeader || publicHeaderGenerator != CM_NULLPTR;
  593. installsResource = installsResource || resourceGenerator;
  594. this->Makefile->AddInstallGenerator(archiveGenerator);
  595. this->Makefile->AddInstallGenerator(libraryGenerator);
  596. this->Makefile->AddInstallGenerator(runtimeGenerator);
  597. this->Makefile->AddInstallGenerator(frameworkGenerator);
  598. this->Makefile->AddInstallGenerator(bundleGenerator);
  599. this->Makefile->AddInstallGenerator(privateHeaderGenerator);
  600. this->Makefile->AddInstallGenerator(publicHeaderGenerator);
  601. this->Makefile->AddInstallGenerator(resourceGenerator);
  602. // Add this install rule to an export if one was specified and
  603. // this is not a namelink-only rule.
  604. if (!exports.GetString().empty() && !namelinkOnly) {
  605. cmTargetExport* te = new cmTargetExport;
  606. te->TargetName = target.GetName();
  607. te->ArchiveGenerator = archiveGenerator;
  608. te->BundleGenerator = bundleGenerator;
  609. te->FrameworkGenerator = frameworkGenerator;
  610. te->HeaderGenerator = publicHeaderGenerator;
  611. te->LibraryGenerator = libraryGenerator;
  612. te->RuntimeGenerator = runtimeGenerator;
  613. this->Makefile->GetGlobalGenerator()
  614. ->GetExportSets()[exports.GetString()]
  615. ->AddTargetExport(te);
  616. te->InterfaceIncludeDirectories =
  617. cmJoin(includesArgs.GetIncludeDirs(), ";");
  618. }
  619. }
  620. // Tell the global generator about any installation component names
  621. // specified
  622. if (installsArchive) {
  623. this->Makefile->GetGlobalGenerator()->AddInstallComponent(
  624. archiveArgs.GetComponent().c_str());
  625. }
  626. if (installsLibrary) {
  627. this->Makefile->GetGlobalGenerator()->AddInstallComponent(
  628. libraryArgs.GetComponent().c_str());
  629. }
  630. if (installsRuntime) {
  631. this->Makefile->GetGlobalGenerator()->AddInstallComponent(
  632. runtimeArgs.GetComponent().c_str());
  633. }
  634. if (installsFramework) {
  635. this->Makefile->GetGlobalGenerator()->AddInstallComponent(
  636. frameworkArgs.GetComponent().c_str());
  637. }
  638. if (installsBundle) {
  639. this->Makefile->GetGlobalGenerator()->AddInstallComponent(
  640. bundleArgs.GetComponent().c_str());
  641. }
  642. if (installsPrivateHeader) {
  643. this->Makefile->GetGlobalGenerator()->AddInstallComponent(
  644. privateHeaderArgs.GetComponent().c_str());
  645. }
  646. if (installsPublicHeader) {
  647. this->Makefile->GetGlobalGenerator()->AddInstallComponent(
  648. publicHeaderArgs.GetComponent().c_str());
  649. }
  650. if (installsResource) {
  651. this->Makefile->GetGlobalGenerator()->AddInstallComponent(
  652. resourceArgs.GetComponent().c_str());
  653. }
  654. return true;
  655. }
  656. bool cmInstallCommand::HandleFilesMode(std::vector<std::string> const& args)
  657. {
  658. // This is the FILES mode.
  659. bool programs = (args[0] == "PROGRAMS");
  660. cmInstallCommandArguments ica(this->DefaultComponentName);
  661. cmCAStringVector files(&ica.Parser, programs ? "PROGRAMS" : "FILES");
  662. files.Follows(CM_NULLPTR);
  663. ica.ArgumentGroup.Follows(&files);
  664. std::vector<std::string> unknownArgs;
  665. ica.Parse(&args, &unknownArgs);
  666. if (!unknownArgs.empty()) {
  667. // Unknown argument.
  668. std::ostringstream e;
  669. e << args[0] << " given unknown argument \"" << unknownArgs[0] << "\".";
  670. this->SetError(e.str());
  671. return false;
  672. }
  673. const std::vector<std::string>& filesVector = files.GetVector();
  674. // Check if there is something to do.
  675. if (filesVector.empty()) {
  676. return true;
  677. }
  678. if (!ica.GetRename().empty() && filesVector.size() > 1) {
  679. // The rename option works only with one file.
  680. std::ostringstream e;
  681. e << args[0] << " given RENAME option with more than one file.";
  682. this->SetError(e.str());
  683. return false;
  684. }
  685. std::vector<std::string> absFiles;
  686. if (!this->MakeFilesFullPath(args[0].c_str(), filesVector, absFiles)) {
  687. return false;
  688. }
  689. cmPolicies::PolicyStatus status =
  690. this->Makefile->GetPolicyStatus(cmPolicies::CMP0062);
  691. cmGlobalGenerator* gg = this->Makefile->GetGlobalGenerator();
  692. for (std::vector<std::string>::const_iterator fileIt = filesVector.begin();
  693. fileIt != filesVector.end(); ++fileIt) {
  694. if (gg->IsExportedTargetsFile(*fileIt)) {
  695. const char* modal = CM_NULLPTR;
  696. std::ostringstream e;
  697. cmake::MessageType messageType = cmake::AUTHOR_WARNING;
  698. switch (status) {
  699. case cmPolicies::WARN:
  700. e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0062) << "\n";
  701. modal = "should";
  702. case cmPolicies::OLD:
  703. break;
  704. case cmPolicies::REQUIRED_IF_USED:
  705. case cmPolicies::REQUIRED_ALWAYS:
  706. case cmPolicies::NEW:
  707. modal = "may";
  708. messageType = cmake::FATAL_ERROR;
  709. }
  710. if (modal) {
  711. e << "The file\n " << *fileIt << "\nwas generated by the export() "
  712. "command. It "
  713. << modal << " not be installed with the "
  714. "install() command. Use the install(EXPORT) mechanism "
  715. "instead. See the cmake-packages(7) manual for more.\n";
  716. this->Makefile->IssueMessage(messageType, e.str());
  717. if (messageType == cmake::FATAL_ERROR) {
  718. return false;
  719. }
  720. }
  721. }
  722. }
  723. if (!ica.Finalize()) {
  724. return false;
  725. }
  726. if (ica.GetDestination().empty()) {
  727. // A destination is required.
  728. std::ostringstream e;
  729. e << args[0] << " given no DESTINATION!";
  730. this->SetError(e.str());
  731. return false;
  732. }
  733. // Create the files install generator.
  734. this->Makefile->AddInstallGenerator(
  735. CreateInstallFilesGenerator(this->Makefile, absFiles, ica, programs));
  736. // Tell the global generator about any installation component names
  737. // specified.
  738. this->Makefile->GetGlobalGenerator()->AddInstallComponent(
  739. ica.GetComponent().c_str());
  740. return true;
  741. }
  742. bool cmInstallCommand::HandleDirectoryMode(
  743. std::vector<std::string> const& args)
  744. {
  745. enum Doing
  746. {
  747. DoingNone,
  748. DoingDirs,
  749. DoingDestination,
  750. DoingPattern,
  751. DoingRegex,
  752. DoingPermsFile,
  753. DoingPermsDir,
  754. DoingPermsMatch,
  755. DoingConfigurations,
  756. DoingComponent
  757. };
  758. Doing doing = DoingDirs;
  759. bool in_match_mode = false;
  760. bool optional = false;
  761. bool exclude_from_all = false;
  762. bool message_never = false;
  763. std::vector<std::string> dirs;
  764. const char* destination = CM_NULLPTR;
  765. std::string permissions_file;
  766. std::string permissions_dir;
  767. std::vector<std::string> configurations;
  768. std::string component = this->DefaultComponentName;
  769. std::string literal_args;
  770. for (unsigned int i = 1; i < args.size(); ++i) {
  771. if (args[i] == "DESTINATION") {
  772. if (in_match_mode) {
  773. std::ostringstream e;
  774. e << args[0] << " does not allow \"" << args[i]
  775. << "\" after PATTERN or REGEX.";
  776. this->SetError(e.str());
  777. return false;
  778. }
  779. // Switch to setting the destination property.
  780. doing = DoingDestination;
  781. } else if (args[i] == "OPTIONAL") {
  782. if (in_match_mode) {
  783. std::ostringstream e;
  784. e << args[0] << " does not allow \"" << args[i]
  785. << "\" after PATTERN or REGEX.";
  786. this->SetError(e.str());
  787. return false;
  788. }
  789. // Mark the rule as optional.
  790. optional = true;
  791. doing = DoingNone;
  792. } else if (args[i] == "MESSAGE_NEVER") {
  793. if (in_match_mode) {
  794. std::ostringstream e;
  795. e << args[0] << " does not allow \"" << args[i]
  796. << "\" after PATTERN or REGEX.";
  797. this->SetError(e.str());
  798. return false;
  799. }
  800. // Mark the rule as quiet.
  801. message_never = true;
  802. doing = DoingNone;
  803. } else if (args[i] == "PATTERN") {
  804. // Switch to a new pattern match rule.
  805. doing = DoingPattern;
  806. in_match_mode = true;
  807. } else if (args[i] == "REGEX") {
  808. // Switch to a new regex match rule.
  809. doing = DoingRegex;
  810. in_match_mode = true;
  811. } else if (args[i] == "EXCLUDE") {
  812. // Add this property to the current match rule.
  813. if (!in_match_mode || doing == DoingPattern || doing == DoingRegex) {
  814. std::ostringstream e;
  815. e << args[0] << " does not allow \"" << args[i]
  816. << "\" before a PATTERN or REGEX is given.";
  817. this->SetError(e.str());
  818. return false;
  819. }
  820. literal_args += " EXCLUDE";
  821. doing = DoingNone;
  822. } else if (args[i] == "PERMISSIONS") {
  823. if (!in_match_mode) {
  824. std::ostringstream e;
  825. e << args[0] << " does not allow \"" << args[i]
  826. << "\" before a PATTERN or REGEX is given.";
  827. this->SetError(e.str());
  828. return false;
  829. }
  830. // Switch to setting the current match permissions property.
  831. literal_args += " PERMISSIONS";
  832. doing = DoingPermsMatch;
  833. } else if (args[i] == "FILE_PERMISSIONS") {
  834. if (in_match_mode) {
  835. std::ostringstream e;
  836. e << args[0] << " does not allow \"" << args[i]
  837. << "\" after PATTERN or REGEX.";
  838. this->SetError(e.str());
  839. return false;
  840. }
  841. // Switch to setting the file permissions property.
  842. doing = DoingPermsFile;
  843. } else if (args[i] == "DIRECTORY_PERMISSIONS") {
  844. if (in_match_mode) {
  845. std::ostringstream e;
  846. e << args[0] << " does not allow \"" << args[i]
  847. << "\" after PATTERN or REGEX.";
  848. this->SetError(e.str());
  849. return false;
  850. }
  851. // Switch to setting the directory permissions property.
  852. doing = DoingPermsDir;
  853. } else if (args[i] == "USE_SOURCE_PERMISSIONS") {
  854. if (in_match_mode) {
  855. std::ostringstream e;
  856. e << args[0] << " does not allow \"" << args[i]
  857. << "\" after PATTERN or REGEX.";
  858. this->SetError(e.str());
  859. return false;
  860. }
  861. // Add this option literally.
  862. literal_args += " USE_SOURCE_PERMISSIONS";
  863. doing = DoingNone;
  864. } else if (args[i] == "FILES_MATCHING") {
  865. if (in_match_mode) {
  866. std::ostringstream e;
  867. e << args[0] << " does not allow \"" << args[i]
  868. << "\" after PATTERN or REGEX.";
  869. this->SetError(e.str());
  870. return false;
  871. }
  872. // Add this option literally.
  873. literal_args += " FILES_MATCHING";
  874. doing = DoingNone;
  875. } else if (args[i] == "CONFIGURATIONS") {
  876. if (in_match_mode) {
  877. std::ostringstream e;
  878. e << args[0] << " does not allow \"" << args[i]
  879. << "\" after PATTERN or REGEX.";
  880. this->SetError(e.str());
  881. return false;
  882. }
  883. // Switch to setting the configurations property.
  884. doing = DoingConfigurations;
  885. } else if (args[i] == "COMPONENT") {
  886. if (in_match_mode) {
  887. std::ostringstream e;
  888. e << args[0] << " does not allow \"" << args[i]
  889. << "\" after PATTERN or REGEX.";
  890. this->SetError(e.str());
  891. return false;
  892. }
  893. // Switch to setting the component property.
  894. doing = DoingComponent;
  895. } else if (args[i] == "EXCLUDE_FROM_ALL") {
  896. if (in_match_mode) {
  897. std::ostringstream e;
  898. e << args[0] << " does not allow \"" << args[i]
  899. << "\" after PATTERN or REGEX.";
  900. this->SetError(e.str().c_str());
  901. return false;
  902. }
  903. exclude_from_all = true;
  904. doing = DoingNone;
  905. } else if (doing == DoingDirs) {
  906. // Convert this directory to a full path.
  907. std::string dir = args[i];
  908. std::string::size_type gpos = cmGeneratorExpression::Find(dir);
  909. if (gpos != 0 && !cmSystemTools::FileIsFullPath(dir.c_str())) {
  910. dir = this->Makefile->GetCurrentSourceDirectory();
  911. dir += "/";
  912. dir += args[i];
  913. }
  914. // Make sure the name is a directory.
  915. if (cmSystemTools::FileExists(dir.c_str()) &&
  916. !cmSystemTools::FileIsDirectory(dir)) {
  917. std::ostringstream e;
  918. e << args[0] << " given non-directory \"" << args[i]
  919. << "\" to install.";
  920. this->SetError(e.str());
  921. return false;
  922. }
  923. // Store the directory for installation.
  924. dirs.push_back(dir);
  925. } else if (doing == DoingConfigurations) {
  926. configurations.push_back(args[i]);
  927. } else if (doing == DoingDestination) {
  928. destination = args[i].c_str();
  929. doing = DoingNone;
  930. } else if (doing == DoingPattern) {
  931. // Convert the pattern to a regular expression. Require a
  932. // leading slash and trailing end-of-string in the matched
  933. // string to make sure the pattern matches only whole file
  934. // names.
  935. literal_args += " REGEX \"/";
  936. std::string regex = cmsys::Glob::PatternToRegex(args[i], false);
  937. cmSystemTools::ReplaceString(regex, "\\", "\\\\");
  938. literal_args += regex;
  939. literal_args += "$\"";
  940. doing = DoingNone;
  941. } else if (doing == DoingRegex) {
  942. literal_args += " REGEX \"";
  943. // Match rules are case-insensitive on some platforms.
  944. #if defined(_WIN32) || defined(__APPLE__) || defined(__CYGWIN__)
  945. std::string regex = cmSystemTools::LowerCase(args[i]);
  946. #else
  947. std::string regex = args[i];
  948. #endif
  949. cmSystemTools::ReplaceString(regex, "\\", "\\\\");
  950. literal_args += regex;
  951. literal_args += "\"";
  952. doing = DoingNone;
  953. } else if (doing == DoingComponent) {
  954. component = args[i];
  955. doing = DoingNone;
  956. } else if (doing == DoingPermsFile) {
  957. // Check the requested permission.
  958. if (!cmInstallCommandArguments::CheckPermissions(args[i],
  959. permissions_file)) {
  960. std::ostringstream e;
  961. e << args[0] << " given invalid file permission \"" << args[i]
  962. << "\".";
  963. this->SetError(e.str());
  964. return false;
  965. }
  966. } else if (doing == DoingPermsDir) {
  967. // Check the requested permission.
  968. if (!cmInstallCommandArguments::CheckPermissions(args[i],
  969. permissions_dir)) {
  970. std::ostringstream e;
  971. e << args[0] << " given invalid directory permission \"" << args[i]
  972. << "\".";
  973. this->SetError(e.str());
  974. return false;
  975. }
  976. } else if (doing == DoingPermsMatch) {
  977. // Check the requested permission.
  978. if (!cmInstallCommandArguments::CheckPermissions(args[i],
  979. literal_args)) {
  980. std::ostringstream e;
  981. e << args[0] << " given invalid permission \"" << args[i] << "\".";
  982. this->SetError(e.str());
  983. return false;
  984. }
  985. } else {
  986. // Unknown argument.
  987. std::ostringstream e;
  988. e << args[0] << " given unknown argument \"" << args[i] << "\".";
  989. this->SetError(e.str());
  990. return false;
  991. }
  992. }
  993. // Support installing an empty directory.
  994. if (dirs.empty() && destination) {
  995. dirs.push_back("");
  996. }
  997. // Check if there is something to do.
  998. if (dirs.empty()) {
  999. return true;
  1000. }
  1001. if (!destination) {
  1002. // A destination is required.
  1003. std::ostringstream e;
  1004. e << args[0] << " given no DESTINATION!";
  1005. this->SetError(e.str());
  1006. return false;
  1007. }
  1008. cmInstallGenerator::MessageLevel message =
  1009. cmInstallGenerator::SelectMessageLevel(this->Makefile, message_never);
  1010. // Create the directory install generator.
  1011. this->Makefile->AddInstallGenerator(new cmInstallDirectoryGenerator(
  1012. dirs, destination, permissions_file.c_str(), permissions_dir.c_str(),
  1013. configurations, component.c_str(), message, exclude_from_all,
  1014. literal_args.c_str(), optional));
  1015. // Tell the global generator about any installation component names
  1016. // specified.
  1017. this->Makefile->GetGlobalGenerator()->AddInstallComponent(component.c_str());
  1018. return true;
  1019. }
  1020. bool cmInstallCommand::HandleExportAndroidMKMode(
  1021. std::vector<std::string> const& args)
  1022. {
  1023. #ifdef CMAKE_BUILD_WITH_CMAKE
  1024. // This is the EXPORT mode.
  1025. cmInstallCommandArguments ica(this->DefaultComponentName);
  1026. cmCAString exp(&ica.Parser, "EXPORT_ANDROID_MK");
  1027. cmCAString name_space(&ica.Parser, "NAMESPACE", &ica.ArgumentGroup);
  1028. cmCAEnabler exportOld(&ica.Parser, "EXPORT_LINK_INTERFACE_LIBRARIES",
  1029. &ica.ArgumentGroup);
  1030. cmCAString filename(&ica.Parser, "FILE", &ica.ArgumentGroup);
  1031. exp.Follows(0);
  1032. ica.ArgumentGroup.Follows(&exp);
  1033. std::vector<std::string> unknownArgs;
  1034. ica.Parse(&args, &unknownArgs);
  1035. if (!unknownArgs.empty()) {
  1036. // Unknown argument.
  1037. std::ostringstream e;
  1038. e << args[0] << " given unknown argument \"" << unknownArgs[0] << "\".";
  1039. this->SetError(e.str());
  1040. return false;
  1041. }
  1042. if (!ica.Finalize()) {
  1043. return false;
  1044. }
  1045. // Make sure there is a destination.
  1046. if (ica.GetDestination().empty()) {
  1047. // A destination is required.
  1048. std::ostringstream e;
  1049. e << args[0] << " given no DESTINATION!";
  1050. this->SetError(e.str());
  1051. return false;
  1052. }
  1053. // Check the file name.
  1054. std::string fname = filename.GetString();
  1055. if (fname.find_first_of(":/\\") != fname.npos) {
  1056. std::ostringstream e;
  1057. e << args[0] << " given invalid export file name \"" << fname << "\". "
  1058. << "The FILE argument may not contain a path. "
  1059. << "Specify the path in the DESTINATION argument.";
  1060. this->SetError(e.str());
  1061. return false;
  1062. }
  1063. // Check the file extension.
  1064. if (!fname.empty() &&
  1065. cmSystemTools::GetFilenameLastExtension(fname) != ".mk") {
  1066. std::ostringstream e;
  1067. e << args[0] << " given invalid export file name \"" << fname << "\". "
  1068. << "The FILE argument must specify a name ending in \".mk\".";
  1069. this->SetError(e.str());
  1070. return false;
  1071. }
  1072. if (fname.find_first_of(":/\\") != fname.npos) {
  1073. std::ostringstream e;
  1074. e << args[0] << " given export name \"" << exp.GetString() << "\". "
  1075. << "This name cannot be safely converted to a file name. "
  1076. << "Specify a different export name or use the FILE option to set "
  1077. << "a file name explicitly.";
  1078. this->SetError(e.str());
  1079. return false;
  1080. }
  1081. // Use the default name
  1082. if (fname.empty()) {
  1083. fname = "Android.mk";
  1084. }
  1085. cmExportSet* exportSet =
  1086. this->Makefile->GetGlobalGenerator()->GetExportSets()[exp.GetString()];
  1087. cmInstallGenerator::MessageLevel message =
  1088. cmInstallGenerator::SelectMessageLevel(this->Makefile);
  1089. // Create the export install generator.
  1090. cmInstallExportGenerator* exportGenerator = new cmInstallExportGenerator(
  1091. exportSet, ica.GetDestination().c_str(), ica.GetPermissions().c_str(),
  1092. ica.GetConfigurations(), ica.GetComponent().c_str(), message,
  1093. ica.GetExcludeFromAll(), fname.c_str(), name_space.GetCString(),
  1094. exportOld.IsEnabled(), true);
  1095. this->Makefile->AddInstallGenerator(exportGenerator);
  1096. return true;
  1097. #else
  1098. static_cast<void>(args);
  1099. this->SetError("EXPORT_ANDROID_MK not supported in bootstrap cmake");
  1100. return false;
  1101. #endif
  1102. }
  1103. bool cmInstallCommand::HandleExportMode(std::vector<std::string> const& args)
  1104. {
  1105. // This is the EXPORT mode.
  1106. cmInstallCommandArguments ica(this->DefaultComponentName);
  1107. cmCAString exp(&ica.Parser, "EXPORT");
  1108. cmCAString name_space(&ica.Parser, "NAMESPACE", &ica.ArgumentGroup);
  1109. cmCAEnabler exportOld(&ica.Parser, "EXPORT_LINK_INTERFACE_LIBRARIES",
  1110. &ica.ArgumentGroup);
  1111. cmCAString filename(&ica.Parser, "FILE", &ica.ArgumentGroup);
  1112. exp.Follows(CM_NULLPTR);
  1113. ica.ArgumentGroup.Follows(&exp);
  1114. std::vector<std::string> unknownArgs;
  1115. ica.Parse(&args, &unknownArgs);
  1116. if (!unknownArgs.empty()) {
  1117. // Unknown argument.
  1118. std::ostringstream e;
  1119. e << args[0] << " given unknown argument \"" << unknownArgs[0] << "\".";
  1120. this->SetError(e.str());
  1121. return false;
  1122. }
  1123. if (!ica.Finalize()) {
  1124. return false;
  1125. }
  1126. // Make sure there is a destination.
  1127. if (ica.GetDestination().empty()) {
  1128. // A destination is required.
  1129. std::ostringstream e;
  1130. e << args[0] << " given no DESTINATION!";
  1131. this->SetError(e.str());
  1132. return false;
  1133. }
  1134. // Check the file name.
  1135. std::string fname = filename.GetString();
  1136. if (fname.find_first_of(":/\\") != fname.npos) {
  1137. std::ostringstream e;
  1138. e << args[0] << " given invalid export file name \"" << fname << "\". "
  1139. << "The FILE argument may not contain a path. "
  1140. << "Specify the path in the DESTINATION argument.";
  1141. this->SetError(e.str());
  1142. return false;
  1143. }
  1144. // Check the file extension.
  1145. if (!fname.empty() &&
  1146. cmSystemTools::GetFilenameLastExtension(fname) != ".cmake") {
  1147. std::ostringstream e;
  1148. e << args[0] << " given invalid export file name \"" << fname << "\". "
  1149. << "The FILE argument must specify a name ending in \".cmake\".";
  1150. this->SetError(e.str());
  1151. return false;
  1152. }
  1153. // Construct the file name.
  1154. if (fname.empty()) {
  1155. fname = exp.GetString();
  1156. fname += ".cmake";
  1157. if (fname.find_first_of(":/\\") != fname.npos) {
  1158. std::ostringstream e;
  1159. e << args[0] << " given export name \"" << exp.GetString() << "\". "
  1160. << "This name cannot be safely converted to a file name. "
  1161. << "Specify a different export name or use the FILE option to set "
  1162. << "a file name explicitly.";
  1163. this->SetError(e.str());
  1164. return false;
  1165. }
  1166. }
  1167. cmExportSet* exportSet =
  1168. this->Makefile->GetGlobalGenerator()->GetExportSets()[exp.GetString()];
  1169. if (exportOld.IsEnabled()) {
  1170. for (std::vector<cmTargetExport*>::const_iterator tei =
  1171. exportSet->GetTargetExports()->begin();
  1172. tei != exportSet->GetTargetExports()->end(); ++tei) {
  1173. cmTargetExport const* te = *tei;
  1174. cmTarget* tgt =
  1175. this->Makefile->GetGlobalGenerator()->FindTarget(te->TargetName);
  1176. const bool newCMP0022Behavior =
  1177. (tgt && tgt->GetPolicyStatusCMP0022() != cmPolicies::WARN &&
  1178. tgt->GetPolicyStatusCMP0022() != cmPolicies::OLD);
  1179. if (!newCMP0022Behavior) {
  1180. std::ostringstream e;
  1181. e << "INSTALL(EXPORT) given keyword \""
  1182. << "EXPORT_LINK_INTERFACE_LIBRARIES"
  1183. << "\", but target \"" << te->TargetName
  1184. << "\" does not have policy CMP0022 set to NEW.";
  1185. this->SetError(e.str());
  1186. return false;
  1187. }
  1188. }
  1189. }
  1190. cmInstallGenerator::MessageLevel message =
  1191. cmInstallGenerator::SelectMessageLevel(this->Makefile);
  1192. // Create the export install generator.
  1193. cmInstallExportGenerator* exportGenerator = new cmInstallExportGenerator(
  1194. exportSet, ica.GetDestination().c_str(), ica.GetPermissions().c_str(),
  1195. ica.GetConfigurations(), ica.GetComponent().c_str(), message,
  1196. ica.GetExcludeFromAll(), fname.c_str(), name_space.GetCString(),
  1197. exportOld.IsEnabled(), false);
  1198. this->Makefile->AddInstallGenerator(exportGenerator);
  1199. return true;
  1200. }
  1201. bool cmInstallCommand::MakeFilesFullPath(
  1202. const char* modeName, const std::vector<std::string>& relFiles,
  1203. std::vector<std::string>& absFiles)
  1204. {
  1205. for (std::vector<std::string>::const_iterator fileIt = relFiles.begin();
  1206. fileIt != relFiles.end(); ++fileIt) {
  1207. std::string file = (*fileIt);
  1208. std::string::size_type gpos = cmGeneratorExpression::Find(file);
  1209. if (gpos != 0 && !cmSystemTools::FileIsFullPath(file.c_str())) {
  1210. file = this->Makefile->GetCurrentSourceDirectory();
  1211. file += "/";
  1212. file += *fileIt;
  1213. }
  1214. // Make sure the file is not a directory.
  1215. if (gpos == file.npos && cmSystemTools::FileIsDirectory(file)) {
  1216. std::ostringstream e;
  1217. e << modeName << " given directory \"" << (*fileIt) << "\" to install.";
  1218. this->SetError(e.str());
  1219. return false;
  1220. }
  1221. // Store the file for installation.
  1222. absFiles.push_back(file);
  1223. }
  1224. return true;
  1225. }
  1226. bool cmInstallCommand::CheckCMP0006(bool& failure)
  1227. {
  1228. switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0006)) {
  1229. case cmPolicies::WARN: {
  1230. this->Makefile->IssueMessage(
  1231. cmake::AUTHOR_WARNING,
  1232. cmPolicies::GetPolicyWarning(cmPolicies::CMP0006));
  1233. }
  1234. case cmPolicies::OLD:
  1235. // OLD behavior is to allow compatibility
  1236. return true;
  1237. case cmPolicies::NEW:
  1238. // NEW behavior is to disallow compatibility
  1239. break;
  1240. case cmPolicies::REQUIRED_IF_USED:
  1241. case cmPolicies::REQUIRED_ALWAYS:
  1242. failure = true;
  1243. this->Makefile->IssueMessage(
  1244. cmake::FATAL_ERROR,
  1245. cmPolicies::GetRequiredPolicyError(cmPolicies::CMP0006));
  1246. break;
  1247. }
  1248. return false;
  1249. }