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.
This commit is contained in:
Kyle Edwards
2018-11-02 12:42:41 -04:00
parent 71db32660e
commit 9fc20a4f3e
36 changed files with 834 additions and 81 deletions

View File

@@ -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 std::string& destination)
{
cmInstallGenerator::MessageLevel message =
cmInstallGenerator::SelectMessageLevel(mf);
return new cmInstallFilesGenerator(
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)
{
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());
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 "";
}

View File

@@ -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;
};

View File

@@ -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
{

View File

@@ -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;

View File

@@ -0,0 +1 @@
1

View File

@@ -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\)$

View File

@@ -0,0 +1 @@
install(DIRECTORY dir TYPE BIN DESTINATION mybin)

View File

@@ -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}$")

View File

@@ -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)

View File

@@ -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}$")

View File

@@ -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)

View File

@@ -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}$")

View File

@@ -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)

View File

@@ -0,0 +1 @@
1

View File

@@ -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\)$

View File

@@ -0,0 +1 @@
install(FILES main.c TYPE BIN DESTINATION mybin)

View File

@@ -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}$")

View File

@@ -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)

View File

@@ -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}$")

View File

@@ -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)

View File

@@ -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}$")

View File

@@ -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)

View File

@@ -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)

View File

@@ -0,0 +1 @@
1

View File

@@ -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\)$

View File

@@ -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)

View File

@@ -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}$")

View File

@@ -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
)

View File

@@ -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}$")

View File

@@ -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
)

View File

@@ -0,0 +1,7 @@
#ifdef _WIN32
__declspec(dllexport)
#endif
int obj3(void)
{
return 0;
}

View File

@@ -0,0 +1,6 @@
#ifndef OBJ3_H
#define OBJ3_H
int obj3(void);
#endif /* OBJ3_H */

View File

@@ -0,0 +1,7 @@
#ifdef _WIN32
__declspec(dllexport)
#endif
int obj4(void)
{
return 0;
}

View File

@@ -0,0 +1,6 @@
#ifndef OBJ4_H
#define OBJ4_H
int obj4(void);
#endif /* OBJ4_H */

View File

@@ -0,0 +1,7 @@
#ifdef _WIN32
__declspec(dllexport)
#endif
int obj5(void)
{
return 0;
}

View File

@@ -0,0 +1,6 @@
#ifndef OBJ5_H
#define OBJ5_H
int obj5(void);
#endif /* OBJ5_H */