summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Source/cmFileCommand.cxx394
-rw-r--r--Source/cmInstallCommand.cxx80
-rw-r--r--Source/cmInstallCommand.h30
-rw-r--r--Source/cmInstallFilesGenerator.cxx12
-rw-r--r--Source/cmInstallFilesGenerator.h5
-rw-r--r--Source/cmInstallGenerator.cxx12
-rw-r--r--Source/cmInstallGenerator.h4
-rw-r--r--Source/cmLocalGenerator.cxx10
-rw-r--r--Tests/SimpleInstall/CMakeLists.txt10
-rw-r--r--Tests/SimpleInstall/inst.cxx10
-rw-r--r--Tests/SimpleInstall/inst2.cxx2
-rw-r--r--Tests/SimpleInstallS2/CMakeLists.txt10
-rw-r--r--Tests/SimpleInstallS2/inst.cxx10
-rw-r--r--Tests/SimpleInstallS2/inst2.cxx2
14 files changed, 446 insertions, 145 deletions
diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx
index 36d309e799..3c45d666f0 100644
--- a/Source/cmFileCommand.cxx
+++ b/Source/cmFileCommand.cxx
@@ -276,6 +276,7 @@ bool cmFileCommand::HandleInstallCommand(
return false;
}
+ std::string rename = "";
std::string destination = "";
std::string stype = "FILES";
const char* build_type = m_Makefile->GetDefinition("BUILD_TYPE");
@@ -298,8 +299,38 @@ bool cmFileCommand::HandleInstallCommand(
std::map<cmStdString, const char*> properties;
+ // Build a table of permissions flags.
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ mode_t mode_owner_read = S_IREAD;
+ mode_t mode_owner_write = S_IWRITE;
+ mode_t mode_owner_execute = S_IEXEC;
+ mode_t mode_group_read = 0;
+ mode_t mode_group_write = 0;
+ mode_t mode_group_execute = 0;
+ mode_t mode_world_read = 0;
+ mode_t mode_world_write = 0;
+ mode_t mode_world_execute = 0;
+ mode_t mode_setuid = 0;
+ mode_t mode_setgid = 0;
+#else
+ mode_t mode_owner_read = S_IRUSR;
+ mode_t mode_owner_write = S_IWUSR;
+ mode_t mode_owner_execute = S_IXUSR;
+ mode_t mode_group_read = S_IRGRP;
+ mode_t mode_group_write = S_IWGRP;
+ mode_t mode_group_execute = S_IXGRP;
+ mode_t mode_world_read = S_IROTH;
+ mode_t mode_world_write = S_IWOTH;
+ mode_t mode_world_execute = S_IXOTH;
+ mode_t mode_setuid = S_ISUID;
+ mode_t mode_setgid = S_ISGID;
+#endif
+
bool in_files = false;
bool in_properties = false;
+ bool in_permissions = false;
+ bool use_given_permissions = false;
+ mode_t permissions = 0;
bool optional = false;
for ( ; i != args.size(); ++i )
{
@@ -310,6 +341,7 @@ bool cmFileCommand::HandleInstallCommand(
destination = args[i];
in_files = false;
in_properties = false;
+ in_permissions = false;
}
else if ( *cstr == "TYPE" && i < args.size()-1 )
{
@@ -322,16 +354,34 @@ bool cmFileCommand::HandleInstallCommand(
}
in_properties = false;
in_files = false;
+ in_permissions = false;
+ }
+ else if ( *cstr == "RENAME" && i < args.size()-1 )
+ {
+ i++;
+ rename = args[i];
+ in_properties = false;
+ in_files = false;
+ in_permissions = false;
}
else if ( *cstr == "PROPERTIES" )
{
in_properties = true;
in_files = false;
+ in_permissions = false;
+ }
+ else if ( *cstr == "PERMISSIONS" )
+ {
+ use_given_permissions = true;
+ in_properties = false;
+ in_files = false;
+ in_permissions = true;
}
else if ( *cstr == "FILES" && !in_files)
{
in_files = true;
in_properties = false;
+ in_permissions = false;
}
else if ( in_properties && i < args.size()-1 )
{
@@ -342,6 +392,50 @@ bool cmFileCommand::HandleInstallCommand(
{
files.push_back(*cstr);
}
+ else if(in_permissions && args[i] == "OWNER_READ")
+ {
+ permissions |= mode_owner_read;
+ }
+ else if(in_permissions && args[i] == "OWNER_WRITE")
+ {
+ permissions |= mode_owner_write;
+ }
+ else if(in_permissions && args[i] == "OWNER_EXECUTE")
+ {
+ permissions |= mode_owner_execute;
+ }
+ else if(in_permissions && args[i] == "GROUP_READ")
+ {
+ permissions |= mode_group_read;
+ }
+ else if(in_permissions && args[i] == "GROUP_WRITE")
+ {
+ permissions |= mode_group_write;
+ }
+ else if(in_permissions && args[i] == "GROUP_EXECUTE")
+ {
+ permissions |= mode_group_execute;
+ }
+ else if(in_permissions && args[i] == "WORLD_READ")
+ {
+ permissions |= mode_world_read;
+ }
+ else if(in_permissions && args[i] == "WORLD_WRITE")
+ {
+ permissions |= mode_world_write;
+ }
+ else if(in_permissions && args[i] == "WORLD_EXECUTE")
+ {
+ permissions |= mode_world_execute;
+ }
+ else if(in_permissions && args[i] == "SETUID")
+ {
+ permissions |= mode_setuid;
+ }
+ else if(in_permissions && args[i] == "SETGID")
+ {
+ permissions |= mode_setgid;
+ }
else
{
this->SetError("called with inappropriate arguments");
@@ -458,6 +552,61 @@ bool cmFileCommand::HandleInstallCommand(
return false;
}
+ // Check rename form.
+ if(!rename.empty())
+ {
+ if(itype != cmTarget::INSTALL_FILES)
+ {
+ this->SetError("INSTALL option RENAME may be used only with FILES.");
+ return false;
+ }
+ if(files.size() > 1)
+ {
+ this->SetError("INSTALL option RENAME may be used only with one file.");
+ return false;
+ }
+ }
+
+ // If permissions were not specified set default permissions for
+ // this target type.
+ bool use_source_permissions = false;
+ if(!use_given_permissions)
+ {
+ switch(itype)
+ {
+ case cmTarget::SHARED_LIBRARY:
+ case cmTarget::MODULE_LIBRARY:
+#if !defined(_WIN32) && !defined(__APPLE_CC__)
+ // Use read/write permissions.
+ use_given_permissions = true;
+ permissions = 0;
+ permissions |= mode_owner_read;
+ permissions |= mode_owner_write;
+ permissions |= mode_group_read;
+ permissions |= mode_world_read;
+ break;
+#endif
+ case cmTarget::EXECUTABLE:
+ case cmTarget::INSTALL_PROGRAMS:
+ // Use read/write/executable permissions.
+ use_given_permissions = true;
+ permissions = 0;
+ permissions |= mode_owner_read;
+ permissions |= mode_owner_write;
+ permissions |= mode_owner_execute;
+ permissions |= mode_group_read;
+ permissions |= mode_group_execute;
+ permissions |= mode_world_read;
+ permissions |= mode_world_execute;
+ break;
+ default:
+ // Use the permissions of the file being copied.
+ use_source_permissions = true;
+ break;
+ }
+ }
+
+ // Get the current manifest.
const char* manifest_files =
m_Makefile->GetDefinition("CMAKE_INSTALL_MANIFEST_FILES");
std::string smanifest_files;
@@ -466,26 +615,24 @@ bool cmFileCommand::HandleInstallCommand(
smanifest_files = manifest_files;
}
+ // Handle each file listed.
for ( i = 0; i < files.size(); i ++ )
{
- std::string destfilewe
- = destination + "/"
- + cmSystemTools::GetFilenameWithoutExtension(files[i]);
- std::string ctarget = files[i].c_str();
- std::string fname = cmSystemTools::GetFilenameName(ctarget);
- std::string ext = cmSystemTools::GetFilenameExtension(ctarget);
- std::string fnamewe
- = cmSystemTools::GetFilenameWithoutExtension(ctarget);
- std::string destfile = destfilewe;
- if ( ext.size() )
- {
- destfile += ext;
- }
- switch( itype )
+ // Split the input file into its directory and name components.
+ std::string fromDir = cmSystemTools::GetFilenamePath(files[i]);
+ std::string fromName = cmSystemTools::GetFilenameName(files[i]);
+
+ // Compute the full path to the destination file.
+ std::string toFile = destination;
+ toFile += "/";
+ toFile += rename.empty()? fromName : rename;
+
+ // Handle type-specific installation details.
+ switch(itype)
{
- case cmTarget::MODULE_LIBRARY:
- case cmTarget::STATIC_LIBRARY:
- case cmTarget::SHARED_LIBRARY:
+ case cmTarget::MODULE_LIBRARY:
+ case cmTarget::STATIC_LIBRARY:
+ case cmTarget::SHARED_LIBRARY:
{
// Handle shared library versioning
const char* lib_version = 0;
@@ -508,18 +655,18 @@ bool cmFileCommand::HandleInstallCommand(
}
if ( lib_version && lib_soversion )
{
- std::string libname = destfile;
- std::string soname = destfile;
- std::string soname_nopath = fname;
+ std::string libname = toFile;
+ std::string soname = toFile;
+ std::string soname_nopath = fromName;
soname += ".";
soname += lib_soversion;
soname_nopath += ".";
soname_nopath += lib_soversion;
- fname += ".";
- fname += lib_version;
- destfile += ".";
- destfile += lib_version;
+ fromName += ".";
+ fromName += lib_version;
+ toFile += ".";
+ toFile += lib_version;
cmSystemTools::RemoveFile(soname.c_str());
cmSystemTools::RemoveFile(libname.c_str());
@@ -532,11 +679,11 @@ bool cmFileCommand::HandleInstallCommand(
}
smanifest_files += ";";
smanifest_files += libname.substr(destDirLength);;
- if ( destfile != soname )
+ if ( toFile != soname )
{
- if ( !cmSystemTools::CreateSymlink(fname.c_str(), soname.c_str()) )
+ if ( !cmSystemTools::CreateSymlink(fromName.c_str(), soname.c_str()) )
{
- std::string errstring = "error when creating symlink from: " + soname + " to " + fname;
+ std::string errstring = "error when creating symlink from: " + soname + " to " + fromName;
this->SetError(errstring.c_str());
return false;
}
@@ -544,129 +691,134 @@ bool cmFileCommand::HandleInstallCommand(
smanifest_files += soname.substr(destDirLength);
}
}
-
- // Reconstruct the source file path taking into account the
- // possibly new file name.
- cmOStringStream str;
- str << cmSystemTools::GetFilenamePath(ctarget) << "/" << fname;
- ctarget = str.str();
- }
- break;
- case cmTarget::EXECUTABLE:
- {
- // Handle executable versioning
- const char* exe_version = 0;
- if ( properties.find("VERSION") != properties.end() )
- {
- exe_version = properties["VERSION"];
}
- if ( exe_version )
+ break;
+ case cmTarget::EXECUTABLE:
{
- std::string exename = destfile;
- std::string exename_nopath = fname;
- exename_nopath += "-";
- exename_nopath += exe_version;
+ // Handle executable versioning
+ const char* exe_version = 0;
+ if ( properties.find("VERSION") != properties.end() )
+ {
+ exe_version = properties["VERSION"];
+ }
+ if ( exe_version )
+ {
+ std::string exename = toFile;
+ std::string exename_nopath = fromName;
+ exename_nopath += "-";
+ exename_nopath += exe_version;
- fname += "-";
- fname += exe_version;
- destfile += "-";
- destfile += exe_version;
+ fromName += "-";
+ fromName += exe_version;
+ toFile += "-";
+ toFile += exe_version;
- cmSystemTools::RemoveFile(exename.c_str());
+ cmSystemTools::RemoveFile(exename.c_str());
- if (!cmSystemTools::CreateSymlink(exename_nopath.c_str(), exename.c_str()) )
- {
- std::string errstring = "error when creating symlink from: " + exename + " to " + exename_nopath;
- this->SetError(errstring.c_str());
- return false;
+ if (!cmSystemTools::CreateSymlink(exename_nopath.c_str(), exename.c_str()) )
+ {
+ std::string errstring = "error when creating symlink from: " + exename + " to " + exename_nopath;
+ this->SetError(errstring.c_str());
+ return false;
+ }
+ smanifest_files += ";";
+ smanifest_files += exename.substr(destDirLength);
}
- smanifest_files += ";";
- smanifest_files += exename.substr(destDirLength);
}
-
- // Reconstruct the source file path taking into account the
- // possibly new file name.
- cmOStringStream str;
- str << cmSystemTools::GetFilenamePath(ctarget) << "/" << fname;
- ctarget = str.str();
- }
- break;
+ break;
}
+ // Construct the full path to the source file. The file name may
+ // have been changed above.
+ std::string fromFile = fromDir;
+ fromFile += "/";
+ fromFile += fromName;
+
std::string message;
- if ( !cmSystemTools::SameFile(ctarget.c_str(), destfile.c_str()) )
+ if(!cmSystemTools::SameFile(fromFile.c_str(), toFile.c_str()))
{
- if ( cmSystemTools::FileExists(ctarget.c_str()) )
+ if(cmSystemTools::FileExists(fromFile.c_str()))
{
+ // We will install this file. Display the information.
message = "Installing ";
- message += destfile.c_str();
+ message += toFile.c_str();
m_Makefile->DisplayStatus(message.c_str(), -1);
- cmSystemTools::RemoveFile(destfile.c_str());
- if ( !cmSystemTools::CopyFileAlways(ctarget.c_str(),
- destination.c_str()) )
+
+ // If no permissions were already given use the permissions of
+ // the file being copied.
+ if(!use_given_permissions &&
+ (!use_source_permissions ||
+ !cmSystemTools::GetPermissions(fromFile.c_str(), permissions)))
{
- std::string errstring = "cannot copy file: " + ctarget +
- " to directory : " + destination + ".";
- this->SetError(errstring.c_str());
- return false;
+ // Set default permissions.
+ permissions = 0;
+ permissions |= mode_owner_read;
+ permissions |= mode_owner_write;
+ permissions |= mode_group_read;
+ permissions |= mode_world_read;
}
- switch( itype )
+
+ // Remove the original file and try copying the new file.
+ // TODO: This should be copy-if-different. Don't forget to
+ // edit the destination file permissions, or compare files
+ // first. This would need a new SystemTools::FilesDiffer that
+ // does not read all of the files at once.
+ cmSystemTools::RemoveFile(toFile.c_str());
+ if(!cmSystemTools::CopyFileAlways(fromFile.c_str(), toFile.c_str()))
{
- case cmTarget::STATIC_LIBRARY:
+ cmOStringStream e;
+ e << "INSTALL cannot copy file \"" << fromFile
+ << "\" to \"" << toFile + "\".";
+ this->SetError(e.str().c_str());
+ return false;
+ }
+
+ // Perform post-installation processing on the file depending
+ // on its type.
#if defined(__APPLE_CC__)
+ // Static libraries need ranlib on this platform.
+ if(itype == cmTarget::STATIC_LIBRARY)
+ {
+ std::string ranlib = "ranlib ";
+ ranlib += cmSystemTools::ConvertToOutputPath(toFile.c_str());
+ if(!cmSystemTools::RunSingleCommand(ranlib.c_str()))
{
- std::string ranlib = "ranlib ";
- ranlib += cmSystemTools::ConvertToOutputPath(destfile.c_str());
- if(!cmSystemTools::RunSingleCommand(ranlib.c_str()))
- {
- std::string err = "ranlib failed: ";
- err += ranlib;
- this->SetError(err.c_str());
- }
+ std::string err = "ranlib failed: ";
+ err += ranlib;
+ this->SetError(err.c_str());
+ return false;
}
+ }
#endif
- break;
-
- case cmTarget::MODULE_LIBRARY:
- case cmTarget::SHARED_LIBRARY:
- case cmTarget::EXECUTABLE:
- case cmTarget::INSTALL_PROGRAMS:
-
- if ( !cmSystemTools::SetPermissions(destfile.c_str(),
-#if defined( _MSC_VER ) || defined( __MINGW32__ )
- S_IREAD | S_IWRITE | S_IEXEC
-#elif defined( __BORLANDC__ )
- S_IRUSR | S_IWUSR | S_IXUSR
-#else
- S_IRUSR | S_IWUSR | S_IXUSR |
- S_IRGRP | S_IXGRP |
- S_IROTH | S_IXOTH
-#endif
- ) )
- {
- cmOStringStream err;
- err << "Problem setting permissions on file: "
- << destfile.c_str();
- perror(err.str().c_str());
- }
+
+ // Set permissions of the destination file.
+ if(!cmSystemTools::SetPermissions(toFile.c_str(), permissions))
+ {
+ cmOStringStream e;
+ e << "Problem setting permissions on file \""
+ << toFile.c_str() << "\"";
+ this->SetError(e.str().c_str());
+ return false;
}
+
+ // Add the file to the manifest.
smanifest_files += ";";
- smanifest_files += destfile.substr(destDirLength);
+ smanifest_files += toFile.substr(destDirLength);
}
- else
+ else if(!optional)
{
- if ( !optional )
- {
- std::string errstring = "cannot find file: " +
- ctarget + " to install.";
- this->SetError(errstring.c_str());
- return false;
- }
+ // The input file does not exist and installation is not optional.
+ cmOStringStream e;
+ e << "INSTALL cannot find file \"" << fromFile << "\" to install.";
+ this->SetError(e.str().c_str());
+ return false;
}
}
}
+
+ // Save the updated install manifest.
m_Makefile->AddDefinition("CMAKE_INSTALL_MANIFEST_FILES",
- smanifest_files.c_str());
+ smanifest_files.c_str());
return true;
}
diff --git a/Source/cmInstallCommand.cxx b/Source/cmInstallCommand.cxx
index 6f86ee697a..15a0f2bf49 100644
--- a/Source/cmInstallCommand.cxx
+++ b/Source/cmInstallCommand.cxx
@@ -299,8 +299,12 @@ bool cmInstallCommand::HandleFilesMode(std::vector<std::string> const& args)
bool programs = (args[0] == "PROGRAMS");
bool doing_files = true;
bool doing_destination = false;
+ bool doing_permissions = false;
+ bool doing_rename = false;
std::vector<std::string> files;
const char* destination = 0;
+ std::string rename;
+ std::string permissions;
for(unsigned int i=1; i < args.size(); ++i)
{
if(args[i] == "DESTINATION")
@@ -308,6 +312,24 @@ bool cmInstallCommand::HandleFilesMode(std::vector<std::string> const& args)
// Switch to setting the destination property.
doing_files = false;
doing_destination = true;
+ doing_permissions = false;
+ doing_rename = false;
+ }
+ else if(args[i] == "PERMISSIONS")
+ {
+ // Switch to setting the permissions property.
+ doing_files = false;
+ doing_destination = false;
+ doing_permissions = true;
+ doing_rename = false;
+ }
+ else if(args[i] == "RENAME")
+ {
+ // Switch to setting the rename property.
+ doing_files = false;
+ doing_destination = false;
+ doing_permissions = false;
+ doing_rename = true;
}
else if(doing_files)
{
@@ -337,6 +359,23 @@ bool cmInstallCommand::HandleFilesMode(std::vector<std::string> const& args)
destination = args[i].c_str();
doing_destination = false;
}
+ else if(doing_permissions)
+ {
+ // Check the requested permission.
+ if(!this->CheckPermissions(args[i], permissions))
+ {
+ cmOStringStream e;
+ e << args[0] << " given invalid permission \""
+ << args[i] << "\".";
+ this->SetError(e.str().c_str());
+ return false;
+ }
+ }
+ else if(doing_rename)
+ {
+ rename = args[i];
+ doing_rename = false;
+ }
else
{
// Unknown argument.
@@ -354,11 +393,20 @@ bool cmInstallCommand::HandleFilesMode(std::vector<std::string> const& args)
}
if(!destination)
{
+ // A destination is required.
cmOStringStream e;
e << args[0] << " given no DESTINATION!";
this->SetError(e.str().c_str());
return false;
}
+ if(!rename.empty() && files.size() > 1)
+ {
+ // The rename option works only with one file.
+ cmOStringStream e;
+ e << args[0] << " given RENAME option with more than one file.";
+ this->SetError(e.str().c_str());
+ return false;
+ }
// Compute destination path.
std::string dest;
@@ -366,7 +414,8 @@ bool cmInstallCommand::HandleFilesMode(std::vector<std::string> const& args)
// Create the files install generator.
m_Makefile->AddInstallGenerator(
- new cmInstallFilesGenerator(files, dest.c_str(), programs));
+ new cmInstallFilesGenerator(files, dest.c_str(), programs,
+ permissions.c_str(), rename.c_str()));
return true;
}
@@ -398,3 +447,32 @@ void cmInstallCommand::ComputeDestination(const char* destination,
dest = "";
}
}
+
+//----------------------------------------------------------------------------
+bool cmInstallCommand::CheckPermissions(std::string const& arg,
+ std::string& permissions)
+{
+ // Table of valid permissions.
+ const char* table[] =
+ {
+ "OWNER_READ", "OWNER_WRITE", "OWNER_EXECUTE",
+ "GROUP_READ", "GROUP_WRITE", "GROUP_EXECUTE",
+ "WORLD_READ", "WORLD_WRITE", "WORLD_EXECUTE",
+ "SETUID", "SETGID", 0
+ };
+
+ // Check the permission against the table.
+ for(const char** valid = table; *valid; ++valid)
+ {
+ if(arg == *valid)
+ {
+ // This is a valid permission.
+ permissions += " ";
+ permissions += arg;
+ return true;
+ }
+ }
+
+ // This is not a valid permission.
+ return false;
+}
diff --git a/Source/cmInstallCommand.h b/Source/cmInstallCommand.h
index 296bc3f0ca..c692c223bc 100644
--- a/Source/cmInstallCommand.h
+++ b/Source/cmInstallCommand.h
@@ -68,16 +68,29 @@ public:
"\n"
"There are multiple signatures for this command. Some of them define "
"installation properties for files and targets. Properties common to "
- "multiple signatures are covered here. DESTINATION arguments specify "
+ "multiple signatures are covered here but they are valid only for "
+ "signatures that specify them. "
+ "DESTINATION arguments specify "
"the directory on disk to which a file will be installed. "
"If a full path (with a leading slash or drive letter) is given it "
"is used directly. If a relative path is given it is interpreted "
- "relative to the value of CMAKE_INSTALL_PREFIX."
+ "relative to the value of CMAKE_INSTALL_PREFIX. "
+ "PERMISSIONS arguments specify permissions for installed files. "
+ "Valid permissions are "
+ "OWNER_READ, OWNER_WRITE, OWNER_EXECUTE, "
+ "GROUP_READ, GROUP_WRITE, GROUP_EXECUTE, "
+ "WORLD_READ, WORLD_WRITE, WORLD_EXECUTE, "
+ "SETUID, and SETGID. "
+ "Permissions that do not make sense on certain platforms are ignored "
+ "on those platforms. "
+ "The RENAME argument specifies a name for an installed file that "
+ "may be different from the original file. Renaming is allowed only "
+ "when a single file is installed by the command. "
"\n"
"The TARGETS signature:\n"
- " INSTALL(TARGETS [targets...] [[LIBRARY|RUNTIME]\n"
- " [DESTINATION <dir>]\n"
- " ] [...])\n"
+ " INSTALL(TARGETS targets... [[LIBRARY|RUNTIME]\n"
+ " [DESTINATION <dir>]\n"
+ " ] [...])\n"
"The TARGETS form specifies rules for installing targets from a "
"project. There are two kinds of target files that may be "
"installed: library and runtime. Static libraries and modules "
@@ -110,14 +123,16 @@ public:
"/some/full/path."
"\n"
"The FILES signature:\n"
- " INSTALL(FILES [files...] DESTINATION <dir>)\n"
+ " INSTALL(FILES files... DESTINATION <dir>\n"
+ " [PERMISSIONS permissions...] [RENAME <name>])\n"
"The FILES form specifies rules for installing files for a "
"project. File names given as relative paths are interpreted with "
"respect to the current source directory. Files installed by this "
"form are given the same permissions as the original file by default."
"\n"
"The PROGRAMS signature:\n"
- " INSTALL(PROGRAMS [files...] DESTINATION <dir>)\n"
+ " INSTALL(PROGRAMS files... DESTINATION <dir>\n"
+ " [PERMISSIONS permissions...] [RENAME <name>])\n"
"The PROGRAMS form is identical to the FILES form except that the "
"default permissions for the installed file mark it as executable. "
"This form is intended to install programs that are not targets, "
@@ -147,6 +162,7 @@ private:
bool HandleTargetsMode(std::vector<std::string> const& args);
bool HandleFilesMode(std::vector<std::string> const& args);
void ComputeDestination(const char* destination, std::string& dest);
+ bool CheckPermissions(std::string const& arg, std::string& permissions);
};
diff --git a/Source/cmInstallFilesGenerator.cxx b/Source/cmInstallFilesGenerator.cxx
index 7a73327cef..ff32fe2bde 100644
--- a/Source/cmInstallFilesGenerator.cxx
+++ b/Source/cmInstallFilesGenerator.cxx
@@ -21,8 +21,10 @@
//----------------------------------------------------------------------------
cmInstallFilesGenerator
::cmInstallFilesGenerator(std::vector<std::string> const& files,
- const char* dest, bool programs):
- Files(files), Destination(dest), Programs(programs)
+ const char* dest, bool programs,
+ const char* permissions, const char* rename):
+ Files(files), Destination(dest), Programs(programs),
+ Permissions(permissions), Rename(rename)
{
}
@@ -39,9 +41,13 @@ void cmInstallFilesGenerator::GenerateScript(std::ostream& os)
for(std::vector<std::string>::const_iterator fi = this->Files.begin();
fi != this->Files.end(); ++fi)
{
+ bool not_optional = false;
+ const char* no_properties = 0;
this->AddInstallRule(os, this->Destination.c_str(),
(this->Programs
? cmTarget::INSTALL_PROGRAMS
- : cmTarget::INSTALL_FILES), fi->c_str());
+ : cmTarget::INSTALL_FILES), fi->c_str(),
+ not_optional, no_properties,
+ this->Permissions.c_str(), this->Rename.c_str());
}
}
diff --git a/Source/cmInstallFilesGenerator.h b/Source/cmInstallFilesGenerator.h
index 9d35c73e0a..dc2094fc3b 100644
--- a/Source/cmInstallFilesGenerator.h
+++ b/Source/cmInstallFilesGenerator.h
@@ -26,7 +26,8 @@ class cmInstallFilesGenerator: public cmInstallGenerator
{
public:
cmInstallFilesGenerator(std::vector<std::string> const& files,
- const char* dest, bool programs);
+ const char* dest, bool programs,
+ const char* permissions, const char* rename);
virtual ~cmInstallFilesGenerator();
protected:
@@ -34,6 +35,8 @@ protected:
std::vector<std::string> Files;
std::string Destination;
bool Programs;
+ std::string Permissions;
+ std::string Rename;
};
#endif
diff --git a/Source/cmInstallGenerator.cxx b/Source/cmInstallGenerator.cxx
index a7e1d6f934..0cb3a51a65 100644
--- a/Source/cmInstallGenerator.cxx
+++ b/Source/cmInstallGenerator.cxx
@@ -52,7 +52,9 @@ void cmInstallGenerator::AddInstallRule(std::ostream& os,
int type,
const char* file,
bool optional /* = false */,
- const char* properties /* = 0 */)
+ const char* properties /* = 0 */,
+ const char* permissions /* = 0 */,
+ const char* rename /* = 0 */)
{
// Use the FILE command to install the file.
std::string stype;
@@ -75,5 +77,13 @@ void cmInstallGenerator::AddInstallRule(std::ostream& os,
{
os << " PROPERTIES" << properties;
}
+ if(permissions && *permissions)
+ {
+ os << " PERMISSIONS" << permissions;
+ }
+ if(rename && *rename)
+ {
+ os << " RENAME \"" << rename << "\"";
+ }
os << " FILES \"" << file << "\")\n";
}
diff --git a/Source/cmInstallGenerator.h b/Source/cmInstallGenerator.h
index e04ba52c08..73aa4ff13d 100644
--- a/Source/cmInstallGenerator.h
+++ b/Source/cmInstallGenerator.h
@@ -36,7 +36,9 @@ public:
static void AddInstallRule(std::ostream& os, const char* dest, int type,
const char* file, bool optional = false,
- const char* properties = 0);
+ const char* properties = 0,
+ const char* permissions = 0,
+ const char* rename = 0);
protected:
virtual void GenerateScript(std::ostream& os)=0;
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index ab2d31d9b0..ba62ebb9cd 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -1654,16 +1654,22 @@ cmLocalGenerator
case cmTarget::INSTALL_FILES:
{
// Use a file install generator.
+ const char* no_permissions = "";
+ const char* no_rename = "";
cmInstallFilesGenerator g(l->second.GetSourceLists(),
- destination.c_str(), false);
+ destination.c_str(), false,
+ no_permissions, no_rename);
g.Generate(os, config, configurationTypes);
}
break;
case cmTarget::INSTALL_PROGRAMS:
{
// Use a file install generator.
+ const char* no_permissions = "";
+ const char* no_rename = "";
cmInstallFilesGenerator g(l->second.GetSourceLists(),
- destination.c_str(), true);
+ destination.c_str(), true,
+ no_permissions, no_rename);
g.Generate(os, config, configurationTypes);
}
break;
diff --git a/Tests/SimpleInstall/CMakeLists.txt b/Tests/SimpleInstall/CMakeLists.txt
index 14beef3035..fc5c861e33 100644
--- a/Tests/SimpleInstall/CMakeLists.txt
+++ b/Tests/SimpleInstall/CMakeLists.txt
@@ -58,7 +58,8 @@ IF(STAGE2)
PATHS ${LIBPATHS}
DOC "Fourth library")
- ADD_EXECUTABLE (SimpleInstallS2 inst.cxx foo.c foo.h)
+ INCLUDE_DIRECTORIES(${CMAKE_INSTALL_PREFIX}/include)
+ ADD_EXECUTABLE (SimpleInstallS2 inst2.cxx foo.c foo.h)
TARGET_LINK_LIBRARIES(SimpleInstallS2 ${TEST1_LIBRARY} ${TEST2_LIBRARY} ${TEST4_LIBRARY})
SET(install_target SimpleInstallS2)
@@ -93,7 +94,12 @@ ELSE(STAGE2)
INSTALL(TARGETS SimpleInstall test1 test2 test3 test4
RUNTIME DESTINATION bin LIBRARY DESTINATION lib)
- INSTALL(FILES lib1.h lib2.h DESTINATION include)
+ INSTALL(FILES lib1.h DESTINATION include/foo)
+ INSTALL(FILES lib2.h
+ DESTINATION include/foo
+ PERMISSIONS OWNER_READ OWNER_WRITE
+ RENAME lib2renamed.h
+ )
INSTALL_FILES(/include FILES lib3.h)
# Test user-specified install scripts.
diff --git a/Tests/SimpleInstall/inst.cxx b/Tests/SimpleInstall/inst.cxx
index 241a296b4f..53082dcee8 100644
--- a/Tests/SimpleInstall/inst.cxx
+++ b/Tests/SimpleInstall/inst.cxx
@@ -1,7 +1,13 @@
#include "foo.h"
-#include "lib1.h"
-#include "lib2.h"
+#ifdef STAGE_2
+# include <foo/lib1.h>
+# include <foo/lib2renamed.h>
+#else
+# include "lib1.h"
+# include "lib2.h"
+#endif
+
#include "lib4.h"
#include <stdio.h>
diff --git a/Tests/SimpleInstall/inst2.cxx b/Tests/SimpleInstall/inst2.cxx
new file mode 100644
index 0000000000..c70b93af1d
--- /dev/null
+++ b/Tests/SimpleInstall/inst2.cxx
@@ -0,0 +1,2 @@
+#define STAGE_2
+#include "inst.cxx"
diff --git a/Tests/SimpleInstallS2/CMakeLists.txt b/Tests/SimpleInstallS2/CMakeLists.txt
index 14beef3035..fc5c861e33 100644
--- a/Tests/SimpleInstallS2/CMakeLists.txt
+++ b/Tests/SimpleInstallS2/CMakeLists.txt
@@ -58,7 +58,8 @@ IF(STAGE2)
PATHS ${LIBPATHS}
DOC "Fourth library")
- ADD_EXECUTABLE (SimpleInstallS2 inst.cxx foo.c foo.h)
+ INCLUDE_DIRECTORIES(${CMAKE_INSTALL_PREFIX}/include)
+ ADD_EXECUTABLE (SimpleInstallS2 inst2.cxx foo.c foo.h)
TARGET_LINK_LIBRARIES(SimpleInstallS2 ${TEST1_LIBRARY} ${TEST2_LIBRARY} ${TEST4_LIBRARY})
SET(install_target SimpleInstallS2)
@@ -93,7 +94,12 @@ ELSE(STAGE2)
INSTALL(TARGETS SimpleInstall test1 test2 test3 test4
RUNTIME DESTINATION bin LIBRARY DESTINATION lib)
- INSTALL(FILES lib1.h lib2.h DESTINATION include)
+ INSTALL(FILES lib1.h DESTINATION include/foo)
+ INSTALL(FILES lib2.h
+ DESTINATION include/foo
+ PERMISSIONS OWNER_READ OWNER_WRITE
+ RENAME lib2renamed.h
+ )
INSTALL_FILES(/include FILES lib3.h)
# Test user-specified install scripts.
diff --git a/Tests/SimpleInstallS2/inst.cxx b/Tests/SimpleInstallS2/inst.cxx
index 241a296b4f..53082dcee8 100644
--- a/Tests/SimpleInstallS2/inst.cxx
+++ b/Tests/SimpleInstallS2/inst.cxx
@@ -1,7 +1,13 @@
#include "foo.h"
-#include "lib1.h"
-#include "lib2.h"
+#ifdef STAGE_2
+# include <foo/lib1.h>
+# include <foo/lib2renamed.h>
+#else
+# include "lib1.h"
+# include "lib2.h"
+#endif
+
#include "lib4.h"
#include <stdio.h>
diff --git a/Tests/SimpleInstallS2/inst2.cxx b/Tests/SimpleInstallS2/inst2.cxx
new file mode 100644
index 0000000000..c70b93af1d
--- /dev/null
+++ b/Tests/SimpleInstallS2/inst2.cxx
@@ -0,0 +1,2 @@
+#define STAGE_2
+#include "inst.cxx"