1 /*=========================================================================
3 Program: CMake - Cross-Platform Makefile Generator
4 Module: $RCSfile: cmInstallCommand.cxx,v $
6 Date: $Date: 2008-01-23 15:27:59 $
7 Version: $Revision: 1.39 $
9 Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved.
10 See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
12 This software is distributed WITHOUT ANY WARRANTY; without even
13 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14 PURPOSE. See the above copyright notices for more information.
16 =========================================================================*/
17 #include "cmInstallCommand.h"
19 #include "cmInstallDirectoryGenerator.h"
20 #include "cmInstallFilesGenerator.h"
21 #include "cmInstallScriptGenerator.h"
22 #include "cmInstallTargetGenerator.h"
23 #include "cmInstallExportGenerator.h"
24 #include "cmInstallCommandArguments.h"
26 #include <cmsys/Glob.hxx>
28 static cmInstallTargetGenerator
* CreateInstallTargetGenerator(cmTarget
& target
,
29 const cmInstallCommandArguments
& args
, bool impLib
, bool forceOpt
= false)
31 return new cmInstallTargetGenerator(target
, args
.GetDestination().c_str(),
32 impLib
, args
.GetPermissions().c_str(),
33 args
.GetConfigurations(), args
.GetComponent().c_str(),
34 args
.GetOptional() || forceOpt
);
37 static cmInstallFilesGenerator
* CreateInstallFilesGenerator(
38 const std::vector
<std::string
>& absFiles
,
39 const cmInstallCommandArguments
& args
, bool programs
)
41 return new cmInstallFilesGenerator(absFiles
, args
.GetDestination().c_str(),
42 programs
, args
.GetPermissions().c_str(),
43 args
.GetConfigurations(), args
.GetComponent().c_str(),
44 args
.GetRename().c_str(), args
.GetOptional());
49 bool cmInstallCommand::InitialPass(std::vector
<std::string
> const& args
,
52 // Allow calling with no arguments so that arguments may be built up
53 // using a variable that may be left empty.
59 // Enable the install target.
60 this->Makefile
->GetLocalGenerator()
61 ->GetGlobalGenerator()->EnableInstallTarget();
63 // Switch among the command modes.
64 if(args
[0] == "SCRIPT")
66 return this->HandleScriptMode(args
);
68 else if(args
[0] == "CODE")
70 return this->HandleScriptMode(args
);
72 else if(args
[0] == "TARGETS")
74 return this->HandleTargetsMode(args
);
76 else if(args
[0] == "FILES")
78 return this->HandleFilesMode(args
);
80 else if(args
[0] == "PROGRAMS")
82 return this->HandleFilesMode(args
);
84 else if(args
[0] == "DIRECTORY")
86 return this->HandleDirectoryMode(args
);
88 else if(args
[0] == "EXPORT")
90 return this->HandleExportMode(args
);
94 cmStdString e
= "called with unknown mode ";
96 this->SetError(e
.c_str());
100 //----------------------------------------------------------------------------
101 bool cmInstallCommand::HandleScriptMode(std::vector
<std::string
> const& args
)
103 std::string
component("Unspecified");
104 int componentCount
= 0;
105 bool doing_script
= false;
106 bool doing_code
= false;
108 // Scan the args once for COMPONENT. Only allow one.
110 for(size_t i
=0; i
< args
.size(); ++i
)
112 if(args
[i
] == "COMPONENT" && i
+1 < args
.size())
122 this->SetError("given more than one COMPONENT for the SCRIPT or CODE "
123 "signature of the INSTALL command. "
124 "Use multiple INSTALL commands with one COMPONENT each.");
128 // Scan the args again, this time adding install generators each time we
129 // encounter a SCRIPT or CODE arg:
131 for(size_t i
=0; i
< args
.size(); ++i
)
133 if(args
[i
] == "SCRIPT")
138 else if(args
[i
] == "CODE")
140 doing_script
= false;
143 else if(args
[i
] == "COMPONENT")
145 doing_script
= false;
148 else if(doing_script
)
150 doing_script
= false;
151 std::string script
= args
[i
];
152 if(!cmSystemTools::FileIsFullPath(script
.c_str()))
154 script
= this->Makefile
->GetCurrentDirectory();
158 if(cmSystemTools::FileIsDirectory(script
.c_str()))
160 this->SetError("given a directory as value of SCRIPT argument.");
163 this->Makefile
->AddInstallGenerator(
164 new cmInstallScriptGenerator(script
.c_str(), false,
170 std::string code
= args
[i
];
171 this->Makefile
->AddInstallGenerator(
172 new cmInstallScriptGenerator(code
.c_str(), true,
179 this->SetError("given no value for SCRIPT argument.");
184 this->SetError("given no value for CODE argument.");
188 //Tell the global generator about any installation component names specified.
189 this->Makefile
->GetLocalGenerator()->GetGlobalGenerator()
190 ->AddInstallComponent(component
.c_str());
198 InstallPart(cmCommandArgumentsHelper* helper, const char* key,
199 cmCommandArgumentGroup* group);
200 cmCAStringVector argVector;
201 cmInstallCommandArguments args;
204 //----------------------------------------------------------------------------
205 bool cmInstallCommand::HandleTargetsMode(std::vector
<std::string
> const& args
)
207 // This is the TARGETS mode.
208 std::vector
<cmTarget
*> targets
;
210 cmCommandArgumentsHelper argHelper
;
211 cmCommandArgumentGroup group
;
212 cmCAStringVector
genericArgVector (&argHelper
,0);
213 cmCAStringVector
archiveArgVector (&argHelper
,"ARCHIVE",&group
);
214 cmCAStringVector
libraryArgVector (&argHelper
,"LIBRARY",&group
);
215 cmCAStringVector
runtimeArgVector (&argHelper
,"RUNTIME",&group
);
216 cmCAStringVector
frameworkArgVector (&argHelper
,"FRAMEWORK",&group
);
217 cmCAStringVector
bundleArgVector (&argHelper
,"BUNDLE",&group
);
218 cmCAStringVector
privateHeaderArgVector(&argHelper
,"PRIVATE_HEADER",&group
);
219 cmCAStringVector
publicHeaderArgVector (&argHelper
,"PUBLIC_HEADER",&group
);
220 cmCAStringVector
resourceArgVector (&argHelper
,"RESOURCE",&group
);
221 genericArgVector
.Follows(0);
222 group
.Follows(&genericArgVector
);
224 argHelper
.Parse(&args
, 0);
226 std::vector
<std::string
> unknownArgs
;
227 cmInstallCommandArguments genericArgs
;
228 cmCAStringVector
targetList(&genericArgs
.Parser
, "TARGETS");
229 cmCAString
exports(&genericArgs
.Parser
,"EXPORT", &genericArgs
.ArgumentGroup
);
230 targetList
.Follows(0);
231 genericArgs
.ArgumentGroup
.Follows(&targetList
);
232 genericArgs
.Parse(&genericArgVector
.GetVector(), &unknownArgs
);
233 bool success
= genericArgs
.Finalize();
235 cmInstallCommandArguments archiveArgs
;
236 cmInstallCommandArguments libraryArgs
;
237 cmInstallCommandArguments runtimeArgs
;
238 cmInstallCommandArguments frameworkArgs
;
239 cmInstallCommandArguments bundleArgs
;
240 cmInstallCommandArguments privateHeaderArgs
;
241 cmInstallCommandArguments publicHeaderArgs
;
242 cmInstallCommandArguments resourceArgs
;
244 archiveArgs
.Parse (&archiveArgVector
.GetVector(), &unknownArgs
);
245 libraryArgs
.Parse (&libraryArgVector
.GetVector(), &unknownArgs
);
246 runtimeArgs
.Parse (&runtimeArgVector
.GetVector(), &unknownArgs
);
247 frameworkArgs
.Parse (&frameworkArgVector
.GetVector(), &unknownArgs
);
248 bundleArgs
.Parse (&bundleArgVector
.GetVector(), &unknownArgs
);
249 privateHeaderArgs
.Parse(&privateHeaderArgVector
.GetVector(), &unknownArgs
);
250 publicHeaderArgs
.Parse (&publicHeaderArgVector
.GetVector(), &unknownArgs
);
251 resourceArgs
.Parse (&resourceArgVector
.GetVector(), &unknownArgs
);
253 if(!unknownArgs
.empty())
257 e
<< "TARGETS given unknown argument \"" << unknownArgs
[0] << "\".";
258 this->SetError(e
.str().c_str());
262 // apply generic args
263 archiveArgs
.SetGenericArguments(&genericArgs
);
264 libraryArgs
.SetGenericArguments(&genericArgs
);
265 runtimeArgs
.SetGenericArguments(&genericArgs
);
266 frameworkArgs
.SetGenericArguments(&genericArgs
);
267 bundleArgs
.SetGenericArguments(&genericArgs
);
268 privateHeaderArgs
.SetGenericArguments(&genericArgs
);
269 publicHeaderArgs
.SetGenericArguments(&genericArgs
);
270 resourceArgs
.SetGenericArguments(&genericArgs
);
272 success
= success
&& archiveArgs
.Finalize();
273 success
= success
&& libraryArgs
.Finalize();
274 success
= success
&& runtimeArgs
.Finalize();
275 success
= success
&& frameworkArgs
.Finalize();
276 success
= success
&& bundleArgs
.Finalize();
277 success
= success
&& privateHeaderArgs
.Finalize();
278 success
= success
&& publicHeaderArgs
.Finalize();
279 success
= success
&& resourceArgs
.Finalize();
286 // Check if there is something to do.
287 if(targetList
.GetVector().empty())
292 // Check whether this is a DLL platform.
293 bool dll_platform
= (this->Makefile
->IsOn("WIN32") ||
294 this->Makefile
->IsOn("CYGWIN") ||
295 this->Makefile
->IsOn("MINGW"));
297 for(std::vector
<std::string
>::const_iterator
298 targetIt
=targetList
.GetVector().begin();
299 targetIt
!=targetList
.GetVector().end();
302 // Lookup this target in the current directory.
303 if(cmTarget
* target
=this->Makefile
->FindTarget(targetIt
->c_str(), false))
305 // Found the target. Check its type.
306 if(target
->GetType() != cmTarget::EXECUTABLE
&&
307 target
->GetType() != cmTarget::STATIC_LIBRARY
&&
308 target
->GetType() != cmTarget::SHARED_LIBRARY
&&
309 target
->GetType() != cmTarget::MODULE_LIBRARY
)
312 e
<< "TARGETS given target \"" << (*targetIt
)
313 << "\" which is not an executable, library, or module.";
314 this->SetError(e
.str().c_str());
317 // Store the target in the list to be installed.
318 targets
.push_back(target
);
322 // Did not find the target.
324 e
<< "TARGETS given target \"" << (*targetIt
)
325 << "\" which does not exist in this directory.";
326 this->SetError(e
.str().c_str());
331 // Generate install script code to install the given targets.
332 for(std::vector
<cmTarget
*>::iterator ti
= targets
.begin();
333 ti
!= targets
.end(); ++ti
)
335 // Handle each target type.
336 cmTarget
& target
= *(*ti
);
337 cmInstallTargetGenerator
* archiveGenerator
= 0;
338 cmInstallTargetGenerator
* libraryGenerator
= 0;
339 cmInstallTargetGenerator
* runtimeGenerator
= 0;
340 cmInstallTargetGenerator
* frameworkGenerator
= 0;
341 cmInstallTargetGenerator
* bundleGenerator
= 0;
342 cmInstallFilesGenerator
* privateHeaderGenerator
= 0;
343 cmInstallFilesGenerator
* publicHeaderGenerator
= 0;
344 cmInstallFilesGenerator
* resourceGenerator
= 0;
346 switch(target
.GetType())
348 case cmTarget::SHARED_LIBRARY
:
350 // Shared libraries are handled differently on DLL and non-DLL
351 // platforms. All windows platforms are DLL platforms including
352 // cygwin. Currently no other platform is a DLL platform.
355 // This is a DLL platform.
356 if(!archiveArgs
.GetDestination().empty())
358 // The import library uses the ARCHIVE properties.
359 archiveGenerator
= CreateInstallTargetGenerator(target
,
362 if(!runtimeArgs
.GetDestination().empty())
364 // The DLL uses the RUNTIME properties.
365 runtimeGenerator
= CreateInstallTargetGenerator(target
,
368 if ((archiveGenerator
==0) && (runtimeGenerator
==0))
370 this->SetError("Library TARGETS given no DESTINATION!");
376 // This is a non-DLL platform.
377 // If it is marked with FRAMEWORK property use the FRAMEWORK set of
378 // INSTALL properties. Otherwise, use the LIBRARY properties.
379 if(target
.GetPropertyAsBool("FRAMEWORK"))
381 // Use the FRAMEWORK properties.
382 if (!frameworkArgs
.GetDestination().empty())
384 frameworkGenerator
= CreateInstallTargetGenerator(target
,
385 frameworkArgs
, false);
390 e
<< "TARGETS given no FRAMEWORK DESTINATION for shared library "
391 "FRAMEWORK target \"" << target
.GetName() << "\".";
392 this->SetError(e
.str().c_str());
398 // The shared library uses the LIBRARY properties.
399 if (!libraryArgs
.GetDestination().empty())
401 libraryGenerator
= CreateInstallTargetGenerator(target
,
407 e
<< "TARGETS given no LIBRARY DESTINATION for shared library "
408 "target \"" << target
.GetName() << "\".";
409 this->SetError(e
.str().c_str());
416 case cmTarget::STATIC_LIBRARY
:
418 // Static libraries use ARCHIVE properties.
419 if (!archiveArgs
.GetDestination().empty())
421 archiveGenerator
= CreateInstallTargetGenerator(target
, archiveArgs
,
427 e
<< "TARGETS given no ARCHIVE DESTINATION for static library "
428 "target \"" << target
.GetName() << "\".";
429 this->SetError(e
.str().c_str());
434 case cmTarget::MODULE_LIBRARY
:
436 // Modules use LIBRARY properties.
437 if (!libraryArgs
.GetDestination().empty())
439 libraryGenerator
= CreateInstallTargetGenerator(target
, libraryArgs
,
445 e
<< "TARGETS given no LIBRARY DESTINATION for module target \""
446 << target
.GetName() << "\".";
447 this->SetError(e
.str().c_str());
452 case cmTarget::EXECUTABLE
:
454 // Executables use the RUNTIME properties.
455 if(target
.GetPropertyAsBool("MACOSX_BUNDLE"))
457 if (!bundleArgs
.GetDestination().empty())
459 bundleGenerator
= CreateInstallTargetGenerator(target
, bundleArgs
,
465 e
<< "TARGETS given no BUNDLE DESTINATION for MACOSX_BUNDLE "
466 "executable target \"" << target
.GetName() << "\".";
467 this->SetError(e
.str().c_str());
473 if (!runtimeArgs
.GetDestination().empty())
475 runtimeGenerator
= CreateInstallTargetGenerator(target
,
481 e
<< "TARGETS given no RUNTIME DESTINATION for executable "
482 "target \"" << target
.GetName() << "\".";
483 this->SetError(e
.str().c_str());
488 // On DLL platforms an executable may also have an import
489 // library. Install it to the archive destination if it
491 if(dll_platform
&& !archiveArgs
.GetDestination().empty() &&
492 target
.GetPropertyAsBool("ENABLE_EXPORTS"))
494 // The import library uses the ARCHIVE properties.
495 archiveGenerator
= CreateInstallTargetGenerator(target
,
496 archiveArgs
, true, true);
501 // This should never happen due to the above type check.
506 // if(target.GetProperty("ASSOCIATED_FILES");
508 // These well-known sets of files are installed *automatically* for FRAMEWORK
509 // SHARED library targets on the Mac as part of installing the FRAMEWORK.
510 // For other target types or on other platforms, they are not installed
511 // automatically and so we need to create install files generators for them.
513 bool createInstallGeneratorsForTargetFileSets
= true;
515 if(cmTarget::SHARED_LIBRARY
== target
.GetType() &&
516 target
.GetPropertyAsBool("FRAMEWORK") &&
517 this->Makefile
->IsOn("APPLE"))
519 createInstallGeneratorsForTargetFileSets
= false;
522 if(createInstallGeneratorsForTargetFileSets
)
524 const char* files
= target
.GetProperty("PRIVATE_HEADER");
525 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
))
535 // Create the files install generator.
536 if (!privateHeaderArgs
.GetDestination().empty())
538 privateHeaderGenerator
= CreateInstallFilesGenerator(absFiles
,
539 privateHeaderArgs
, false);
544 e
<< "INSTALL TARGETS - target " << target
.GetName() << " has "
545 << "PRIVATE_HEADER files but no PRIVATE_HEADER DESTINATION.";
546 cmSystemTools::Message(e
.str().c_str(), "Warning");
550 files
= target
.GetProperty("PUBLIC_HEADER");
551 if ((files
) && (*files
))
553 std::vector
<std::string
> relFiles
;
554 cmSystemTools::ExpandListArgument(files
, relFiles
);
555 std::vector
<std::string
> absFiles
;
556 if (!this->MakeFilesFullPath("PUBLIC_HEADER", relFiles
, absFiles
))
561 // Create the files install generator.
562 if (!publicHeaderArgs
.GetDestination().empty())
564 publicHeaderGenerator
= CreateInstallFilesGenerator(absFiles
,
565 publicHeaderArgs
, false);
570 e
<< "INSTALL TARGETS - target " << target
.GetName() << " has "
571 << "PUBLIC_HEADER files but no PUBLIC_HEADER DESTINATION.";
572 cmSystemTools::Message(e
.str().c_str(), "Warning");
576 files
= target
.GetProperty("RESOURCE");
577 if ((files
) && (*files
))
579 std::vector
<std::string
> relFiles
;
580 cmSystemTools::ExpandListArgument(files
, relFiles
);
581 std::vector
<std::string
> absFiles
;
582 if (!this->MakeFilesFullPath("RESOURCE", relFiles
, absFiles
))
587 // Create the files install generator.
588 if (!resourceArgs
.GetDestination().empty())
590 resourceGenerator
= CreateInstallFilesGenerator(absFiles
,
591 resourceArgs
, false);
596 e
<< "INSTALL TARGETS - target " << target
.GetName() << " has "
597 << "RESOURCE files but no RESOURCE DESTINATION.";
598 cmSystemTools::Message(e
.str().c_str(), "Warning");
603 this->Makefile
->AddInstallGenerator(archiveGenerator
);
604 this->Makefile
->AddInstallGenerator(libraryGenerator
);
605 this->Makefile
->AddInstallGenerator(runtimeGenerator
);
606 this->Makefile
->AddInstallGenerator(frameworkGenerator
);
607 this->Makefile
->AddInstallGenerator(bundleGenerator
);
608 this->Makefile
->AddInstallGenerator(privateHeaderGenerator
);
609 this->Makefile
->AddInstallGenerator(publicHeaderGenerator
);
610 this->Makefile
->AddInstallGenerator(resourceGenerator
);
612 if (!exports
.GetString().empty())
614 this->Makefile
->GetLocalGenerator()->GetGlobalGenerator()
615 ->AddTargetToExports(exports
.GetCString(), &target
,
616 archiveGenerator
, runtimeGenerator
,
617 libraryGenerator
, frameworkGenerator
,
618 bundleGenerator
, publicHeaderGenerator
);
622 // Tell the global generator about any installation component names specified
623 this->Makefile
->GetLocalGenerator()->GetGlobalGenerator()
624 ->AddInstallComponent(archiveArgs
.GetComponent().c_str());
625 this->Makefile
->GetLocalGenerator()->GetGlobalGenerator()
626 ->AddInstallComponent(libraryArgs
.GetComponent().c_str());
627 this->Makefile
->GetLocalGenerator()->GetGlobalGenerator()
628 ->AddInstallComponent(runtimeArgs
.GetComponent().c_str());
629 this->Makefile
->GetLocalGenerator()->GetGlobalGenerator()
630 ->AddInstallComponent(frameworkArgs
.GetComponent().c_str());
631 this->Makefile
->GetLocalGenerator()->GetGlobalGenerator()
632 ->AddInstallComponent(bundleArgs
.GetComponent().c_str());
633 this->Makefile
->GetLocalGenerator()->GetGlobalGenerator()
634 ->AddInstallComponent(privateHeaderArgs
.GetComponent().c_str());
635 this->Makefile
->GetLocalGenerator()->GetGlobalGenerator()
636 ->AddInstallComponent(publicHeaderArgs
.GetComponent().c_str());
637 this->Makefile
->GetLocalGenerator()->GetGlobalGenerator()
638 ->AddInstallComponent(resourceArgs
.GetComponent().c_str());
643 //----------------------------------------------------------------------------
644 bool cmInstallCommand::HandleFilesMode(std::vector
<std::string
> const& args
)
646 // This is the FILES mode.
647 bool programs
= (args
[0] == "PROGRAMS");
648 cmInstallCommandArguments ica
;
649 cmCAStringVector
files(&ica
.Parser
, programs
? "PROGRAMS" : "FILES");
651 ica
.ArgumentGroup
.Follows(&files
);
652 std::vector
<std::string
> unknownArgs
;
653 ica
.Parse(&args
, &unknownArgs
);
655 if(!unknownArgs
.empty())
659 e
<< args
[0] << " given unknown argument \"" << unknownArgs
[0] << "\".";
660 this->SetError(e
.str().c_str());
664 // Check if there is something to do.
665 if(files
.GetVector().empty())
670 if(!ica
.GetRename().empty() && files
.GetVector().size() > 1)
672 // The rename option works only with one file.
674 e
<< args
[0] << " given RENAME option with more than one file.";
675 this->SetError(e
.str().c_str());
679 std::vector
<std::string
> absFiles
;
680 if (!this->MakeFilesFullPath(args
[0].c_str(), files
.GetVector(), absFiles
))
690 if(ica
.GetDestination().empty())
692 // A destination is required.
694 e
<< args
[0] << " given no DESTINATION!";
695 this->SetError(e
.str().c_str());
699 // Create the files install generator.
700 this->Makefile
->AddInstallGenerator(
701 CreateInstallFilesGenerator(absFiles
, ica
, programs
));
703 //Tell the global generator about any installation component names specified.
704 this->Makefile
->GetLocalGenerator()->GetGlobalGenerator()
705 ->AddInstallComponent(ica
.GetComponent().c_str());
710 //----------------------------------------------------------------------------
712 cmInstallCommand::HandleDirectoryMode(std::vector
<std::string
> const& args
)
714 bool doing_dirs
= true;
715 bool doing_destination
= false;
716 bool doing_pattern
= false;
717 bool doing_regex
= false;
718 bool doing_permissions_file
= false;
719 bool doing_permissions_dir
= false;
720 bool doing_permissions_match
= false;
721 bool doing_configurations
= false;
722 bool doing_component
= false;
723 bool in_match_mode
= false;
724 std::vector
<std::string
> dirs
;
725 const char* destination
= 0;
726 std::string permissions_file
;
727 std::string permissions_dir
;
728 std::vector
<std::string
> configurations
;
729 std::string component
= "Unspecified";
730 std::string literal_args
;
731 for(unsigned int i
=1; i
< args
.size(); ++i
)
733 if(args
[i
] == "DESTINATION")
738 e
<< args
[0] << " does not allow \""
739 << args
[i
] << "\" after PATTERN or REGEX.";
740 this->SetError(e
.str().c_str());
744 // Switch to setting the destination property.
746 doing_destination
= true;
747 doing_pattern
= false;
749 doing_permissions_file
= false;
750 doing_permissions_dir
= false;
751 doing_configurations
= false;
752 doing_component
= false;
754 else if(args
[i
] == "PATTERN")
756 // Switch to a new pattern match rule.
758 doing_destination
= false;
759 doing_pattern
= true;
761 doing_permissions_file
= false;
762 doing_permissions_dir
= false;
763 doing_permissions_match
= false;
764 doing_configurations
= false;
765 doing_component
= false;
766 in_match_mode
= true;
768 else if(args
[i
] == "REGEX")
770 // Switch to a new regex match rule.
772 doing_destination
= false;
773 doing_pattern
= false;
775 doing_permissions_file
= false;
776 doing_permissions_dir
= false;
777 doing_permissions_match
= false;
778 doing_configurations
= false;
779 doing_component
= false;
780 in_match_mode
= true;
782 else if(args
[i
] == "EXCLUDE")
784 // Add this property to the current match rule.
785 if(!in_match_mode
|| doing_pattern
|| doing_regex
)
788 e
<< args
[0] << " does not allow \""
789 << args
[i
] << "\" before a PATTERN or REGEX is given.";
790 this->SetError(e
.str().c_str());
793 literal_args
+= " EXCLUDE";
794 doing_permissions_match
= false;
796 else if(args
[i
] == "PERMISSIONS")
801 e
<< args
[0] << " does not allow \""
802 << args
[i
] << "\" before a PATTERN or REGEX is given.";
803 this->SetError(e
.str().c_str());
807 // Switch to setting the current match permissions property.
808 literal_args
+= " PERMISSIONS";
809 doing_permissions_match
= true;
811 else if(args
[i
] == "FILE_PERMISSIONS")
816 e
<< args
[0] << " does not allow \""
817 << args
[i
] << "\" after PATTERN or REGEX.";
818 this->SetError(e
.str().c_str());
822 // Switch to setting the file permissions property.
824 doing_destination
= false;
825 doing_pattern
= false;
827 doing_permissions_file
= true;
828 doing_permissions_dir
= false;
829 doing_configurations
= false;
830 doing_component
= false;
832 else if(args
[i
] == "DIRECTORY_PERMISSIONS")
837 e
<< args
[0] << " does not allow \""
838 << args
[i
] << "\" after PATTERN or REGEX.";
839 this->SetError(e
.str().c_str());
843 // Switch to setting the directory permissions property.
845 doing_destination
= false;
846 doing_pattern
= false;
848 doing_permissions_file
= false;
849 doing_permissions_dir
= true;
850 doing_configurations
= false;
851 doing_component
= false;
853 else if(args
[i
] == "USE_SOURCE_PERMISSIONS")
858 e
<< args
[0] << " does not allow \""
859 << args
[i
] << "\" after PATTERN or REGEX.";
860 this->SetError(e
.str().c_str());
864 // Add this option literally.
866 doing_destination
= false;
867 doing_pattern
= false;
869 doing_permissions_file
= false;
870 doing_permissions_dir
= false;
871 doing_configurations
= false;
872 doing_component
= false;
873 literal_args
+= " USE_SOURCE_PERMISSIONS";
875 else if(args
[i
] == "FILES_MATCHING")
880 e
<< args
[0] << " does not allow \""
881 << args
[i
] << "\" after PATTERN or REGEX.";
882 this->SetError(e
.str().c_str());
886 // Add this option literally.
888 doing_destination
= false;
889 doing_pattern
= false;
891 doing_permissions_file
= false;
892 doing_permissions_dir
= false;
893 doing_permissions_match
= false;
894 doing_configurations
= false;
895 doing_component
= false;
896 literal_args
+= " FILES_MATCHING";
898 else if(args
[i
] == "CONFIGURATIONS")
903 e
<< args
[0] << " does not allow \""
904 << args
[i
] << "\" after PATTERN or REGEX.";
905 this->SetError(e
.str().c_str());
909 // Switch to setting the configurations property.
911 doing_destination
= false;
912 doing_pattern
= false;
914 doing_permissions_file
= false;
915 doing_permissions_dir
= false;
916 doing_configurations
= true;
917 doing_component
= false;
919 else if(args
[i
] == "COMPONENT")
924 e
<< args
[0] << " does not allow \""
925 << args
[i
] << "\" after PATTERN or REGEX.";
926 this->SetError(e
.str().c_str());
930 // Switch to setting the component property.
932 doing_destination
= false;
933 doing_pattern
= false;
935 doing_permissions_file
= false;
936 doing_permissions_dir
= false;
937 doing_configurations
= false;
938 doing_component
= true;
942 // Convert this directory to a full path.
943 std::string dir
= args
[i
];
944 if(!cmSystemTools::FileIsFullPath(dir
.c_str()))
946 dir
= this->Makefile
->GetCurrentDirectory();
951 // Make sure the name is a directory.
952 if(cmSystemTools::FileExists(dir
.c_str()) &&
953 !cmSystemTools::FileIsDirectory(dir
.c_str()))
956 e
<< args
[0] << " given non-directory \""
957 << args
[i
] << "\" to install.";
958 this->SetError(e
.str().c_str());
962 // Store the directory for installation.
965 else if(doing_configurations
)
967 configurations
.push_back(args
[i
]);
969 else if(doing_destination
)
971 destination
= args
[i
].c_str();
972 doing_destination
= false;
974 else if(doing_pattern
)
976 // Convert the pattern to a regular expression. Require a
977 // leading slash and trailing end-of-string in the matched
978 // string to make sure the pattern matches only whole file
980 literal_args
+= " REGEX \"/";
981 std::string regex
= cmsys::Glob::PatternToRegex(args
[i
], false);
982 cmSystemTools::ReplaceString(regex
, "\\", "\\\\");
983 literal_args
+= regex
;
984 literal_args
+= "$\"";
985 doing_pattern
= false;
989 literal_args
+= " REGEX \"";
990 // Match rules are case-insensitive on some platforms.
991 #if defined(_WIN32) || defined(__APPLE__) || defined(__CYGWIN__)
992 std::string regex
= cmSystemTools::LowerCase(args
[i
]);
994 std::string regex
= args
[i
];
996 cmSystemTools::ReplaceString(regex
, "\\", "\\\\");
997 literal_args
+= regex
;
998 literal_args
+= "\"";
1001 else if(doing_component
)
1003 component
= args
[i
];
1004 doing_component
= false;
1006 else if(doing_permissions_file
)
1008 // Check the requested permission.
1009 if(!cmInstallCommandArguments::CheckPermissions(args
[i
],permissions_file
))
1012 e
<< args
[0] << " given invalid file permission \""
1013 << args
[i
] << "\".";
1014 this->SetError(e
.str().c_str());
1018 else if(doing_permissions_dir
)
1020 // Check the requested permission.
1021 if(!cmInstallCommandArguments::CheckPermissions(args
[i
],permissions_dir
))
1024 e
<< args
[0] << " given invalid directory permission \""
1025 << args
[i
] << "\".";
1026 this->SetError(e
.str().c_str());
1030 else if(doing_permissions_match
)
1032 // Check the requested permission.
1033 if(!cmInstallCommandArguments::CheckPermissions(args
[i
], literal_args
))
1036 e
<< args
[0] << " given invalid permission \""
1037 << args
[i
] << "\".";
1038 this->SetError(e
.str().c_str());
1044 // Unknown argument.
1046 e
<< args
[0] << " given unknown argument \"" << args
[i
] << "\".";
1047 this->SetError(e
.str().c_str());
1052 // Support installing an empty directory.
1053 if(dirs
.empty() && destination
)
1058 // Check if there is something to do.
1065 // A destination is required.
1067 e
<< args
[0] << " given no DESTINATION!";
1068 this->SetError(e
.str().c_str());
1072 // Compute destination path.
1074 cmInstallCommandArguments::ComputeDestination(destination
, dest
);
1076 // Create the directory install generator.
1077 this->Makefile
->AddInstallGenerator(
1078 new cmInstallDirectoryGenerator(dirs
, dest
.c_str(),
1079 permissions_file
.c_str(),
1080 permissions_dir
.c_str(),
1083 literal_args
.c_str()));
1085 // Tell the global generator about any installation component names
1087 this->Makefile
->GetLocalGenerator()->GetGlobalGenerator()
1088 ->AddInstallComponent(component
.c_str());
1093 //----------------------------------------------------------------------------
1094 bool cmInstallCommand::HandleExportMode(std::vector
<std::string
> const& args
)
1096 // This is the EXPORT mode.
1097 cmInstallCommandArguments ica
;
1098 cmCAStringVector
exports(&ica
.Parser
, "EXPORT");
1099 cmCAString
prefix(&ica
.Parser
, "PREFIX", &ica
.ArgumentGroup
);
1100 cmCAString
filename(&ica
.Parser
, "FILE", &ica
.ArgumentGroup
);
1103 ica
.ArgumentGroup
.Follows(&exports
);
1104 std::vector
<std::string
> unknownArgs
;
1105 ica
.Parse(&args
, &unknownArgs
);
1107 if (!unknownArgs
.empty())
1109 // Unknown argument.
1111 e
<< args
[0] << " given unknown argument \"" << unknownArgs
[0] << "\".";
1112 this->SetError(e
.str().c_str());
1116 if (!ica
.Finalize())
1121 std::string cmakeDir
= this->Makefile
->GetHomeOutputDirectory();
1122 cmakeDir
+= cmake::GetCMakeFilesDirectory();
1123 for(std::vector
<std::string
>::const_iterator
1124 exportIt
= exports
.GetVector().begin();
1125 exportIt
!= exports
.GetVector().end();
1128 const std::vector
<cmTargetExport
*>* exportSet
= this->
1129 Makefile
->GetLocalGenerator()->GetGlobalGenerator()->
1130 GetExportSet(exportIt
->c_str());
1134 e
<< "EXPORT given unknown export name \"" << exportIt
->c_str() << "\".";
1135 this->SetError(e
.str().c_str());
1139 // Create the export install generator.
1140 cmInstallExportGenerator
* exportGenerator
= new cmInstallExportGenerator(
1141 ica
.GetDestination().c_str(), ica
.GetPermissions().c_str(),
1142 ica
.GetConfigurations(),0 , filename
.GetCString(),
1143 prefix
.GetCString(), cmakeDir
.c_str());
1145 if (exportGenerator
->SetExportSet(exportIt
->c_str(),exportSet
))
1147 this->Makefile
->AddInstallGenerator(exportGenerator
);
1152 e
<< "EXPORT failed, maybe a target is exported more than once.";
1153 this->SetError(e
.str().c_str());
1154 delete exportGenerator
;
1162 bool cmInstallCommand::MakeFilesFullPath(const char* modeName
,
1163 const std::vector
<std::string
>& relFiles
,
1164 std::vector
<std::string
>& absFiles
)
1166 for(std::vector
<std::string
>::const_iterator fileIt
= relFiles
.begin();
1167 fileIt
!= relFiles
.end();
1170 std::string file
= (*fileIt
);
1171 if(!cmSystemTools::FileIsFullPath(file
.c_str()))
1173 file
= this->Makefile
->GetCurrentDirectory();
1178 // Make sure the file is not a directory.
1179 if(cmSystemTools::FileIsDirectory(file
.c_str()))
1182 e
<< modeName
<< " given directory \"" << (*fileIt
) << "\" to install.";
1183 this->SetError(e
.str().c_str());
1186 // Store the file for installation.
1187 absFiles
.push_back(file
);