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.

This commit is contained in:
Brad King 2006-02-19 15:25:27 -05:00
parent 90c8ea1c03
commit 96f0266228
18 changed files with 974 additions and 407 deletions

View File

@ -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

View File

@ -16,8 +16,38 @@
=========================================================================*/
#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 = "";
}
}

View File

@ -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);
};

View File

@ -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";
}

View File

@ -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

View File

@ -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";
}

View File

@ -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

View File

@ -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;
}
}

View File

@ -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

View File

@ -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 "

View File

@ -15,13 +15,18 @@
=========================================================================*/
#include "cmLocalGenerator.h"
#include "cmGlobalGenerator.h"
#include "cmake.h"
#include "cmMakefile.h"
#include "cmGeneratedFileStream.h"
#include "cmSourceFile.h"
#include "cmGlobalGenerator.h"
#include "cmInstallGenerator.h"
#include "cmInstallScriptGenerator.h"
#include "cmInstallTargetGenerator.h"
#include "cmMakefile.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 += "/";
}
}
(*gi)->Generate(fout, config, configurationTypes);
}
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;
}
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,
@ -1632,78 +1382,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);
}
}
}

View File

@ -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;

View File

@ -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)
{

View File

@ -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;

View File

@ -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);

View File

@ -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.

View File

@ -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.

View File

@ -97,6 +97,9 @@ CMAKE_CXX_SOURCES="\
cmGlobalGenerator \
cmGlob \
cmLocalGenerator \
cmInstallGenerator \
cmInstallScriptGenerator \
cmInstallTargetGenerator \
cmSourceFile \
cmSystemTools \
cmFileTimeComparison \