Merge topic 'test-export-iface-genex'
1d74ba2
Test evaluation target via export for generator expressions522bdac
Export the INTERFACE_PIC property.4ee872c
Make the BUILD_INTERFACE of export()ed targets work.1d47cd9
Add a test for the interfaces in targets exported from the build tree.6c828f9
Move the exported check for file existence.cfd4f0a
Move the exported check for dependencies of targetsd8fe1fc
Only generate one check per missing target.f623d37
Don't write a comment in the export file without the code.b279f2b
Strip consecutive semicolons when preprocessing genex strings.
This commit is contained in:
commit
3a7d1ce3ff
|
@ -62,6 +62,8 @@ bool cmExportBuildFileGenerator::GenerateMainFile(std::ostream& os)
|
||||||
cmTarget* te = *tei;
|
cmTarget* te = *tei;
|
||||||
this->GenerateImportTargetCode(os, te);
|
this->GenerateImportTargetCode(os, te);
|
||||||
|
|
||||||
|
te->AppendBuildInterfaceIncludes();
|
||||||
|
|
||||||
ImportPropertyMap properties;
|
ImportPropertyMap properties;
|
||||||
|
|
||||||
this->PopulateInterfaceProperty("INTERFACE_INCLUDE_DIRECTORIES", te,
|
this->PopulateInterfaceProperty("INTERFACE_INCLUDE_DIRECTORIES", te,
|
||||||
|
@ -70,20 +72,22 @@ bool cmExportBuildFileGenerator::GenerateMainFile(std::ostream& os)
|
||||||
this->PopulateInterfaceProperty("INTERFACE_COMPILE_DEFINITIONS", te,
|
this->PopulateInterfaceProperty("INTERFACE_COMPILE_DEFINITIONS", te,
|
||||||
cmGeneratorExpression::BuildInterface,
|
cmGeneratorExpression::BuildInterface,
|
||||||
properties, missingTargets);
|
properties, missingTargets);
|
||||||
|
this->PopulateInterfaceProperty("INTERFACE_POSITION_INDEPENDENT_CODE",
|
||||||
|
te, properties);
|
||||||
|
|
||||||
this->GenerateInterfaceProperties(te, os, properties);
|
this->GenerateInterfaceProperties(te, os, properties);
|
||||||
}
|
}
|
||||||
|
|
||||||
this->GenerateMissingTargetsCheckCode(os, missingTargets);
|
|
||||||
|
|
||||||
// Generate import file content for each configuration.
|
// Generate import file content for each configuration.
|
||||||
for(std::vector<std::string>::const_iterator
|
for(std::vector<std::string>::const_iterator
|
||||||
ci = this->Configurations.begin();
|
ci = this->Configurations.begin();
|
||||||
ci != this->Configurations.end(); ++ci)
|
ci != this->Configurations.end(); ++ci)
|
||||||
{
|
{
|
||||||
this->GenerateImportConfig(os, ci->c_str());
|
this->GenerateImportConfig(os, ci->c_str(), missingTargets);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this->GenerateMissingTargetsCheckCode(os, missingTargets);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,7 +95,8 @@ bool cmExportBuildFileGenerator::GenerateMainFile(std::ostream& os)
|
||||||
void
|
void
|
||||||
cmExportBuildFileGenerator
|
cmExportBuildFileGenerator
|
||||||
::GenerateImportTargetsConfig(std::ostream& os,
|
::GenerateImportTargetsConfig(std::ostream& os,
|
||||||
const char* config, std::string const& suffix)
|
const char* config, std::string const& suffix,
|
||||||
|
std::vector<std::string> &missingTargets)
|
||||||
{
|
{
|
||||||
for(std::vector<cmTarget*>::const_iterator
|
for(std::vector<cmTarget*>::const_iterator
|
||||||
tei = this->Exports->begin();
|
tei = this->Exports->begin();
|
||||||
|
@ -104,7 +109,6 @@ cmExportBuildFileGenerator
|
||||||
if(!properties.empty())
|
if(!properties.empty())
|
||||||
{
|
{
|
||||||
// Get the rest of the target details.
|
// Get the rest of the target details.
|
||||||
std::vector<std::string> missingTargets;
|
|
||||||
this->SetImportDetailProperties(config, suffix,
|
this->SetImportDetailProperties(config, suffix,
|
||||||
target, properties, missingTargets);
|
target, properties, missingTargets);
|
||||||
this->SetImportLinkInterface(config, suffix,
|
this->SetImportLinkInterface(config, suffix,
|
||||||
|
@ -119,7 +123,6 @@ cmExportBuildFileGenerator
|
||||||
// properties);
|
// properties);
|
||||||
|
|
||||||
// Generate code in the export file.
|
// Generate code in the export file.
|
||||||
this->GenerateMissingTargetsCheckCode(os, missingTargets);
|
|
||||||
this->GenerateImportPropertyCode(os, config, target, properties);
|
this->GenerateImportPropertyCode(os, config, target, properties);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,7 +44,8 @@ protected:
|
||||||
virtual bool GenerateMainFile(std::ostream& os);
|
virtual bool GenerateMainFile(std::ostream& os);
|
||||||
virtual void GenerateImportTargetsConfig(std::ostream& os,
|
virtual void GenerateImportTargetsConfig(std::ostream& os,
|
||||||
const char* config,
|
const char* config,
|
||||||
std::string const& suffix);
|
std::string const& suffix,
|
||||||
|
std::vector<std::string> &missingTargets);
|
||||||
virtual void HandleMissingTarget(std::string& link_libs,
|
virtual void HandleMissingTarget(std::string& link_libs,
|
||||||
std::vector<std::string>& missingTargets,
|
std::vector<std::string>& missingTargets,
|
||||||
cmMakefile* mf,
|
cmMakefile* mf,
|
||||||
|
|
|
@ -107,7 +107,8 @@ bool cmExportFileGenerator::GenerateImportFile()
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
void cmExportFileGenerator::GenerateImportConfig(std::ostream& os,
|
void cmExportFileGenerator::GenerateImportConfig(std::ostream& os,
|
||||||
const char* config)
|
const char* config,
|
||||||
|
std::vector<std::string> &missingTargets)
|
||||||
{
|
{
|
||||||
// Construct the property configuration suffix.
|
// Construct the property configuration suffix.
|
||||||
std::string suffix = "_";
|
std::string suffix = "_";
|
||||||
|
@ -121,7 +122,19 @@ void cmExportFileGenerator::GenerateImportConfig(std::ostream& os,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate the per-config target information.
|
// Generate the per-config target information.
|
||||||
this->GenerateImportTargetsConfig(os, config, suffix);
|
this->GenerateImportTargetsConfig(os, config, suffix, missingTargets);
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void cmExportFileGenerator::PopulateInterfaceProperty(const char *propName,
|
||||||
|
cmTarget *target,
|
||||||
|
ImportPropertyMap &properties)
|
||||||
|
{
|
||||||
|
const char *input = target->GetProperty(propName);
|
||||||
|
if (input)
|
||||||
|
{
|
||||||
|
properties[propName] = input;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
@ -665,9 +678,16 @@ cmExportFileGenerator
|
||||||
void cmExportFileGenerator::GenerateMissingTargetsCheckCode(std::ostream& os,
|
void cmExportFileGenerator::GenerateMissingTargetsCheckCode(std::ostream& os,
|
||||||
const std::vector<std::string>& missingTargets)
|
const std::vector<std::string>& missingTargets)
|
||||||
{
|
{
|
||||||
|
if (missingTargets.empty())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
os << "# Make sure the targets which have been exported in some other \n"
|
os << "# Make sure the targets which have been exported in some other \n"
|
||||||
"# export set exist.\n";
|
"# export set exist.\n";
|
||||||
|
std::set<std::string> emitted;
|
||||||
for(unsigned int i=0; i<missingTargets.size(); ++i)
|
for(unsigned int i=0; i<missingTargets.size(); ++i)
|
||||||
|
{
|
||||||
|
if (emitted.insert(missingTargets[i]).second)
|
||||||
{
|
{
|
||||||
os << "IF(NOT TARGET \"" << missingTargets[i] << "\" )\n"
|
os << "IF(NOT TARGET \"" << missingTargets[i] << "\" )\n"
|
||||||
<< " IF(CMAKE_FIND_PACKAGE_NAME)\n"
|
<< " IF(CMAKE_FIND_PACKAGE_NAME)\n"
|
||||||
|
@ -681,6 +701,7 @@ void cmExportFileGenerator::GenerateMissingTargetsCheckCode(std::ostream& os,
|
||||||
<< " ENDIF()\n"
|
<< " ENDIF()\n"
|
||||||
<< "ENDIF()\n";
|
<< "ENDIF()\n";
|
||||||
}
|
}
|
||||||
|
}
|
||||||
os << "\n";
|
os << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -47,7 +47,8 @@ protected:
|
||||||
|
|
||||||
// Generate per-configuration target information to the given output
|
// Generate per-configuration target information to the given output
|
||||||
// stream.
|
// stream.
|
||||||
void GenerateImportConfig(std::ostream& os, const char* config);
|
void GenerateImportConfig(std::ostream& os, const char* config,
|
||||||
|
std::vector<std::string> &missingTargets);
|
||||||
|
|
||||||
// Methods to implement export file code generation.
|
// Methods to implement export file code generation.
|
||||||
void GenerateImportHeaderCode(std::ostream& os, const char* config = 0);
|
void GenerateImportHeaderCode(std::ostream& os, const char* config = 0);
|
||||||
|
@ -85,7 +86,8 @@ protected:
|
||||||
/** Each subclass knows where the target files are located. */
|
/** Each subclass knows where the target files are located. */
|
||||||
virtual void GenerateImportTargetsConfig(std::ostream& os,
|
virtual void GenerateImportTargetsConfig(std::ostream& os,
|
||||||
const char* config,
|
const char* config,
|
||||||
std::string const& suffix) = 0;
|
std::string const& suffix,
|
||||||
|
std::vector<std::string> &missingTargets) = 0;
|
||||||
|
|
||||||
/** Each subclass knows how to deal with a target that is missing from an
|
/** Each subclass knows how to deal with a target that is missing from an
|
||||||
* export set. */
|
* export set. */
|
||||||
|
@ -99,6 +101,8 @@ protected:
|
||||||
cmGeneratorExpression::PreprocessContext,
|
cmGeneratorExpression::PreprocessContext,
|
||||||
ImportPropertyMap &properties,
|
ImportPropertyMap &properties,
|
||||||
std::vector<std::string> &missingTargets);
|
std::vector<std::string> &missingTargets);
|
||||||
|
void PopulateInterfaceProperty(const char *propName, cmTarget *target,
|
||||||
|
ImportPropertyMap &properties);
|
||||||
void GenerateInterfaceProperties(cmTarget *target, std::ostream& os,
|
void GenerateInterfaceProperties(cmTarget *target, std::ostream& os,
|
||||||
const ImportPropertyMap &properties);
|
const ImportPropertyMap &properties);
|
||||||
|
|
||||||
|
|
|
@ -89,11 +89,12 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os)
|
||||||
te,
|
te,
|
||||||
cmGeneratorExpression::InstallInterface,
|
cmGeneratorExpression::InstallInterface,
|
||||||
properties, missingTargets);
|
properties, missingTargets);
|
||||||
|
this->PopulateInterfaceProperty("INTERFACE_POSITION_INDEPENDENT_CODE",
|
||||||
|
te, properties);
|
||||||
|
|
||||||
this->GenerateInterfaceProperties(te, os, properties);
|
this->GenerateInterfaceProperties(te, os, properties);
|
||||||
}
|
}
|
||||||
|
|
||||||
this->GenerateMissingTargetsCheckCode(os, missingTargets);
|
|
||||||
|
|
||||||
// Now load per-configuration properties for them.
|
// Now load per-configuration properties for them.
|
||||||
os << "# Load information for each installed configuration.\n"
|
os << "# Load information for each installed configuration.\n"
|
||||||
|
@ -105,23 +106,29 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os)
|
||||||
<< "ENDFOREACH(f)\n"
|
<< "ENDFOREACH(f)\n"
|
||||||
<< "\n";
|
<< "\n";
|
||||||
|
|
||||||
|
this->GenerateImportedFileCheckLoop(os);
|
||||||
|
|
||||||
// Generate an import file for each configuration.
|
// Generate an import file for each configuration.
|
||||||
bool result = true;
|
bool result = true;
|
||||||
for(std::vector<std::string>::const_iterator
|
for(std::vector<std::string>::const_iterator
|
||||||
ci = this->Configurations.begin();
|
ci = this->Configurations.begin();
|
||||||
ci != this->Configurations.end(); ++ci)
|
ci != this->Configurations.end(); ++ci)
|
||||||
{
|
{
|
||||||
if(!this->GenerateImportFileConfig(ci->c_str()))
|
if(!this->GenerateImportFileConfig(ci->c_str(), missingTargets))
|
||||||
{
|
{
|
||||||
result = false;
|
result = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this->GenerateMissingTargetsCheckCode(os, missingTargets);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool
|
bool
|
||||||
cmExportInstallFileGenerator::GenerateImportFileConfig(const char* config)
|
cmExportInstallFileGenerator::GenerateImportFileConfig(const char* config,
|
||||||
|
std::vector<std::string> &missingTargets)
|
||||||
{
|
{
|
||||||
// Skip configurations not enabled for this export.
|
// Skip configurations not enabled for this export.
|
||||||
if(!this->IEGen->InstallsForConfig(config))
|
if(!this->IEGen->InstallsForConfig(config))
|
||||||
|
@ -161,7 +168,7 @@ cmExportInstallFileGenerator::GenerateImportFileConfig(const char* config)
|
||||||
this->GenerateImportHeaderCode(os, config);
|
this->GenerateImportHeaderCode(os, config);
|
||||||
|
|
||||||
// Generate the per-config target information.
|
// Generate the per-config target information.
|
||||||
this->GenerateImportConfig(os, config);
|
this->GenerateImportConfig(os, config, missingTargets);
|
||||||
|
|
||||||
// End with the import file footer.
|
// End with the import file footer.
|
||||||
this->GenerateImportFooterCode(os);
|
this->GenerateImportFooterCode(os);
|
||||||
|
@ -176,7 +183,8 @@ cmExportInstallFileGenerator::GenerateImportFileConfig(const char* config)
|
||||||
void
|
void
|
||||||
cmExportInstallFileGenerator
|
cmExportInstallFileGenerator
|
||||||
::GenerateImportTargetsConfig(std::ostream& os,
|
::GenerateImportTargetsConfig(std::ostream& os,
|
||||||
const char* config, std::string const& suffix)
|
const char* config, std::string const& suffix,
|
||||||
|
std::vector<std::string> &missingTargets)
|
||||||
{
|
{
|
||||||
// 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.
|
||||||
|
@ -225,7 +233,6 @@ cmExportInstallFileGenerator
|
||||||
if(!properties.empty())
|
if(!properties.empty())
|
||||||
{
|
{
|
||||||
// Get the rest of the target details.
|
// Get the rest of the target details.
|
||||||
std::vector<std::string> missingTargets;
|
|
||||||
this->SetImportDetailProperties(config, suffix,
|
this->SetImportDetailProperties(config, suffix,
|
||||||
te->Target, properties, missingTargets);
|
te->Target, properties, missingTargets);
|
||||||
|
|
||||||
|
@ -240,15 +247,12 @@ cmExportInstallFileGenerator
|
||||||
// properties);
|
// properties);
|
||||||
|
|
||||||
// Generate code in the export file.
|
// Generate code in the export file.
|
||||||
this->GenerateMissingTargetsCheckCode(os, missingTargets);
|
|
||||||
this->GenerateImportPropertyCode(os, config, te->Target, properties);
|
this->GenerateImportPropertyCode(os, config, te->Target, properties);
|
||||||
this->GenerateImportedFileChecksCode(os, te->Target, properties,
|
this->GenerateImportedFileChecksCode(os, te->Target, properties,
|
||||||
importedLocations);
|
importedLocations);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this->GenerateImportedFileCheckLoop(os);
|
|
||||||
|
|
||||||
// Cleanup the import prefix variable.
|
// Cleanup the import prefix variable.
|
||||||
if(!this->ImportPrefix.empty())
|
if(!this->ImportPrefix.empty())
|
||||||
{
|
{
|
||||||
|
|
|
@ -56,7 +56,8 @@ protected:
|
||||||
virtual bool GenerateMainFile(std::ostream& os);
|
virtual bool GenerateMainFile(std::ostream& os);
|
||||||
virtual void GenerateImportTargetsConfig(std::ostream& os,
|
virtual void GenerateImportTargetsConfig(std::ostream& os,
|
||||||
const char* config,
|
const char* config,
|
||||||
std::string const& suffix);
|
std::string const& suffix,
|
||||||
|
std::vector<std::string> &missingTargets);
|
||||||
virtual void HandleMissingTarget(std::string& link_libs,
|
virtual void HandleMissingTarget(std::string& link_libs,
|
||||||
std::vector<std::string>& missingTargets,
|
std::vector<std::string>& missingTargets,
|
||||||
cmMakefile* mf,
|
cmMakefile* mf,
|
||||||
|
@ -72,7 +73,8 @@ protected:
|
||||||
|
|
||||||
|
|
||||||
/** Generate a per-configuration file for the targets. */
|
/** Generate a per-configuration file for the targets. */
|
||||||
bool GenerateImportFileConfig(const char* config);
|
bool GenerateImportFileConfig(const char* config,
|
||||||
|
std::vector<std::string> &missingTargets);
|
||||||
|
|
||||||
/** Fill in properties indicating installed file locations. */
|
/** Fill in properties indicating installed file locations. */
|
||||||
void SetImportLocationProperty(const char* config,
|
void SetImportLocationProperty(const char* config,
|
||||||
|
|
|
@ -147,6 +147,38 @@ cmCompiledGeneratorExpression::~cmCompiledGeneratorExpression()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
static std::string stripEmptyListElements(const std::string &input)
|
||||||
|
{
|
||||||
|
std::string result;
|
||||||
|
|
||||||
|
const char *c = input.c_str();
|
||||||
|
bool skipSemiColons = true;
|
||||||
|
for ( ; *c; ++c)
|
||||||
|
{
|
||||||
|
if(c[0] == ';')
|
||||||
|
{
|
||||||
|
if(skipSemiColons)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
skipSemiColons = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
skipSemiColons = false;
|
||||||
|
}
|
||||||
|
result += *c;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!result.empty() && *(result.end() - 1) == ';')
|
||||||
|
{
|
||||||
|
result.resize(result.size() - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
static std::string stripAllGeneratorExpressions(const std::string &input)
|
static std::string stripAllGeneratorExpressions(const std::string &input)
|
||||||
{
|
{
|
||||||
|
@ -186,7 +218,7 @@ static std::string stripAllGeneratorExpressions(const std::string &input)
|
||||||
lastPos = pos;
|
lastPos = pos;
|
||||||
}
|
}
|
||||||
result += input.substr(lastPos);
|
result += input.substr(lastPos);
|
||||||
return result;
|
return stripEmptyListElements(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
@ -247,7 +279,7 @@ static std::string stripExportInterface(const std::string &input,
|
||||||
}
|
}
|
||||||
result += input.substr(lastPos);
|
result += input.substr(lastPos);
|
||||||
|
|
||||||
return result;
|
return stripEmptyListElements(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
|
|
@ -941,19 +941,7 @@ void cmGlobalGenerator::Generate()
|
||||||
|
|
||||||
for ( tit = targets->begin(); tit != targets->end(); ++ tit )
|
for ( tit = targets->begin(); tit != targets->end(); ++ tit )
|
||||||
{
|
{
|
||||||
if (mf->IsOn("CMAKE_BUILD_INTERFACE_INCLUDES"))
|
tit->second.AppendBuildInterfaceIncludes();
|
||||||
{
|
|
||||||
const char *binDir = mf->GetStartOutputDirectory();
|
|
||||||
const char *srcDir = mf->GetStartDirectory();
|
|
||||||
const std::string dirs = std::string(binDir ? binDir : "")
|
|
||||||
+ std::string(binDir ? ";" : "")
|
|
||||||
+ std::string(srcDir ? srcDir : "");
|
|
||||||
if (!dirs.empty())
|
|
||||||
{
|
|
||||||
tit->second.AppendProperty("INTERFACE_INCLUDE_DIRECTORIES",
|
|
||||||
("$<BUILD_INTERFACE:" + dirs + ">").c_str());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -150,6 +150,7 @@ cmTarget::cmTarget()
|
||||||
this->DLLPlatform = false;
|
this->DLLPlatform = false;
|
||||||
this->IsApple = false;
|
this->IsApple = false;
|
||||||
this->IsImportedTarget = false;
|
this->IsImportedTarget = false;
|
||||||
|
this->BuildInterfaceIncludesAppended = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
@ -2680,6 +2681,30 @@ void cmTarget::AppendProperty(const char* prop, const char* value,
|
||||||
this->MaybeInvalidatePropertyCache(prop);
|
this->MaybeInvalidatePropertyCache(prop);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void cmTarget::AppendBuildInterfaceIncludes()
|
||||||
|
{
|
||||||
|
if (this->BuildInterfaceIncludesAppended)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this->BuildInterfaceIncludesAppended = true;
|
||||||
|
|
||||||
|
if (this->Makefile->IsOn("CMAKE_BUILD_INTERFACE_INCLUDES"))
|
||||||
|
{
|
||||||
|
const char *binDir = this->Makefile->GetStartOutputDirectory();
|
||||||
|
const char *srcDir = this->Makefile->GetStartDirectory();
|
||||||
|
const std::string dirs = std::string(binDir ? binDir : "")
|
||||||
|
+ std::string(binDir ? ";" : "")
|
||||||
|
+ std::string(srcDir ? srcDir : "");
|
||||||
|
if (!dirs.empty())
|
||||||
|
{
|
||||||
|
this->AppendProperty("INTERFACE_INCLUDE_DIRECTORIES",
|
||||||
|
("$<BUILD_INTERFACE:" + dirs + ">").c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
void cmTarget::InsertInclude(const cmMakefileIncludeDirectoriesEntry &entry,
|
void cmTarget::InsertInclude(const cmMakefileIncludeDirectoriesEntry &entry,
|
||||||
bool before)
|
bool before)
|
||||||
|
|
|
@ -490,6 +490,8 @@ public:
|
||||||
void InsertInclude(const cmMakefileIncludeDirectoriesEntry &entry,
|
void InsertInclude(const cmMakefileIncludeDirectoriesEntry &entry,
|
||||||
bool before = false);
|
bool before = false);
|
||||||
|
|
||||||
|
void AppendBuildInterfaceIncludes();
|
||||||
|
|
||||||
void GetLinkDependentTargetsForProperty(const std::string &p,
|
void GetLinkDependentTargetsForProperty(const std::string &p,
|
||||||
std::set<std::string> &targets);
|
std::set<std::string> &targets);
|
||||||
bool IsNullImpliedByLinkLibraries(const std::string &p);
|
bool IsNullImpliedByLinkLibraries(const std::string &p);
|
||||||
|
@ -611,6 +613,7 @@ private:
|
||||||
mutable std::map<cmStdString, std::set<std::string> >
|
mutable std::map<cmStdString, std::set<std::string> >
|
||||||
LinkDependentProperties;
|
LinkDependentProperties;
|
||||||
mutable std::set<std::string> LinkImplicitNullProperties;
|
mutable std::set<std::string> LinkImplicitNullProperties;
|
||||||
|
bool BuildInterfaceIncludesAppended;
|
||||||
|
|
||||||
// Cache target output paths for each configuration.
|
// Cache target output paths for each configuration.
|
||||||
struct OutputInfo;
|
struct OutputInfo;
|
||||||
|
|
|
@ -162,6 +162,10 @@ include(GenerateExportHeader)
|
||||||
|
|
||||||
add_library(testSharedLibRequired SHARED testSharedLibRequired.cpp)
|
add_library(testSharedLibRequired SHARED testSharedLibRequired.cpp)
|
||||||
generate_export_header(testSharedLibRequired)
|
generate_export_header(testSharedLibRequired)
|
||||||
|
set_property(TARGET testSharedLibRequired
|
||||||
|
PROPERTY
|
||||||
|
INTERFACE_POSITION_INDEPENDENT_CODE ON
|
||||||
|
)
|
||||||
set_property(TARGET testSharedLibRequired APPEND PROPERTY
|
set_property(TARGET testSharedLibRequired APPEND PROPERTY
|
||||||
INCLUDE_DIRECTORIES "${CMAKE_CURRENT_BINARY_DIR}"
|
INCLUDE_DIRECTORIES "${CMAKE_CURRENT_BINARY_DIR}"
|
||||||
)
|
)
|
||||||
|
@ -182,7 +186,7 @@ set_property(TARGET testSharedLibDepends APPEND PROPERTY
|
||||||
)
|
)
|
||||||
set_property(TARGET testSharedLibDepends APPEND PROPERTY
|
set_property(TARGET testSharedLibDepends APPEND PROPERTY
|
||||||
LINK_INTERFACE_LIBRARIES
|
LINK_INTERFACE_LIBRARIES
|
||||||
$<1:$<TARGET_NAME:testSharedLibRequired>>
|
$<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,EXECUTABLE>:$<TARGET_NAME:testSharedLibRequired>>
|
||||||
)
|
)
|
||||||
|
|
||||||
# LINK_PRIVATE because the LINK_INTERFACE_LIBRARIES is specified above.
|
# LINK_PRIVATE because the LINK_INTERFACE_LIBRARIES is specified above.
|
||||||
|
@ -247,9 +251,12 @@ if(WIN32)
|
||||||
install(TARGETS testLib5 RUNTIME DESTINATION bin)
|
install(TARGETS testLib5 RUNTIME DESTINATION bin)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
add_subdirectory(sublib) # For CMAKE_BUILD_INTERFACE_INCLUDES test.
|
||||||
|
|
||||||
# Export from build tree.
|
# Export from build tree.
|
||||||
export(TARGETS testExe1 testLib1 testLib2 testLib3
|
export(TARGETS testExe1 testLib1 testLib2 testLib3
|
||||||
testExe2libImp testLib3Imp testLib3ImpDep
|
testExe2libImp testLib3Imp testLib3ImpDep subdirlib
|
||||||
|
testSharedLibRequired testSharedLibDepends
|
||||||
NAMESPACE bld_
|
NAMESPACE bld_
|
||||||
FILE ExportBuildTree.cmake
|
FILE ExportBuildTree.cmake
|
||||||
)
|
)
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
|
||||||
|
set(CMAKE_BUILD_INTERFACE_INCLUDES ON)
|
||||||
|
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||||
|
|
||||||
|
add_library(subdirlib SHARED subdir.cpp)
|
||||||
|
generate_export_header(subdirlib)
|
|
@ -0,0 +1,7 @@
|
||||||
|
|
||||||
|
#include "subdir.h"
|
||||||
|
|
||||||
|
int SubDirObject::foo()
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
|
||||||
|
#ifndef SUBDIR_H
|
||||||
|
#define SUBDIR_H
|
||||||
|
|
||||||
|
#include "subdirlib_export.h"
|
||||||
|
|
||||||
|
struct SUBDIRLIB_EXPORT SubDirObject
|
||||||
|
{
|
||||||
|
int foo();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -159,22 +159,39 @@ endif()
|
||||||
|
|
||||||
add_executable(deps_iface deps_iface.c)
|
add_executable(deps_iface deps_iface.c)
|
||||||
target_link_libraries(deps_iface testLibDepends)
|
target_link_libraries(deps_iface testLibDepends)
|
||||||
set_property(TARGET deps_iface APPEND PROPERTY
|
target_include_directories(deps_iface PRIVATE testLibDepends)
|
||||||
COMPILE_DEFINITIONS
|
target_compile_definitions(deps_iface PRIVATE testLibDepends)
|
||||||
$<TARGET_PROPERTY:testLibDepends,INTERFACE_COMPILE_DEFINITIONS>
|
|
||||||
)
|
|
||||||
set_property(TARGET deps_iface APPEND PROPERTY
|
|
||||||
INCLUDE_DIRECTORIES
|
|
||||||
$<TARGET_PROPERTY:testLibDepends,INTERFACE_INCLUDE_DIRECTORIES>
|
|
||||||
)
|
|
||||||
|
|
||||||
add_executable(deps_shared_iface deps_shared_iface.cpp)
|
add_executable(deps_shared_iface deps_shared_iface.cpp)
|
||||||
target_link_libraries(deps_shared_iface testSharedLibDepends)
|
target_link_libraries(deps_shared_iface testSharedLibDepends)
|
||||||
set_property(TARGET deps_shared_iface APPEND PROPERTY
|
target_include_directories(deps_shared_iface PRIVATE testSharedLibDepends)
|
||||||
COMPILE_DEFINITIONS
|
target_compile_definitions(deps_shared_iface PRIVATE testSharedLibDepends)
|
||||||
$<TARGET_PROPERTY:testSharedLibDepends,INTERFACE_COMPILE_DEFINITIONS>
|
|
||||||
)
|
if (APPLE OR CMAKE_CXX_COMPILER_ID MATCHES "GNU")
|
||||||
set_property(TARGET deps_shared_iface APPEND PROPERTY
|
include(CheckCXXCompilerFlag)
|
||||||
INCLUDE_DIRECTORIES
|
check_cxx_compiler_flag(-fPIE run_pic_test)
|
||||||
$<TARGET_PROPERTY:testSharedLibDepends,INTERFACE_INCLUDE_DIRECTORIES>
|
else()
|
||||||
|
if (CMAKE_CXX_COMPILER_ID MATCHES "PGI"
|
||||||
|
OR CMAKE_CXX_COMPILER_ID MATCHES "PathScale"
|
||||||
|
OR CMAKE_SYSTEM_NAME MATCHES "IRIX64"
|
||||||
|
OR CMAKE_CXX_COMPILER_ID MATCHES "Intel")
|
||||||
|
set(run_pic_test 0)
|
||||||
|
else()
|
||||||
|
set(run_pic_test 1)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (run_pic_test)
|
||||||
|
target_compile_definitions(deps_shared_iface PRIVATE CHECK_PIC_WORKS)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
#-----------------------------------------------------------------------------
|
||||||
|
# Test that targets imported from the build tree have their dependencies
|
||||||
|
# evaluated correctly. The above already tests the same for the install tree.
|
||||||
|
|
||||||
|
add_executable(deps_shared_iface2 deps_shared_iface.cpp)
|
||||||
|
target_link_libraries(deps_shared_iface2 bld_testSharedLibDepends bld_subdirlib)
|
||||||
|
target_include_directories(deps_shared_iface2 PRIVATE bld_testSharedLibDepends bld_subdirlib)
|
||||||
|
target_compile_definitions(deps_shared_iface2
|
||||||
|
PRIVATE bld_testSharedLibDepends TEST_SUBDIR_LIB
|
||||||
)
|
)
|
||||||
|
|
|
@ -2,10 +2,28 @@
|
||||||
|
|
||||||
#include "testSharedLibDepends.h"
|
#include "testSharedLibDepends.h"
|
||||||
|
|
||||||
|
#ifdef CHECK_PIC_WORKS
|
||||||
|
#if defined(__ELF__) && !defined(__PIC__) && !defined(__PIE__)
|
||||||
|
#error Expected by INTERFACE_POSITION_INDEPENDENT_CODE property of dependency
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef TEST_SUBDIR_LIB
|
||||||
|
#include "subdir.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
int main(int,char **)
|
int main(int,char **)
|
||||||
{
|
{
|
||||||
TestSharedLibDepends dep;
|
TestSharedLibDepends dep;
|
||||||
TestSharedLibRequired req;
|
TestSharedLibRequired req;
|
||||||
|
|
||||||
return dep.foo() + req.foo();
|
#ifdef TEST_SUBDIR_LIB
|
||||||
|
SubDirObject sdo;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return dep.foo() + req.foo()
|
||||||
|
#ifdef TEST_SUBDIR_LIB
|
||||||
|
+ sdo.foo()
|
||||||
|
#endif
|
||||||
|
;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue