Merge topic 'install-interface-includes'
650e61f Add a convenient way to add the includes install dir to the INTERFACE.
This commit is contained in:
commit
c82b1cbe83
@ -277,27 +277,31 @@ static bool checkInterfaceDirs(const std::string &prepro,
|
|||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
void cmExportFileGenerator::PopulateIncludeDirectoriesInterface(
|
void cmExportFileGenerator::PopulateIncludeDirectoriesInterface(
|
||||||
cmTarget *target,
|
cmTargetExport *tei,
|
||||||
cmGeneratorExpression::PreprocessContext preprocessRule,
|
cmGeneratorExpression::PreprocessContext preprocessRule,
|
||||||
ImportPropertyMap &properties,
|
ImportPropertyMap &properties,
|
||||||
std::vector<std::string> &missingTargets)
|
std::vector<std::string> &missingTargets)
|
||||||
{
|
{
|
||||||
|
cmTarget *target = tei->Target;
|
||||||
assert(preprocessRule == cmGeneratorExpression::InstallInterface);
|
assert(preprocessRule == cmGeneratorExpression::InstallInterface);
|
||||||
|
|
||||||
const char *propName = "INTERFACE_INCLUDE_DIRECTORIES";
|
const char *propName = "INTERFACE_INCLUDE_DIRECTORIES";
|
||||||
const char *input = target->GetProperty(propName);
|
const char *input = target->GetProperty(propName);
|
||||||
if (!input)
|
if (!input && tei->InterfaceIncludeDirectories.empty())
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!*input)
|
if (!*input && tei->InterfaceIncludeDirectories.empty())
|
||||||
{
|
{
|
||||||
// Set to empty
|
// Set to empty
|
||||||
properties[propName] = "";
|
properties[propName] = "";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string prepro = cmGeneratorExpression::Preprocess(input,
|
std::string includes = (input?input:"");
|
||||||
|
const char* sep = input ? ";" : "";
|
||||||
|
includes += sep + tei->InterfaceIncludeDirectories;
|
||||||
|
std::string prepro = cmGeneratorExpression::Preprocess(includes,
|
||||||
preprocessRule);
|
preprocessRule);
|
||||||
if (!prepro.empty())
|
if (!prepro.empty())
|
||||||
{
|
{
|
||||||
|
@ -15,6 +15,8 @@
|
|||||||
#include "cmCommand.h"
|
#include "cmCommand.h"
|
||||||
#include "cmGeneratorExpression.h"
|
#include "cmGeneratorExpression.h"
|
||||||
|
|
||||||
|
class cmTargetExport;
|
||||||
|
|
||||||
/** \class cmExportFileGenerator
|
/** \class cmExportFileGenerator
|
||||||
* \brief Generate a file exporting targets from a build or install tree.
|
* \brief Generate a file exporting targets from a build or install tree.
|
||||||
*
|
*
|
||||||
@ -114,7 +116,7 @@ protected:
|
|||||||
void GenerateInterfaceProperties(cmTarget *target, std::ostream& os,
|
void GenerateInterfaceProperties(cmTarget *target, std::ostream& os,
|
||||||
const ImportPropertyMap &properties);
|
const ImportPropertyMap &properties);
|
||||||
void PopulateIncludeDirectoriesInterface(
|
void PopulateIncludeDirectoriesInterface(
|
||||||
cmTarget *target,
|
cmTargetExport *target,
|
||||||
cmGeneratorExpression::PreprocessContext preprocessRule,
|
cmGeneratorExpression::PreprocessContext preprocessRule,
|
||||||
ImportPropertyMap &properties,
|
ImportPropertyMap &properties,
|
||||||
std::vector<std::string> &missingTargets);
|
std::vector<std::string> &missingTargets);
|
||||||
|
@ -39,7 +39,7 @@ std::string cmExportInstallFileGenerator::GetConfigImportFileGlob()
|
|||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os)
|
bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os)
|
||||||
{
|
{
|
||||||
std::vector<cmTarget*> allTargets;
|
std::vector<cmTargetExport*> allTargets;
|
||||||
{
|
{
|
||||||
std::string expectedTargets;
|
std::string expectedTargets;
|
||||||
std::string sep;
|
std::string sep;
|
||||||
@ -49,10 +49,10 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os)
|
|||||||
{
|
{
|
||||||
expectedTargets += sep + this->Namespace + (*tei)->Target->GetExportName();
|
expectedTargets += sep + this->Namespace + (*tei)->Target->GetExportName();
|
||||||
sep = " ";
|
sep = " ";
|
||||||
cmTargetExport const* te = *tei;
|
cmTargetExport * te = *tei;
|
||||||
if(this->ExportedTargets.insert(te->Target).second)
|
if(this->ExportedTargets.insert(te->Target).second)
|
||||||
{
|
{
|
||||||
allTargets.push_back(te->Target);
|
allTargets.push_back(te);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -115,16 +115,16 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os)
|
|||||||
|
|
||||||
bool require2_8_12 = false;
|
bool require2_8_12 = false;
|
||||||
// Create all the imported targets.
|
// Create all the imported targets.
|
||||||
for(std::vector<cmTarget*>::const_iterator
|
for(std::vector<cmTargetExport*>::const_iterator
|
||||||
tei = allTargets.begin();
|
tei = allTargets.begin();
|
||||||
tei != allTargets.end(); ++tei)
|
tei != allTargets.end(); ++tei)
|
||||||
{
|
{
|
||||||
cmTarget* te = *tei;
|
cmTarget* te = (*tei)->Target;
|
||||||
this->GenerateImportTargetCode(os, te);
|
this->GenerateImportTargetCode(os, te);
|
||||||
|
|
||||||
ImportPropertyMap properties;
|
ImportPropertyMap properties;
|
||||||
|
|
||||||
this->PopulateIncludeDirectoriesInterface(te,
|
this->PopulateIncludeDirectoriesInterface(*tei,
|
||||||
cmGeneratorExpression::InstallInterface,
|
cmGeneratorExpression::InstallInterface,
|
||||||
properties, missingTargets);
|
properties, missingTargets);
|
||||||
this->PopulateInterfaceProperty("INTERFACE_SYSTEM_INCLUDE_DIRECTORIES",
|
this->PopulateInterfaceProperty("INTERFACE_SYSTEM_INCLUDE_DIRECTORIES",
|
||||||
|
@ -219,6 +219,7 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
|
|||||||
cmCAStringVector runtimeArgVector (&argHelper,"RUNTIME",&group);
|
cmCAStringVector runtimeArgVector (&argHelper,"RUNTIME",&group);
|
||||||
cmCAStringVector frameworkArgVector (&argHelper,"FRAMEWORK",&group);
|
cmCAStringVector frameworkArgVector (&argHelper,"FRAMEWORK",&group);
|
||||||
cmCAStringVector bundleArgVector (&argHelper,"BUNDLE",&group);
|
cmCAStringVector bundleArgVector (&argHelper,"BUNDLE",&group);
|
||||||
|
cmCAStringVector includesArgVector (&argHelper,"INCLUDES",&group);
|
||||||
cmCAStringVector privateHeaderArgVector(&argHelper,"PRIVATE_HEADER",&group);
|
cmCAStringVector privateHeaderArgVector(&argHelper,"PRIVATE_HEADER",&group);
|
||||||
cmCAStringVector publicHeaderArgVector (&argHelper,"PUBLIC_HEADER",&group);
|
cmCAStringVector publicHeaderArgVector (&argHelper,"PUBLIC_HEADER",&group);
|
||||||
cmCAStringVector resourceArgVector (&argHelper,"RESOURCE",&group);
|
cmCAStringVector resourceArgVector (&argHelper,"RESOURCE",&group);
|
||||||
@ -247,6 +248,7 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
|
|||||||
cmInstallCommandArguments privateHeaderArgs(this->DefaultComponentName);
|
cmInstallCommandArguments privateHeaderArgs(this->DefaultComponentName);
|
||||||
cmInstallCommandArguments publicHeaderArgs(this->DefaultComponentName);
|
cmInstallCommandArguments publicHeaderArgs(this->DefaultComponentName);
|
||||||
cmInstallCommandArguments resourceArgs(this->DefaultComponentName);
|
cmInstallCommandArguments resourceArgs(this->DefaultComponentName);
|
||||||
|
cmInstallCommandIncludesArgument includesArgs;
|
||||||
|
|
||||||
// now parse the args for specific parts of the target (e.g. LIBRARY,
|
// now parse the args for specific parts of the target (e.g. LIBRARY,
|
||||||
// RUNTIME, ARCHIVE etc.
|
// RUNTIME, ARCHIVE etc.
|
||||||
@ -258,6 +260,7 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
|
|||||||
privateHeaderArgs.Parse(&privateHeaderArgVector.GetVector(), &unknownArgs);
|
privateHeaderArgs.Parse(&privateHeaderArgVector.GetVector(), &unknownArgs);
|
||||||
publicHeaderArgs.Parse (&publicHeaderArgVector.GetVector(), &unknownArgs);
|
publicHeaderArgs.Parse (&publicHeaderArgVector.GetVector(), &unknownArgs);
|
||||||
resourceArgs.Parse (&resourceArgVector.GetVector(), &unknownArgs);
|
resourceArgs.Parse (&resourceArgVector.GetVector(), &unknownArgs);
|
||||||
|
includesArgs.Parse (&includesArgVector.GetVector(), &unknownArgs);
|
||||||
|
|
||||||
if(!unknownArgs.empty())
|
if(!unknownArgs.empty())
|
||||||
{
|
{
|
||||||
@ -292,6 +295,13 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(!includesArgs.GetIncludeDirs().empty() && exports.GetString().empty())
|
||||||
|
{
|
||||||
|
this->SetError("TARGETS given INCLUDES DESTINATION, but EXPORT set "
|
||||||
|
"not specified.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Enforce argument rules too complex to specify for the
|
// Enforce argument rules too complex to specify for the
|
||||||
// general-purpose parser.
|
// general-purpose parser.
|
||||||
if(archiveArgs.GetNamelinkOnly() ||
|
if(archiveArgs.GetNamelinkOnly() ||
|
||||||
@ -747,6 +757,20 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
|
|||||||
te->RuntimeGenerator = runtimeGenerator;
|
te->RuntimeGenerator = runtimeGenerator;
|
||||||
this->Makefile->GetLocalGenerator()->GetGlobalGenerator()
|
this->Makefile->GetLocalGenerator()->GetGlobalGenerator()
|
||||||
->GetExportSets()[exports.GetString()]->AddTargetExport(te);
|
->GetExportSets()[exports.GetString()]->AddTargetExport(te);
|
||||||
|
|
||||||
|
std::vector<std::string> dirs = includesArgs.GetIncludeDirs();
|
||||||
|
if(!dirs.empty())
|
||||||
|
{
|
||||||
|
std::string dirString;
|
||||||
|
const char *sep = "";
|
||||||
|
for (std::vector<std::string>::const_iterator it = dirs.begin();
|
||||||
|
it != dirs.end(); ++it)
|
||||||
|
{
|
||||||
|
te->InterfaceIncludeDirectories += sep;
|
||||||
|
te->InterfaceIncludeDirectories += *it;
|
||||||
|
sep = ";";
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,6 +102,7 @@ public:
|
|||||||
" [[ARCHIVE|LIBRARY|RUNTIME|FRAMEWORK|BUNDLE|\n"
|
" [[ARCHIVE|LIBRARY|RUNTIME|FRAMEWORK|BUNDLE|\n"
|
||||||
" PRIVATE_HEADER|PUBLIC_HEADER|RESOURCE]\n"
|
" PRIVATE_HEADER|PUBLIC_HEADER|RESOURCE]\n"
|
||||||
" [DESTINATION <dir>]\n"
|
" [DESTINATION <dir>]\n"
|
||||||
|
" [INCLUDES DESTINATION [<dir> ...]]\n"
|
||||||
" [PERMISSIONS permissions...]\n"
|
" [PERMISSIONS permissions...]\n"
|
||||||
" [CONFIGURATIONS [Debug|Release|...]]\n"
|
" [CONFIGURATIONS [Debug|Release|...]]\n"
|
||||||
" [COMPONENT <component>]\n"
|
" [COMPONENT <component>]\n"
|
||||||
@ -130,6 +131,10 @@ public:
|
|||||||
"all target types. If only one is given then only targets of that "
|
"all 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 "
|
"type will be installed (which can be used to install just a DLL or "
|
||||||
"just an import library)."
|
"just an import library)."
|
||||||
|
"The INCLUDES DESTINATION specifies a list of directories which will "
|
||||||
|
"be added to the INTERFACE_INCLUDE_DIRECTORIES of the <targets> when "
|
||||||
|
"exported by install(EXPORT). If a relative path is specified, it is "
|
||||||
|
"treated as relative to the $<INSTALL_PREFIX>."
|
||||||
"\n"
|
"\n"
|
||||||
"The PRIVATE_HEADER, PUBLIC_HEADER, and RESOURCE arguments cause "
|
"The PRIVATE_HEADER, PUBLIC_HEADER, and RESOURCE arguments cause "
|
||||||
"subsequent properties to be applied to installing a FRAMEWORK "
|
"subsequent properties to be applied to installing a FRAMEWORK "
|
||||||
|
@ -203,3 +203,37 @@ bool cmInstallCommandArguments::CheckPermissions(
|
|||||||
// This is not a valid permission.
|
// This is not a valid permission.
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cmInstallCommandIncludesArgument::cmInstallCommandIncludesArgument()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::vector<std::string>&
|
||||||
|
cmInstallCommandIncludesArgument::GetIncludeDirs() const
|
||||||
|
{
|
||||||
|
return this->IncludeDirs;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cmInstallCommandIncludesArgument::Parse(
|
||||||
|
const std::vector<std::string>* args,
|
||||||
|
std::vector<std::string>*)
|
||||||
|
{
|
||||||
|
if(args->empty())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
std::vector<std::string>::const_iterator it = args->begin();
|
||||||
|
++it;
|
||||||
|
for ( ; it != args->end(); ++it)
|
||||||
|
{
|
||||||
|
std::string dir = *it;
|
||||||
|
if (!cmSystemTools::FileIsFullPath(it->c_str())
|
||||||
|
&& cmGeneratorExpression::Find(*it) == std::string::npos)
|
||||||
|
{
|
||||||
|
dir = "$<INSTALL_PREFIX>/" + dir;
|
||||||
|
}
|
||||||
|
cmSystemTools::ConvertToUnixSlashes(dir);
|
||||||
|
this->IncludeDirs.push_back(dir);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -65,4 +65,17 @@ class cmInstallCommandArguments
|
|||||||
bool CheckPermissions();
|
bool CheckPermissions();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class cmInstallCommandIncludesArgument
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
cmInstallCommandIncludesArgument();
|
||||||
|
void Parse(const std::vector<std::string>* args,
|
||||||
|
std::vector<std::string>* unconsumedArgs);
|
||||||
|
|
||||||
|
const std::vector<std::string>& GetIncludeDirs() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::vector<std::string> IncludeDirs;
|
||||||
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -12,6 +12,8 @@
|
|||||||
#ifndef cmTargetExport_h
|
#ifndef cmTargetExport_h
|
||||||
#define cmTargetExport_h
|
#define cmTargetExport_h
|
||||||
|
|
||||||
|
#include "cmStandardIncludes.h"
|
||||||
|
|
||||||
class cmTarget;
|
class cmTarget;
|
||||||
class cmInstallTargetGenerator;
|
class cmInstallTargetGenerator;
|
||||||
class cmInstallFilesGenerator;
|
class cmInstallFilesGenerator;
|
||||||
@ -33,6 +35,7 @@ public:
|
|||||||
cmInstallTargetGenerator* FrameworkGenerator;
|
cmInstallTargetGenerator* FrameworkGenerator;
|
||||||
cmInstallTargetGenerator* BundleGenerator;
|
cmInstallTargetGenerator* BundleGenerator;
|
||||||
cmInstallFilesGenerator* HeaderGenerator;
|
cmInstallFilesGenerator* HeaderGenerator;
|
||||||
|
std::string InterfaceIncludeDirectories;
|
||||||
///@}
|
///@}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -271,9 +271,26 @@ install(TARGETS testLibRequired
|
|||||||
testLibIncludeRequired5
|
testLibIncludeRequired5
|
||||||
testLibIncludeRequired6
|
testLibIncludeRequired6
|
||||||
testSharedLibRequired
|
testSharedLibRequired
|
||||||
EXPORT RequiredExp DESTINATION lib )
|
EXPORT RequiredExp DESTINATION lib
|
||||||
|
INCLUDES DESTINATION
|
||||||
|
installIncludesTest
|
||||||
|
$<INSTALL_PREFIX>/installIncludesTest2)
|
||||||
install(EXPORT RequiredExp NAMESPACE Req:: FILE testLibRequiredTargets.cmake DESTINATION lib/cmake/testLibRequired)
|
install(EXPORT RequiredExp NAMESPACE Req:: FILE testLibRequiredTargets.cmake DESTINATION lib/cmake/testLibRequired)
|
||||||
|
|
||||||
|
file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/installIncludesTest")
|
||||||
|
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/installIncludesTest/installIncludesTest.h" "// No content\n")
|
||||||
|
|
||||||
|
file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/installIncludesTest2")
|
||||||
|
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/installIncludesTest2/installIncludesTest2.h" "// No content\n")
|
||||||
|
install(FILES
|
||||||
|
"${CMAKE_CURRENT_BINARY_DIR}/installIncludesTest/installIncludesTest.h"
|
||||||
|
DESTINATION installIncludesTest
|
||||||
|
)
|
||||||
|
install(FILES
|
||||||
|
"${CMAKE_CURRENT_BINARY_DIR}/installIncludesTest2/installIncludesTest2.h"
|
||||||
|
DESTINATION installIncludesTest2
|
||||||
|
)
|
||||||
|
|
||||||
install(TARGETS testLibDepends testSharedLibDepends EXPORT DependsExp DESTINATION lib )
|
install(TARGETS testLibDepends testSharedLibDepends EXPORT DependsExp DESTINATION lib )
|
||||||
install(EXPORT DependsExp FILE testLibDependsTargets.cmake DESTINATION lib/cmake/testLibDepends)
|
install(EXPORT DependsExp FILE testLibDependsTargets.cmake DESTINATION lib/cmake/testLibDepends)
|
||||||
|
|
||||||
|
@ -3,6 +3,9 @@
|
|||||||
#include "testLibIncludeRequired2.h"
|
#include "testLibIncludeRequired2.h"
|
||||||
#include "testLibIncludeRequired6.h"
|
#include "testLibIncludeRequired6.h"
|
||||||
|
|
||||||
|
#include "installIncludesTest.h"
|
||||||
|
#include "installIncludesTest2.h"
|
||||||
|
|
||||||
#ifndef testLibRequired_IFACE_DEFINE
|
#ifndef testLibRequired_IFACE_DEFINE
|
||||||
#error Expected testLibRequired_IFACE_DEFINE
|
#error Expected testLibRequired_IFACE_DEFINE
|
||||||
#endif
|
#endif
|
||||||
|
@ -9,3 +9,4 @@ run_cmake(RelativePathInInterface)
|
|||||||
run_cmake(ImportedTarget)
|
run_cmake(ImportedTarget)
|
||||||
run_cmake(RelativePathInGenex)
|
run_cmake(RelativePathInGenex)
|
||||||
run_cmake(CMP0021)
|
run_cmake(CMP0021)
|
||||||
|
run_cmake(TargetInterfaceIncludes)
|
||||||
|
@ -0,0 +1 @@
|
|||||||
|
1
|
@ -0,0 +1,4 @@
|
|||||||
|
CMake Error at TargetInterfaceIncludes.cmake:3 \(install\):
|
||||||
|
install TARGETS given INCLUDES DESTINATION, but EXPORT set not specified.
|
||||||
|
Call Stack \(most recent call first\):
|
||||||
|
CMakeLists.txt:3 \(include\)
|
@ -0,0 +1,4 @@
|
|||||||
|
|
||||||
|
add_library(empty empty.cpp)
|
||||||
|
install(TARGETS empty DESTINATION lib INCLUDES DESTINATION include)
|
||||||
|
# install(EXPORT )
|
Loading…
x
Reference in New Issue
Block a user