summaryrefslogtreecommitdiffstats
path: root/Source/cmInstallCommand.cxx
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2006-02-19 20:25:27 (GMT)
committerBrad King <brad.king@kitware.com>2006-02-19 20:25:27 (GMT)
commit96f0266228d8fdf7d420c4a562e6988830fa4996 (patch)
tree2525ae96a1752df9f6024ee4f08c84c480bbe0a6 /Source/cmInstallCommand.cxx
parent90c8ea1c03dea51c87fc75a38e018e5f9ce11546 (diff)
downloadCMake-96f0266228d8fdf7d420c4a562e6988830fa4996.zip
CMake-96f0266228d8fdf7d420c4a562e6988830fa4996.tar.gz
CMake-96f0266228d8fdf7d420c4a562e6988830fa4996.tar.bz2
ENH: Created new install script generation framework. The INSTALL command creates the generators which are later used by cmLocalGenerator to create the cmake_install.cmake files. A new target installation interface is provided by the INSTALL command which fixes several problems with the INSTALL_TARGETS command. See bug#2691. Bugs 1481 and 1695 are addressed by these changes.
Diffstat (limited to 'Source/cmInstallCommand.cxx')
-rw-r--r--Source/cmInstallCommand.cxx262
1 files changed, 261 insertions, 1 deletions
diff --git a/Source/cmInstallCommand.cxx b/Source/cmInstallCommand.cxx
index 97f12ca..1a5b722 100644
--- a/Source/cmInstallCommand.cxx
+++ b/Source/cmInstallCommand.cxx
@@ -16,9 +16,39 @@
=========================================================================*/
#include "cmInstallCommand.h"
+#include "cmInstallScriptGenerator.h"
+#include "cmInstallTargetGenerator.h"
+
// cmInstallCommand
bool cmInstallCommand::InitialPass(std::vector<std::string> const& args)
{
+ // Allow calling with no arguments so that arguments may be built up
+ // using a variable that may be left empty.
+ if(args.empty())
+ {
+ return true;
+ }
+
+ // Switch among the command modes.
+ if(args[0] == "SCRIPT")
+ {
+ return this->HandleScriptMode(args);
+ }
+ else if(args[0] == "TARGETS")
+ {
+ return this->HandleTargetsMode(args);
+ }
+
+ // Unknown mode.
+ cmStdString e = "called with unknown mode ";
+ e += args[0];
+ this->SetError(e.c_str());
+ return false;
+}
+
+//----------------------------------------------------------------------------
+bool cmInstallCommand::HandleScriptMode(std::vector<std::string> const& args)
+{
bool doing_script = false;
for(size_t i=0; i < args.size(); ++i)
{
@@ -41,7 +71,8 @@ bool cmInstallCommand::InitialPass(std::vector<std::string> const& args)
this->SetError("given a directory as value of SCRIPT argument.");
return false;
}
- m_Makefile->AddInstallScript(script.c_str());
+ m_Makefile->AddInstallGenerator(
+ new cmInstallScriptGenerator(script.c_str()));
}
}
if(doing_script)
@@ -49,6 +80,235 @@ bool cmInstallCommand::InitialPass(std::vector<std::string> const& args)
this->SetError("given no value for SCRIPT argument.");
return false;
}
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
+{
+ // This is the TARGETS mode.
+ bool doing_targets = true;
+ bool doing_destination = false;
+ bool library_settings = true;
+ bool runtime_settings = true;
+ std::vector<cmTarget*> targets;
+ const char* library_destination = 0;
+ const char* runtime_destination = 0;
+ cmLocalGenerator* lg = m_Makefile->GetLocalGenerator();
+ cmGlobalGenerator* gg = lg->GetGlobalGenerator();
+ for(unsigned int i=1; i < args.size(); ++i)
+ {
+ if(args[i] == "DESTINATION")
+ {
+ // Switch to setting the destination property.
+ doing_targets = false;
+ doing_destination = true;
+ }
+ else if(args[i] == "LIBRARY")
+ {
+ // Switch to setting only library properties.
+ doing_targets = false;
+ doing_destination = false;
+ library_settings = true;
+ runtime_settings = false;
+ }
+ else if(args[i] == "RUNTIME")
+ {
+ // Switch to setting only runtime properties.
+ doing_targets = false;
+ doing_destination = false;
+ library_settings = false;
+ runtime_settings = true;
+ }
+ else if(doing_targets)
+ {
+ // Lookup this target in the current project.
+ if(cmTarget* target = m_Makefile->FindTarget(args[i].c_str()))
+ {
+ // Found the target. Check its type.
+ if(target->GetType() != cmTarget::EXECUTABLE &&
+ target->GetType() != cmTarget::STATIC_LIBRARY &&
+ target->GetType() != cmTarget::SHARED_LIBRARY &&
+ target->GetType() != cmTarget::MODULE_LIBRARY)
+ {
+ cmOStringStream e;
+ e << "TARGETS given target \"" << args[i]
+ << "\" which is not an executable, library, or module.";
+ this->SetError(e.str().c_str());
+ return false;
+ }
+
+ // Store the target in the list to be installed.
+ targets.push_back(target);
+ }
+ else
+ {
+ // Did not find the target.
+ cmOStringStream e;
+ e << "TARGETS given target \"" << args[i]
+ << "\" which does not exist in this directory.";
+ this->SetError(e.str().c_str());
+ return false;
+ }
+ }
+ else if(doing_destination)
+ {
+ // Set the destination in the active set(s) of properties.
+ if(library_settings)
+ {
+ library_destination = args[i].c_str();
+ }
+ if(runtime_settings)
+ {
+ runtime_destination = args[i].c_str();
+ }
+ doing_destination = false;
+ }
+ else
+ {
+ // Unknown argument.
+ cmOStringStream e;
+ e << "TARGETS given unknown argument \"" << args[i] << "\".";
+ this->SetError(e.str().c_str());
+ return false;
+ }
+ }
+
+ // Check if there is something to do.
+ if(targets.empty())
+ {
+ return true;
+ }
+ if(!library_destination && !runtime_destination)
+ {
+ this->SetError("TARGETS given no DESTINATION!");
+ return false;
+ }
+
+ // Compute destination paths.
+ std::string library_dest;
+ std::string runtime_dest;
+ this->ComputeDestination(library_destination, library_dest);
+ this->ComputeDestination(runtime_destination, runtime_dest);
+
+ // Generate install script code to install the given targets.
+ for(std::vector<cmTarget*>::iterator ti = targets.begin();
+ ti != targets.end(); ++ti)
+ {
+ // Handle each target type.
+ cmTarget& target = *(*ti);
+ switch(target.GetType())
+ {
+ case cmTarget::SHARED_LIBRARY:
+ {
+ // Shared libraries are handled differently on DLL and non-DLL
+ // platforms. All windows platforms are DLL platforms
+ // including cygwin. Currently no other platform is a DLL
+ // platform.
+#if defined(_WIN32) || defined(__CYGWIN__)
+ // This is a DLL platform.
+ if(library_destination)
+ {
+ // The import library uses the LIBRARY properties.
+ m_Makefile->AddInstallGenerator(
+ new cmInstallTargetGenerator(target, library_dest.c_str(), true));
+ }
+ if(runtime_destination)
+ {
+ // The DLL uses the RUNTIME properties.
+ m_Makefile->AddInstallGenerator(
+ new cmInstallTargetGenerator(target, runtime_dest.c_str(), false));
+ }
+#else
+ // This is a non-DLL platform.
+ if(library_destination)
+ {
+ // The shared library uses the LIBRARY properties.
+ m_Makefile->AddInstallGenerator(
+ new cmInstallTargetGenerator(target, library_dest.c_str()));
+ }
+#endif
+ }
+ break;
+ case cmTarget::STATIC_LIBRARY:
+ case cmTarget::MODULE_LIBRARY:
+ {
+ // Static libraries and modules use LIBRARY properties.
+ if(library_destination)
+ {
+ m_Makefile->AddInstallGenerator(
+ new cmInstallTargetGenerator(target, library_dest.c_str()));
+ }
+ else
+ {
+ cmOStringStream e;
+ e << "TARGETS given no LIBRARY DESTINATION for ";
+ if(target.GetType() == cmTarget::STATIC_LIBRARY)
+ {
+ e << "static library";
+ }
+ else
+ {
+ e << "module";
+ }
+ e << " target \"" << target.GetName() << "\".";
+ this->SetError(e.str().c_str());
+ return false;
+ }
+ }
+ break;
+ case cmTarget::EXECUTABLE:
+ {
+ // Executables use the RUNTIME properties.
+ if(runtime_destination)
+ {
+ m_Makefile->AddInstallGenerator(
+ new cmInstallTargetGenerator(target, runtime_dest.c_str()));
+ }
+ else
+ {
+ cmOStringStream e;
+ e << "TARGETS given no RUNTIME DESTINATION for executable target \""
+ << target.GetName() << "\".";
+ this->SetError(e.str().c_str());
+ return false;
+ }
+ }
+ break;
+ default:
+ // This should never happen due to the above type check.
+ // Ignore the case.
+ break;
+ }
+ }
return true;
}
+
+//----------------------------------------------------------------------------
+void cmInstallCommand::ComputeDestination(const char* destination,
+ std::string& dest)
+{
+ if(destination)
+ {
+ if(cmSystemTools::FileIsFullPath(destination))
+ {
+ // Full paths are absolute.
+ dest = destination;
+ }
+ else
+ {
+ // Relative paths are treated with respect to the installation prefix.
+ dest = "${CMAKE_INSTALL_PREFIX}/";
+ dest += destination;
+ }
+
+ // Format the path nicely. Note this also removes trailing
+ // slashes.
+ cmSystemTools::ConvertToUnixSlashes(dest);
+ }
+ else
+ {
+ dest = "";
+ }
+}