From 96f0266228d8fdf7d420c4a562e6988830fa4996 Mon Sep 17 00:00:00 2001 From: Brad King Date: Sun, 19 Feb 2006 15:25:27 -0500 Subject: 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. --- Source/CMakeLists.txt | 6 + Source/cmInstallCommand.cxx | 262 ++++++++++++++++- Source/cmInstallCommand.h | 64 ++++- Source/cmInstallGenerator.cxx | 82 ++++++ Source/cmInstallGenerator.h | 48 ++++ Source/cmInstallScriptGenerator.cxx | 35 +++ Source/cmInstallScriptGenerator.h | 36 +++ Source/cmInstallTargetGenerator.cxx | 191 +++++++++++++ Source/cmInstallTargetGenerator.h | 43 +++ Source/cmInstallTargetsCommand.h | 4 +- Source/cmLocalGenerator.cxx | 525 +++++++++++----------------------- Source/cmLocalGenerator.h | 15 +- Source/cmMakefile.cxx | 8 + Source/cmMakefile.h | 13 +- Source/cmSetTargetPropertiesCommand.h | 36 ++- Tests/SimpleInstall/CMakeLists.txt | 4 +- Tests/SimpleInstallS2/CMakeLists.txt | 4 +- bootstrap | 3 + 18 files changed, 973 insertions(+), 406 deletions(-) create mode 100644 Source/cmInstallGenerator.cxx create mode 100644 Source/cmInstallGenerator.h create mode 100644 Source/cmInstallScriptGenerator.cxx create mode 100644 Source/cmInstallScriptGenerator.h create mode 100644 Source/cmInstallTargetGenerator.cxx create mode 100644 Source/cmInstallTargetGenerator.h diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index eebc4f3..b7c83e6 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -115,6 +115,12 @@ SET(SRCS cmGlobalGenerator.h cmGlobalUnixMakefileGenerator3.cxx cmGlobalUnixMakefileGenerator3.h + cmInstallGenerator.h + cmInstallGenerator.cxx + cmInstallScriptGenerator.h + cmInstallScriptGenerator.cxx + cmInstallTargetGenerator.h + cmInstallTargetGenerator.cxx cmListFileCache.cxx cmListFileCache.h cmListFileLexer.c 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 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 const& args) +{ bool doing_script = false; for(size_t i=0; i < args.size(); ++i) { @@ -41,7 +71,8 @@ bool cmInstallCommand::InitialPass(std::vector 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 const& args) this->SetError("given no value for SCRIPT argument."); return false; } + return true; +} + +//---------------------------------------------------------------------------- +bool cmInstallCommand::HandleTargetsMode(std::vector 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 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::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 = ""; + } +} diff --git a/Source/cmInstallCommand.h b/Source/cmInstallCommand.h index 789cc79..586209e 100644 --- a/Source/cmInstallCommand.h +++ b/Source/cmInstallCommand.h @@ -52,7 +52,7 @@ public: */ virtual const char* GetTerseDocumentation() { - return "Install rule specification interface command."; + return "Specify rules to run at install time."; } /** @@ -61,19 +61,65 @@ public: virtual const char* GetFullDocumentation() { return - " INSTALL(SCRIPT [SCRIPT [...]])\n" - "Specify rules to run at install time. If SCRIPT is given the " - "file named after it will be included in the install scripts. " - "Multiple SCRIPTs may be given within a single source directory " - "and the scripts will be run in the order given. " - "The processing order of these scripts relative to install rules " + "This command generates installation rules for a project. " + "Rules specified by calls to this command within a source directory " + "are executed in order during installation. " + "The order across directories is not defined.\n" + "There are multiple signatures for this command:\n" + " INSTALL(TARGETS [targets...] [[LIBRARY|RUNTIME]\n" + " [DESTINATION ]\n" + " ] [...])\n" + "The TARGETS form specifies rules for installing targets from a " + "project. There are two kinds of target files that may be " + "installed: library and runtime. Static libraries and modules " + "are always treated as library targets. Executables are always " + "treated as runtime targets. For non-DLL platforms, shared libraries " + "are treated as library targets. For DLL platforms, the DLL part of " + "a shared library is treated as a runtime target and the corresponding " + "import library is treated as a library target. All Windows-based " + "systems including Cygwin are DLL platforms. The LIBRARY and RUNTIME " + "arguments change the type of target to which the following properties " + "apply. If neither is given the installation properties apply to " + "both target types. If only one is given then only targets of that " + "type will be installed (which can be used to install just a DLL or " + "just an import library).\n" + "DESTINATION arguments specify the directory on disk to which the " + "target file will be installed. " + "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 " + "relative to the value of CMAKE_INSTALL_PREFIX.\n" + "One or more groups of properties may be specified in a single call " + "to the TARGETS form of this command. A target may be installed more " + "than once to different locations. Consider hypothetical " + "targets \"myExe\", \"mySharedLib\", and \"myStaticLib\". The code\n" + " INSTALL(TARGETS myExe mySharedLib myStaticLib\n" + " RUNTIME DESTINATION bin\n" + " LIBRARY DESTINATION lib)\n" + " INSTALL(TARGETS mySharedLib DESTINATION /some/full/path)\n" + "will install myExe to /bin and myStaticLib to /lib. " + "On non-DLL platforms mySharedLib will be installed to /lib and " + "/some/full/path. On DLL platforms the mySharedLib DLL will be " + "installed to /bin and /some/full/path and its import library " + "will be installed to /lib and /some/full/path. On non-DLL " + "platforms mySharedLib will be installed to /lib and " + "/some/full/path.\n" + " INSTALL(SCRIPT [SCRIPT [...]])\n" + "The SCRIPT form will invoke the given CMake script files during " + "installation.\n" + "NOTE: This command supercedes the INSTALL_TARGETS command and the " + "target properties PRE_INSTALL_SCRIPT and POST_INSTALL_SCRIPT. " + "The processing order of these install rules relative to those " "generated by INSTALL_TARGETS, INSTALL_FILES, and INSTALL_PROGRAMS " - "commands is not specified.\n" - "This command is a placeholder for a future larger interface." + "commands is not defined.\n" ; } cmTypeMacro(cmInstallCommand, cmCommand); + +private: + bool HandleScriptMode(std::vector const& args); + bool HandleTargetsMode(std::vector const& args); + void ComputeDestination(const char* destination, std::string& dest); }; diff --git a/Source/cmInstallGenerator.cxx b/Source/cmInstallGenerator.cxx new file mode 100644 index 0000000..5448383 --- /dev/null +++ b/Source/cmInstallGenerator.cxx @@ -0,0 +1,82 @@ +/*========================================================================= + + Program: CMake - Cross-Platform Makefile Generator + Module: $RCSfile$ + Language: C++ + Date: $Date$ + Version: $Revision$ + + Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved. + See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details. + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ +#include "cmInstallGenerator.h" + +#include "cmSystemTools.h" +#include "cmTarget.h" + +//---------------------------------------------------------------------------- +cmInstallGenerator +::cmInstallGenerator() +{ + this->ConfigurationName = 0; + this->ConfigurationTypes = 0; +} + +//---------------------------------------------------------------------------- +cmInstallGenerator +::~cmInstallGenerator() +{ +} + +//---------------------------------------------------------------------------- +void +cmInstallGenerator +::Generate(std::ostream& os, const char* config, + std::vector const& configurationTypes) +{ + this->ConfigurationName = config; + this->ConfigurationTypes = &configurationTypes; + this->GenerateScript(os); + this->ConfigurationName = 0; + this->ConfigurationTypes = 0; +} + +//---------------------------------------------------------------------------- +void cmInstallGenerator::AddInstallRule(std::ostream& os, + const char* dest, + int type, + const char* files, + bool optional /* = false */, + const char* properties /* = 0 */) +{ + // TODO: Make optional files use IF(EXISTS) to not report if not + // installing. + std::string sfiles = files; + std::string destination = dest; + std::string stype; + switch(type) + { + case cmTarget::INSTALL_PROGRAMS: stype = "PROGRAM"; break; + case cmTarget::EXECUTABLE: stype = "EXECUTABLE"; break; + case cmTarget::STATIC_LIBRARY: stype = "STATIC_LIBRARY"; break; + case cmTarget::SHARED_LIBRARY: stype = "SHARED_LIBRARY"; break; + case cmTarget::MODULE_LIBRARY: stype = "MODULE"; break; + case cmTarget::INSTALL_FILES: + default: stype = "FILE"; break; + } + std::string fname = cmSystemTools::GetFilenameName(sfiles.c_str()); + os << "MESSAGE(STATUS \"Installing " << destination.c_str() + << "/" << fname.c_str() << "\")\n" + << "FILE(INSTALL DESTINATION \"" << destination.c_str() + << "\" TYPE " << stype.c_str() << (optional?" OPTIONAL":"") ; + if(properties && *properties) + { + os << " PROPERTIES" << properties; + } + os << " FILES \"" << sfiles.c_str() << "\")\n"; +} diff --git a/Source/cmInstallGenerator.h b/Source/cmInstallGenerator.h new file mode 100644 index 0000000..fcb496c --- /dev/null +++ b/Source/cmInstallGenerator.h @@ -0,0 +1,48 @@ +/*========================================================================= + + Program: CMake - Cross-Platform Makefile Generator + Module: $RCSfile$ + Language: C++ + Date: $Date$ + Version: $Revision$ + + Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved. + See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details. + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ +#ifndef cmInstallGenerator_h +#define cmInstallGenerator_h + +#include "cmStandardIncludes.h" + +class cmLocalGenerator; + +/** \class cmInstallGenerator + * \brief Support class for generating install scripts. + * + */ +class cmInstallGenerator +{ +public: + cmInstallGenerator(); + virtual ~cmInstallGenerator(); + + void Generate(std::ostream& os, const char* config, + std::vector const& configurationTypes); + + static void AddInstallRule(std::ostream& os, const char* dest, int type, + const char* files, bool optional = false, + const char* properties = 0); + +protected: + virtual void GenerateScript(std::ostream& os)=0; + + const char* ConfigurationName; + std::vector const* ConfigurationTypes; +}; + +#endif diff --git a/Source/cmInstallScriptGenerator.cxx b/Source/cmInstallScriptGenerator.cxx new file mode 100644 index 0000000..1322f72 --- /dev/null +++ b/Source/cmInstallScriptGenerator.cxx @@ -0,0 +1,35 @@ +/*========================================================================= + + Program: CMake - Cross-Platform Makefile Generator + Module: $RCSfile$ + Language: C++ + Date: $Date$ + Version: $Revision$ + + Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved. + See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details. + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ +#include "cmInstallScriptGenerator.h" + +//---------------------------------------------------------------------------- +cmInstallScriptGenerator +::cmInstallScriptGenerator(const char* script): Script(script) +{ +} + +//---------------------------------------------------------------------------- +cmInstallScriptGenerator +::~cmInstallScriptGenerator() +{ +} + +//---------------------------------------------------------------------------- +void cmInstallScriptGenerator::GenerateScript(std::ostream& os) +{ + os << "INCLUDE(\"" << this->Script << "\")\n"; +} diff --git a/Source/cmInstallScriptGenerator.h b/Source/cmInstallScriptGenerator.h new file mode 100644 index 0000000..6b3cdfc --- /dev/null +++ b/Source/cmInstallScriptGenerator.h @@ -0,0 +1,36 @@ +/*========================================================================= + + Program: CMake - Cross-Platform Makefile Generator + Module: $RCSfile$ + Language: C++ + Date: $Date$ + Version: $Revision$ + + Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved. + See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details. + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ +#ifndef cmInstallScriptGenerator_h +#define cmInstallScriptGenerator_h + +#include "cmInstallGenerator.h" + +/** \class cmInstallScriptGenerator + * \brief Generate target installation rules. + */ +class cmInstallScriptGenerator: public cmInstallGenerator +{ +public: + cmInstallScriptGenerator(const char* script); + virtual ~cmInstallScriptGenerator(); + +protected: + virtual void GenerateScript(std::ostream& os); + std::string Script; +}; + +#endif diff --git a/Source/cmInstallTargetGenerator.cxx b/Source/cmInstallTargetGenerator.cxx new file mode 100644 index 0000000..7e07597 --- /dev/null +++ b/Source/cmInstallTargetGenerator.cxx @@ -0,0 +1,191 @@ +/*========================================================================= + + Program: CMake - Cross-Platform Makefile Generator + Module: $RCSfile$ + Language: C++ + Date: $Date$ + Version: $Revision$ + + Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved. + See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details. + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ +#include "cmInstallTargetGenerator.h" + +#include "cmGlobalGenerator.h" +#include "cmLocalGenerator.h" +#include "cmMakefile.h" +#include "cmTarget.h" + +//---------------------------------------------------------------------------- +cmInstallTargetGenerator +::cmInstallTargetGenerator(cmTarget& t, const char* dest, bool implib): + Target(&t), Destination(dest), ImportLibrary(implib) +{ +} + +//---------------------------------------------------------------------------- +cmInstallTargetGenerator +::~cmInstallTargetGenerator() +{ +} + +//---------------------------------------------------------------------------- +void cmInstallTargetGenerator::GenerateScript(std::ostream& os) +{ + // Compute the build tree directory from which to copy the target. + std::string fromDir; + if(this->Target->NeedRelinkBeforeInstall()) + { + fromDir = this->Target->GetMakefile()->GetStartOutputDirectory(); + fromDir += "/CMakeFiles/CMakeRelink.dir/"; + } + else + { + fromDir = this->Target->GetDirectory(); + fromDir += "/"; + } + + // Write variable settings to do per-configuration references. + this->PrepareInstallReference(os); + + // Create the per-configuration reference. + std::string fromName = this->GetInstallReference(); + std::string fromFile = fromDir; + fromFile += fromName; + + // Setup special properties for some target types. + std::string props; + const char* properties = 0; + cmTarget::TargetType type = this->Target->GetType(); + switch(type) + { + case cmTarget::SHARED_LIBRARY: + { + // Add shared library installation properties if this platform + // supports them. + const char* lib_version = this->Target->GetProperty("VERSION"); + const char* lib_soversion = this->Target->GetProperty("SOVERSION"); + if(!this->Target->GetMakefile() + ->GetDefinition("CMAKE_SHARED_LIBRARY_SONAME_C_FLAG")) + { + // Versioning is supported only for shared libraries and modules, + // and then only when the platform supports an soname flag. + lib_version = 0; + lib_soversion = 0; + } + if(lib_version) + { + props += " VERSION "; + props += lib_version; + } + if(lib_soversion) + { + props += " SOVERSION "; + props += lib_soversion; + } + properties = props.c_str(); + } + break; + case cmTarget::EXECUTABLE: + { + // Add executable installation properties if this platform + // supports them. +#if defined(_WIN32) && !defined(__CYGWIN__) + const char* exe_version = 0; +#else + const char* exe_version = this->Target->GetProperty("VERSION"); +#endif + if(exe_version) + { + props += " VERSION "; + props += exe_version; + properties = props.c_str(); + } + + // Handle OSX Bundles. + if(this->Target->GetPropertyAsBool("MACOSX_BUNDLE")) + { + // Compute the source locations of the bundle executable and + // Info.plist file. + std::string plist = fromFile; + plist += ".app/Contents/Info.plist"; + fromFile += ".app/Contents/MacOS/"; + fromFile += fromName; + + // Compute the destination locations of the bundle executable + // and Info.plist file. + std::string bdest = this->Destination; + bdest += "/"; + bdest += fromName; + std::string pdest = bdest; + pdest += ".app/Contents"; + bdest += ".app/Contents/MacOS"; + + // Install the Info.plist file. + this->AddInstallRule(os, pdest.c_str(), cmTarget::INSTALL_FILES, + plist.c_str()); + } + } + break; + case cmTarget::STATIC_LIBRARY: + case cmTarget::MODULE_LIBRARY: + // Nothing special for modules or static libraries. + break; + default: + break; + } + + // Write code to install the target file. + this->AddInstallRule(os, this->Destination.c_str(), type, fromFile.c_str(), + this->ImportLibrary, properties); +} + +//---------------------------------------------------------------------------- +void +cmInstallTargetGenerator +::PrepareInstallReference(std::ostream& os) +{ + // If the target name may vary with the configuration type then + // store all possible names ahead of time in variables. + std::string fname; + for(std::vector::const_iterator i = + this->ConfigurationTypes->begin(); + i != this->ConfigurationTypes->end(); ++i) + { + // Set a variable with the target name for this configuration. + fname = this->Target->GetFullName(i->c_str(), this->ImportLibrary); + os << "SET(" << this->Target->GetName() + << (this->ImportLibrary? "_IMPNAME_" : "_NAME_") << *i + << " \"" << fname << "\")\n"; + } +} + +//---------------------------------------------------------------------------- +std::string cmInstallTargetGenerator::GetInstallReference() +{ + if(this->ConfigurationTypes->empty()) + { + return this->Target->GetFullName(this->ConfigurationName, + this->ImportLibrary); + } + else + { + std::string ref = "${"; + ref += this->Target->GetName(); + if(this->ImportLibrary) + { + ref += "_IMPNAME_"; + } + else + { + ref += "_NAME_"; + } + ref += "${CMAKE_INSTALL_CONFIG_NAME}}"; + return ref; + } +} diff --git a/Source/cmInstallTargetGenerator.h b/Source/cmInstallTargetGenerator.h new file mode 100644 index 0000000..6e13ac8 --- /dev/null +++ b/Source/cmInstallTargetGenerator.h @@ -0,0 +1,43 @@ +/*========================================================================= + + Program: CMake - Cross-Platform Makefile Generator + Module: $RCSfile$ + Language: C++ + Date: $Date$ + Version: $Revision$ + + Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved. + See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details. + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ +#ifndef cmInstallTargetGenerator_h +#define cmInstallTargetGenerator_h + +#include "cmInstallGenerator.h" + +class cmTarget; + +/** \class cmInstallTargetGenerator + * \brief Generate target installation rules. + */ +class cmInstallTargetGenerator: public cmInstallGenerator +{ +public: + cmInstallTargetGenerator(cmTarget& t, const char* dest, + bool implib = false); + virtual ~cmInstallTargetGenerator(); + +protected: + virtual void GenerateScript(std::ostream& os); + void PrepareInstallReference(std::ostream& os); + std::string GetInstallReference(); + cmTarget* Target; + std::string Destination; + bool ImportLibrary; +}; + +#endif diff --git a/Source/cmInstallTargetsCommand.h b/Source/cmInstallTargetsCommand.h index b8e86d9..10ab457 100644 --- a/Source/cmInstallTargetsCommand.h +++ b/Source/cmInstallTargetsCommand.h @@ -53,7 +53,7 @@ public: */ virtual const char* GetTerseDocumentation() { - return "Create install rules for targets."; + return "Old installation command. Use the INSTALL command."; } /** @@ -62,6 +62,8 @@ public: virtual const char* GetFullDocumentation() { return + "This command has been superceded by the INSTALL command. It " + "is provided for compatibility with older CMake code.\n" " INSTALL_TARGETS( [RUNTIME_DIRECTORY dir] target target)\n" "Create rules to install the listed targets into the given directory. " "The directory is relative to the installation prefix, which " diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index d7cbd5b..b6e1369 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -15,13 +15,18 @@ =========================================================================*/ #include "cmLocalGenerator.h" + +#include "cmGeneratedFileStream.h" #include "cmGlobalGenerator.h" -#include "cmake.h" +#include "cmInstallGenerator.h" +#include "cmInstallScriptGenerator.h" +#include "cmInstallTargetGenerator.h" #include "cmMakefile.h" -#include "cmGeneratedFileStream.h" -#include "cmSourceFile.h" #include "cmOrderLinkDirectories.h" +#include "cmSourceFile.h" #include "cmTest.h" +#include "cmake.h" + #include // for isalpha cmLocalGenerator::cmLocalGenerator() @@ -238,11 +243,11 @@ void cmLocalGenerator::GenerateTestFiles() } } +//---------------------------------------------------------------------------- void cmLocalGenerator::GenerateInstallRules() { - cmTargets &tgts = m_Makefile->GetTargets(); - const char* prefix - = m_Makefile->GetDefinition("CMAKE_INSTALL_PREFIX"); + // Compute the install prefix. + const char* prefix = m_Makefile->GetDefinition("CMAKE_INSTALL_PREFIX"); #if defined(_WIN32) && !defined(__CYGWIN__) std::string prefix_win32; if(!prefix) @@ -270,6 +275,19 @@ void cmLocalGenerator::GenerateInstallRules() } #endif + // Compute the set of configurations. + std::vector configurationTypes; + if(const char* types = m_Makefile->GetDefinition("CMAKE_CONFIGURATION_TYPES")) + { + cmSystemTools::ExpandListArgument(types, configurationTypes); + } + const char* config = 0; + if(configurationTypes.empty()) + { + config = m_Makefile->GetDefinition("CMAKE_BUILD_TYPE"); + } + + // Create the install script file. std::string file = m_Makefile->GetStartOutputDirectory(); std::string homedir = m_Makefile->GetHomeOutputDirectory(); std::string currdir = m_Makefile->GetCurrentOutputDirectory(); @@ -285,25 +303,16 @@ void cmLocalGenerator::GenerateInstallRules() cmGeneratedFileStream fout(file.c_str()); fout.SetCopyIfDifferent(true); - fout << "# Install script for directory: " << m_Makefile->GetCurrentDirectory() - << std::endl << std::endl; + // Write the header. + fout << "# Install script for directory: " + << m_Makefile->GetCurrentDirectory() << std::endl << std::endl; fout << "# Set the install prefix" << std::endl << "IF(NOT CMAKE_INSTALL_PREFIX)" << std::endl << " SET(CMAKE_INSTALL_PREFIX \"" << prefix << "\")" << std::endl << "ENDIF(NOT CMAKE_INSTALL_PREFIX)" << std::endl << std::endl; - std::vector configurationTypes; - if(const char* types = m_Makefile->GetDefinition("CMAKE_CONFIGURATION_TYPES")) - { - cmSystemTools::ExpandListArgument(types, configurationTypes); - } - const char* config = 0; - if(configurationTypes.empty()) - { - config = m_Makefile->GetDefinition("CMAKE_BUILD_TYPE"); - } - + // Write support code for generating per-configuration install rules. fout << "# Set the install configuration name.\n" "IF(NOT CMAKE_INSTALL_CONFIG_NAME)\n" @@ -317,250 +326,19 @@ void cmLocalGenerator::GenerateInstallRules() "ENDIF(NOT CMAKE_INSTALL_CONFIG_NAME)\n" "\n"; - std::string libOutPath = ""; - if (m_Makefile->GetDefinition("LIBRARY_OUTPUT_PATH")) + // Ask each install generator to write its code. + std::vector const& installers = + m_Makefile->GetInstallGenerators(); + for(std::vector::const_iterator gi = installers.begin(); + gi != installers.end(); ++gi) { - libOutPath = m_Makefile->GetDefinition("LIBRARY_OUTPUT_PATH"); - if(libOutPath.size()) - { - if(libOutPath[libOutPath.size() -1] != '/') - { - libOutPath += "/"; - } - } - } - - std::string exeOutPath = ""; - if (m_Makefile->GetDefinition("EXECUTABLE_OUTPUT_PATH")) - { - exeOutPath = - m_Makefile->GetDefinition("EXECUTABLE_OUTPUT_PATH"); - if(exeOutPath.size()) - { - if(exeOutPath[exeOutPath.size() -1] != '/') - { - exeOutPath += "/"; - } - } - } - if ( libOutPath.size() == 0 ) - { - // LIBRARY_OUTPUT_PATH not defined - libOutPath = currdir + "/"; - } - if ( exeOutPath.size() == 0 ) - { - // EXECUTABLE_OUTPUT_PATH not defined - exeOutPath = currdir + "/"; - } - std::string relinkDir = currdir + "/CMakeFiles/CMakeRelink.dir/"; - - // Include user-specified install scripts. - std::vector const& installScripts = - m_Makefile->GetInstallScripts(); - for(std::vector::const_iterator s = installScripts.begin(); - s != installScripts.end(); ++s) - { - fout << "INCLUDE(\"" << s->c_str() << "\")" << std::endl; + (*gi)->Generate(fout, config, configurationTypes); } - std::string destination; - for(cmTargets::iterator l = tgts.begin(); - l != tgts.end(); l++) - { - const char* preinstall = l->second.GetProperty("PRE_INSTALL_SCRIPT"); - const char* postinstall = l->second.GetProperty("POST_INSTALL_SCRIPT"); - if ( preinstall ) - { - fout << "INCLUDE(\"" << preinstall << "\")" << std::endl; - } - if (l->second.GetInstallPath() != "") - { - bool need_relink = l->second.NeedRelinkBeforeInstall(); - destination = "${CMAKE_INSTALL_PREFIX}" + l->second.GetInstallPath(); - if(destination[destination.size()-1] == '/') - { - destination = destination.substr(0, destination.size()-1); - } - cmSystemTools::ConvertToUnixSlashes(destination); - const char* dest = destination.c_str(); - int type = l->second.GetType(); - std::string fname; - std::string props; - const char* properties = 0; - const char* files; - - this->PrepareInstallReference(fout, l->second, configurationTypes); - - // now install the target - switch (type) - { - case cmTarget::SHARED_LIBRARY: - { - // Special code to handle DLL - fname = l->second.GetFullName(); - std::string ext = cmSystemTools::GetFilenameLastExtension(fname); - ext = cmSystemTools::LowerCase(ext); - if ( ext == ".dll" ) - { - // Install the .lib separately. - std::string libname = need_relink? relinkDir : libOutPath; - libname += this->GetInstallReference(l->second, config, - configurationTypes, - true); - files = libname.c_str(); - this->AddInstallRule(fout, dest, cmTarget::STATIC_LIBRARY, files, true); - - // Change the destination to the .dll destination. - destination = "${CMAKE_INSTALL_PREFIX}" + l->second.GetRuntimeInstallPath(); - if(destination[destination.size()-1] == '/') - { - destination = destination.substr(0, destination.size()-1); - } - dest = destination.c_str(); - } - else - { - // Add shared library installation properties. - const char* lib_version = l->second.GetProperty("VERSION"); - const char* lib_soversion = l->second.GetProperty("SOVERSION"); - if(!m_Makefile->GetDefinition("CMAKE_SHARED_LIBRARY_SONAME_C_FLAG")) - { - // Versioning is supported only for shared libraries and modules, - // and then only when the platform supports an soname flag. - lib_version = 0; - lib_soversion = 0; - } - if ( lib_version ) - { - props += " VERSION "; - props += lib_version; - } - if ( lib_soversion ) - { - props += " SOVERSION "; - props += lib_soversion; - } - properties = props.c_str(); - } - } - /* No "break;" because we want to install the library here. */ - case cmTarget::STATIC_LIBRARY: - case cmTarget::MODULE_LIBRARY: - { - fname = need_relink? relinkDir : libOutPath; - fname += this->GetInstallReference(l->second, config, - configurationTypes); - files = fname.c_str(); - this->AddInstallRule(fout, dest, type, files, false, properties); - } - break; - case cmTarget::EXECUTABLE: - { -#if defined(_WIN32) && !defined(__CYGWIN__) - const char* exe_version = 0; -#else - const char* exe_version = l->second.GetProperty("VERSION"); -#endif - if(exe_version) - { - props += " VERSION "; - props += exe_version; - properties = props.c_str(); - } - std::string exeName = - this->GetInstallReference(l->second, config, configurationTypes); - fname = need_relink? relinkDir : exeOutPath; - fname += exeName; - if(l->second.GetPropertyAsBool("MACOSX_BUNDLE")) - { - std::string plist = fname; - plist += ".app/Contents/Info.plist"; - fname += ".app/Contents/MacOS/"; - fname += exeName; - files = fname.c_str(); - std::string bdest = dest; - bdest += "/"; - bdest += exeName; - std::string pdest = bdest; - pdest += ".app/Contents"; - bdest += ".app/Contents/MacOS"; - // first install the actual executable - this->AddInstallRule(fout, bdest.c_str(), type, files, - false, properties); - files = plist.c_str(); - // now install the Info.plist file - this->AddInstallRule(fout, pdest.c_str(), - cmTarget::INSTALL_FILES, files); - } - else - { - files = fname.c_str(); - this->AddInstallRule(fout, dest, type, files, false, - properties); - } - } - break; - case cmTarget::INSTALL_FILES: - { - std::string sourcePath = m_Makefile->GetCurrentDirectory(); - std::string binaryPath = m_Makefile->GetCurrentOutputDirectory(); - sourcePath += "/"; - binaryPath += "/"; - const std::vector &sf = l->second.GetSourceLists(); - std::vector::const_iterator i; - for (i = sf.begin(); i != sf.end(); ++i) - { - std::string f = *i; - if(f.substr(0, sourcePath.length()) == sourcePath) - { - f = f.substr(sourcePath.length()); - } - else if(f.substr(0, binaryPath.length()) == binaryPath) - { - f = f.substr(binaryPath.length()); - } - - files = i->c_str(); - this->AddInstallRule(fout, dest, type, files); - } - } - break; - case cmTarget::INSTALL_PROGRAMS: - { - std::string sourcePath = m_Makefile->GetCurrentDirectory(); - std::string binaryPath = m_Makefile->GetCurrentOutputDirectory(); - sourcePath += "/"; - binaryPath += "/"; - const std::vector &sf = l->second.GetSourceLists(); - std::vector::const_iterator i; - for (i = sf.begin(); i != sf.end(); ++i) - { - std::string f = *i; - if(f.substr(0, sourcePath.length()) == sourcePath) - { - f = f.substr(sourcePath.length()); - } - else if(f.substr(0, binaryPath.length()) == binaryPath) - { - f = f.substr(binaryPath.length()); - } - files = i->c_str(); - this->AddInstallRule(fout, dest, type, files); - } - } - break; - case cmTarget::UTILITY: - default: - break; - } - } - if ( postinstall ) - { - fout << "INCLUDE(\"" << postinstall << "\")" << std::endl; - } - } + // Write rules from old-style specification stored in targets. + this->GenerateTargetInstallRules(fout, config, configurationTypes); + // Include install scripts from subdirectories. if ( this->Children.size()) { std::vector::const_iterator i = this->Children.begin(); @@ -573,6 +351,8 @@ void cmLocalGenerator::GenerateInstallRules() } fout << std::endl;; } + + // Record the install manifest. if ( toplevel_install ) { fout << "FILE(WRITE \"" << homedir.c_str() << "/install_manifest.txt\" " @@ -584,36 +364,6 @@ void cmLocalGenerator::GenerateInstallRules() } } -void cmLocalGenerator::AddInstallRule(std::ostream& fout, const char* dest, - int type, const char* files, bool optional /* = false */, const char* properties /* = 0 */) -{ - std::string sfiles = files; - std::string destination = dest; - std::string stype; - switch ( type ) - { - case cmTarget::INSTALL_PROGRAMS: stype = "PROGRAM"; break; - case cmTarget::EXECUTABLE: stype = "EXECUTABLE"; break; - case cmTarget::STATIC_LIBRARY: stype = "STATIC_LIBRARY"; break; - case cmTarget::SHARED_LIBRARY: stype = "SHARED_LIBRARY"; break; - case cmTarget::MODULE_LIBRARY: stype = "MODULE"; break; - case cmTarget::INSTALL_FILES: - default: stype = "FILE"; break; - } - std::string fname = cmSystemTools::GetFilenameName(sfiles.c_str()); - fout - << "MESSAGE(STATUS \"Installing " << destination.c_str() - << "/" << fname.c_str() << "\")\n" - << "FILE(INSTALL DESTINATION \"" << destination.c_str() - << "\" TYPE " << stype.c_str() << (optional?" OPTIONAL":"") ; - if ( properties && *properties ) - { - fout << " PROPERTIES" << properties; - } - fout - << " FILES \"" << sfiles.c_str() << "\")\n"; -} - void cmLocalGenerator::AddCustomCommandToCreateObject(const char* ofname, const char* lang, cmSourceFile& source, @@ -1633,78 +1383,6 @@ cmLocalGenerator::ComputeLinkInformation(cmTarget& target, } //---------------------------------------------------------------------------- -std::string -cmLocalGenerator::GetInstallReference(cmTarget& target, const char* config, - std::vector const& configs, - bool implib /* = false*/) -{ - if(configs.empty()) - { - std::string ref = target.GetFullName(config); - if(implib) - { - ref = cmSystemTools::GetFilenameWithoutLastExtension(ref); - ref += ".lib"; - } - return ref; - } - else - { - std::string ref = "${"; - ref += target.GetName(); - if(implib) - { - ref += "_LIBNAME_"; - } - else - { - ref += "_NAME_"; - } - ref += "${CMAKE_INSTALL_CONFIG_NAME}}"; - return ref; - } -} - -//---------------------------------------------------------------------------- -void -cmLocalGenerator -::PrepareInstallReference(std::ostream& fout, cmTarget& target, - std::vector const& configs) -{ - // If the target name may vary with the configuration type then - // store all possible names ahead of time in variables. - cmTarget::TargetType type = target.GetType(); - if(type == cmTarget::SHARED_LIBRARY || - type == cmTarget::STATIC_LIBRARY || - type == cmTarget::MODULE_LIBRARY || - type == cmTarget::EXECUTABLE) - { - std::string fname; - for(std::vector::const_iterator i = configs.begin(); - i != configs.end(); ++i) - { - // Set a variable with the target name for this - // configuration. - fname = target.GetFullName(i->c_str()); - fout << "SET(" << target.GetName() << "_NAME_" << *i - << " \"" << fname << "\")\n"; - -#ifdef _WIN32 - // If the target is a .dll then add the corresponding .lib - // name in its own variable. - if(type == cmTarget::SHARED_LIBRARY) - { - fname = cmSystemTools::GetFilenameWithoutExtension(fname); - fname += ".lib"; - fout << "SET(" << target.GetName() << "_LIBNAME_" << *i - << " \"" << fname << "\")\n"; - } -#endif - } - } -} - -//---------------------------------------------------------------------------- void cmLocalGenerator::AddLanguageFlags(std::string& flags, const char* lang) { @@ -1938,3 +1616,128 @@ std::string cmLocalGenerator::Convert(const char* source, } return result; } + +//---------------------------------------------------------------------------- +void +cmLocalGenerator +::GenerateTargetInstallRules( + std::ostream& os, const char* config, + std::vector const& configurationTypes) +{ + // Convert the old-style install specification from each target to + // an install generator and run it. + cmTargets& tgts = m_Makefile->GetTargets(); + for(cmTargets::iterator l = tgts.begin(); l != tgts.end(); ++l) + { + // Include the user-specified pre-install script for this target. + if(const char* preinstall = l->second.GetProperty("PRE_INSTALL_SCRIPT")) + { + cmInstallScriptGenerator g(preinstall); + g.Generate(os, config, configurationTypes); + } + + // Install this target if a destination is given. + if(l->second.GetInstallPath() != "") + { + // Compute the full install destination. Note that converting + // to unix slashes also removes any trailing slash. + std::string destination = "${CMAKE_INSTALL_PREFIX}"; + destination += l->second.GetInstallPath(); + cmSystemTools::ConvertToUnixSlashes(destination); + + // Generate the proper install generator for this target type. + switch(l->second.GetType()) + { + case cmTarget::EXECUTABLE: + case cmTarget::STATIC_LIBRARY: + case cmTarget::MODULE_LIBRARY: + { + // Use a target install generator. + cmInstallTargetGenerator g(l->second, destination.c_str(), false); + g.Generate(os, config, configurationTypes); + } + break; + case cmTarget::SHARED_LIBRARY: + { +#if defined(_WIN32) || defined(__CYGWIN__) + // Special code to handle DLL. Install the import library + // to the normal destination and the DLL to the runtime + // destination. + cmInstallTargetGenerator g1(l->second, destination.c_str(), true); + g1.Generate(os, config, configurationTypes); + destination = "${CMAKE_INSTALL_PREFIX}"; + destination += l->second.GetRuntimeInstallPath(); + cmSystemTools::ConvertToUnixSlashes(destination); + cmInstallTargetGenerator g2(l->second, destination.c_str(), false); + g2.Generate(os, config, configurationTypes); +#else + // Use a target install generator. + cmInstallTargetGenerator g(l->second, destination.c_str(), false); + g.Generate(os, config, configurationTypes); +#endif + } + break; + case cmTarget::INSTALL_FILES: + { + std::string sourcePath = m_Makefile->GetCurrentDirectory(); + std::string binaryPath = m_Makefile->GetCurrentOutputDirectory(); + sourcePath += "/"; + binaryPath += "/"; + const std::vector &sf = l->second.GetSourceLists(); + std::vector::const_iterator i; + for (i = sf.begin(); i != sf.end(); ++i) + { + std::string f = *i; + if(f.substr(0, sourcePath.length()) == sourcePath) + { + f = f.substr(sourcePath.length()); + } + else if(f.substr(0, binaryPath.length()) == binaryPath) + { + f = f.substr(binaryPath.length()); + } + cmInstallGenerator::AddInstallRule(os, destination.c_str(), + cmTarget::INSTALL_FILES, + i->c_str()); + } + } + break; + case cmTarget::INSTALL_PROGRAMS: + { + std::string sourcePath = m_Makefile->GetCurrentDirectory(); + std::string binaryPath = m_Makefile->GetCurrentOutputDirectory(); + sourcePath += "/"; + binaryPath += "/"; + const std::vector &sf = l->second.GetSourceLists(); + std::vector::const_iterator i; + for (i = sf.begin(); i != sf.end(); ++i) + { + std::string f = *i; + if(f.substr(0, sourcePath.length()) == sourcePath) + { + f = f.substr(sourcePath.length()); + } + else if(f.substr(0, binaryPath.length()) == binaryPath) + { + f = f.substr(binaryPath.length()); + } + cmInstallGenerator::AddInstallRule(os, destination.c_str(), + cmTarget::INSTALL_PROGRAMS, + i->c_str()); + } + } + break; + case cmTarget::UTILITY: + default: + break; + } + } + + // Include the user-specified post-install script for this target. + if(const char* postinstall = l->second.GetProperty("POST_INSTALL_SCRIPT")) + { + cmInstallScriptGenerator g(postinstall); + g.Generate(os, config, configurationTypes); + } + } +} diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h index 9b33118..b90abcc 100644 --- a/Source/cmLocalGenerator.h +++ b/Source/cmLocalGenerator.h @@ -177,14 +177,6 @@ protected: ///! put all the libraries for a target on into the given stream virtual void OutputLinkLibraries(std::ostream&, cmTarget&, bool relink); - /** Compute the string to use to refer to a target in an install - file. */ - std::string GetInstallReference(cmTarget& target, const char* config, - std::vector const& configs, - bool implib = false); - void PrepareInstallReference(std::ostream& fout, cmTarget& target, - std::vector const& configs); - /** Get the include flags for the current makefile and language. */ void GetIncludeDirectories(std::vector& dirs); @@ -226,8 +218,11 @@ protected: // of the types listed will be compiled as custom commands and added // to a custom target. void CreateCustomTargetsAndCommands(std::set const&); - virtual void AddInstallRule(std::ostream& fout, const char* dest, int type, - const char* files, bool optional = false, const char* properties = 0); + + // Handle old-style install rules stored in the targets. + void GenerateTargetInstallRules( + std::ostream& os, const char* config, + std::vector const& configurationTypes); cmMakefile *m_Makefile; cmGlobalGenerator *m_GlobalGenerator; diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index 85c6620..c4dffc2 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -15,6 +15,7 @@ =========================================================================*/ #include "cmMakefile.h" + #include "cmCommand.h" #include "cmSourceFile.h" #include "cmSystemTools.h" @@ -29,6 +30,7 @@ #ifdef CMAKE_BUILD_WITH_CMAKE # include "cmVariableWatch.h" #endif +#include "cmInstallGenerator.h" #include "cmake.h" #include // required for atoi @@ -125,6 +127,12 @@ unsigned int cmMakefile::GetCacheMinorVersion() cmMakefile::~cmMakefile() { + for(std::vector::iterator + i = m_InstallGenerators.begin(); + i != m_InstallGenerators.end(); ++i) + { + delete *i; + } for(std::vector::iterator i = m_SourceFiles.begin(); i != m_SourceFiles.end(); ++i) { diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h index cdd0adc..fd8de7b 100644 --- a/Source/cmMakefile.h +++ b/Source/cmMakefile.h @@ -28,6 +28,7 @@ class cmFunctionBlocker; class cmCommand; +class cmInstallGenerator; class cmLocalGenerator; class cmMakeDepend; class cmSourceFile; @@ -672,11 +673,10 @@ public: void SetPreOrder(bool p) { this->PreOrder = p; } bool GetPreOrder() { return this->PreOrder; } - /** Add a script file to be invoked during installation. */ - void AddInstallScript(const char* script) - { m_InstallScripts.push_back(script); } - std::vector const& GetInstallScripts() - { return m_InstallScripts; } + void AddInstallGenerator(cmInstallGenerator* g) + { m_InstallGenerators.push_back(g); } + std::vector& GetInstallGenerators() + { return m_InstallGenerators; } protected: // add link libraries and directories to the target void AddGlobalLinkInformation(const char* name, cmTarget& target); @@ -709,8 +709,7 @@ protected: cmTarget::LinkLibraries m_LinkLibraries; - // List of install-time scripts. This should not be inherited. - std::vector m_InstallScripts; + std::vector m_InstallGenerators; std::string m_IncludeFileRegularExpression; std::string m_ComplainFileRegularExpression; diff --git a/Source/cmSetTargetPropertiesCommand.h b/Source/cmSetTargetPropertiesCommand.h index c24ec76..e3afd76 100644 --- a/Source/cmSetTargetPropertiesCommand.h +++ b/Source/cmSetTargetPropertiesCommand.h @@ -58,17 +58,25 @@ public: "Set properties on a target. The syntax for the command is to " "list all the files you want " "to change, and then provide the values you want to set next. " - "Properties that cmake knows about are PREFIX and SUFFIX for UNIX " - "systems and libraries. CMake also knows about LINK_FLAGS, which " - "can be used to add extra flags to the link step of a target. " + "You can use any prop value pair you want and " + "extract it later with the GET_TARGET_PROPERTY command.\n" + "Properties that affect the name of a target's output file are " + "as follows. " + "The PREFIX and SUFFIX properties override the default target name " + "prefix (such as \"lib\") and suffix (such as \".so\"). " + "IMPORT_PREFIX and IMPORT_SUFFIX are the equivalent properties for " + "the import library corresponding to a DLL " + "(for SHARED library targets). " + "OUTPUT_NAME sets the real name of a target when it is built and " + "can be used to help create two targets of the same name even though " + "CMake requires unique logical target names.\n" + "The LINK_FLAGS property can be used to add extra flags to the " + "link step of a target. " "DEFINE_SYMBOL sets the name of the preprocessor symbol defined when " "compiling sources in a shared library. " "If not set here then it is set to target_EXPORTS by default " "(with some substitutions if the target is not a valid C " - "identifier). " - "PRE_INSTALL_SCRIPT specifies a CMake script that is run " - "prior to installing the target. POST_INSTALL_SCRIPT specifies " - "a CMake script that is run after target is installed. " + "identifier).\n" "For shared libraries VERSION and SOVERSION can be used to specify " "the build version and api version respectively. When building or " "installing appropriate symlinks are created if the platform " @@ -77,9 +85,7 @@ public: "the same version number. " "For executables VERSION can be used to specify the build version. " "When building or installing appropriate symlinks are created if " - "the platform supports symlinks. " - "The OUTPUT_NAME can be used to set an output name that is " - "used in place of the target name when creating executables.\n" + "the platform supports symlinks.\n" "There are a few properties used to specify RPATH rules. " "INSTALL_RPATH is a semicolon-separated list specifying the rpath " "to use in installed targets (for platforms that support it). " @@ -96,9 +102,13 @@ public: "PROJECT_LABEL can be used to change the name of " "the target in an IDE like visual studio. VS_KEYWORD can be set " "to change the visual studio keyword, for example QT integration " - "works better if this is set to Qt4VSv1.0. " - "You can use any prop value pair you want and " - "extract it later with the GET_TARGET_PROPERTY command."; + "works better if this is set to Qt4VSv1.0.\n" + "The PRE_INSTALL_SCRIPT and POST_INSTALL_SCRIPT properties are the " + "old way to specify CMake scripts to run before and after " + "installing a target. They are used only when the old " + "INSTALL_TARGETS command is used to install the target. Use the " + "INSTALL command instead." + ; } cmTypeMacro(cmSetTargetPropertiesCommand, cmCommand); diff --git a/Tests/SimpleInstall/CMakeLists.txt b/Tests/SimpleInstall/CMakeLists.txt index 03efbec..db2d9fd 100644 --- a/Tests/SimpleInstall/CMakeLists.txt +++ b/Tests/SimpleInstall/CMakeLists.txt @@ -83,8 +83,8 @@ ELSE(STAGE2) ADD_DEPENDENCIES(test2 test3) ADD_DEPENDENCIES(test4 test2) - INSTALL_TARGETS(/bin SimpleInstall) - INSTALL_TARGETS(/lib test1 test2 test3 test4) + INSTALL(TARGETS SimpleInstall test1 test2 test3 test4 + RUNTIME DESTINATION bin LIBRARY DESTINATION lib) INSTALL_FILES(/include FILES lib1.h lib2.h lib3.h) # Test user-specified install scripts. diff --git a/Tests/SimpleInstallS2/CMakeLists.txt b/Tests/SimpleInstallS2/CMakeLists.txt index 03efbec..db2d9fd 100644 --- a/Tests/SimpleInstallS2/CMakeLists.txt +++ b/Tests/SimpleInstallS2/CMakeLists.txt @@ -83,8 +83,8 @@ ELSE(STAGE2) ADD_DEPENDENCIES(test2 test3) ADD_DEPENDENCIES(test4 test2) - INSTALL_TARGETS(/bin SimpleInstall) - INSTALL_TARGETS(/lib test1 test2 test3 test4) + INSTALL(TARGETS SimpleInstall test1 test2 test3 test4 + RUNTIME DESTINATION bin LIBRARY DESTINATION lib) INSTALL_FILES(/include FILES lib1.h lib2.h lib3.h) # Test user-specified install scripts. diff --git a/bootstrap b/bootstrap index 0e858d2..d2974f8 100755 --- a/bootstrap +++ b/bootstrap @@ -97,6 +97,9 @@ CMAKE_CXX_SOURCES="\ cmGlobalGenerator \ cmGlob \ cmLocalGenerator \ + cmInstallGenerator \ + cmInstallScriptGenerator \ + cmInstallTargetGenerator \ cmSourceFile \ cmSystemTools \ cmFileTimeComparison \ -- cgit v0.12