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:
parent
5792dc8da8
commit
a2e136fd17
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
|
@ -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);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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";
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
#define STAGE_2
|
||||||
|
#include "inst.cxx"
|
|
@ -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.
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
#define STAGE_2
|
||||||
|
#include "inst.cxx"
|
Loading…
Reference in New Issue