Compute install destination for all target files

In cmInstallTargetGenerator::GenerateScriptForConfig we were computing
the full 'from' paths for all target files to be installed, but only
computing a 'to' path for the "main" target file.  This commit teaches
the method to compute both 'from' and 'to' paths for every target file
to be installed.  The result is cleaner, easier to follow, and will
allow installation tweaks to be added later on all target files.
This commit is contained in:
Brad King 2009-10-21 13:10:51 -04:00
parent 22cbfefb76
commit a52fd03a2a

View File

@ -75,19 +75,16 @@ void cmInstallTargetGenerator::GenerateScriptForConfig(std::ostream& os,
fromDirConfig = this->Target->GetDirectory(config, this->ImportLibrary); fromDirConfig = this->Target->GetDirectory(config, this->ImportLibrary);
fromDirConfig += "/"; fromDirConfig += "/";
} }
std::string toDir = this->GetInstallDestination();
// Compute the full path to the main installed file for this target. toDir += "/";
NameType nameType = this->ImportLibrary? NameImplib : NameNormal;
std::string toInstallPath = this->GetInstallDestination();
toInstallPath += "/";
toInstallPath += this->GetInstallFilename(this->Target, config, nameType);
// Track whether post-install operations should be added to the // Track whether post-install operations should be added to the
// script. // script.
bool tweakInstalledFile = true; bool tweakInstalledFile = true;
// Compute the list of files to install for this target. // Compute the list of files to install for this target.
std::vector<std::string> files; std::vector<std::string> filesFrom;
std::vector<std::string> filesTo;
std::string literal_args; std::string literal_args;
cmTarget::TargetType type = this->Target->GetType(); cmTarget::TargetType type = this->Target->GetType();
if(type == cmTarget::EXECUTABLE) if(type == cmTarget::EXECUTABLE)
@ -104,49 +101,45 @@ void cmInstallTargetGenerator::GenerateScriptForConfig(std::ostream& os,
config); config);
if(this->ImportLibrary) if(this->ImportLibrary)
{ {
std::string from1 = fromDirConfig; std::string from1 = fromDirConfig + targetNameImport;
from1 += targetNameImport; std::string to1 = toDir + targetNameImport;
files.push_back(from1); filesFrom.push_back(from1);
filesTo.push_back(to1);
// An import library looks like a static library. // An import library looks like a static library.
type = cmTarget::STATIC_LIBRARY; type = cmTarget::STATIC_LIBRARY;
} }
else else
{ {
std::string from1 = fromDirConfig; std::string from1 = fromDirConfig + targetName;
from1 += targetName; std::string to1 = toDir + targetName;
// Handle OSX Bundles. // Handle OSX Bundles.
if(this->Target->IsAppBundleOnApple()) if(this->Target->IsAppBundleOnApple())
{ {
// Compute the source locations of the bundle executable and // Install the whole app bundle directory.
// Info.plist file.
from1 += ".app";
files.push_back(from1);
type = cmTarget::INSTALL_DIRECTORY; type = cmTarget::INSTALL_DIRECTORY;
// Need to apply install_name_tool and stripping to binary
// inside bundle.
toInstallPath += ".app/Contents/MacOS/";
toInstallPath +=
this->GetInstallFilename(this->Target, config, nameType);
literal_args += " USE_SOURCE_PERMISSIONS"; literal_args += " USE_SOURCE_PERMISSIONS";
from1 += ".app";
// Tweaks apply to the binary inside the bundle.
to1 += ".app/Contents/MacOS/";
to1 += targetName;
} }
else else
{ {
// Operations done at install time on the installed file should // Tweaks apply to the real file, so list it first.
// be done on the real file and not any of the symlinks.
toInstallPath = this->GetInstallDestination();
toInstallPath += "/";
toInstallPath += targetNameReal;
files.push_back(from1);
if(targetNameReal != targetName) if(targetNameReal != targetName)
{ {
std::string from2 = fromDirConfig; std::string from2 = fromDirConfig + targetNameReal;
from2 += targetNameReal; std::string to2 = toDir += targetNameReal;
files.push_back(from2); filesFrom.push_back(from2);
filesTo.push_back(to2);
} }
} }
filesFrom.push_back(from1);
filesTo.push_back(to1);
} }
} }
else else
@ -164,9 +157,10 @@ void cmInstallTargetGenerator::GenerateScriptForConfig(std::ostream& os,
// There is a bug in cmInstallCommand if this fails. // There is a bug in cmInstallCommand if this fails.
assert(this->NamelinkMode == NamelinkModeNone); assert(this->NamelinkMode == NamelinkModeNone);
std::string from1 = fromDirConfig; std::string from1 = fromDirConfig + targetNameImport;
from1 += targetNameImport; std::string to1 = toDir + targetNameImport;
files.push_back(from1); filesFrom.push_back(from1);
filesTo.push_back(to1);
// An import library looks like a static library. // An import library looks like a static library.
type = cmTarget::STATIC_LIBRARY; type = cmTarget::STATIC_LIBRARY;
@ -176,51 +170,48 @@ void cmInstallTargetGenerator::GenerateScriptForConfig(std::ostream& os,
// There is a bug in cmInstallCommand if this fails. // There is a bug in cmInstallCommand if this fails.
assert(this->NamelinkMode == NamelinkModeNone); assert(this->NamelinkMode == NamelinkModeNone);
// Compute the build tree location of the framework directory // Install the whole framework directory.
std::string from1 = fromDirConfig;
from1 += targetName;
from1 += ".framework";
files.push_back(from1);
type = cmTarget::INSTALL_DIRECTORY; type = cmTarget::INSTALL_DIRECTORY;
// Need to apply install_name_tool and stripping to binary
// inside framework.
toInstallPath += ".framework/Versions/";
toInstallPath += this->Target->GetFrameworkVersion();
toInstallPath += "/";
toInstallPath += this->GetInstallFilename(this->Target, config,
NameNormal);
literal_args += " USE_SOURCE_PERMISSIONS"; literal_args += " USE_SOURCE_PERMISSIONS";
std::string from1 = fromDirConfig + targetName + ".framework";
// Tweaks apply to the binary inside the bundle.
std::string to1 = toDir + targetName;
to1 += ".framework/Versions/";
to1 += this->Target->GetFrameworkVersion();
to1 += "/";
to1 += targetName;
filesFrom.push_back(from1);
filesTo.push_back(to1);
} }
else else
{ {
// Operations done at install time on the installed file should
// be done on the real file and not any of the symlinks.
toInstallPath = this->GetInstallDestination();
toInstallPath += "/";
toInstallPath += targetNameReal;
// Construct the list of file names to install for this library.
bool haveNamelink = false; bool haveNamelink = false;
std::string fromName;
// Library link name.
std::string fromName = fromDirConfig + targetName;
std::string toName = toDir + targetName;
// Library interface name.
std::string fromSOName; std::string fromSOName;
std::string fromRealName; std::string toSOName;
fromName = fromDirConfig;
fromName += targetName;
if(targetNameSO != targetName) if(targetNameSO != targetName)
{ {
haveNamelink = true; haveNamelink = true;
fromSOName = fromDirConfig; fromSOName = fromDirConfig + targetNameSO;
fromSOName += targetNameSO; toSOName = toDir + targetNameSO;
} }
// Library implementation name.
std::string fromRealName;
std::string toRealName;
if(targetNameReal != targetName && if(targetNameReal != targetName &&
targetNameReal != targetNameSO) targetNameReal != targetNameSO)
{ {
haveNamelink = true; haveNamelink = true;
fromRealName = fromDirConfig; fromRealName = fromDirConfig + targetNameReal;
fromRealName += targetNameReal; toRealName = toDir + targetNameReal;
} }
// Add the names based on the current namelink mode. // Add the names based on the current namelink mode.
@ -230,7 +221,8 @@ void cmInstallTargetGenerator::GenerateScriptForConfig(std::ostream& os,
if(this->NamelinkMode == NamelinkModeOnly) if(this->NamelinkMode == NamelinkModeOnly)
{ {
// Install the namelink only. // Install the namelink only.
files.push_back(fromName); filesFrom.push_back(fromName);
filesTo.push_back(toName);
tweakInstalledFile = false; tweakInstalledFile = false;
} }
else else
@ -238,19 +230,22 @@ void cmInstallTargetGenerator::GenerateScriptForConfig(std::ostream& os,
// Install the real file if it has its own name. // Install the real file if it has its own name.
if(!fromRealName.empty()) if(!fromRealName.empty())
{ {
files.push_back(fromRealName); filesFrom.push_back(fromRealName);
filesTo.push_back(toRealName);
} }
// Install the soname link if it has its own name. // Install the soname link if it has its own name.
if(!fromSOName.empty()) if(!fromSOName.empty())
{ {
files.push_back(fromSOName); filesFrom.push_back(fromSOName);
filesTo.push_back(toSOName);
} }
// Install the namelink if it is not to be skipped. // Install the namelink if it is not to be skipped.
if(this->NamelinkMode != NamelinkModeSkip) if(this->NamelinkMode != NamelinkModeSkip)
{ {
files.push_back(fromName); filesFrom.push_back(fromName);
filesTo.push_back(toName);
} }
} }
} }
@ -260,20 +255,25 @@ void cmInstallTargetGenerator::GenerateScriptForConfig(std::ostream& os,
// if this is not a namelink-only rule. // if this is not a namelink-only rule.
if(this->NamelinkMode != NamelinkModeOnly) if(this->NamelinkMode != NamelinkModeOnly)
{ {
files.push_back(fromName); filesFrom.push_back(fromName);
filesTo.push_back(toName);
} }
} }
} }
} }
// If this fails the above code is buggy.
assert(filesFrom.size() == filesTo.size());
// Skip this rule if no files are to be installed for the target. // Skip this rule if no files are to be installed for the target.
if(files.empty()) if(filesFrom.empty())
{ {
return; return;
} }
// Construct the path of the file on disk after installation on // Construct the path of the file on disk after installation on
// which tweaks may be performed. // which tweaks may be performed.
std::string const& toInstallPath = filesTo[0];
std::string toDestDirPath = "$ENV{DESTDIR}"; std::string toDestDirPath = "$ENV{DESTDIR}";
if(toInstallPath[0] != '/' && toInstallPath[0] != '$') if(toInstallPath[0] != '/' && toInstallPath[0] != '$')
{ {
@ -302,7 +302,7 @@ void cmInstallTargetGenerator::GenerateScriptForConfig(std::ostream& os,
const char* no_dir_permissions = 0; const char* no_dir_permissions = 0;
const char* no_rename = 0; const char* no_rename = 0;
bool optional = this->Optional || this->ImportLibrary; bool optional = this->Optional || this->ImportLibrary;
this->AddInstallRule(os, type, files, this->AddInstallRule(os, type, filesFrom,
optional, optional,
this->FilePermissions.c_str(), no_dir_permissions, this->FilePermissions.c_str(), no_dir_permissions,
no_rename, literal_args.c_str(), no_rename, literal_args.c_str(),