diff options
author | Brad King <brad.king@kitware.com> | 2006-02-19 20:25:27 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2006-02-19 20:25:27 (GMT) |
commit | 96f0266228d8fdf7d420c4a562e6988830fa4996 (patch) | |
tree | 2525ae96a1752df9f6024ee4f08c84c480bbe0a6 /Source/cmInstallCommand.cxx | |
parent | 90c8ea1c03dea51c87fc75a38e018e5f9ce11546 (diff) | |
download | CMake-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.cxx | 262 |
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 = ""; + } +} |