ENH: Added PERMISSIONS and RENAME options to the INSTALL command's FILES and PROGRAMS mode, and corresponding support to FILE(INSTALL). Default permissions for shared libraries on non-Windows/non-OSX platforms no longer has the execute bit set.

This commit is contained in:
Brad King 2006-03-03 18:44:32 -05:00
parent 5792dc8da8
commit a2e136fd17
14 changed files with 452 additions and 151 deletions

View File

@ -276,6 +276,7 @@ bool cmFileCommand::HandleInstallCommand(
return false; return false;
} }
std::string rename = "";
std::string destination = ""; std::string destination = "";
std::string stype = "FILES"; std::string stype = "FILES";
const char* build_type = m_Makefile->GetDefinition("BUILD_TYPE"); const char* build_type = m_Makefile->GetDefinition("BUILD_TYPE");
@ -298,8 +299,38 @@ bool cmFileCommand::HandleInstallCommand(
std::map<cmStdString, const char*> properties; 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_files = false;
bool in_properties = false; bool in_properties = false;
bool in_permissions = false;
bool use_given_permissions = false;
mode_t permissions = 0;
bool optional = false; bool optional = false;
for ( ; i != args.size(); ++i ) for ( ; i != args.size(); ++i )
{ {
@ -310,6 +341,7 @@ bool cmFileCommand::HandleInstallCommand(
destination = args[i]; destination = args[i];
in_files = false; in_files = false;
in_properties = false; in_properties = false;
in_permissions = false;
} }
else if ( *cstr == "TYPE" && i < args.size()-1 ) else if ( *cstr == "TYPE" && i < args.size()-1 )
{ {
@ -322,16 +354,34 @@ bool cmFileCommand::HandleInstallCommand(
} }
in_properties = false; in_properties = false;
in_files = 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" ) else if ( *cstr == "PROPERTIES" )
{ {
in_properties = true; in_properties = true;
in_files = false; 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) else if ( *cstr == "FILES" && !in_files)
{ {
in_files = true; in_files = true;
in_properties = false; in_properties = false;
in_permissions = false;
} }
else if ( in_properties && i < args.size()-1 ) else if ( in_properties && i < args.size()-1 )
{ {
@ -342,6 +392,50 @@ bool cmFileCommand::HandleInstallCommand(
{ {
files.push_back(*cstr); 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 else
{ {
this->SetError("called with inappropriate arguments"); this->SetError("called with inappropriate arguments");
@ -458,6 +552,61 @@ bool cmFileCommand::HandleInstallCommand(
return false; 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 = const char* manifest_files =
m_Makefile->GetDefinition("CMAKE_INSTALL_MANIFEST_FILES"); m_Makefile->GetDefinition("CMAKE_INSTALL_MANIFEST_FILES");
std::string smanifest_files; std::string smanifest_files;
@ -466,26 +615,24 @@ bool cmFileCommand::HandleInstallCommand(
smanifest_files = manifest_files; smanifest_files = manifest_files;
} }
// Handle each file listed.
for ( i = 0; i < files.size(); i ++ ) for ( i = 0; i < files.size(); i ++ )
{ {
std::string destfilewe // Split the input file into its directory and name components.
= destination + "/" std::string fromDir = cmSystemTools::GetFilenamePath(files[i]);
+ cmSystemTools::GetFilenameWithoutExtension(files[i]); std::string fromName = cmSystemTools::GetFilenameName(files[i]);
std::string ctarget = files[i].c_str();
std::string fname = cmSystemTools::GetFilenameName(ctarget); // Compute the full path to the destination file.
std::string ext = cmSystemTools::GetFilenameExtension(ctarget); std::string toFile = destination;
std::string fnamewe toFile += "/";
= cmSystemTools::GetFilenameWithoutExtension(ctarget); toFile += rename.empty()? fromName : rename;
std::string destfile = destfilewe;
if ( ext.size() ) // Handle type-specific installation details.
switch(itype)
{ {
destfile += ext; case cmTarget::MODULE_LIBRARY:
} case cmTarget::STATIC_LIBRARY:
switch( itype ) case cmTarget::SHARED_LIBRARY:
{
case cmTarget::MODULE_LIBRARY:
case cmTarget::STATIC_LIBRARY:
case cmTarget::SHARED_LIBRARY:
{ {
// Handle shared library versioning // Handle shared library versioning
const char* lib_version = 0; const char* lib_version = 0;
@ -508,18 +655,18 @@ bool cmFileCommand::HandleInstallCommand(
} }
if ( lib_version && lib_soversion ) if ( lib_version && lib_soversion )
{ {
std::string libname = destfile; std::string libname = toFile;
std::string soname = destfile; std::string soname = toFile;
std::string soname_nopath = fname; std::string soname_nopath = fromName;
soname += "."; soname += ".";
soname += lib_soversion; soname += lib_soversion;
soname_nopath += "."; soname_nopath += ".";
soname_nopath += lib_soversion; soname_nopath += lib_soversion;
fname += "."; fromName += ".";
fname += lib_version; fromName += lib_version;
destfile += "."; toFile += ".";
destfile += lib_version; toFile += lib_version;
cmSystemTools::RemoveFile(soname.c_str()); cmSystemTools::RemoveFile(soname.c_str());
cmSystemTools::RemoveFile(libname.c_str()); cmSystemTools::RemoveFile(libname.c_str());
@ -532,11 +679,11 @@ bool cmFileCommand::HandleInstallCommand(
} }
smanifest_files += ";"; smanifest_files += ";";
smanifest_files += libname.substr(destDirLength);; 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()); this->SetError(errstring.c_str());
return false; return false;
} }
@ -544,129 +691,134 @@ bool cmFileCommand::HandleInstallCommand(
smanifest_files += soname.substr(destDirLength); 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; break;
case cmTarget::EXECUTABLE: case cmTarget::EXECUTABLE:
{
// Handle executable versioning
const char* exe_version = 0;
if ( properties.find("VERSION") != properties.end() )
{ {
exe_version = properties["VERSION"]; // Handle executable versioning
} const char* exe_version = 0;
if ( exe_version ) if ( properties.find("VERSION") != properties.end() )
{
std::string exename = destfile;
std::string exename_nopath = fname;
exename_nopath += "-";
exename_nopath += exe_version;
fname += "-";
fname += exe_version;
destfile += "-";
destfile += exe_version;
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; exe_version = properties["VERSION"];
this->SetError(errstring.c_str());
return false;
} }
smanifest_files += ";"; if ( exe_version )
smanifest_files += exename.substr(destDirLength); {
} std::string exename = toFile;
std::string exename_nopath = fromName;
exename_nopath += "-";
exename_nopath += exe_version;
// Reconstruct the source file path taking into account the fromName += "-";
// possibly new file name. fromName += exe_version;
cmOStringStream str; toFile += "-";
str << cmSystemTools::GetFilenamePath(ctarget) << "/" << fname; toFile += exe_version;
ctarget = str.str();
} cmSystemTools::RemoveFile(exename.c_str());
break;
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);
}
}
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; 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 = "Installing ";
message += destfile.c_str(); message += toFile.c_str();
m_Makefile->DisplayStatus(message.c_str(), -1); m_Makefile->DisplayStatus(message.c_str(), -1);
cmSystemTools::RemoveFile(destfile.c_str());
if ( !cmSystemTools::CopyFileAlways(ctarget.c_str(), // If no permissions were already given use the permissions of
destination.c_str()) ) // the file being copied.
if(!use_given_permissions &&
(!use_source_permissions ||
!cmSystemTools::GetPermissions(fromFile.c_str(), permissions)))
{ {
std::string errstring = "cannot copy file: " + ctarget + // Set default permissions.
" to directory : " + destination + "."; permissions = 0;
this->SetError(errstring.c_str()); permissions |= mode_owner_read;
permissions |= mode_owner_write;
permissions |= mode_group_read;
permissions |= mode_world_read;
}
// 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()))
{
cmOStringStream e;
e << "INSTALL cannot copy file \"" << fromFile
<< "\" to \"" << toFile + "\".";
this->SetError(e.str().c_str());
return false; return false;
} }
switch( itype )
{ // Perform post-installation processing on the file depending
case cmTarget::STATIC_LIBRARY: // on its type.
#if defined(__APPLE_CC__) #if defined(__APPLE_CC__)
{ // Static libraries need ranlib on this platform.
std::string ranlib = "ranlib "; if(itype == cmTarget::STATIC_LIBRARY)
ranlib += cmSystemTools::ConvertToOutputPath(destfile.c_str());
if(!cmSystemTools::RunSingleCommand(ranlib.c_str()))
{
std::string err = "ranlib failed: ";
err += ranlib;
this->SetError(err.c_str());
}
}
#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());
}
}
smanifest_files += ";";
smanifest_files += destfile.substr(destDirLength);
}
else
{
if ( !optional )
{ {
std::string errstring = "cannot find file: " + std::string ranlib = "ranlib ";
ctarget + " to install."; ranlib += cmSystemTools::ConvertToOutputPath(toFile.c_str());
this->SetError(errstring.c_str()); if(!cmSystemTools::RunSingleCommand(ranlib.c_str()))
{
std::string err = "ranlib failed: ";
err += ranlib;
this->SetError(err.c_str());
return false;
}
}
#endif
// 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; return false;
} }
// Add the file to the manifest.
smanifest_files += ";";
smanifest_files += toFile.substr(destDirLength);
}
else if(!optional)
{
// 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", m_Makefile->AddDefinition("CMAKE_INSTALL_MANIFEST_FILES",
smanifest_files.c_str()); smanifest_files.c_str());
return true; return true;
} }

View File

@ -299,8 +299,12 @@ bool cmInstallCommand::HandleFilesMode(std::vector<std::string> const& args)
bool programs = (args[0] == "PROGRAMS"); bool programs = (args[0] == "PROGRAMS");
bool doing_files = true; bool doing_files = true;
bool doing_destination = false; bool doing_destination = false;
bool doing_permissions = false;
bool doing_rename = false;
std::vector<std::string> files; std::vector<std::string> files;
const char* destination = 0; const char* destination = 0;
std::string rename;
std::string permissions;
for(unsigned int i=1; i < args.size(); ++i) for(unsigned int i=1; i < args.size(); ++i)
{ {
if(args[i] == "DESTINATION") if(args[i] == "DESTINATION")
@ -308,6 +312,24 @@ bool cmInstallCommand::HandleFilesMode(std::vector<std::string> const& args)
// Switch to setting the destination property. // Switch to setting the destination property.
doing_files = false; doing_files = false;
doing_destination = true; 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) else if(doing_files)
{ {
@ -337,6 +359,23 @@ bool cmInstallCommand::HandleFilesMode(std::vector<std::string> const& args)
destination = args[i].c_str(); destination = args[i].c_str();
doing_destination = false; 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 else
{ {
// Unknown argument. // Unknown argument.
@ -354,11 +393,20 @@ bool cmInstallCommand::HandleFilesMode(std::vector<std::string> const& args)
} }
if(!destination) if(!destination)
{ {
// A destination is required.
cmOStringStream e; cmOStringStream e;
e << args[0] << " given no DESTINATION!"; e << args[0] << " given no DESTINATION!";
this->SetError(e.str().c_str()); this->SetError(e.str().c_str());
return false; 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. // Compute destination path.
std::string dest; std::string dest;
@ -366,7 +414,8 @@ bool cmInstallCommand::HandleFilesMode(std::vector<std::string> const& args)
// Create the files install generator. // Create the files install generator.
m_Makefile->AddInstallGenerator( 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; return true;
} }
@ -398,3 +447,32 @@ void cmInstallCommand::ComputeDestination(const char* destination,
dest = ""; 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;
}

View File

@ -68,16 +68,29 @@ public:
"\n" "\n"
"There are multiple signatures for this command. Some of them define " "There are multiple signatures for this command. Some of them define "
"installation properties for files and targets. Properties common to " "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. " "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 " "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 " "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" "\n"
"The TARGETS signature:\n" "The TARGETS signature:\n"
" INSTALL(TARGETS [targets...] [[LIBRARY|RUNTIME]\n" " INSTALL(TARGETS targets... [[LIBRARY|RUNTIME]\n"
" [DESTINATION <dir>]\n" " [DESTINATION <dir>]\n"
" ] [...])\n" " ] [...])\n"
"The TARGETS form specifies rules for installing targets from a " "The TARGETS form specifies rules for installing targets from a "
"project. There are two kinds of target files that may be " "project. There are two kinds of target files that may be "
"installed: library and runtime. Static libraries and modules " "installed: library and runtime. Static libraries and modules "
@ -110,14 +123,16 @@ public:
"/some/full/path." "/some/full/path."
"\n" "\n"
"The FILES signature:\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 " "The FILES form specifies rules for installing files for a "
"project. File names given as relative paths are interpreted with " "project. File names given as relative paths are interpreted with "
"respect to the current source directory. Files installed by this " "respect to the current source directory. Files installed by this "
"form are given the same permissions as the original file by default." "form are given the same permissions as the original file by default."
"\n" "\n"
"The PROGRAMS signature:\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 " "The PROGRAMS form is identical to the FILES form except that the "
"default permissions for the installed file mark it as executable. " "default permissions for the installed file mark it as executable. "
"This form is intended to install programs that are not targets, " "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 HandleTargetsMode(std::vector<std::string> const& args);
bool HandleFilesMode(std::vector<std::string> const& args); bool HandleFilesMode(std::vector<std::string> const& args);
void ComputeDestination(const char* destination, std::string& dest); void ComputeDestination(const char* destination, std::string& dest);
bool CheckPermissions(std::string const& arg, std::string& permissions);
}; };

View File

@ -21,8 +21,10 @@
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
cmInstallFilesGenerator cmInstallFilesGenerator
::cmInstallFilesGenerator(std::vector<std::string> const& files, ::cmInstallFilesGenerator(std::vector<std::string> const& files,
const char* dest, bool programs): const char* dest, bool programs,
Files(files), Destination(dest), Programs(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(); for(std::vector<std::string>::const_iterator fi = this->Files.begin();
fi != this->Files.end(); ++fi) fi != this->Files.end(); ++fi)
{ {
bool not_optional = false;
const char* no_properties = 0;
this->AddInstallRule(os, this->Destination.c_str(), this->AddInstallRule(os, this->Destination.c_str(),
(this->Programs (this->Programs
? cmTarget::INSTALL_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());
} }
} }

View File

@ -26,7 +26,8 @@ class cmInstallFilesGenerator: public cmInstallGenerator
{ {
public: public:
cmInstallFilesGenerator(std::vector<std::string> const& files, 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(); virtual ~cmInstallFilesGenerator();
protected: protected:
@ -34,6 +35,8 @@ protected:
std::vector<std::string> Files; std::vector<std::string> Files;
std::string Destination; std::string Destination;
bool Programs; bool Programs;
std::string Permissions;
std::string Rename;
}; };
#endif #endif

View File

@ -52,7 +52,9 @@ void cmInstallGenerator::AddInstallRule(std::ostream& os,
int type, int type,
const char* file, const char* file,
bool optional /* = false */, 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. // Use the FILE command to install the file.
std::string stype; std::string stype;
@ -75,5 +77,13 @@ void cmInstallGenerator::AddInstallRule(std::ostream& os,
{ {
os << " PROPERTIES" << properties; os << " PROPERTIES" << properties;
} }
if(permissions && *permissions)
{
os << " PERMISSIONS" << permissions;
}
if(rename && *rename)
{
os << " RENAME \"" << rename << "\"";
}
os << " FILES \"" << file << "\")\n"; os << " FILES \"" << file << "\")\n";
} }

View File

@ -36,7 +36,9 @@ public:
static void AddInstallRule(std::ostream& os, const char* dest, int type, static void AddInstallRule(std::ostream& os, const char* dest, int type,
const char* file, bool optional = false, const char* file, bool optional = false,
const char* properties = 0); const char* properties = 0,
const char* permissions = 0,
const char* rename = 0);
protected: protected:
virtual void GenerateScript(std::ostream& os)=0; virtual void GenerateScript(std::ostream& os)=0;

View File

@ -1654,16 +1654,22 @@ cmLocalGenerator
case cmTarget::INSTALL_FILES: case cmTarget::INSTALL_FILES:
{ {
// Use a file install generator. // Use a file install generator.
const char* no_permissions = "";
const char* no_rename = "";
cmInstallFilesGenerator g(l->second.GetSourceLists(), cmInstallFilesGenerator g(l->second.GetSourceLists(),
destination.c_str(), false); destination.c_str(), false,
no_permissions, no_rename);
g.Generate(os, config, configurationTypes); g.Generate(os, config, configurationTypes);
} }
break; break;
case cmTarget::INSTALL_PROGRAMS: case cmTarget::INSTALL_PROGRAMS:
{ {
// Use a file install generator. // Use a file install generator.
const char* no_permissions = "";
const char* no_rename = "";
cmInstallFilesGenerator g(l->second.GetSourceLists(), cmInstallFilesGenerator g(l->second.GetSourceLists(),
destination.c_str(), true); destination.c_str(), true,
no_permissions, no_rename);
g.Generate(os, config, configurationTypes); g.Generate(os, config, configurationTypes);
} }
break; break;

View File

@ -58,7 +58,8 @@ IF(STAGE2)
PATHS ${LIBPATHS} PATHS ${LIBPATHS}
DOC "Fourth library") 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}) TARGET_LINK_LIBRARIES(SimpleInstallS2 ${TEST1_LIBRARY} ${TEST2_LIBRARY} ${TEST4_LIBRARY})
SET(install_target SimpleInstallS2) SET(install_target SimpleInstallS2)
@ -93,7 +94,12 @@ ELSE(STAGE2)
INSTALL(TARGETS SimpleInstall test1 test2 test3 test4 INSTALL(TARGETS SimpleInstall test1 test2 test3 test4
RUNTIME DESTINATION bin LIBRARY DESTINATION lib) 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) INSTALL_FILES(/include FILES lib3.h)
# Test user-specified install scripts. # Test user-specified install scripts.

View File

@ -1,7 +1,13 @@
#include "foo.h" #include "foo.h"
#include "lib1.h" #ifdef STAGE_2
#include "lib2.h" # include <foo/lib1.h>
# include <foo/lib2renamed.h>
#else
# include "lib1.h"
# include "lib2.h"
#endif
#include "lib4.h" #include "lib4.h"
#include <stdio.h> #include <stdio.h>

View File

@ -0,0 +1,2 @@
#define STAGE_2
#include "inst.cxx"

View File

@ -58,7 +58,8 @@ IF(STAGE2)
PATHS ${LIBPATHS} PATHS ${LIBPATHS}
DOC "Fourth library") 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}) TARGET_LINK_LIBRARIES(SimpleInstallS2 ${TEST1_LIBRARY} ${TEST2_LIBRARY} ${TEST4_LIBRARY})
SET(install_target SimpleInstallS2) SET(install_target SimpleInstallS2)
@ -93,7 +94,12 @@ ELSE(STAGE2)
INSTALL(TARGETS SimpleInstall test1 test2 test3 test4 INSTALL(TARGETS SimpleInstall test1 test2 test3 test4
RUNTIME DESTINATION bin LIBRARY DESTINATION lib) 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) INSTALL_FILES(/include FILES lib3.h)
# Test user-specified install scripts. # Test user-specified install scripts.

View File

@ -1,7 +1,13 @@
#include "foo.h" #include "foo.h"
#include "lib1.h" #ifdef STAGE_2
#include "lib2.h" # include <foo/lib1.h>
# include <foo/lib2renamed.h>
#else
# include "lib1.h"
# include "lib2.h"
#endif
#include "lib4.h" #include "lib4.h"
#include <stdio.h> #include <stdio.h>

View File

@ -0,0 +1,2 @@
#define STAGE_2
#include "inst.cxx"