summaryrefslogtreecommitdiffstats
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
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.
-rw-r--r--Source/CMakeLists.txt6
-rw-r--r--Source/cmInstallCommand.cxx262
-rw-r--r--Source/cmInstallCommand.h64
-rw-r--r--Source/cmInstallGenerator.cxx82
-rw-r--r--Source/cmInstallGenerator.h48
-rw-r--r--Source/cmInstallScriptGenerator.cxx35
-rw-r--r--Source/cmInstallScriptGenerator.h36
-rw-r--r--Source/cmInstallTargetGenerator.cxx191
-rw-r--r--Source/cmInstallTargetGenerator.h43
-rw-r--r--Source/cmInstallTargetsCommand.h4
-rw-r--r--Source/cmLocalGenerator.cxx525
-rw-r--r--Source/cmLocalGenerator.h15
-rw-r--r--Source/cmMakefile.cxx8
-rw-r--r--Source/cmMakefile.h13
-rw-r--r--Source/cmSetTargetPropertiesCommand.h36
-rw-r--r--Tests/SimpleInstall/CMakeLists.txt4
-rw-r--r--Tests/SimpleInstallS2/CMakeLists.txt4
-rwxr-xr-xbootstrap3
18 files changed, 973 insertions, 406 deletions
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<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 = "";
+ }
+}
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 <script1> [SCRIPT <script2> [...]])\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 <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 <prefix>/bin and myStaticLib to <prefix>/lib. "
+ "On non-DLL platforms mySharedLib will be installed to <prefix>/lib and "
+ "/some/full/path. On DLL platforms the mySharedLib DLL will be "
+ "installed to <prefix>/bin and /some/full/path and its import library "
+ "will be installed to <prefix>/lib and /some/full/path. On non-DLL "
+ "platforms mySharedLib will be installed to <prefix>/lib and "
+ "/some/full/path.\n"
+ " INSTALL(SCRIPT <file1> [SCRIPT <file2> [...]])\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<std::string> const& args);
+ bool HandleTargetsMode(std::vector<std::string> 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<std::string> 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<std::string> 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<std::string> 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<std::string>::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(<dir> [RUNTIME_DIRECTORY dir] target target)\n"
"Create rules to install the listed targets into the given directory. "
"The directory <dir> 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 <ctype.h> // 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<std::string> 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<std::string> 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<cmInstallGenerator*> const& installers =
+ m_Makefile->GetInstallGenerators();
+ for(std::vector<cmInstallGenerator*>::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<std::string> const& installScripts =
- m_Makefile->GetInstallScripts();
- for(std::vector<std::string>::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<std::string> &sf = l->second.GetSourceLists();
- std::vector<std::string>::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<std::string> &sf = l->second.GetSourceLists();
- std::vector<std::string>::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<cmLocalGenerator*>::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<std::string> 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<std::string> 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<std::string>::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<std::string> 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<std::string> &sf = l->second.GetSourceLists();
+ std::vector<std::string>::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<std::string> &sf = l->second.GetSourceLists();
+ std::vector<std::string>::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<std::string> const& configs,
- bool implib = false);
- void PrepareInstallReference(std::ostream& fout, cmTarget& target,
- std::vector<std::string> const& configs);
-
/** Get the include flags for the current makefile and language. */
void GetIncludeDirectories(std::vector<std::string>& 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<cmStdString> 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<std::string> 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 <stdlib.h> // required for atoi
@@ -125,6 +127,12 @@ unsigned int cmMakefile::GetCacheMinorVersion()
cmMakefile::~cmMakefile()
{
+ for(std::vector<cmInstallGenerator*>::iterator
+ i = m_InstallGenerators.begin();
+ i != m_InstallGenerators.end(); ++i)
+ {
+ delete *i;
+ }
for(std::vector<cmSourceFile*>::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<std::string> const& GetInstallScripts()
- { return m_InstallScripts; }
+ void AddInstallGenerator(cmInstallGenerator* g)
+ { m_InstallGenerators.push_back(g); }
+ std::vector<cmInstallGenerator*>& 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<std::string> m_InstallScripts;
+ std::vector<cmInstallGenerator*> 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 \