1 /*============================================================================
2 CMake - Cross Platform Makefile Generator
3 Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
5 Distributed under the OSI-approved BSD License (the "License");
6 see accompanying file Copyright.txt for details.
8 This software is distributed WITHOUT ANY WARRANTY; without even the
9 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
10 See the License for more information.
11 ============================================================================*/
12 #include "cmInstallCommand.h"
14 #include "cmInstallDirectoryGenerator.h"
15 #include "cmInstallFilesGenerator.h"
16 #include "cmInstallScriptGenerator.h"
17 #include "cmInstallTargetGenerator.h"
18 #include "cmInstallExportGenerator.h"
19 #include "cmInstallCommandArguments.h"
20 #include "cmTargetExport.h"
21 #include "cmExportSet.h"
23 #include <cmsys/Glob.hxx>
25 static cmInstallTargetGenerator* CreateInstallTargetGenerator(cmTarget& target,
26 const cmInstallCommandArguments& args, bool impLib, bool forceOpt = false)
28 return new cmInstallTargetGenerator(target, args.GetDestination().c_str(),
29 impLib, args.GetPermissions().c_str(),
30 args.GetConfigurations(), args.GetComponent().c_str(),
31 args.GetOptional() || forceOpt);
34 static cmInstallFilesGenerator* CreateInstallFilesGenerator(
35 const std::vector<std::string>& absFiles,
36 const cmInstallCommandArguments& args, bool programs)
38 return new cmInstallFilesGenerator(absFiles, args.GetDestination().c_str(),
39 programs, args.GetPermissions().c_str(),
40 args.GetConfigurations(), args.GetComponent().c_str(),
41 args.GetRename().c_str(), args.GetOptional());
46 bool cmInstallCommand::InitialPass(std::vector<std::string> const& args,
49 // Allow calling with no arguments so that arguments may be built up
50 // using a variable that may be left empty.
56 // Enable the install target.
57 this->Makefile->GetLocalGenerator()
58 ->GetGlobalGenerator()->EnableInstallTarget();
60 this->DefaultComponentName = this->Makefile->GetSafeDefinition(
61 "CMAKE_INSTALL_DEFAULT_COMPONENT_NAME");
62 if (this->DefaultComponentName.empty())
64 this->DefaultComponentName = "Unspecified";
67 // Switch among the command modes.
68 if(args[0] == "SCRIPT")
70 return this->HandleScriptMode(args);
72 else if(args[0] == "CODE")
74 return this->HandleScriptMode(args);
76 else if(args[0] == "TARGETS")
78 return this->HandleTargetsMode(args);
80 else if(args[0] == "FILES")
82 return this->HandleFilesMode(args);
84 else if(args[0] == "PROGRAMS")
86 return this->HandleFilesMode(args);
88 else if(args[0] == "DIRECTORY")
90 return this->HandleDirectoryMode(args);
92 else if(args[0] == "EXPORT")
94 return this->HandleExportMode(args);
98 cmStdString e = "called with unknown mode ";
100 this->SetError(e.c_str());
104 //----------------------------------------------------------------------------
105 bool cmInstallCommand::HandleScriptMode(std::vector<std::string> const& args)
107 std::string component = this->DefaultComponentName;
108 int componentCount = 0;
109 bool doing_script = false;
110 bool doing_code = false;
112 // Scan the args once for COMPONENT. Only allow one.
114 for(size_t i=0; i < args.size(); ++i)
116 if(args[i] == "COMPONENT" && i+1 < args.size())
126 this->SetError("given more than one COMPONENT for the SCRIPT or CODE "
127 "signature of the INSTALL command. "
128 "Use multiple INSTALL commands with one COMPONENT each.");
132 // Scan the args again, this time adding install generators each time we
133 // encounter a SCRIPT or CODE arg:
135 for(size_t i=0; i < args.size(); ++i)
137 if(args[i] == "SCRIPT")
142 else if(args[i] == "CODE")
144 doing_script = false;
147 else if(args[i] == "COMPONENT")
149 doing_script = false;
152 else if(doing_script)
154 doing_script = false;
155 std::string script = args[i];
156 if(!cmSystemTools::FileIsFullPath(script.c_str()))
158 script = this->Makefile->GetCurrentDirectory();
162 if(cmSystemTools::FileIsDirectory(script.c_str()))
164 this->SetError("given a directory as value of SCRIPT argument.");
167 this->Makefile->AddInstallGenerator(
168 new cmInstallScriptGenerator(script.c_str(), false,
174 std::string code = args[i];
175 this->Makefile->AddInstallGenerator(
176 new cmInstallScriptGenerator(code.c_str(), true,
183 this->SetError("given no value for SCRIPT argument.");
188 this->SetError("given no value for CODE argument.");
192 //Tell the global generator about any installation component names specified.
193 this->Makefile->GetLocalGenerator()->GetGlobalGenerator()
194 ->AddInstallComponent(component.c_str());
202 InstallPart(cmCommandArgumentsHelper* helper, const char* key,
203 cmCommandArgumentGroup* group);
204 cmCAStringVector argVector;
205 cmInstallCommandArguments args;
208 //----------------------------------------------------------------------------
209 bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
211 // This is the TARGETS mode.
212 std::vector<cmTarget*> targets;
214 cmCommandArgumentsHelper argHelper;
215 cmCommandArgumentGroup group;
216 cmCAStringVector genericArgVector (&argHelper,0);
217 cmCAStringVector archiveArgVector (&argHelper,"ARCHIVE",&group);
218 cmCAStringVector libraryArgVector (&argHelper,"LIBRARY",&group);
219 cmCAStringVector runtimeArgVector (&argHelper,"RUNTIME",&group);
220 cmCAStringVector frameworkArgVector (&argHelper,"FRAMEWORK",&group);
221 cmCAStringVector bundleArgVector (&argHelper,"BUNDLE",&group);
222 cmCAStringVector includesArgVector (&argHelper,"INCLUDES",&group);
223 cmCAStringVector privateHeaderArgVector(&argHelper,"PRIVATE_HEADER",&group);
224 cmCAStringVector publicHeaderArgVector (&argHelper,"PUBLIC_HEADER",&group);
225 cmCAStringVector resourceArgVector (&argHelper,"RESOURCE",&group);
226 genericArgVector.Follows(0);
227 group.Follows(&genericArgVector);
229 argHelper.Parse(&args, 0);
231 // now parse the generic args (i.e. the ones not specialized on LIBRARY/
232 // ARCHIVE, RUNTIME etc. (see above)
233 // These generic args also contain the targets and the export stuff
234 std::vector<std::string> unknownArgs;
235 cmInstallCommandArguments genericArgs(this->DefaultComponentName);
236 cmCAStringVector targetList(&genericArgs.Parser, "TARGETS");
237 cmCAString exports(&genericArgs.Parser,"EXPORT", &genericArgs.ArgumentGroup);
238 targetList.Follows(0);
239 genericArgs.ArgumentGroup.Follows(&targetList);
240 genericArgs.Parse(&genericArgVector.GetVector(), &unknownArgs);
241 bool success = genericArgs.Finalize();
243 cmInstallCommandArguments archiveArgs(this->DefaultComponentName);
244 cmInstallCommandArguments libraryArgs(this->DefaultComponentName);
245 cmInstallCommandArguments runtimeArgs(this->DefaultComponentName);
246 cmInstallCommandArguments frameworkArgs(this->DefaultComponentName);
247 cmInstallCommandArguments bundleArgs(this->DefaultComponentName);
248 cmInstallCommandArguments privateHeaderArgs(this->DefaultComponentName);
249 cmInstallCommandArguments publicHeaderArgs(this->DefaultComponentName);
250 cmInstallCommandArguments resourceArgs(this->DefaultComponentName);
251 cmInstallCommandIncludesArgument includesArgs;
253 // now parse the args for specific parts of the target (e.g. LIBRARY,
254 // RUNTIME, ARCHIVE etc.
255 archiveArgs.Parse (&archiveArgVector.GetVector(), &unknownArgs);
256 libraryArgs.Parse (&libraryArgVector.GetVector(), &unknownArgs);
257 runtimeArgs.Parse (&runtimeArgVector.GetVector(), &unknownArgs);
258 frameworkArgs.Parse (&frameworkArgVector.GetVector(), &unknownArgs);
259 bundleArgs.Parse (&bundleArgVector.GetVector(), &unknownArgs);
260 privateHeaderArgs.Parse(&privateHeaderArgVector.GetVector(), &unknownArgs);
261 publicHeaderArgs.Parse (&publicHeaderArgVector.GetVector(), &unknownArgs);
262 resourceArgs.Parse (&resourceArgVector.GetVector(), &unknownArgs);
263 includesArgs.Parse (&includesArgVector.GetVector(), &unknownArgs);
265 if(!unknownArgs.empty())
269 e << "TARGETS given unknown argument \"" << unknownArgs[0] << "\".";
270 this->SetError(e.str().c_str());
274 // apply generic args
275 archiveArgs.SetGenericArguments(&genericArgs);
276 libraryArgs.SetGenericArguments(&genericArgs);
277 runtimeArgs.SetGenericArguments(&genericArgs);
278 frameworkArgs.SetGenericArguments(&genericArgs);
279 bundleArgs.SetGenericArguments(&genericArgs);
280 privateHeaderArgs.SetGenericArguments(&genericArgs);
281 publicHeaderArgs.SetGenericArguments(&genericArgs);
282 resourceArgs.SetGenericArguments(&genericArgs);
284 success = success && archiveArgs.Finalize();
285 success = success && libraryArgs.Finalize();
286 success = success && runtimeArgs.Finalize();
287 success = success && frameworkArgs.Finalize();
288 success = success && bundleArgs.Finalize();
289 success = success && privateHeaderArgs.Finalize();
290 success = success && publicHeaderArgs.Finalize();
291 success = success && resourceArgs.Finalize();
298 // Enforce argument rules too complex to specify for the
299 // general-purpose parser.
300 if(archiveArgs.GetNamelinkOnly() ||
301 runtimeArgs.GetNamelinkOnly() ||
302 frameworkArgs.GetNamelinkOnly() ||
303 bundleArgs.GetNamelinkOnly() ||
304 privateHeaderArgs.GetNamelinkOnly() ||
305 publicHeaderArgs.GetNamelinkOnly() ||
306 resourceArgs.GetNamelinkOnly())
309 "TARGETS given NAMELINK_ONLY option not in LIBRARY group. "
310 "The NAMELINK_ONLY option may be specified only following LIBRARY."
314 if(archiveArgs.GetNamelinkSkip() ||
315 runtimeArgs.GetNamelinkSkip() ||
316 frameworkArgs.GetNamelinkSkip() ||
317 bundleArgs.GetNamelinkSkip() ||
318 privateHeaderArgs.GetNamelinkSkip() ||
319 publicHeaderArgs.GetNamelinkSkip() ||
320 resourceArgs.GetNamelinkSkip())
323 "TARGETS given NAMELINK_SKIP option not in LIBRARY group. "
324 "The NAMELINK_SKIP option may be specified only following LIBRARY."
328 if(libraryArgs.GetNamelinkOnly() && libraryArgs.GetNamelinkSkip())
331 "TARGETS given NAMELINK_ONLY and NAMELINK_SKIP. "
332 "At most one of these two options may be specified."
337 // Select the mode for installing symlinks to versioned shared libraries.
338 cmInstallTargetGenerator::NamelinkModeType
339 namelinkMode = cmInstallTargetGenerator::NamelinkModeNone;
340 if(libraryArgs.GetNamelinkOnly())
342 namelinkMode = cmInstallTargetGenerator::NamelinkModeOnly;
344 else if(libraryArgs.GetNamelinkSkip())
346 namelinkMode = cmInstallTargetGenerator::NamelinkModeSkip;
349 // Check if there is something to do.
350 if(targetList.GetVector().empty())
355 // Check whether this is a DLL platform.
356 bool dll_platform = (this->Makefile->IsOn("WIN32") ||
357 this->Makefile->IsOn("CYGWIN") ||
358 this->Makefile->IsOn("MINGW"));
360 for(std::vector<std::string>::const_iterator
361 targetIt=targetList.GetVector().begin();
362 targetIt!=targetList.GetVector().end();
366 if (this->Makefile->IsAlias(targetIt->c_str()))
369 e << "TARGETS given target \"" << (*targetIt)
370 << "\" which is an alias.";
371 this->SetError(e.str().c_str());
374 // Lookup this target in the current directory.
375 if(cmTarget* target=this->Makefile->FindTarget(targetIt->c_str()))
377 // Found the target. Check its type.
378 if(target->GetType() != cmTarget::EXECUTABLE &&
379 target->GetType() != cmTarget::STATIC_LIBRARY &&
380 target->GetType() != cmTarget::SHARED_LIBRARY &&
381 target->GetType() != cmTarget::MODULE_LIBRARY &&
382 target->GetType() != cmTarget::OBJECT_LIBRARY)
385 e << "TARGETS given target \"" << (*targetIt)
386 << "\" which is not an executable, library, or module.";
387 this->SetError(e.str().c_str());
390 else if(target->GetType() == cmTarget::OBJECT_LIBRARY)
393 e << "TARGETS given OBJECT library \"" << (*targetIt)
394 << "\" which may not be installed.";
395 this->SetError(e.str().c_str());
398 // Store the target in the list to be installed.
399 targets.push_back(target);
403 // Did not find the target.
405 e << "TARGETS given target \"" << (*targetIt)
406 << "\" which does not exist in this directory.";
407 this->SetError(e.str().c_str());
412 // Keep track of whether we will be performing an installation of
413 // any files of the given type.
414 bool installsArchive = false;
415 bool installsLibrary = false;
416 bool installsRuntime = false;
417 bool installsFramework = false;
418 bool installsBundle = false;
419 bool installsPrivateHeader = false;
420 bool installsPublicHeader = false;
421 bool installsResource = false;
423 // Generate install script code to install the given targets.
424 for(std::vector<cmTarget*>::iterator ti = targets.begin();
425 ti != targets.end(); ++ti)
427 // Handle each target type.
428 cmTarget& target = *(*ti);
429 cmInstallTargetGenerator* archiveGenerator = 0;
430 cmInstallTargetGenerator* libraryGenerator = 0;
431 cmInstallTargetGenerator* runtimeGenerator = 0;
432 cmInstallTargetGenerator* frameworkGenerator = 0;
433 cmInstallTargetGenerator* bundleGenerator = 0;
434 cmInstallFilesGenerator* privateHeaderGenerator = 0;
435 cmInstallFilesGenerator* publicHeaderGenerator = 0;
436 cmInstallFilesGenerator* resourceGenerator = 0;
438 // Track whether this is a namelink-only rule.
439 bool namelinkOnly = false;
441 switch(target.GetType())
443 case cmTarget::SHARED_LIBRARY:
445 // Shared libraries are handled differently on DLL and non-DLL
446 // platforms. All windows platforms are DLL platforms including
447 // cygwin. Currently no other platform is a DLL platform.
450 // When in namelink only mode skip all libraries on Windows.
451 if(namelinkMode == cmInstallTargetGenerator::NamelinkModeOnly)
456 // This is a DLL platform.
457 if(!archiveArgs.GetDestination().empty())
459 // The import library uses the ARCHIVE properties.
460 archiveGenerator = CreateInstallTargetGenerator(target,
463 if(!runtimeArgs.GetDestination().empty())
465 // The DLL uses the RUNTIME properties.
466 runtimeGenerator = CreateInstallTargetGenerator(target,
469 if ((archiveGenerator==0) && (runtimeGenerator==0))
471 this->SetError("Library TARGETS given no DESTINATION!");
477 // This is a non-DLL platform.
478 // If it is marked with FRAMEWORK property use the FRAMEWORK set of
479 // INSTALL properties. Otherwise, use the LIBRARY properties.
480 if(target.IsFrameworkOnApple())
482 // When in namelink only mode skip frameworks.
483 if(namelinkMode == cmInstallTargetGenerator::NamelinkModeOnly)
488 // Use the FRAMEWORK properties.
489 if (!frameworkArgs.GetDestination().empty())
491 frameworkGenerator = CreateInstallTargetGenerator(target,
492 frameworkArgs, false);
497 e << "TARGETS given no FRAMEWORK DESTINATION for shared library "
498 "FRAMEWORK target \"" << target.GetName() << "\".";
499 this->SetError(e.str().c_str());
505 // The shared library uses the LIBRARY properties.
506 if (!libraryArgs.GetDestination().empty())
508 libraryGenerator = CreateInstallTargetGenerator(target,
510 libraryGenerator->SetNamelinkMode(namelinkMode);
512 (namelinkMode == cmInstallTargetGenerator::NamelinkModeOnly);
517 e << "TARGETS given no LIBRARY DESTINATION for shared library "
518 "target \"" << target.GetName() << "\".";
519 this->SetError(e.str().c_str());
526 case cmTarget::STATIC_LIBRARY:
528 // Static libraries use ARCHIVE properties.
529 if (!archiveArgs.GetDestination().empty())
531 archiveGenerator = CreateInstallTargetGenerator(target, archiveArgs,
537 e << "TARGETS given no ARCHIVE DESTINATION for static library "
538 "target \"" << target.GetName() << "\".";
539 this->SetError(e.str().c_str());
544 case cmTarget::MODULE_LIBRARY:
546 // Modules use LIBRARY properties.
547 if (!libraryArgs.GetDestination().empty())
549 libraryGenerator = CreateInstallTargetGenerator(target, libraryArgs,
551 libraryGenerator->SetNamelinkMode(namelinkMode);
553 (namelinkMode == cmInstallTargetGenerator::NamelinkModeOnly);
558 e << "TARGETS given no LIBRARY DESTINATION for module target \""
559 << target.GetName() << "\".";
560 this->SetError(e.str().c_str());
565 case cmTarget::EXECUTABLE:
567 if(target.IsAppBundleOnApple())
569 // Application bundles use the BUNDLE properties.
570 if (!bundleArgs.GetDestination().empty())
572 bundleGenerator = CreateInstallTargetGenerator(target, bundleArgs,
575 else if(!runtimeArgs.GetDestination().empty())
577 bool failure = false;
578 if(this->CheckCMP0006(failure))
580 // For CMake 2.4 compatibility fallback to the RUNTIME
583 CreateInstallTargetGenerator(target, runtimeArgs, false);
593 e << "TARGETS given no BUNDLE DESTINATION for MACOSX_BUNDLE "
594 "executable target \"" << target.GetName() << "\".";
595 this->SetError(e.str().c_str());
601 // Executables use the RUNTIME properties.
602 if (!runtimeArgs.GetDestination().empty())
604 runtimeGenerator = CreateInstallTargetGenerator(target,
610 e << "TARGETS given no RUNTIME DESTINATION for executable "
611 "target \"" << target.GetName() << "\".";
612 this->SetError(e.str().c_str());
617 // On DLL platforms an executable may also have an import
618 // library. Install it to the archive destination if it
620 if(dll_platform && !archiveArgs.GetDestination().empty() &&
621 target.IsExecutableWithExports())
623 // The import library uses the ARCHIVE properties.
624 archiveGenerator = CreateInstallTargetGenerator(target,
625 archiveArgs, true, true);
630 // This should never happen due to the above type check.
635 // These well-known sets of files are installed *automatically* for
636 // FRAMEWORK SHARED library targets on the Mac as part of installing the
637 // FRAMEWORK. For other target types or on other platforms, they are not
638 // installed automatically and so we need to create install files
639 // generators for them.
640 bool createInstallGeneratorsForTargetFileSets = true;
642 if(target.IsFrameworkOnApple())
644 createInstallGeneratorsForTargetFileSets = false;
647 if(createInstallGeneratorsForTargetFileSets && !namelinkOnly)
649 const char* files = target.GetProperty("PRIVATE_HEADER");
650 if ((files) && (*files))
652 std::vector<std::string> relFiles;
653 cmSystemTools::ExpandListArgument(files, relFiles);
654 std::vector<std::string> absFiles;
655 if (!this->MakeFilesFullPath("PRIVATE_HEADER", relFiles, absFiles))
660 // Create the files install generator.
661 if (!privateHeaderArgs.GetDestination().empty())
663 privateHeaderGenerator =
664 CreateInstallFilesGenerator(absFiles, privateHeaderArgs, false);
669 e << "INSTALL TARGETS - target " << target.GetName() << " has "
670 << "PRIVATE_HEADER files but no PRIVATE_HEADER DESTINATION.";
671 cmSystemTools::Message(e.str().c_str(), "Warning");
675 files = target.GetProperty("PUBLIC_HEADER");
676 if ((files) && (*files))
678 std::vector<std::string> relFiles;
679 cmSystemTools::ExpandListArgument(files, relFiles);
680 std::vector<std::string> absFiles;
681 if (!this->MakeFilesFullPath("PUBLIC_HEADER", relFiles, absFiles))
686 // Create the files install generator.
687 if (!publicHeaderArgs.GetDestination().empty())
689 publicHeaderGenerator =
690 CreateInstallFilesGenerator(absFiles, publicHeaderArgs, false);
695 e << "INSTALL TARGETS - target " << target.GetName() << " has "
696 << "PUBLIC_HEADER files but no PUBLIC_HEADER DESTINATION.";
697 cmSystemTools::Message(e.str().c_str(), "Warning");
701 files = target.GetProperty("RESOURCE");
702 if ((files) && (*files))
704 std::vector<std::string> relFiles;
705 cmSystemTools::ExpandListArgument(files, relFiles);
706 std::vector<std::string> absFiles;
707 if (!this->MakeFilesFullPath("RESOURCE", relFiles, absFiles))
712 // Create the files install generator.
713 if (!resourceArgs.GetDestination().empty())
715 resourceGenerator = CreateInstallFilesGenerator(absFiles,
716 resourceArgs, false);
721 e << "INSTALL TARGETS - target " << target.GetName() << " has "
722 << "RESOURCE files but no RESOURCE DESTINATION.";
723 cmSystemTools::Message(e.str().c_str(), "Warning");
728 // Keep track of whether we're installing anything in each category
729 installsArchive = installsArchive || archiveGenerator != 0;
730 installsLibrary = installsLibrary || libraryGenerator != 0;
731 installsRuntime = installsRuntime || runtimeGenerator != 0;
732 installsFramework = installsFramework || frameworkGenerator != 0;
733 installsBundle = installsBundle || bundleGenerator != 0;
734 installsPrivateHeader = installsPrivateHeader
735 || privateHeaderGenerator != 0;
736 installsPublicHeader = installsPublicHeader || publicHeaderGenerator != 0;
737 installsResource = installsResource || resourceGenerator;
739 this->Makefile->AddInstallGenerator(archiveGenerator);
740 this->Makefile->AddInstallGenerator(libraryGenerator);
741 this->Makefile->AddInstallGenerator(runtimeGenerator);
742 this->Makefile->AddInstallGenerator(frameworkGenerator);
743 this->Makefile->AddInstallGenerator(bundleGenerator);
744 this->Makefile->AddInstallGenerator(privateHeaderGenerator);
745 this->Makefile->AddInstallGenerator(publicHeaderGenerator);
746 this->Makefile->AddInstallGenerator(resourceGenerator);
748 // Add this install rule to an export if one was specified and
749 // this is not a namelink-only rule.
750 if(!exports.GetString().empty() && !namelinkOnly)
752 cmTargetExport *te = new cmTargetExport;
753 te->Target = ⌖
754 te->ArchiveGenerator = archiveGenerator;
755 te->BundleGenerator = bundleGenerator;
756 te->FrameworkGenerator = frameworkGenerator;
757 te->HeaderGenerator = publicHeaderGenerator;
758 te->LibraryGenerator = libraryGenerator;
759 te->RuntimeGenerator = runtimeGenerator;
760 this->Makefile->GetLocalGenerator()->GetGlobalGenerator()
761 ->GetExportSets()[exports.GetString()]->AddTargetExport(te);
763 std::vector<std::string> dirs = includesArgs.GetIncludeDirs();
766 std::string dirString;
767 const char *sep = "";
768 for (std::vector<std::string>::const_iterator it = dirs.begin();
769 it != dirs.end(); ++it)
771 te->InterfaceIncludeDirectories += sep;
772 te->InterfaceIncludeDirectories += *it;
779 // Tell the global generator about any installation component names
783 this->Makefile->GetLocalGenerator()->
785 ->AddInstallComponent(archiveArgs.GetComponent().c_str());
789 this->Makefile->GetLocalGenerator()->GetGlobalGenerator()
790 ->AddInstallComponent(libraryArgs.GetComponent().c_str());
794 this->Makefile->GetLocalGenerator()->GetGlobalGenerator()
795 ->AddInstallComponent(runtimeArgs.GetComponent().c_str());
797 if (installsFramework)
799 this->Makefile->GetLocalGenerator()->GetGlobalGenerator()
800 ->AddInstallComponent(frameworkArgs.GetComponent().c_str());
804 this->Makefile->GetLocalGenerator()->GetGlobalGenerator()
805 ->AddInstallComponent(bundleArgs.GetComponent().c_str());
807 if (installsPrivateHeader)
809 this->Makefile->GetLocalGenerator()->GetGlobalGenerator()
810 ->AddInstallComponent(privateHeaderArgs.GetComponent().c_str());
812 if (installsPublicHeader)
814 this->Makefile->GetLocalGenerator()->GetGlobalGenerator()
815 ->AddInstallComponent(publicHeaderArgs.GetComponent().c_str());
817 if (installsResource)
819 this->Makefile->GetLocalGenerator()->GetGlobalGenerator()
820 ->AddInstallComponent(resourceArgs.GetComponent().c_str());
826 //----------------------------------------------------------------------------
827 bool cmInstallCommand::HandleFilesMode(std::vector<std::string> const& args)
829 // This is the FILES mode.
830 bool programs = (args[0] == "PROGRAMS");
831 cmInstallCommandArguments ica(this->DefaultComponentName);
832 cmCAStringVector files(&ica.Parser, programs ? "PROGRAMS" : "FILES");
834 ica.ArgumentGroup.Follows(&files);
835 std::vector<std::string> unknownArgs;
836 ica.Parse(&args, &unknownArgs);
838 if(!unknownArgs.empty())
842 e << args[0] << " given unknown argument \"" << unknownArgs[0] << "\".";
843 this->SetError(e.str().c_str());
847 // Check if there is something to do.
848 if(files.GetVector().empty())
853 if(!ica.GetRename().empty() && files.GetVector().size() > 1)
855 // The rename option works only with one file.
857 e << args[0] << " given RENAME option with more than one file.";
858 this->SetError(e.str().c_str());
862 std::vector<std::string> absFiles;
863 if (!this->MakeFilesFullPath(args[0].c_str(), files.GetVector(), absFiles))
873 if(ica.GetDestination().empty())
875 // A destination is required.
877 e << args[0] << " given no DESTINATION!";
878 this->SetError(e.str().c_str());
882 // Create the files install generator.
883 this->Makefile->AddInstallGenerator(
884 CreateInstallFilesGenerator(absFiles, ica, programs));
886 //Tell the global generator about any installation component names specified.
887 this->Makefile->GetLocalGenerator()->GetGlobalGenerator()
888 ->AddInstallComponent(ica.GetComponent().c_str());
893 //----------------------------------------------------------------------------
895 cmInstallCommand::HandleDirectoryMode(std::vector<std::string> const& args)
897 enum Doing { DoingNone, DoingDirs, DoingDestination, DoingPattern,
898 DoingRegex, DoingPermsFile, DoingPermsDir, DoingPermsMatch,
899 DoingConfigurations, DoingComponent };
900 Doing doing = DoingDirs;
901 bool in_match_mode = false;
902 bool optional = false;
903 std::vector<std::string> dirs;
904 const char* destination = 0;
905 std::string permissions_file;
906 std::string permissions_dir;
907 std::vector<std::string> configurations;
908 std::string component = this->DefaultComponentName;
909 std::string literal_args;
910 for(unsigned int i=1; i < args.size(); ++i)
912 if(args[i] == "DESTINATION")
917 e << args[0] << " does not allow \""
918 << args[i] << "\" after PATTERN or REGEX.";
919 this->SetError(e.str().c_str());
923 // Switch to setting the destination property.
924 doing = DoingDestination;
926 else if(args[i] == "OPTIONAL")
931 e << args[0] << " does not allow \""
932 << args[i] << "\" after PATTERN or REGEX.";
933 this->SetError(e.str().c_str());
937 // Mark the rule as optional.
941 else if(args[i] == "PATTERN")
943 // Switch to a new pattern match rule.
944 doing = DoingPattern;
945 in_match_mode = true;
947 else if(args[i] == "REGEX")
949 // Switch to a new regex match rule.
951 in_match_mode = true;
953 else if(args[i] == "EXCLUDE")
955 // Add this property to the current match rule.
956 if(!in_match_mode || doing == DoingPattern || doing == DoingRegex)
959 e << args[0] << " does not allow \""
960 << args[i] << "\" before a PATTERN or REGEX is given.";
961 this->SetError(e.str().c_str());
964 literal_args += " EXCLUDE";
967 else if(args[i] == "PERMISSIONS")
972 e << args[0] << " does not allow \""
973 << args[i] << "\" before a PATTERN or REGEX is given.";
974 this->SetError(e.str().c_str());
978 // Switch to setting the current match permissions property.
979 literal_args += " PERMISSIONS";
980 doing = DoingPermsMatch;
982 else if(args[i] == "FILE_PERMISSIONS")
987 e << args[0] << " does not allow \""
988 << args[i] << "\" after PATTERN or REGEX.";
989 this->SetError(e.str().c_str());
993 // Switch to setting the file permissions property.
994 doing = DoingPermsFile;
996 else if(args[i] == "DIRECTORY_PERMISSIONS")
1001 e << args[0] << " does not allow \""
1002 << args[i] << "\" after PATTERN or REGEX.";
1003 this->SetError(e.str().c_str());
1007 // Switch to setting the directory permissions property.
1008 doing = DoingPermsDir;
1010 else if(args[i] == "USE_SOURCE_PERMISSIONS")
1015 e << args[0] << " does not allow \""
1016 << args[i] << "\" after PATTERN or REGEX.";
1017 this->SetError(e.str().c_str());
1021 // Add this option literally.
1022 literal_args += " USE_SOURCE_PERMISSIONS";
1025 else if(args[i] == "FILES_MATCHING")
1030 e << args[0] << " does not allow \""
1031 << args[i] << "\" after PATTERN or REGEX.";
1032 this->SetError(e.str().c_str());
1036 // Add this option literally.
1037 literal_args += " FILES_MATCHING";
1040 else if(args[i] == "CONFIGURATIONS")
1045 e << args[0] << " does not allow \""
1046 << args[i] << "\" after PATTERN or REGEX.";
1047 this->SetError(e.str().c_str());
1051 // Switch to setting the configurations property.
1052 doing = DoingConfigurations;
1054 else if(args[i] == "COMPONENT")
1059 e << args[0] << " does not allow \""
1060 << args[i] << "\" after PATTERN or REGEX.";
1061 this->SetError(e.str().c_str());
1065 // Switch to setting the component property.
1066 doing = DoingComponent;
1068 else if(doing == DoingDirs)
1070 // Convert this directory to a full path.
1071 std::string dir = args[i];
1072 if(!cmSystemTools::FileIsFullPath(dir.c_str()))
1074 dir = this->Makefile->GetCurrentDirectory();
1079 // Make sure the name is a directory.
1080 if(cmSystemTools::FileExists(dir.c_str()) &&
1081 !cmSystemTools::FileIsDirectory(dir.c_str()))
1084 e << args[0] << " given non-directory \""
1085 << args[i] << "\" to install.";
1086 this->SetError(e.str().c_str());
1090 // Store the directory for installation.
1091 dirs.push_back(dir);
1093 else if(doing == DoingConfigurations)
1095 configurations.push_back(args[i]);
1097 else if(doing == DoingDestination)
1099 destination = args[i].c_str();
1102 else if(doing == DoingPattern)
1104 // Convert the pattern to a regular expression. Require a
1105 // leading slash and trailing end-of-string in the matched
1106 // string to make sure the pattern matches only whole file
1108 literal_args += " REGEX \"/";
1109 std::string regex = cmsys::Glob::PatternToRegex(args[i], false);
1110 cmSystemTools::ReplaceString(regex, "\\", "\\\\");
1111 literal_args += regex;
1112 literal_args += "$\"";
1115 else if(doing == DoingRegex)
1117 literal_args += " REGEX \"";
1118 // Match rules are case-insensitive on some platforms.
1119 #if defined(_WIN32) || defined(__APPLE__) || defined(__CYGWIN__)
1120 std::string regex = cmSystemTools::LowerCase(args[i]);
1122 std::string regex = args[i];
1124 cmSystemTools::ReplaceString(regex, "\\", "\\\\");
1125 literal_args += regex;
1126 literal_args += "\"";
1129 else if(doing == DoingComponent)
1131 component = args[i];
1134 else if(doing == DoingPermsFile)
1136 // Check the requested permission.
1137 if(!cmInstallCommandArguments::CheckPermissions(args[i],permissions_file))
1140 e << args[0] << " given invalid file permission \""
1141 << args[i] << "\".";
1142 this->SetError(e.str().c_str());
1146 else if(doing == DoingPermsDir)
1148 // Check the requested permission.
1149 if(!cmInstallCommandArguments::CheckPermissions(args[i],permissions_dir))
1152 e << args[0] << " given invalid directory permission \""
1153 << args[i] << "\".";
1154 this->SetError(e.str().c_str());
1158 else if(doing == DoingPermsMatch)
1160 // Check the requested permission.
1161 if(!cmInstallCommandArguments::CheckPermissions(args[i], literal_args))
1164 e << args[0] << " given invalid permission \""
1165 << args[i] << "\".";
1166 this->SetError(e.str().c_str());
1172 // Unknown argument.
1174 e << args[0] << " given unknown argument \"" << args[i] << "\".";
1175 this->SetError(e.str().c_str());
1180 // Support installing an empty directory.
1181 if(dirs.empty() && destination)
1186 // Check if there is something to do.
1193 // A destination is required.
1195 e << args[0] << " given no DESTINATION!";
1196 this->SetError(e.str().c_str());
1200 // Create the directory install generator.
1201 this->Makefile->AddInstallGenerator(
1202 new cmInstallDirectoryGenerator(dirs, destination,
1203 permissions_file.c_str(),
1204 permissions_dir.c_str(),
1207 literal_args.c_str(),
1210 // Tell the global generator about any installation component names
1212 this->Makefile->GetLocalGenerator()->GetGlobalGenerator()
1213 ->AddInstallComponent(component.c_str());
1218 //----------------------------------------------------------------------------
1219 bool cmInstallCommand::HandleExportMode(std::vector<std::string> const& args)
1221 // This is the EXPORT mode.
1222 cmInstallCommandArguments ica(this->DefaultComponentName);
1223 cmCAString exp(&ica.Parser, "EXPORT");
1224 cmCAString name_space(&ica.Parser, "NAMESPACE", &ica.ArgumentGroup);
1225 cmCAEnabler exportOld(&ica.Parser, "EXPORT_LINK_INTERFACE_LIBRARIES",
1226 &ica.ArgumentGroup);
1227 cmCAString filename(&ica.Parser, "FILE", &ica.ArgumentGroup);
1230 ica.ArgumentGroup.Follows(&exp);
1231 std::vector<std::string> unknownArgs;
1232 ica.Parse(&args, &unknownArgs);
1234 if (!unknownArgs.empty())
1236 // Unknown argument.
1238 e << args[0] << " given unknown argument \"" << unknownArgs[0] << "\".";
1239 this->SetError(e.str().c_str());
1243 if (!ica.Finalize())
1248 // Make sure there is a destination.
1249 if(ica.GetDestination().empty())
1251 // A destination is required.
1253 e << args[0] << " given no DESTINATION!";
1254 this->SetError(e.str().c_str());
1258 // Check the file name.
1259 std::string fname = filename.GetString();
1260 if(fname.find_first_of(":/\\") != fname.npos)
1263 e << args[0] << " given invalid export file name \"" << fname << "\". "
1264 << "The FILE argument may not contain a path. "
1265 << "Specify the path in the DESTINATION argument.";
1266 this->SetError(e.str().c_str());
1270 // Check the file extension.
1271 if(!fname.empty() &&
1272 cmSystemTools::GetFilenameLastExtension(fname) != ".cmake")
1275 e << args[0] << " given invalid export file name \"" << fname << "\". "
1276 << "The FILE argument must specify a name ending in \".cmake\".";
1277 this->SetError(e.str().c_str());
1281 // Construct the file name.
1284 fname = exp.GetString();
1287 if(fname.find_first_of(":/\\") != fname.npos)
1290 e << args[0] << " given export name \"" << exp.GetString() << "\". "
1291 << "This name cannot be safely converted to a file name. "
1292 << "Specify a different export name or use the FILE option to set "
1293 << "a file name explicitly.";
1294 this->SetError(e.str().c_str());
1299 cmExportSet *exportSet = this->Makefile->GetLocalGenerator()
1300 ->GetGlobalGenerator()->GetExportSets()[exp.GetString()];
1301 if (exportOld.IsEnabled())
1303 for(std::vector<cmTargetExport*>::const_iterator
1304 tei = exportSet->GetTargetExports()->begin();
1305 tei != exportSet->GetTargetExports()->end(); ++tei)
1307 cmTargetExport const* te = *tei;
1308 const bool newCMP0022Behavior =
1309 te->Target->GetPolicyStatusCMP0022() != cmPolicies::WARN
1310 && te->Target->GetPolicyStatusCMP0022() != cmPolicies::OLD;
1312 if(!newCMP0022Behavior)
1315 e << "INSTALL(EXPORT) given keyword \""
1316 << "EXPORT_LINK_INTERFACE_LIBRARIES" << "\", but target \""
1317 << te->Target->GetName()
1318 << "\" does not have policy CMP0022 set to NEW.";
1319 this->SetError(e.str().c_str());
1325 // Create the export install generator.
1326 cmInstallExportGenerator* exportGenerator =
1327 new cmInstallExportGenerator(
1329 ica.GetDestination().c_str(),
1330 ica.GetPermissions().c_str(), ica.GetConfigurations(),
1331 ica.GetComponent().c_str(), fname.c_str(),
1332 name_space.GetCString(), exportOld.IsEnabled(), this->Makefile);
1333 this->Makefile->AddInstallGenerator(exportGenerator);
1338 bool cmInstallCommand::MakeFilesFullPath(const char* modeName,
1339 const std::vector<std::string>& relFiles,
1340 std::vector<std::string>& absFiles)
1342 for(std::vector<std::string>::const_iterator fileIt = relFiles.begin();
1343 fileIt != relFiles.end();
1346 std::string file = (*fileIt);
1347 if(!cmSystemTools::FileIsFullPath(file.c_str()))
1349 file = this->Makefile->GetCurrentDirectory();
1354 // Make sure the file is not a directory.
1355 if(cmSystemTools::FileIsDirectory(file.c_str()))
1358 e << modeName << " given directory \"" << (*fileIt) << "\" to install.";
1359 this->SetError(e.str().c_str());
1362 // Store the file for installation.
1363 absFiles.push_back(file);
1368 //----------------------------------------------------------------------------
1369 bool cmInstallCommand::CheckCMP0006(bool& failure)
1371 switch(this->Makefile->GetPolicyStatus(cmPolicies::CMP0006))
1373 case cmPolicies::WARN:
1375 this->Makefile->IssueMessage(
1376 cmake::AUTHOR_WARNING,
1377 this->Makefile->GetPolicies()->GetPolicyWarning(cmPolicies::CMP0006)
1380 case cmPolicies::OLD:
1381 // OLD behavior is to allow compatibility
1383 case cmPolicies::NEW:
1384 // NEW behavior is to disallow compatibility
1386 case cmPolicies::REQUIRED_IF_USED:
1387 case cmPolicies::REQUIRED_ALWAYS:
1389 this->Makefile->IssueMessage(
1391 this->Makefile->GetPolicies()
1392 ->GetRequiredPolicyError(cmPolicies::CMP0006)