Merge topic 'install-DESTINATION-genex'
f30022eb
install: Allow generator expressions in TARGETS DESTINATION (#14317)7607c3d1
cmInstallGenerator: Pass destination explicitly to AddInstallRuleebd556ca
cmInstallGenerator: Fix check for absolute install destinations290ca8e2
cmInstallGenerator: Refactor computation of absolute install destf99991db
cmInstallGenerator: Move GetDestination to subclasses that need it
This commit is contained in:
commit
fc7e15691a
|
@ -159,6 +159,10 @@ file itself, call ``install(EXPORT)``, documented below.
|
||||||
Installing a target with the :prop_tgt:`EXCLUDE_FROM_ALL` target property
|
Installing a target with the :prop_tgt:`EXCLUDE_FROM_ALL` target property
|
||||||
set to ``TRUE`` has undefined behavior.
|
set to ``TRUE`` has undefined behavior.
|
||||||
|
|
||||||
|
The install destination given to the target install ``DESTINATION`` may
|
||||||
|
use "generator expressions" with the syntax ``$<...>``. See the
|
||||||
|
:manual:`cmake-generator-expressions(7)` manual for available expressions.
|
||||||
|
|
||||||
Installing Files
|
Installing Files
|
||||||
^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
install-DESTINATION-genex
|
||||||
|
-------------------------
|
||||||
|
|
||||||
|
* The :command:`install(TARGETS)` command learned to support
|
||||||
|
generator expressions in the ``DESTINATION`` value.
|
|
@ -73,8 +73,8 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os)
|
||||||
// to reference if they are relative to the install prefix.
|
// to reference if they are relative to the install prefix.
|
||||||
std::string installPrefix =
|
std::string installPrefix =
|
||||||
this->IEGen->GetMakefile()->GetSafeDefinition("CMAKE_INSTALL_PREFIX");
|
this->IEGen->GetMakefile()->GetSafeDefinition("CMAKE_INSTALL_PREFIX");
|
||||||
const char* installDest = this->IEGen->GetDestination();
|
std::string const& expDest = this->IEGen->GetDestination();
|
||||||
if(cmSystemTools::FileIsFullPath(installDest))
|
if(cmSystemTools::FileIsFullPath(expDest))
|
||||||
{
|
{
|
||||||
// The export file is being installed to an absolute path so the
|
// The export file is being installed to an absolute path so the
|
||||||
// package is not relocatable. Use the configured install prefix.
|
// package is not relocatable. Use the configured install prefix.
|
||||||
|
@ -87,7 +87,7 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os)
|
||||||
{
|
{
|
||||||
// Add code to compute the installation prefix relative to the
|
// Add code to compute the installation prefix relative to the
|
||||||
// import file location.
|
// import file location.
|
||||||
std::string absDest = installPrefix + "/" + installDest;
|
std::string absDest = installPrefix + "/" + expDest;
|
||||||
std::string absDestS = absDest + "/";
|
std::string absDestS = absDest + "/";
|
||||||
os << "# Compute the installation prefix relative to this file.\n"
|
os << "# Compute the installation prefix relative to this file.\n"
|
||||||
<< "get_filename_component(_IMPORT_PREFIX"
|
<< "get_filename_component(_IMPORT_PREFIX"
|
||||||
|
@ -109,7 +109,7 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os)
|
||||||
"unset(_realOrig)\n"
|
"unset(_realOrig)\n"
|
||||||
"unset(_realCurr)\n";
|
"unset(_realCurr)\n";
|
||||||
}
|
}
|
||||||
std::string dest = installDest;
|
std::string dest = expDest;
|
||||||
while(!dest.empty())
|
while(!dest.empty())
|
||||||
{
|
{
|
||||||
os <<
|
os <<
|
||||||
|
@ -398,7 +398,7 @@ cmExportInstallFileGenerator
|
||||||
cmTarget* target = itgen->GetTarget();
|
cmTarget* target = itgen->GetTarget();
|
||||||
|
|
||||||
// Construct the installed location of the target.
|
// Construct the installed location of the target.
|
||||||
std::string dest = itgen->GetDestination();
|
std::string dest = itgen->GetDestination(config);
|
||||||
std::string value;
|
std::string value;
|
||||||
if(!cmSystemTools::FileIsFullPath(dest.c_str()))
|
if(!cmSystemTools::FileIsFullPath(dest.c_str()))
|
||||||
{
|
{
|
||||||
|
|
|
@ -44,7 +44,9 @@ cmInstallDirectoryGenerator::GenerateScriptActions(std::ostream& os,
|
||||||
{
|
{
|
||||||
// Write code to install the directories.
|
// Write code to install the directories.
|
||||||
const char* no_rename = 0;
|
const char* no_rename = 0;
|
||||||
this->AddInstallRule(os, cmInstallType_DIRECTORY,
|
this->AddInstallRule(os,
|
||||||
|
this->Destination,
|
||||||
|
cmInstallType_DIRECTORY,
|
||||||
this->Directories,
|
this->Directories,
|
||||||
this->Optional,
|
this->Optional,
|
||||||
this->FilePermissions.c_str(),
|
this->FilePermissions.c_str(),
|
||||||
|
|
|
@ -185,7 +185,8 @@ cmInstallExportGenerator::GenerateScriptConfigs(std::ostream& os,
|
||||||
files.push_back(i->second);
|
files.push_back(i->second);
|
||||||
std::string config_test = this->CreateConfigTest(i->first);
|
std::string config_test = this->CreateConfigTest(i->first);
|
||||||
os << indent << "if(" << config_test << ")\n";
|
os << indent << "if(" << config_test << ")\n";
|
||||||
this->AddInstallRule(os, cmInstallType_FILES, files, false,
|
this->AddInstallRule(os, this->Destination,
|
||||||
|
cmInstallType_FILES, files, false,
|
||||||
this->FilePermissions.c_str(), 0, 0, 0,
|
this->FilePermissions.c_str(), 0, 0, 0,
|
||||||
indent.Next());
|
indent.Next());
|
||||||
os << indent << "endif()\n";
|
os << indent << "endif()\n";
|
||||||
|
@ -199,7 +200,7 @@ void cmInstallExportGenerator::GenerateScriptActions(std::ostream& os,
|
||||||
{
|
{
|
||||||
// Remove old per-configuration export files if the main changes.
|
// Remove old per-configuration export files if the main changes.
|
||||||
std::string installedDir = "$ENV{DESTDIR}";
|
std::string installedDir = "$ENV{DESTDIR}";
|
||||||
installedDir += this->GetInstallDestination();
|
installedDir += this->ConvertToAbsoluteDestination(this->Destination);
|
||||||
installedDir += "/";
|
installedDir += "/";
|
||||||
std::string installedFile = installedDir;
|
std::string installedFile = installedDir;
|
||||||
installedFile += this->FileName;
|
installedFile += this->FileName;
|
||||||
|
@ -224,6 +225,7 @@ void cmInstallExportGenerator::GenerateScriptActions(std::ostream& os,
|
||||||
// Install the main export file.
|
// Install the main export file.
|
||||||
std::vector<std::string> files;
|
std::vector<std::string> files;
|
||||||
files.push_back(this->MainImportFile);
|
files.push_back(this->MainImportFile);
|
||||||
this->AddInstallRule(os, cmInstallType_FILES, files, false,
|
this->AddInstallRule(os, this->Destination,
|
||||||
|
cmInstallType_FILES, files, false,
|
||||||
this->FilePermissions.c_str(), 0, 0, 0, indent);
|
this->FilePermissions.c_str(), 0, 0, 0, indent);
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,6 +41,9 @@ public:
|
||||||
|
|
||||||
const std::string& GetNamespace() const { return this->Namespace; }
|
const std::string& GetNamespace() const { return this->Namespace; }
|
||||||
|
|
||||||
|
std::string const& GetDestination() const
|
||||||
|
{ return this->Destination; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void GenerateScript(std::ostream& os);
|
virtual void GenerateScript(std::ostream& os);
|
||||||
virtual void GenerateScriptConfigs(std::ostream& os, Indent const& indent);
|
virtual void GenerateScriptConfigs(std::ostream& os, Indent const& indent);
|
||||||
|
|
|
@ -57,6 +57,7 @@ void cmInstallFilesGenerator::AddFilesInstallRule(
|
||||||
// Write code to install the files.
|
// Write code to install the files.
|
||||||
const char* no_dir_permissions = 0;
|
const char* no_dir_permissions = 0;
|
||||||
this->AddInstallRule(os,
|
this->AddInstallRule(os,
|
||||||
|
this->Destination,
|
||||||
(this->Programs
|
(this->Programs
|
||||||
? cmInstallType_PROGRAMS
|
? cmInstallType_PROGRAMS
|
||||||
: cmInstallType_FILES),
|
: cmInstallType_FILES),
|
||||||
|
|
|
@ -37,6 +37,7 @@ cmInstallGenerator
|
||||||
void cmInstallGenerator
|
void cmInstallGenerator
|
||||||
::AddInstallRule(
|
::AddInstallRule(
|
||||||
std::ostream& os,
|
std::ostream& os,
|
||||||
|
std::string const& dest,
|
||||||
cmInstallType type,
|
cmInstallType type,
|
||||||
std::vector<std::string> const& files,
|
std::vector<std::string> const& files,
|
||||||
bool optional /* = false */,
|
bool optional /* = false */,
|
||||||
|
@ -60,7 +61,6 @@ void cmInstallGenerator
|
||||||
case cmInstallType_FILES: stype = "FILE"; break;
|
case cmInstallType_FILES: stype = "FILE"; break;
|
||||||
}
|
}
|
||||||
os << indent;
|
os << indent;
|
||||||
std::string dest = this->GetInstallDestination();
|
|
||||||
if (cmSystemTools::FileIsFullPath(dest.c_str()))
|
if (cmSystemTools::FileIsFullPath(dest.c_str()))
|
||||||
{
|
{
|
||||||
os << "list(APPEND CMAKE_ABSOLUTE_DESTINATION_FILES\n";
|
os << "list(APPEND CMAKE_ABSOLUTE_DESTINATION_FILES\n";
|
||||||
|
@ -94,7 +94,8 @@ void cmInstallGenerator
|
||||||
<< "${CMAKE_ABSOLUTE_DESTINATION_FILES}\")\n";
|
<< "${CMAKE_ABSOLUTE_DESTINATION_FILES}\")\n";
|
||||||
os << indent << "endif()\n";
|
os << indent << "endif()\n";
|
||||||
}
|
}
|
||||||
os << "file(INSTALL DESTINATION \"" << dest << "\" TYPE " << stype;
|
std::string absDest = this->ConvertToAbsoluteDestination(dest);
|
||||||
|
os << "file(INSTALL DESTINATION \"" << absDest << "\" TYPE " << stype;
|
||||||
if(optional)
|
if(optional)
|
||||||
{
|
{
|
||||||
os << " OPTIONAL";
|
os << " OPTIONAL";
|
||||||
|
@ -179,15 +180,16 @@ bool cmInstallGenerator::InstallsForConfig(const std::string& config)
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
std::string cmInstallGenerator::GetInstallDestination() const
|
std::string
|
||||||
|
cmInstallGenerator::ConvertToAbsoluteDestination(std::string const& dest) const
|
||||||
{
|
{
|
||||||
std::string result;
|
std::string result;
|
||||||
if(!this->Destination.empty() &&
|
if(!dest.empty() &&
|
||||||
!cmSystemTools::FileIsFullPath(this->Destination.c_str()))
|
!cmSystemTools::FileIsFullPath(dest.c_str()))
|
||||||
{
|
{
|
||||||
result = "${CMAKE_INSTALL_PREFIX}/";
|
result = "${CMAKE_INSTALL_PREFIX}/";
|
||||||
}
|
}
|
||||||
result += this->Destination;
|
result += dest;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,9 @@ public:
|
||||||
virtual ~cmInstallGenerator();
|
virtual ~cmInstallGenerator();
|
||||||
|
|
||||||
void AddInstallRule(
|
void AddInstallRule(
|
||||||
std::ostream& os, cmInstallType type,
|
std::ostream& os,
|
||||||
|
std::string const& dest,
|
||||||
|
cmInstallType type,
|
||||||
std::vector<std::string> const& files,
|
std::vector<std::string> const& files,
|
||||||
bool optional = false,
|
bool optional = false,
|
||||||
const char* permissions_file = 0,
|
const char* permissions_file = 0,
|
||||||
|
@ -50,12 +52,9 @@ public:
|
||||||
Indent const& indent = Indent()
|
Indent const& indent = Indent()
|
||||||
);
|
);
|
||||||
|
|
||||||
const char* GetDestination() const
|
|
||||||
{ return this->Destination.c_str(); }
|
|
||||||
|
|
||||||
/** Get the install destination as it should appear in the
|
/** Get the install destination as it should appear in the
|
||||||
installation script. */
|
installation script. */
|
||||||
std::string GetInstallDestination() const;
|
std::string ConvertToAbsoluteDestination(std::string const& dest) const;
|
||||||
|
|
||||||
/** Test if this generator installs something for a given configuration. */
|
/** Test if this generator installs something for a given configuration. */
|
||||||
bool InstallsForConfig(const std::string& config);
|
bool InstallsForConfig(const std::string& config);
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#include "cmInstallTargetGenerator.h"
|
#include "cmInstallTargetGenerator.h"
|
||||||
|
|
||||||
#include "cmComputeLinkInformation.h"
|
#include "cmComputeLinkInformation.h"
|
||||||
|
#include "cmGeneratorExpression.h"
|
||||||
#include "cmGlobalGenerator.h"
|
#include "cmGlobalGenerator.h"
|
||||||
#include "cmLocalGenerator.h"
|
#include "cmLocalGenerator.h"
|
||||||
#include "cmMakefile.h"
|
#include "cmMakefile.h"
|
||||||
|
@ -77,7 +78,8 @@ void cmInstallTargetGenerator::GenerateScriptForConfig(std::ostream& os,
|
||||||
fromDirConfig = this->Target->GetDirectory(config, this->ImportLibrary);
|
fromDirConfig = this->Target->GetDirectory(config, this->ImportLibrary);
|
||||||
fromDirConfig += "/";
|
fromDirConfig += "/";
|
||||||
}
|
}
|
||||||
std::string toDir = this->GetInstallDestination();
|
std::string toDir =
|
||||||
|
this->ConvertToAbsoluteDestination(this->GetDestination(config));
|
||||||
toDir += "/";
|
toDir += "/";
|
||||||
|
|
||||||
// Compute the list of files to install for this target.
|
// Compute the list of files to install for this target.
|
||||||
|
@ -322,8 +324,8 @@ void cmInstallTargetGenerator::GenerateScriptForConfig(std::ostream& os,
|
||||||
const char* no_dir_permissions = 0;
|
const char* no_dir_permissions = 0;
|
||||||
const char* no_rename = 0;
|
const char* no_rename = 0;
|
||||||
bool optional = this->Optional || this->ImportLibrary;
|
bool optional = this->Optional || this->ImportLibrary;
|
||||||
this->AddInstallRule(os, type, filesFrom,
|
this->AddInstallRule(os, this->GetDestination(config),
|
||||||
optional,
|
type, filesFrom, optional,
|
||||||
this->FilePermissions.c_str(), no_dir_permissions,
|
this->FilePermissions.c_str(), no_dir_permissions,
|
||||||
no_rename, literal_args.c_str(),
|
no_rename, literal_args.c_str(),
|
||||||
indent);
|
indent);
|
||||||
|
@ -333,6 +335,15 @@ void cmInstallTargetGenerator::GenerateScriptForConfig(std::ostream& os,
|
||||||
&cmInstallTargetGenerator::PostReplacementTweaks);
|
&cmInstallTargetGenerator::PostReplacementTweaks);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
std::string
|
||||||
|
cmInstallTargetGenerator::GetDestination(std::string const& config) const
|
||||||
|
{
|
||||||
|
cmGeneratorExpression ge;
|
||||||
|
return ge.Parse(this->Destination)
|
||||||
|
->Evaluate(this->Target->GetMakefile(), config);
|
||||||
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
std::string
|
std::string
|
||||||
cmInstallTargetGenerator::GetInstallFilename(const std::string& config) const
|
cmInstallTargetGenerator::GetInstallFilename(const std::string& config) const
|
||||||
|
|
|
@ -60,6 +60,8 @@ public:
|
||||||
cmTarget* GetTarget() const { return this->Target; }
|
cmTarget* GetTarget() const { return this->Target; }
|
||||||
bool IsImportLibrary() const { return this->ImportLibrary; }
|
bool IsImportLibrary() const { return this->ImportLibrary; }
|
||||||
|
|
||||||
|
std::string GetDestination(std::string const& config) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void GenerateScript(std::ostream& os);
|
virtual void GenerateScript(std::ostream& os);
|
||||||
virtual void GenerateScriptForConfig(std::ostream& os,
|
virtual void GenerateScriptForConfig(std::ostream& os,
|
||||||
|
|
|
@ -68,6 +68,11 @@ add_library(testLib5 SHARED testLib5.c)
|
||||||
|
|
||||||
add_library(testLib6 STATIC testLib6.cxx testLib6c.c)
|
add_library(testLib6 STATIC testLib6.cxx testLib6c.c)
|
||||||
|
|
||||||
|
add_library(testLibPerConfigDest STATIC testLibPerConfigDest.c)
|
||||||
|
install(TARGETS testLibPerConfigDest EXPORT exp
|
||||||
|
DESTINATION lib/$<$<BOOL:$<CONFIG>>:$<CONFIG>>$<$<NOT:$<BOOL:$<CONFIG>>>:NoConfig>
|
||||||
|
)
|
||||||
|
|
||||||
# Work-around: Visual Studio 6 does not support per-target object files.
|
# Work-around: Visual Studio 6 does not support per-target object files.
|
||||||
set(VS6)
|
set(VS6)
|
||||||
if("${CMAKE_GENERATOR}" MATCHES "Visual Studio 6")
|
if("${CMAKE_GENERATOR}" MATCHES "Visual Studio 6")
|
||||||
|
@ -446,9 +451,9 @@ install(
|
||||||
cmp0022NEW cmp0022OLD
|
cmp0022NEW cmp0022OLD
|
||||||
systemlib
|
systemlib
|
||||||
EXPORT exp
|
EXPORT exp
|
||||||
RUNTIME DESTINATION bin
|
RUNTIME DESTINATION $<1:bin>
|
||||||
LIBRARY DESTINATION lib NAMELINK_SKIP
|
LIBRARY DESTINATION $<1:lib> NAMELINK_SKIP
|
||||||
ARCHIVE DESTINATION lib
|
ARCHIVE DESTINATION $<1:lib>
|
||||||
FRAMEWORK DESTINATION Frameworks
|
FRAMEWORK DESTINATION Frameworks
|
||||||
BUNDLE DESTINATION Applications
|
BUNDLE DESTINATION Applications
|
||||||
)
|
)
|
||||||
|
@ -503,6 +508,7 @@ export(TARGETS testExe1 testLib1 testLib2 testLib3
|
||||||
export(TARGETS testExe2 testLib4 testLib5 testLib6 testExe3 testExe2lib
|
export(TARGETS testExe2 testLib4 testLib5 testLib6 testExe3 testExe2lib
|
||||||
testLib4lib testLib4libdbg testLib4libopt
|
testLib4lib testLib4libdbg testLib4libopt
|
||||||
testLibCycleA testLibCycleB
|
testLibCycleA testLibCycleB
|
||||||
|
testLibPerConfigDest
|
||||||
NAMESPACE bld_
|
NAMESPACE bld_
|
||||||
APPEND FILE ExportBuildTree.cmake
|
APPEND FILE ExportBuildTree.cmake
|
||||||
)
|
)
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
int testLibPerConfigDest(void) { return 0; }
|
|
@ -34,6 +34,7 @@ target_link_libraries(imp_testExe1
|
||||||
exp_testLib5
|
exp_testLib5
|
||||||
exp_testLib6
|
exp_testLib6
|
||||||
exp_testLibCycleA
|
exp_testLibCycleA
|
||||||
|
exp_testLibPerConfigDest
|
||||||
)
|
)
|
||||||
|
|
||||||
# Try building a plugin to an executable imported from the install tree.
|
# Try building a plugin to an executable imported from the install tree.
|
||||||
|
@ -66,6 +67,7 @@ target_link_libraries(imp_testExe1b
|
||||||
bld_testLib5
|
bld_testLib5
|
||||||
bld_testLib6
|
bld_testLib6
|
||||||
bld_testLibCycleA
|
bld_testLibCycleA
|
||||||
|
bld_testLibPerConfigDest
|
||||||
)
|
)
|
||||||
|
|
||||||
add_custom_target(check_testLib1_genex ALL
|
add_custom_target(check_testLib1_genex ALL
|
||||||
|
|
|
@ -7,6 +7,7 @@ extern int testLib4lib();
|
||||||
extern int testLib5();
|
extern int testLib5();
|
||||||
extern int testLib6();
|
extern int testLib6();
|
||||||
extern int testLibCycleA1();
|
extern int testLibCycleA1();
|
||||||
|
extern int testLibPerConfigDest();
|
||||||
|
|
||||||
/* Switch a symbol between debug and optimized builds to make sure the
|
/* Switch a symbol between debug and optimized builds to make sure the
|
||||||
proper library is found from the testLib4 link interface. */
|
proper library is found from the testLib4 link interface. */
|
||||||
|
@ -21,5 +22,6 @@ int main()
|
||||||
{
|
{
|
||||||
return (testLib2() + generated_by_testExe1() + testLib3() + testLib4()
|
return (testLib2() + generated_by_testExe1() + testLib3() + testLib4()
|
||||||
+ testLib5() + testLib6() + testLibCycleA1()
|
+ testLib5() + testLib6() + testLibCycleA1()
|
||||||
|
+ testLibPerConfigDest()
|
||||||
+ generated_by_testExe3() + testLib4lib() + testLib4libcfg());
|
+ generated_by_testExe3() + testLib4lib() + testLib4libcfg());
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,3 +6,4 @@ run_cmake(DIRECTORY-message-lazy)
|
||||||
run_cmake(SkipInstallRulesWarning)
|
run_cmake(SkipInstallRulesWarning)
|
||||||
run_cmake(SkipInstallRulesNoWarning1)
|
run_cmake(SkipInstallRulesNoWarning1)
|
||||||
run_cmake(SkipInstallRulesNoWarning2)
|
run_cmake(SkipInstallRulesNoWarning2)
|
||||||
|
run_cmake(TARGETS-DESTINATION-bad)
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
1
|
|
@ -0,0 +1,6 @@
|
||||||
|
CMake Error:
|
||||||
|
Error evaluating generator expression:
|
||||||
|
|
||||||
|
\$<NOTAGENEX>
|
||||||
|
|
||||||
|
Expression did not evaluate to a known generator expression
|
|
@ -0,0 +1,3 @@
|
||||||
|
enable_language(C)
|
||||||
|
add_library(empty empty.c)
|
||||||
|
install(TARGETS empty DESTINATION $<NOTAGENEX>)
|
Loading…
Reference in New Issue