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:
parent
90c8ea1c03
commit
96f0266228
|
@ -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
|
||||
|
|
|
@ -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 = "";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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";
|
||||
}
|
|
@ -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
|
|
@ -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";
|
||||
}
|
|
@ -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
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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
|
|
@ -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 "
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Reference in New Issue