summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKyle Edwards <kyle.edwards@kitware.com>2018-11-02 16:42:41 (GMT)
committerKyle Edwards <kyle.edwards@kitware.com>2018-11-07 19:08:48 (GMT)
commit9fc20a4f3e1865e409d960c87e2e4a366775b72b (patch)
tree5ea698da30b881b7ad4db2e3770e27727f93fcb9
parent71db32660eed1f70c06b624e661f8f5c2b938907 (diff)
downloadCMake-9fc20a4f3e1865e409d960c87e2e4a366775b72b.zip
CMake-9fc20a4f3e1865e409d960c87e2e4a366775b72b.tar.gz
CMake-9fc20a4f3e1865e409d960c87e2e4a366775b72b.tar.bz2
install: Add sane set of defaults for DESTINATION and file type parameters
If the user does not specify a DESTINATION for a target type, the install() command checks to see if the appropriate variable from GNUInstallDirs is set. If it is not, then it uses an appropriate hard-coded guess. In addition, for FILES and DIRECTORY, the user can specify a file type instead of a DESTINATION, and the command will use the appropriate variable from GNUInstallDirs, or a hard-coded guess if it is not set.
-rw-r--r--Source/cmInstallCommand.cxx376
-rw-r--r--Source/cmInstallCommand.h22
-rw-r--r--Source/cmInstallCommandArguments.cxx6
-rw-r--r--Source/cmInstallCommandArguments.h2
-rw-r--r--Tests/RunCMake/install/DIRECTORY-DESTINATION-TYPE-result.txt1
-rw-r--r--Tests/RunCMake/install/DIRECTORY-DESTINATION-TYPE-stderr.txt5
-rw-r--r--Tests/RunCMake/install/DIRECTORY-DESTINATION-TYPE.cmake1
-rw-r--r--Tests/RunCMake/install/DIRECTORY-TYPE-Cache-all-check.cmake42
-rw-r--r--Tests/RunCMake/install/DIRECTORY-TYPE-Cache.cmake13
-rw-r--r--Tests/RunCMake/install/DIRECTORY-TYPE-CacheDependent-all-check.cmake24
-rw-r--r--Tests/RunCMake/install/DIRECTORY-TYPE-CacheDependent.cmake7
-rw-r--r--Tests/RunCMake/install/DIRECTORY-TYPE-all-check.cmake42
-rw-r--r--Tests/RunCMake/install/DIRECTORY-TYPE.cmake13
-rw-r--r--Tests/RunCMake/install/FILES-DESTINATION-TYPE-result.txt1
-rw-r--r--Tests/RunCMake/install/FILES-DESTINATION-TYPE-stderr.txt5
-rw-r--r--Tests/RunCMake/install/FILES-DESTINATION-TYPE.cmake1
-rw-r--r--Tests/RunCMake/install/FILES-TYPE-Cache-all-check.cmake29
-rw-r--r--Tests/RunCMake/install/FILES-TYPE-Cache.cmake13
-rw-r--r--Tests/RunCMake/install/FILES-TYPE-CacheDependent-all-check.cmake17
-rw-r--r--Tests/RunCMake/install/FILES-TYPE-CacheDependent.cmake7
-rw-r--r--Tests/RunCMake/install/FILES-TYPE-all-check.cmake29
-rw-r--r--Tests/RunCMake/install/FILES-TYPE.cmake13
-rw-r--r--Tests/RunCMake/install/RunCMakeTest.cmake46
-rw-r--r--Tests/RunCMake/install/TARGETS-Apple-Defaults-result.txt1
-rw-r--r--Tests/RunCMake/install/TARGETS-Apple-Defaults-stderr.txt12
-rw-r--r--Tests/RunCMake/install/TARGETS-Apple-Defaults.cmake8
-rw-r--r--Tests/RunCMake/install/TARGETS-Defaults-Cache-all-check.cmake49
-rw-r--r--Tests/RunCMake/install/TARGETS-Defaults-Cache.cmake19
-rw-r--r--Tests/RunCMake/install/TARGETS-Defaults-all-check.cmake49
-rw-r--r--Tests/RunCMake/install/TARGETS-Defaults.cmake19
-rw-r--r--Tests/RunCMake/install/obj3.c7
-rw-r--r--Tests/RunCMake/install/obj3.h6
-rw-r--r--Tests/RunCMake/install/obj4.c7
-rw-r--r--Tests/RunCMake/install/obj4.h6
-rw-r--r--Tests/RunCMake/install/obj5.c7
-rw-r--r--Tests/RunCMake/install/obj5.h6
36 files changed, 832 insertions, 79 deletions
diff --git a/Source/cmInstallCommand.cxx b/Source/cmInstallCommand.cxx
index fbc5278..7c8458a 100644
--- a/Source/cmInstallCommand.cxx
+++ b/Source/cmInstallCommand.cxx
@@ -3,6 +3,7 @@
#include "cmInstallCommand.h"
#include "cmsys/Glob.hxx"
+#include <set>
#include <sstream>
#include <stddef.h>
#include <utility>
@@ -33,8 +34,8 @@ class cmExecutionStatus;
static cmInstallTargetGenerator* CreateInstallTargetGenerator(
cmTarget& target, const cmInstallCommandArguments& args, bool impLib,
- cmListFileBacktrace const& backtrace, bool forceOpt = false,
- bool namelink = false)
+ cmListFileBacktrace const& backtrace, const std::string& destination,
+ bool forceOpt = false, bool namelink = false)
{
cmInstallGenerator::MessageLevel message =
cmInstallGenerator::SelectMessageLevel(target.GetMakefile());
@@ -42,25 +43,49 @@ static cmInstallTargetGenerator* CreateInstallTargetGenerator(
const char* component = namelink ? args.GetNamelinkComponent().c_str()
: args.GetComponent().c_str();
return new cmInstallTargetGenerator(
- target.GetName(), args.GetDestination().c_str(), impLib,
+ target.GetName(), destination.c_str(), impLib,
args.GetPermissions().c_str(), args.GetConfigurations(), component,
message, args.GetExcludeFromAll(), args.GetOptional() || forceOpt,
backtrace);
}
+static cmInstallTargetGenerator* CreateInstallTargetGenerator(
+ cmTarget& target, const cmInstallCommandArguments& args, bool impLib,
+ cmListFileBacktrace const& backtrace, bool forceOpt = false,
+ bool namelink = false)
+{
+ return CreateInstallTargetGenerator(target, args, impLib, backtrace,
+ args.GetDestination(), forceOpt,
+ namelink);
+}
+
static cmInstallFilesGenerator* CreateInstallFilesGenerator(
cmMakefile* mf, const std::vector<std::string>& absFiles,
- const cmInstallCommandArguments& args, bool programs)
+ const cmInstallCommandArguments& args, bool programs,
+ const std::string& destination)
{
cmInstallGenerator::MessageLevel message =
cmInstallGenerator::SelectMessageLevel(mf);
return new cmInstallFilesGenerator(
- absFiles, args.GetDestination().c_str(), programs,
- args.GetPermissions().c_str(), args.GetConfigurations(),
- args.GetComponent().c_str(), message, args.GetExcludeFromAll(),
- args.GetRename().c_str(), args.GetOptional());
+ absFiles, destination.c_str(), programs, args.GetPermissions().c_str(),
+ args.GetConfigurations(), args.GetComponent().c_str(), message,
+ args.GetExcludeFromAll(), args.GetRename().c_str(), args.GetOptional());
}
+static cmInstallFilesGenerator* CreateInstallFilesGenerator(
+ cmMakefile* mf, const std::vector<std::string>& absFiles,
+ const cmInstallCommandArguments& args, bool programs)
+{
+ return CreateInstallFilesGenerator(mf, absFiles, args, programs,
+ args.GetDestination());
+}
+
+static const std::set<std::string> allowedTypes{
+ "BIN", "SBIN", "LIB", "INCLUDE", "SYSCONF",
+ "SHAREDSTATE", "LOCALSTATE", "RUNSTATE", "DATA", "INFO",
+ "LOCALE", "MAN", "DOC",
+};
+
// cmInstallCommand
bool cmInstallCommand::InitialPass(std::vector<std::string> const& args,
cmExecutionStatus&)
@@ -335,6 +360,17 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
"At most one of these two options may be specified.");
return false;
}
+ if (!genericArgs.GetType().empty() || !archiveArgs.GetType().empty() ||
+ !libraryArgs.GetType().empty() || !runtimeArgs.GetType().empty() ||
+ !objectArgs.GetType().empty() || !frameworkArgs.GetType().empty() ||
+ !bundleArgs.GetType().empty() || !privateHeaderArgs.GetType().empty() ||
+ !publicHeaderArgs.GetType().empty() || !resourceArgs.GetType().empty()) {
+ std::ostringstream e;
+ e << "TARGETS given TYPE option. The TYPE option may only be specified in "
+ " install(FILES) and install(DIRECTORIES).";
+ this->SetError(e.str());
+ return false;
+ }
// Select the mode for installing symlinks to versioned shared libraries.
cmInstallTargetGenerator::NamelinkModeType namelinkMode =
@@ -447,8 +483,12 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
target, runtimeArgs, false, this->Makefile->GetBacktrace());
}
if ((archiveGenerator == nullptr) && (runtimeGenerator == nullptr)) {
- this->SetError("Library TARGETS given no DESTINATION!");
- return false;
+ archiveGenerator = CreateInstallTargetGenerator(
+ target, archiveArgs, true, this->Makefile->GetBacktrace(),
+ this->GetArchiveDestination(nullptr));
+ runtimeGenerator = CreateInstallTargetGenerator(
+ target, runtimeArgs, false, this->Makefile->GetBacktrace(),
+ this->GetRuntimeDestination(nullptr));
}
} else {
// This is a non-DLL platform.
@@ -474,30 +514,22 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
}
} else {
// The shared library uses the LIBRARY properties.
- if (!libraryArgs.GetDestination().empty()) {
- if (namelinkMode != cmInstallTargetGenerator::NamelinkModeOnly) {
- libraryGenerator = CreateInstallTargetGenerator(
- target, libraryArgs, false, this->Makefile->GetBacktrace());
- libraryGenerator->SetNamelinkMode(
- cmInstallTargetGenerator::NamelinkModeSkip);
- }
- if (namelinkMode != cmInstallTargetGenerator::NamelinkModeSkip) {
- namelinkGenerator = CreateInstallTargetGenerator(
- target, libraryArgs, false, this->Makefile->GetBacktrace(),
- false, true);
- namelinkGenerator->SetNamelinkMode(
- cmInstallTargetGenerator::NamelinkModeOnly);
- }
- namelinkOnly =
- (namelinkMode == cmInstallTargetGenerator::NamelinkModeOnly);
- } else {
- std::ostringstream e;
- e << "TARGETS given no LIBRARY DESTINATION for shared library "
- "target \""
- << target.GetName() << "\".";
- this->SetError(e.str());
- return false;
+ if (namelinkMode != cmInstallTargetGenerator::NamelinkModeOnly) {
+ libraryGenerator = CreateInstallTargetGenerator(
+ target, libraryArgs, false, this->Makefile->GetBacktrace(),
+ this->GetLibraryDestination(&libraryArgs));
+ libraryGenerator->SetNamelinkMode(
+ cmInstallTargetGenerator::NamelinkModeSkip);
+ }
+ if (namelinkMode != cmInstallTargetGenerator::NamelinkModeSkip) {
+ namelinkGenerator = CreateInstallTargetGenerator(
+ target, libraryArgs, false, this->Makefile->GetBacktrace(),
+ this->GetLibraryDestination(&libraryArgs), false, true);
+ namelinkGenerator->SetNamelinkMode(
+ cmInstallTargetGenerator::NamelinkModeOnly);
}
+ namelinkOnly =
+ (namelinkMode == cmInstallTargetGenerator::NamelinkModeOnly);
}
}
} break;
@@ -524,17 +556,9 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
}
} else {
// Static libraries use ARCHIVE properties.
- if (!archiveArgs.GetDestination().empty()) {
- archiveGenerator = CreateInstallTargetGenerator(
- target, archiveArgs, false, this->Makefile->GetBacktrace());
- } else {
- std::ostringstream e;
- e << "TARGETS given no ARCHIVE DESTINATION for static library "
- "target \""
- << target.GetName() << "\".";
- this->SetError(e.str());
- return false;
- }
+ archiveGenerator = CreateInstallTargetGenerator(
+ target, archiveArgs, false, this->Makefile->GetBacktrace(),
+ this->GetArchiveDestination(&archiveArgs));
}
} break;
case cmStateEnums::MODULE_LIBRARY: {
@@ -602,17 +626,9 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
}
} else {
// Executables use the RUNTIME properties.
- if (!runtimeArgs.GetDestination().empty()) {
- runtimeGenerator = CreateInstallTargetGenerator(
- target, runtimeArgs, false, this->Makefile->GetBacktrace());
- } else {
- std::ostringstream e;
- e << "TARGETS given no RUNTIME DESTINATION for executable "
- "target \""
- << target.GetName() << "\".";
- this->SetError(e.str());
- return false;
- }
+ runtimeGenerator = CreateInstallTargetGenerator(
+ target, runtimeArgs, false, this->Makefile->GetBacktrace(),
+ this->GetRuntimeDestination(&runtimeArgs));
}
// On DLL platforms an executable may also have an import
@@ -659,15 +675,9 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
}
// Create the files install generator.
- if (!privateHeaderArgs.GetDestination().empty()) {
- privateHeaderGenerator = CreateInstallFilesGenerator(
- this->Makefile, absFiles, privateHeaderArgs, false);
- } else {
- std::ostringstream e;
- e << "INSTALL TARGETS - target " << target.GetName() << " has "
- << "PRIVATE_HEADER files but no PRIVATE_HEADER DESTINATION.";
- cmSystemTools::Message(e.str().c_str(), "Warning");
- }
+ privateHeaderGenerator = CreateInstallFilesGenerator(
+ this->Makefile, absFiles, privateHeaderArgs, false,
+ this->GetIncludeDestination(&privateHeaderArgs));
}
files = target.GetProperty("PUBLIC_HEADER");
@@ -680,15 +690,9 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
}
// Create the files install generator.
- if (!publicHeaderArgs.GetDestination().empty()) {
- publicHeaderGenerator = CreateInstallFilesGenerator(
- this->Makefile, absFiles, publicHeaderArgs, false);
- } else {
- std::ostringstream e;
- e << "INSTALL TARGETS - target " << target.GetName() << " has "
- << "PUBLIC_HEADER files but no PUBLIC_HEADER DESTINATION.";
- cmSystemTools::Message(e.str().c_str(), "Warning");
- }
+ publicHeaderGenerator = CreateInstallFilesGenerator(
+ this->Makefile, absFiles, publicHeaderArgs, false,
+ this->GetIncludeDestination(&publicHeaderArgs));
}
files = target.GetProperty("RESOURCE");
@@ -824,6 +828,14 @@ bool cmInstallCommand::HandleFilesMode(std::vector<std::string> const& args)
return false;
}
+ std::string type = ica.GetType();
+ if (!type.empty() && allowedTypes.count(type) == 0) {
+ std::ostringstream e;
+ e << args[0] << " given non-type \"" << type << "\" with TYPE argument.";
+ this->SetError(e.str());
+ return false;
+ }
+
const std::vector<std::string>& filesVector = files.GetVector();
// Check if there is something to do.
@@ -886,7 +898,17 @@ bool cmInstallCommand::HandleFilesMode(std::vector<std::string> const& args)
return false;
}
- if (ica.GetDestination().empty()) {
+ if (!type.empty() && !ica.GetDestination().empty()) {
+ std::ostringstream e;
+ e << args[0]
+ << " given both TYPE and DESTINATION arguments. You may only specify "
+ "one.";
+ this->SetError(e.str());
+ return false;
+ }
+
+ std::string destination = this->GetDestinationForType(&ica, type);
+ if (destination.empty()) {
// A destination is required.
std::ostringstream e;
e << args[0] << " given no DESTINATION!";
@@ -895,8 +917,8 @@ bool cmInstallCommand::HandleFilesMode(std::vector<std::string> const& args)
}
// Create the files install generator.
- this->Makefile->AddInstallGenerator(
- CreateInstallFilesGenerator(this->Makefile, absFiles, ica, programs));
+ this->Makefile->AddInstallGenerator(CreateInstallFilesGenerator(
+ this->Makefile, absFiles, ica, programs, destination));
// Tell the global generator about any installation component names
// specified.
@@ -920,7 +942,8 @@ bool cmInstallCommand::HandleDirectoryMode(
DoingPermsDir,
DoingPermsMatch,
DoingConfigurations,
- DoingComponent
+ DoingComponent,
+ DoingType
};
Doing doing = DoingDirs;
bool in_match_mode = false;
@@ -934,6 +957,7 @@ bool cmInstallCommand::HandleDirectoryMode(
std::vector<std::string> configurations;
std::string component = this->DefaultComponentName;
std::string literal_args;
+ std::string type;
for (unsigned int i = 1; i < args.size(); ++i) {
if (args[i] == "DESTINATION") {
if (in_match_mode) {
@@ -946,6 +970,17 @@ bool cmInstallCommand::HandleDirectoryMode(
// Switch to setting the destination property.
doing = DoingDestination;
+ } else if (args[i] == "TYPE") {
+ if (in_match_mode) {
+ std::ostringstream e;
+ e << args[0] << " does not allow \"" << args[i]
+ << "\" after PATTERN or REGEX.";
+ this->SetError(e.str());
+ return false;
+ }
+
+ // Switch to setting the type.
+ doing = DoingType;
} else if (args[i] == "OPTIONAL") {
if (in_match_mode) {
std::ostringstream e;
@@ -1106,6 +1141,17 @@ bool cmInstallCommand::HandleDirectoryMode(
} else if (doing == DoingDestination) {
destination = args[i].c_str();
doing = DoingNone;
+ } else if (doing == DoingType) {
+ if (allowedTypes.count(args[i]) == 0) {
+ std::ostringstream e;
+ e << args[0] << " given non-type \"" << args[i]
+ << "\" with TYPE argument.";
+ this->SetError(e.str());
+ return false;
+ }
+
+ type = args[i];
+ doing = DoingNone;
} else if (doing == DoingPattern) {
// Convert the pattern to a regular expression. Require a
// leading slash and trailing end-of-string in the matched
@@ -1179,10 +1225,22 @@ bool cmInstallCommand::HandleDirectoryMode(
if (dirs.empty()) {
return true;
}
+ std::string destinationStr;
if (!destination) {
- // A destination is required.
+ if (type.empty()) {
+ // A destination is required.
+ std::ostringstream e;
+ e << args[0] << " given no DESTINATION!";
+ this->SetError(e.str());
+ return false;
+ }
+ destinationStr = this->GetDestinationForType(nullptr, type);
+ destination = destinationStr.c_str();
+ } else if (!type.empty()) {
std::ostringstream e;
- e << args[0] << " given no DESTINATION!";
+ e << args[0]
+ << " given both TYPE and DESTINATION arguments. You may only specify "
+ "one.";
this->SetError(e.str());
return false;
}
@@ -1456,3 +1514,163 @@ bool cmInstallCommand::CheckCMP0006(bool& failure)
}
return false;
}
+
+std::string cmInstallCommand::GetDestination(
+ const cmInstallCommandArguments* args, const std::string& varName,
+ const std::string& guess)
+{
+ if (args && !args->GetDestination().empty()) {
+ return args->GetDestination();
+ }
+ std::string val = this->Makefile->GetSafeDefinition(varName);
+ if (!val.empty()) {
+ return val;
+ }
+ return guess;
+}
+
+std::string cmInstallCommand::GetRuntimeDestination(
+ const cmInstallCommandArguments* args)
+{
+ return this->GetDestination(args, "CMAKE_INSTALL_BINDIR", "bin");
+}
+
+std::string cmInstallCommand::GetSbinDestination(
+ const cmInstallCommandArguments* args)
+{
+ return this->GetDestination(args, "CMAKE_INSTALL_SBINDIR", "sbin");
+}
+
+std::string cmInstallCommand::GetArchiveDestination(
+ const cmInstallCommandArguments* args)
+{
+ return this->GetDestination(args, "CMAKE_INSTALL_LIBDIR", "lib");
+}
+
+std::string cmInstallCommand::GetLibraryDestination(
+ const cmInstallCommandArguments* args)
+{
+ return this->GetDestination(args, "CMAKE_INSTALL_LIBDIR", "lib");
+}
+
+std::string cmInstallCommand::GetIncludeDestination(
+ const cmInstallCommandArguments* args)
+{
+ return this->GetDestination(args, "CMAKE_INSTALL_INCLUDEDIR", "include");
+}
+
+std::string cmInstallCommand::GetSysconfDestination(
+ const cmInstallCommandArguments* args)
+{
+ return this->GetDestination(args, "CMAKE_INSTALL_SYSCONFDIR", "etc");
+}
+
+std::string cmInstallCommand::GetSharedStateDestination(
+ const cmInstallCommandArguments* args)
+{
+ return this->GetDestination(args, "CMAKE_INSTALL_SHAREDSTATEDIR", "com");
+}
+
+std::string cmInstallCommand::GetLocalStateDestination(
+ const cmInstallCommandArguments* args)
+{
+ return this->GetDestination(args, "CMAKE_INSTALL_LOCALSTATEDIR", "var");
+}
+
+std::string cmInstallCommand::GetRunStateDestination(
+ const cmInstallCommandArguments* args)
+{
+ return this->GetDestination(args, "CMAKE_INSTALL_RUNSTATEDIR",
+ this->GetLocalStateDestination(nullptr) +
+ "/run");
+}
+
+std::string cmInstallCommand::GetDataRootDestination(
+ const cmInstallCommandArguments* args)
+{
+ return this->GetDestination(args, "CMAKE_INSTALL_DATAROOTDIR", "share");
+}
+
+std::string cmInstallCommand::GetDataDestination(
+ const cmInstallCommandArguments* args)
+{
+ return this->GetDestination(args, "CMAKE_INSTALL_DATADIR",
+ this->GetDataRootDestination(nullptr));
+}
+
+std::string cmInstallCommand::GetInfoDestination(
+ const cmInstallCommandArguments* args)
+{
+ return this->GetDestination(args, "CMAKE_INSTALL_INFODIR",
+ this->GetDataRootDestination(nullptr) + "/info");
+}
+
+std::string cmInstallCommand::GetLocaleDestination(
+ const cmInstallCommandArguments* args)
+{
+ return this->GetDestination(args, "CMAKE_INSTALL_LOCALEDIR",
+ this->GetDataRootDestination(nullptr) +
+ "/locale");
+}
+
+std::string cmInstallCommand::GetManDestination(
+ const cmInstallCommandArguments* args)
+{
+ return this->GetDestination(args, "CMAKE_INSTALL_MANDIR",
+ this->GetDataRootDestination(nullptr) + "/man");
+}
+
+std::string cmInstallCommand::GetDocDestination(
+ const cmInstallCommandArguments* args)
+{
+ return this->GetDestination(args, "CMAKE_INSTALL_DOCDIR",
+ this->GetDataRootDestination(nullptr) + "/doc");
+}
+
+std::string cmInstallCommand::GetDestinationForType(
+ const cmInstallCommandArguments* args, const std::string& type)
+{
+ if (args && !args->GetDestination().empty()) {
+ return args->GetDestination();
+ }
+ if (type == "BIN") {
+ return this->GetRuntimeDestination(nullptr);
+ }
+ if (type == "SBIN") {
+ return this->GetSbinDestination(nullptr);
+ }
+ if (type == "SYSCONF") {
+ return this->GetSysconfDestination(nullptr);
+ }
+ if (type == "SHAREDSTATE") {
+ return this->GetSharedStateDestination(nullptr);
+ }
+ if (type == "LOCALSTATE") {
+ return this->GetLocalStateDestination(nullptr);
+ }
+ if (type == "RUNSTATE") {
+ return this->GetRunStateDestination(nullptr);
+ }
+ if (type == "LIB") {
+ return this->GetLibraryDestination(nullptr);
+ }
+ if (type == "INCLUDE") {
+ return this->GetIncludeDestination(nullptr);
+ }
+ if (type == "DATA") {
+ return this->GetDataDestination(nullptr);
+ }
+ if (type == "INFO") {
+ return this->GetInfoDestination(nullptr);
+ }
+ if (type == "LOCALE") {
+ return this->GetLocaleDestination(nullptr);
+ }
+ if (type == "MAN") {
+ return this->GetManDestination(nullptr);
+ }
+ if (type == "DOC") {
+ return this->GetDocDestination(nullptr);
+ }
+ return "";
+}
diff --git a/Source/cmInstallCommand.h b/Source/cmInstallCommand.h
index 8bd0159..202c438 100644
--- a/Source/cmInstallCommand.h
+++ b/Source/cmInstallCommand.h
@@ -11,6 +11,7 @@
#include "cmCommand.h"
class cmExecutionStatus;
+class cmInstallCommandArguments;
/** \class cmInstallCommand
* \brief Specifies where to install some files
@@ -45,6 +46,27 @@ private:
std::vector<std::string>& absFiles);
bool CheckCMP0006(bool& failure);
+ std::string GetDestination(const cmInstallCommandArguments* args,
+ const std::string& varName,
+ const std::string& guess);
+ std::string GetRuntimeDestination(const cmInstallCommandArguments* args);
+ std::string GetSbinDestination(const cmInstallCommandArguments* args);
+ std::string GetArchiveDestination(const cmInstallCommandArguments* args);
+ std::string GetLibraryDestination(const cmInstallCommandArguments* args);
+ std::string GetIncludeDestination(const cmInstallCommandArguments* args);
+ std::string GetSysconfDestination(const cmInstallCommandArguments* args);
+ std::string GetSharedStateDestination(const cmInstallCommandArguments* args);
+ std::string GetLocalStateDestination(const cmInstallCommandArguments* args);
+ std::string GetRunStateDestination(const cmInstallCommandArguments* args);
+ std::string GetDataRootDestination(const cmInstallCommandArguments* args);
+ std::string GetDataDestination(const cmInstallCommandArguments* args);
+ std::string GetInfoDestination(const cmInstallCommandArguments* args);
+ std::string GetLocaleDestination(const cmInstallCommandArguments* args);
+ std::string GetManDestination(const cmInstallCommandArguments* args);
+ std::string GetDocDestination(const cmInstallCommandArguments* args);
+ std::string GetDestinationForType(const cmInstallCommandArguments* args,
+ const std::string& type);
+
std::string DefaultComponentName;
};
diff --git a/Source/cmInstallCommandArguments.cxx b/Source/cmInstallCommandArguments.cxx
index 2d6dc12..63bdb00 100644
--- a/Source/cmInstallCommandArguments.cxx
+++ b/Source/cmInstallCommandArguments.cxx
@@ -29,6 +29,7 @@ cmInstallCommandArguments::cmInstallCommandArguments(
, Optional(&Parser, "OPTIONAL", &ArgumentGroup)
, NamelinkOnly(&Parser, "NAMELINK_ONLY", &ArgumentGroup)
, NamelinkSkip(&Parser, "NAMELINK_SKIP", &ArgumentGroup)
+ , Type(&Parser, "TYPE", &ArgumentGroup)
, GenericArguments(nullptr)
, DefaultComponentName(defaultComponent)
{
@@ -145,6 +146,11 @@ bool cmInstallCommandArguments::HasNamelinkComponent() const
return false;
}
+const std::string& cmInstallCommandArguments::GetType() const
+{
+ return this->Type.GetString();
+}
+
const std::vector<std::string>& cmInstallCommandArguments::GetConfigurations()
const
{
diff --git a/Source/cmInstallCommandArguments.h b/Source/cmInstallCommandArguments.h
index ee6e865..425e58a 100644
--- a/Source/cmInstallCommandArguments.h
+++ b/Source/cmInstallCommandArguments.h
@@ -35,6 +35,7 @@ public:
bool GetNamelinkOnly() const;
bool GetNamelinkSkip() const;
bool HasNamelinkComponent() const;
+ const std::string& GetType() const;
// once HandleDirectoryMode() is also switched to using
// cmInstallCommandArguments then these two functions can become non-static
@@ -55,6 +56,7 @@ private:
cmCAEnabler Optional;
cmCAEnabler NamelinkOnly;
cmCAEnabler NamelinkSkip;
+ cmCAString Type;
std::string DestinationString;
std::string PermissionsString;
diff --git a/Tests/RunCMake/install/DIRECTORY-DESTINATION-TYPE-result.txt b/Tests/RunCMake/install/DIRECTORY-DESTINATION-TYPE-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/install/DIRECTORY-DESTINATION-TYPE-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/install/DIRECTORY-DESTINATION-TYPE-stderr.txt b/Tests/RunCMake/install/DIRECTORY-DESTINATION-TYPE-stderr.txt
new file mode 100644
index 0000000..c847c43
--- /dev/null
+++ b/Tests/RunCMake/install/DIRECTORY-DESTINATION-TYPE-stderr.txt
@@ -0,0 +1,5 @@
+^CMake Error at DIRECTORY-DESTINATION-TYPE\.cmake:[0-9]+ \(install\):
+ install DIRECTORY given both TYPE and DESTINATION arguments\. You may only
+ specify one\.
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/install/DIRECTORY-DESTINATION-TYPE.cmake b/Tests/RunCMake/install/DIRECTORY-DESTINATION-TYPE.cmake
new file mode 100644
index 0000000..4404d6b
--- /dev/null
+++ b/Tests/RunCMake/install/DIRECTORY-DESTINATION-TYPE.cmake
@@ -0,0 +1 @@
+install(DIRECTORY dir TYPE BIN DESTINATION mybin)
diff --git a/Tests/RunCMake/install/DIRECTORY-TYPE-Cache-all-check.cmake b/Tests/RunCMake/install/DIRECTORY-TYPE-Cache-all-check.cmake
new file mode 100644
index 0000000..fb393e3
--- /dev/null
+++ b/Tests/RunCMake/install/DIRECTORY-TYPE-Cache-all-check.cmake
@@ -0,0 +1,42 @@
+set(_check_files
+ [[mybin]]
+ [[mybin/dir]]
+ [[mybin/dir/empty\.txt]]
+ [[mycom]]
+ [[mycom/dir]]
+ [[mycom/dir/empty\.txt]]
+ [[mydoc]]
+ [[mydoc/dir]]
+ [[mydoc/dir/empty\.txt]]
+ [[myetc]]
+ [[myetc/dir]]
+ [[myetc/dir/empty\.txt]]
+ [[myinclude]]
+ [[myinclude/dir]]
+ [[myinclude/dir/empty\.txt]]
+ [[myinfo]]
+ [[myinfo/dir]]
+ [[myinfo/dir/empty\.txt]]
+ [[mylib]]
+ [[mylib/dir]]
+ [[mylib/dir/empty\.txt]]
+ [[mylocale]]
+ [[mylocale/dir]]
+ [[mylocale/dir/empty\.txt]]
+ [[myman]]
+ [[myman/dir]]
+ [[myman/dir/empty\.txt]]
+ [[myrun]]
+ [[myrun/dir]]
+ [[myrun/dir/empty\.txt]]
+ [[mysbin]]
+ [[mysbin/dir]]
+ [[mysbin/dir/empty\.txt]]
+ [[myshare]]
+ [[myshare/dir]]
+ [[myshare/dir/empty\.txt]]
+ [[myvar]]
+ [[myvar/dir]]
+ [[myvar/dir/empty\.txt]]
+ )
+check_installed("^${_check_files}$")
diff --git a/Tests/RunCMake/install/DIRECTORY-TYPE-Cache.cmake b/Tests/RunCMake/install/DIRECTORY-TYPE-Cache.cmake
new file mode 100644
index 0000000..53e95f8
--- /dev/null
+++ b/Tests/RunCMake/install/DIRECTORY-TYPE-Cache.cmake
@@ -0,0 +1,13 @@
+install(DIRECTORY dir TYPE BIN)
+install(DIRECTORY dir TYPE SBIN)
+install(DIRECTORY dir TYPE LIB)
+install(DIRECTORY dir TYPE INCLUDE)
+install(DIRECTORY dir TYPE SYSCONF)
+install(DIRECTORY dir TYPE SHAREDSTATE)
+install(DIRECTORY dir TYPE LOCALSTATE)
+install(DIRECTORY dir TYPE RUNSTATE)
+install(DIRECTORY dir TYPE DATA)
+install(DIRECTORY dir TYPE INFO)
+install(DIRECTORY dir TYPE LOCALE)
+install(DIRECTORY dir TYPE MAN)
+install(DIRECTORY dir TYPE DOC)
diff --git a/Tests/RunCMake/install/DIRECTORY-TYPE-CacheDependent-all-check.cmake b/Tests/RunCMake/install/DIRECTORY-TYPE-CacheDependent-all-check.cmake
new file mode 100644
index 0000000..03f7bd6
--- /dev/null
+++ b/Tests/RunCMake/install/DIRECTORY-TYPE-CacheDependent-all-check.cmake
@@ -0,0 +1,24 @@
+set(_check_files
+ [[myshare]]
+ [[myshare/dir]]
+ [[myshare/dir/empty\.txt]]
+ [[myshare/doc]]
+ [[myshare/doc/dir]]
+ [[myshare/doc/dir/empty\.txt]]
+ [[myshare/info]]
+ [[myshare/info/dir]]
+ [[myshare/info/dir/empty\.txt]]
+ [[myshare/locale]]
+ [[myshare/locale/dir]]
+ [[myshare/locale/dir/empty\.txt]]
+ [[myshare/man]]
+ [[myshare/man/dir]]
+ [[myshare/man/dir/empty.txt]]
+ [[myvar]]
+ [[myvar/dir]]
+ [[myvar/dir/empty\.txt]]
+ [[myvar/run]]
+ [[myvar/run/dir]]
+ [[myvar/run/dir/empty\.txt]]
+ )
+check_installed("^${_check_files}$")
diff --git a/Tests/RunCMake/install/DIRECTORY-TYPE-CacheDependent.cmake b/Tests/RunCMake/install/DIRECTORY-TYPE-CacheDependent.cmake
new file mode 100644
index 0000000..e797abb
--- /dev/null
+++ b/Tests/RunCMake/install/DIRECTORY-TYPE-CacheDependent.cmake
@@ -0,0 +1,7 @@
+install(DIRECTORY dir TYPE LOCALSTATE)
+install(DIRECTORY dir TYPE RUNSTATE)
+install(DIRECTORY dir TYPE DATA)
+install(DIRECTORY dir TYPE INFO)
+install(DIRECTORY dir TYPE LOCALE)
+install(DIRECTORY dir TYPE MAN)
+install(DIRECTORY dir TYPE DOC)
diff --git a/Tests/RunCMake/install/DIRECTORY-TYPE-all-check.cmake b/Tests/RunCMake/install/DIRECTORY-TYPE-all-check.cmake
new file mode 100644
index 0000000..03fa3c8
--- /dev/null
+++ b/Tests/RunCMake/install/DIRECTORY-TYPE-all-check.cmake
@@ -0,0 +1,42 @@
+set(_check_files
+ [[bin]]
+ [[bin/dir]]
+ [[bin/dir/empty\.txt]]
+ [[com]]
+ [[com/dir]]
+ [[com/dir/empty\.txt]]
+ [[etc]]
+ [[etc/dir]]
+ [[etc/dir/empty\.txt]]
+ [[include]]
+ [[include/dir]]
+ [[include/dir/empty\.txt]]
+ [[lib]]
+ [[lib/dir]]
+ [[lib/dir/empty\.txt]]
+ [[sbin]]
+ [[sbin/dir]]
+ [[sbin/dir/empty\.txt]]
+ [[share]]
+ [[share/dir]]
+ [[share/dir/empty\.txt]]
+ [[share/doc]]
+ [[share/doc/dir]]
+ [[share/doc/dir/empty\.txt]]
+ [[share/info]]
+ [[share/info/dir]]
+ [[share/info/dir/empty\.txt]]
+ [[share/locale]]
+ [[share/locale/dir]]
+ [[share/locale/dir/empty\.txt]]
+ [[share/man]]
+ [[share/man/dir]]
+ [[share/man/dir/empty\.txt]]
+ [[var]]
+ [[var/dir]]
+ [[var/dir/empty\.txt]]
+ [[var/run]]
+ [[var/run/dir]]
+ [[var/run/dir/empty\.txt]]
+ )
+check_installed("^${_check_files}$")
diff --git a/Tests/RunCMake/install/DIRECTORY-TYPE.cmake b/Tests/RunCMake/install/DIRECTORY-TYPE.cmake
new file mode 100644
index 0000000..53e95f8
--- /dev/null
+++ b/Tests/RunCMake/install/DIRECTORY-TYPE.cmake
@@ -0,0 +1,13 @@
+install(DIRECTORY dir TYPE BIN)
+install(DIRECTORY dir TYPE SBIN)
+install(DIRECTORY dir TYPE LIB)
+install(DIRECTORY dir TYPE INCLUDE)
+install(DIRECTORY dir TYPE SYSCONF)
+install(DIRECTORY dir TYPE SHAREDSTATE)
+install(DIRECTORY dir TYPE LOCALSTATE)
+install(DIRECTORY dir TYPE RUNSTATE)
+install(DIRECTORY dir TYPE DATA)
+install(DIRECTORY dir TYPE INFO)
+install(DIRECTORY dir TYPE LOCALE)
+install(DIRECTORY dir TYPE MAN)
+install(DIRECTORY dir TYPE DOC)
diff --git a/Tests/RunCMake/install/FILES-DESTINATION-TYPE-result.txt b/Tests/RunCMake/install/FILES-DESTINATION-TYPE-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/install/FILES-DESTINATION-TYPE-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/install/FILES-DESTINATION-TYPE-stderr.txt b/Tests/RunCMake/install/FILES-DESTINATION-TYPE-stderr.txt
new file mode 100644
index 0000000..ce8fc23
--- /dev/null
+++ b/Tests/RunCMake/install/FILES-DESTINATION-TYPE-stderr.txt
@@ -0,0 +1,5 @@
+^CMake Error at FILES-DESTINATION-TYPE\.cmake:[0-9]+ \(install\):
+ install FILES given both TYPE and DESTINATION arguments\. You may only
+ specify one\.
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/install/FILES-DESTINATION-TYPE.cmake b/Tests/RunCMake/install/FILES-DESTINATION-TYPE.cmake
new file mode 100644
index 0000000..576c98f
--- /dev/null
+++ b/Tests/RunCMake/install/FILES-DESTINATION-TYPE.cmake
@@ -0,0 +1 @@
+install(FILES main.c TYPE BIN DESTINATION mybin)
diff --git a/Tests/RunCMake/install/FILES-TYPE-Cache-all-check.cmake b/Tests/RunCMake/install/FILES-TYPE-Cache-all-check.cmake
new file mode 100644
index 0000000..dfb90cf
--- /dev/null
+++ b/Tests/RunCMake/install/FILES-TYPE-Cache-all-check.cmake
@@ -0,0 +1,29 @@
+set(_check_files
+ [[mybin]]
+ [[mybin/main\.c]]
+ [[mycom]]
+ [[mycom/main\.c]]
+ [[mydoc]]
+ [[mydoc/main\.c]]
+ [[myetc]]
+ [[myetc/main\.c]]
+ [[myinclude]]
+ [[myinclude/main\.c]]
+ [[myinfo]]
+ [[myinfo/main\.c]]
+ [[mylib]]
+ [[mylib/main\.c]]
+ [[mylocale]]
+ [[mylocale/main\.c]]
+ [[myman]]
+ [[myman/main\.c]]
+ [[myrun]]
+ [[myrun/main\.c]]
+ [[mysbin]]
+ [[mysbin/main\.c]]
+ [[myshare]]
+ [[myshare/main\.c]]
+ [[myvar]]
+ [[myvar/main\.c]]
+ )
+check_installed("^${_check_files}$")
diff --git a/Tests/RunCMake/install/FILES-TYPE-Cache.cmake b/Tests/RunCMake/install/FILES-TYPE-Cache.cmake
new file mode 100644
index 0000000..2e2bfc7
--- /dev/null
+++ b/Tests/RunCMake/install/FILES-TYPE-Cache.cmake
@@ -0,0 +1,13 @@
+install(FILES main.c TYPE BIN)
+install(FILES main.c TYPE SBIN)
+install(FILES main.c TYPE LIB)
+install(FILES main.c TYPE INCLUDE)
+install(FILES main.c TYPE SYSCONF)
+install(FILES main.c TYPE SHAREDSTATE)
+install(FILES main.c TYPE LOCALSTATE)
+install(FILES main.c TYPE RUNSTATE)
+install(FILES main.c TYPE DATA)
+install(FILES main.c TYPE INFO)
+install(FILES main.c TYPE LOCALE)
+install(FILES main.c TYPE MAN)
+install(FILES main.c TYPE DOC)
diff --git a/Tests/RunCMake/install/FILES-TYPE-CacheDependent-all-check.cmake b/Tests/RunCMake/install/FILES-TYPE-CacheDependent-all-check.cmake
new file mode 100644
index 0000000..e58c80a
--- /dev/null
+++ b/Tests/RunCMake/install/FILES-TYPE-CacheDependent-all-check.cmake
@@ -0,0 +1,17 @@
+set(_check_files
+ [[myshare]]
+ [[myshare/doc]]
+ [[myshare/doc/main\.c]]
+ [[myshare/info]]
+ [[myshare/info/main\.c]]
+ [[myshare/locale]]
+ [[myshare/locale/main\.c]]
+ [[myshare/main\.c]]
+ [[myshare/man]]
+ [[myshare/man/main\.c]]
+ [[myvar]]
+ [[myvar/main\.c]]
+ [[myvar/run]]
+ [[myvar/run/main\.c]]
+ )
+check_installed("^${_check_files}$")
diff --git a/Tests/RunCMake/install/FILES-TYPE-CacheDependent.cmake b/Tests/RunCMake/install/FILES-TYPE-CacheDependent.cmake
new file mode 100644
index 0000000..d7d5aaa
--- /dev/null
+++ b/Tests/RunCMake/install/FILES-TYPE-CacheDependent.cmake
@@ -0,0 +1,7 @@
+install(FILES main.c TYPE LOCALSTATE)
+install(FILES main.c TYPE RUNSTATE)
+install(FILES main.c TYPE DATA)
+install(FILES main.c TYPE INFO)
+install(FILES main.c TYPE LOCALE)
+install(FILES main.c TYPE MAN)
+install(FILES main.c TYPE DOC)
diff --git a/Tests/RunCMake/install/FILES-TYPE-all-check.cmake b/Tests/RunCMake/install/FILES-TYPE-all-check.cmake
new file mode 100644
index 0000000..c4ec661
--- /dev/null
+++ b/Tests/RunCMake/install/FILES-TYPE-all-check.cmake
@@ -0,0 +1,29 @@
+set(_check_files
+ [[bin]]
+ [[bin/main\.c]]
+ [[com]]
+ [[com/main\.c]]
+ [[etc]]
+ [[etc/main\.c]]
+ [[include]]
+ [[include/main\.c]]
+ [[lib]]
+ [[lib/main\.c]]
+ [[sbin]]
+ [[sbin/main\.c]]
+ [[share]]
+ [[share/doc]]
+ [[share/doc/main\.c]]
+ [[share/info]]
+ [[share/info/main\.c]]
+ [[share/locale]]
+ [[share/locale/main\.c]]
+ [[share/main\.c]]
+ [[share/man]]
+ [[share/man/main\.c]]
+ [[var]]
+ [[var/main\.c]]
+ [[var/run]]
+ [[var/run/main\.c]]
+ )
+check_installed("^${_check_files}$")
diff --git a/Tests/RunCMake/install/FILES-TYPE.cmake b/Tests/RunCMake/install/FILES-TYPE.cmake
new file mode 100644
index 0000000..2e2bfc7
--- /dev/null
+++ b/Tests/RunCMake/install/FILES-TYPE.cmake
@@ -0,0 +1,13 @@
+install(FILES main.c TYPE BIN)
+install(FILES main.c TYPE SBIN)
+install(FILES main.c TYPE LIB)
+install(FILES main.c TYPE INCLUDE)
+install(FILES main.c TYPE SYSCONF)
+install(FILES main.c TYPE SHAREDSTATE)
+install(FILES main.c TYPE LOCALSTATE)
+install(FILES main.c TYPE RUNSTATE)
+install(FILES main.c TYPE DATA)
+install(FILES main.c TYPE INFO)
+install(FILES main.c TYPE LOCALE)
+install(FILES main.c TYPE MAN)
+install(FILES main.c TYPE DOC)
diff --git a/Tests/RunCMake/install/RunCMakeTest.cmake b/Tests/RunCMake/install/RunCMakeTest.cmake
index ec022ca..f7e1dee 100644
--- a/Tests/RunCMake/install/RunCMakeTest.cmake
+++ b/Tests/RunCMake/install/RunCMakeTest.cmake
@@ -65,6 +65,12 @@ run_cmake(CMP0062-NEW)
run_cmake(CMP0062-WARN)
run_cmake(TARGETS-NAMELINK_COMPONENT-bad-all)
run_cmake(TARGETS-NAMELINK_COMPONENT-bad-exc)
+run_cmake(FILES-DESTINATION-TYPE)
+run_cmake(DIRECTORY-DESTINATION-TYPE)
+
+if(APPLE)
+ run_cmake(TARGETS-Apple-Defaults)
+endif()
if(NOT RunCMake_GENERATOR STREQUAL "Xcode" OR NOT "$ENV{CMAKE_OSX_ARCHITECTURES}" MATCHES "[;$]")
run_install_test(FILES-TARGET_OBJECTS)
@@ -74,6 +80,46 @@ run_install_test(TARGETS-InstallFromSubDir)
run_install_test(TARGETS-OPTIONAL)
run_install_test(FILES-OPTIONAL)
run_install_test(DIRECTORY-OPTIONAL)
+run_install_test(TARGETS-Defaults)
+
+set(RunCMake_TEST_OPTIONS
+ "-DCMAKE_INSTALL_BINDIR:PATH=mybin"
+ "-DCMAKE_INSTALL_LIBDIR:PATH=mylib"
+ "-DCMAKE_INSTALL_INCLUDEDIR:PATH=myinclude"
+ )
+run_install_test(TARGETS-Defaults-Cache)
+unset(RunCMake_TEST_OPTIONS)
+
+run_install_test(FILES-TYPE)
+run_install_test(DIRECTORY-TYPE)
+
+set(RunCMake_TEST_OPTIONS
+ "-DCMAKE_INSTALL_BINDIR:PATH=mybin"
+ "-DCMAKE_INSTALL_SBINDIR:PATH=mysbin"
+ "-DCMAKE_INSTALL_LIBEXECDIR:PATH=mylibexec"
+ "-DCMAKE_INSTALL_LIBDIR:PATH=mylib"
+ "-DCMAKE_INSTALL_INCLUDEDIR:PATH=myinclude"
+ "-DCMAKE_INSTALL_SYSCONFDIR:PATH=myetc"
+ "-DCMAKE_INSTALL_SHAREDSTATEDIR:PATH=mycom"
+ "-DCMAKE_INSTALL_LOCALSTATEDIR:PATH=myvar"
+ "-DCMAKE_INSTALL_RUNSTATEDIR:PATH=myrun"
+ "-DCMAKE_INSTALL_DATADIR:PATH=myshare"
+ "-DCMAKE_INSTALL_INFODIR:PATH=myinfo"
+ "-DCMAKE_INSTALL_LOCALEDIR:PATH=mylocale"
+ "-DCMAKE_INSTALL_MANDIR:PATH=myman"
+ "-DCMAKE_INSTALL_DOCDIR:PATH=mydoc"
+ )
+run_install_test(FILES-TYPE-Cache)
+run_install_test(DIRECTORY-TYPE-Cache)
+unset(RunCMake_TEST_OPTIONS)
+
+set(RunCMake_TEST_OPTIONS
+ "-DCMAKE_INSTALL_LOCALSTATEDIR:PATH=myvar"
+ "-DCMAKE_INSTALL_DATAROOTDIR:PATH=myshare"
+ )
+run_install_test(FILES-TYPE-CacheDependent)
+run_install_test(DIRECTORY-TYPE-CacheDependent)
+unset(RunCMake_TEST_OPTIONS)
set(RunCMake_TEST_OPTIONS "-DCMAKE_BUILD_TYPE:STRING=Debug")
run_install_test(TARGETS-OUTPUT_NAME)
diff --git a/Tests/RunCMake/install/TARGETS-Apple-Defaults-result.txt b/Tests/RunCMake/install/TARGETS-Apple-Defaults-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/install/TARGETS-Apple-Defaults-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/install/TARGETS-Apple-Defaults-stderr.txt b/Tests/RunCMake/install/TARGETS-Apple-Defaults-stderr.txt
new file mode 100644
index 0000000..645882f
--- /dev/null
+++ b/Tests/RunCMake/install/TARGETS-Apple-Defaults-stderr.txt
@@ -0,0 +1,12 @@
+^CMake Error at TARGETS-Apple-Defaults\.cmake:[0-9]+ \(install\):
+ install TARGETS given no BUNDLE DESTINATION for MACOSX_BUNDLE executable
+ target "exe"\.
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:[0-9]+ \(include\)
+
+
+CMake Error at TARGETS-Apple-Defaults\.cmake:[0-9]+ \(install\):
+ install TARGETS given no FRAMEWORK DESTINATION for shared library FRAMEWORK
+ target "lib1"\.
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/install/TARGETS-Apple-Defaults.cmake b/Tests/RunCMake/install/TARGETS-Apple-Defaults.cmake
new file mode 100644
index 0000000..b60c318
--- /dev/null
+++ b/Tests/RunCMake/install/TARGETS-Apple-Defaults.cmake
@@ -0,0 +1,8 @@
+enable_language(C)
+
+add_executable(exe MACOSX_BUNDLE main.c)
+add_library(lib1 SHARED obj1.c)
+set_property(TARGET lib1 PROPERTY FRAMEWORK ON)
+
+install(TARGETS exe)
+install(TARGETS lib1)
diff --git a/Tests/RunCMake/install/TARGETS-Defaults-Cache-all-check.cmake b/Tests/RunCMake/install/TARGETS-Defaults-Cache-all-check.cmake
new file mode 100644
index 0000000..6fc735c
--- /dev/null
+++ b/Tests/RunCMake/install/TARGETS-Defaults-Cache-all-check.cmake
@@ -0,0 +1,49 @@
+if(WIN32)
+ set(_check_files
+ [[lib3]]
+ [[lib3/(lib)?lib3\.(dll\.a|lib)]]
+ [[lib4]]
+ [[lib4/(lib)?lib4\.dll]]
+ [[mybin]]
+ [[mybin/exe\.exe]]
+ [[mybin/(lib)?lib1\.dll]]
+ [[myinclude]]
+ [[myinclude/obj4\.h]]
+ [[myinclude/obj5\.h]]
+ [[mylib]]
+ [[mylib/(lib)?lib1\.(dll\.a|lib)]]
+ [[mylib/(lib)?lib2\.(a|lib)]]
+ )
+elseif(CYGWIN)
+ set(_check_files
+ [[lib3]]
+ [[lib3/liblib3\.dll\.a]]
+ [[lib4]]
+ [[lib4/cyglib4\.dll]]
+ [[mybin]]
+ [[mybin/exe\.exe]]
+ [[mybin/cyglib1\.dll]]
+ [[myinclude]]
+ [[myinclude/obj4\.h]]
+ [[myinclude/obj5\.h]]
+ [[mylib]]
+ [[mylib/liblib1\.dll\.a]]
+ [[mylib/liblib2\.a]]
+ )
+else()
+ set(_check_files
+ [[lib3]]
+ [[lib3/liblib3\.(dylib|so)]]
+ [[lib4]]
+ [[lib4/liblib4\.(dylib|so)]]
+ [[mybin]]
+ [[mybin/exe]]
+ [[myinclude]]
+ [[myinclude/obj4\.h]]
+ [[myinclude/obj5\.h]]
+ [[mylib]]
+ [[mylib/liblib1\.(dylib|so)]]
+ [[mylib/liblib2\.a]]
+ )
+endif()
+check_installed("^${_check_files}$")
diff --git a/Tests/RunCMake/install/TARGETS-Defaults-Cache.cmake b/Tests/RunCMake/install/TARGETS-Defaults-Cache.cmake
new file mode 100644
index 0000000..bfd8c2c
--- /dev/null
+++ b/Tests/RunCMake/install/TARGETS-Defaults-Cache.cmake
@@ -0,0 +1,19 @@
+enable_language(C)
+
+add_executable(exe main.c)
+add_library(lib1 SHARED obj1.c)
+add_library(lib2 STATIC obj3.c)
+add_library(lib3 SHARED obj4.c)
+set_property(TARGET lib3 PROPERTY PRIVATE_HEADER ${CMAKE_CURRENT_SOURCE_DIR}/obj4.h)
+add_library(lib4 SHARED obj5.c)
+set_property(TARGET lib4 PROPERTY PUBLIC_HEADER ${CMAKE_CURRENT_SOURCE_DIR}/obj5.h)
+
+install(TARGETS exe lib1 lib2)
+install(TARGETS lib3
+ LIBRARY DESTINATION lib3
+ ARCHIVE DESTINATION lib3
+ )
+install(TARGETS lib4
+ LIBRARY DESTINATION lib4
+ RUNTIME DESTINATION lib4
+ )
diff --git a/Tests/RunCMake/install/TARGETS-Defaults-all-check.cmake b/Tests/RunCMake/install/TARGETS-Defaults-all-check.cmake
new file mode 100644
index 0000000..59209e6
--- /dev/null
+++ b/Tests/RunCMake/install/TARGETS-Defaults-all-check.cmake
@@ -0,0 +1,49 @@
+if(WIN32)
+ set(_check_files
+ [[bin]]
+ [[bin/exe\.exe]]
+ [[bin/(lib)?lib1\.dll]]
+ [[include]]
+ [[include/obj4\.h]]
+ [[include/obj5\.h]]
+ [[lib]]
+ [[lib/(lib)?lib1\.(dll\.a|lib)]]
+ [[lib/(lib)?lib2\.(a|lib)]]
+ [[lib3]]
+ [[lib3/(lib)?lib3\.(dll\.a|lib)]]
+ [[lib4]]
+ [[lib4/(lib)?lib4\.dll]]
+ )
+elseif(CYGWIN)
+ set(_check_files
+ [[bin]]
+ [[bin/exe\.exe]]
+ [[bin/cyglib1\.dll]]
+ [[include]]
+ [[include/obj4\.h]]
+ [[include/obj5\.h]]
+ [[lib]]
+ [[lib/liblib1\.dll\.a]]
+ [[lib/liblib2\.a]]
+ [[lib3]]
+ [[lib3/liblib3\.dll\.a]]
+ [[lib4]]
+ [[lib4/cyglib4\.dll]]
+ )
+else()
+ set(_check_files
+ [[bin]]
+ [[bin/exe]]
+ [[include]]
+ [[include/obj4\.h]]
+ [[include/obj5\.h]]
+ [[lib]]
+ [[lib/liblib1\.(dylib|so)]]
+ [[lib/liblib2\.a]]
+ [[lib3]]
+ [[lib3/liblib3\.(dylib|so)]]
+ [[lib4]]
+ [[lib4/liblib4\.(dylib|so)]]
+ )
+endif()
+check_installed("^${_check_files}$")
diff --git a/Tests/RunCMake/install/TARGETS-Defaults.cmake b/Tests/RunCMake/install/TARGETS-Defaults.cmake
new file mode 100644
index 0000000..bfd8c2c
--- /dev/null
+++ b/Tests/RunCMake/install/TARGETS-Defaults.cmake
@@ -0,0 +1,19 @@
+enable_language(C)
+
+add_executable(exe main.c)
+add_library(lib1 SHARED obj1.c)
+add_library(lib2 STATIC obj3.c)
+add_library(lib3 SHARED obj4.c)
+set_property(TARGET lib3 PROPERTY PRIVATE_HEADER ${CMAKE_CURRENT_SOURCE_DIR}/obj4.h)
+add_library(lib4 SHARED obj5.c)
+set_property(TARGET lib4 PROPERTY PUBLIC_HEADER ${CMAKE_CURRENT_SOURCE_DIR}/obj5.h)
+
+install(TARGETS exe lib1 lib2)
+install(TARGETS lib3
+ LIBRARY DESTINATION lib3
+ ARCHIVE DESTINATION lib3
+ )
+install(TARGETS lib4
+ LIBRARY DESTINATION lib4
+ RUNTIME DESTINATION lib4
+ )
diff --git a/Tests/RunCMake/install/obj3.c b/Tests/RunCMake/install/obj3.c
new file mode 100644
index 0000000..991fed3
--- /dev/null
+++ b/Tests/RunCMake/install/obj3.c
@@ -0,0 +1,7 @@
+#ifdef _WIN32
+__declspec(dllexport)
+#endif
+ int obj3(void)
+{
+ return 0;
+}
diff --git a/Tests/RunCMake/install/obj3.h b/Tests/RunCMake/install/obj3.h
new file mode 100644
index 0000000..9e8bb76
--- /dev/null
+++ b/Tests/RunCMake/install/obj3.h
@@ -0,0 +1,6 @@
+#ifndef OBJ3_H
+#define OBJ3_H
+
+int obj3(void);
+
+#endif /* OBJ3_H */
diff --git a/Tests/RunCMake/install/obj4.c b/Tests/RunCMake/install/obj4.c
new file mode 100644
index 0000000..edd6172
--- /dev/null
+++ b/Tests/RunCMake/install/obj4.c
@@ -0,0 +1,7 @@
+#ifdef _WIN32
+__declspec(dllexport)
+#endif
+ int obj4(void)
+{
+ return 0;
+}
diff --git a/Tests/RunCMake/install/obj4.h b/Tests/RunCMake/install/obj4.h
new file mode 100644
index 0000000..6195aa7
--- /dev/null
+++ b/Tests/RunCMake/install/obj4.h
@@ -0,0 +1,6 @@
+#ifndef OBJ4_H
+#define OBJ4_H
+
+int obj4(void);
+
+#endif /* OBJ4_H */
diff --git a/Tests/RunCMake/install/obj5.c b/Tests/RunCMake/install/obj5.c
new file mode 100644
index 0000000..df3e997
--- /dev/null
+++ b/Tests/RunCMake/install/obj5.c
@@ -0,0 +1,7 @@
+#ifdef _WIN32
+__declspec(dllexport)
+#endif
+ int obj5(void)
+{
+ return 0;
+}
diff --git a/Tests/RunCMake/install/obj5.h b/Tests/RunCMake/install/obj5.h
new file mode 100644
index 0000000..a16a1b0
--- /dev/null
+++ b/Tests/RunCMake/install/obj5.h
@@ -0,0 +1,6 @@
+#ifndef OBJ5_H
+#define OBJ5_H
+
+int obj5(void);
+
+#endif /* OBJ5_H */