summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
Diffstat (limited to 'Source')
-rw-r--r--Source/cmExportBuildFileGenerator.cxx15
-rw-r--r--Source/cmExportInstallFileGenerator.cxx17
-rw-r--r--Source/cmGeneratorExpressionEvaluator.cxx30
-rw-r--r--Source/cmTarget.cxx22
4 files changed, 83 insertions, 1 deletions
diff --git a/Source/cmExportBuildFileGenerator.cxx b/Source/cmExportBuildFileGenerator.cxx
index 3e9a9fd..9533319 100644
--- a/Source/cmExportBuildFileGenerator.cxx
+++ b/Source/cmExportBuildFileGenerator.cxx
@@ -52,6 +52,8 @@ bool cmExportBuildFileGenerator::GenerateMainFile(std::ostream& os)
this->GenerateExpectedTargetsCode(os, expectedTargets);
}
+ std::vector<std::string> missingTargets;
+
// Create all the imported targets.
for(std::vector<cmTarget*>::const_iterator
tei = allTargets.begin();
@@ -59,8 +61,21 @@ bool cmExportBuildFileGenerator::GenerateMainFile(std::ostream& os)
{
cmTarget* te = *tei;
this->GenerateImportTargetCode(os, te);
+
+ ImportPropertyMap properties;
+
+ this->PopulateInterfaceProperty("INTERFACE_INCLUDE_DIRECTORIES", te,
+ cmGeneratorExpression::BuildInterface,
+ properties, missingTargets);
+ this->PopulateInterfaceProperty("INTERFACE_COMPILE_DEFINITIONS", te,
+ cmGeneratorExpression::BuildInterface,
+ properties, missingTargets);
+
+ this->GenerateInterfaceProperties(te, os, properties);
}
+ this->GenerateMissingTargetsCheckCode(os, missingTargets);
+
// Generate import file content for each configuration.
for(std::vector<std::string>::const_iterator
ci = this->Configurations.begin();
diff --git a/Source/cmExportInstallFileGenerator.cxx b/Source/cmExportInstallFileGenerator.cxx
index 2b7937e..bc953c9 100644
--- a/Source/cmExportInstallFileGenerator.cxx
+++ b/Source/cmExportInstallFileGenerator.cxx
@@ -69,6 +69,8 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os)
this->GenerateExpectedTargetsCode(os, expectedTargets);
}
+ std::vector<std::string> missingTargets;
+
// Create all the imported targets.
for(std::vector<cmTarget*>::const_iterator
tei = allTargets.begin();
@@ -76,8 +78,23 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os)
{
cmTarget* te = *tei;
this->GenerateImportTargetCode(os, te);
+
+ ImportPropertyMap properties;
+
+ this->PopulateInterfaceProperty("INTERFACE_INCLUDE_DIRECTORIES",
+ te,
+ cmGeneratorExpression::InstallInterface,
+ properties, missingTargets);
+ this->PopulateInterfaceProperty("INTERFACE_COMPILE_DEFINITIONS",
+ te,
+ cmGeneratorExpression::InstallInterface,
+ properties, missingTargets);
+
+ this->GenerateInterfaceProperties(te, os, properties);
}
+ this->GenerateMissingTargetsCheckCode(os, missingTargets);
+
// Now load per-configuration properties for them.
os << "# Load information for each installed configuration.\n"
<< "GET_FILENAME_COMPONENT(_DIR \"${CMAKE_CURRENT_LIST_FILE}\" PATH)\n"
diff --git a/Source/cmGeneratorExpressionEvaluator.cxx b/Source/cmGeneratorExpressionEvaluator.cxx
index 4b44ebe..b7ce155 100644
--- a/Source/cmGeneratorExpressionEvaluator.cxx
+++ b/Source/cmGeneratorExpressionEvaluator.cxx
@@ -286,6 +286,13 @@ static const struct ConfigurationTestNode : public cmGeneratorExpressionNode
}
} configurationTestNode;
+
+//----------------------------------------------------------------------------
+static const char* targetPropertyTransitiveWhitelist[] = {
+ "INTERFACE_INCLUDE_DIRECTORIES"
+ , "INTERFACE_COMPILE_DEFINITIONS"
+};
+
//----------------------------------------------------------------------------
static const struct TargetPropertyNode : public cmGeneratorExpressionNode
{
@@ -394,7 +401,28 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
}
const char *prop = target->GetProperty(propertyName.c_str());
- return prop ? prop : "";
+ if (!prop)
+ {
+ return std::string();
+ }
+
+ for (size_t i = 0;
+ i < (sizeof(targetPropertyTransitiveWhitelist) /
+ sizeof(*targetPropertyTransitiveWhitelist));
+ ++i)
+ {
+ if (targetPropertyTransitiveWhitelist[i] == propertyName)
+ {
+ cmGeneratorExpression ge(context->Backtrace);
+ return ge.Parse(prop)->Evaluate(context->Makefile,
+ context->Config,
+ context->Quiet,
+ context->HeadTarget,
+ target,
+ &dagChecker);
+ }
+ }
+ return prop;
}
} targetPropertyNode;
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index d60979c..ca53a39 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -720,6 +720,28 @@ void cmTarget::DefineProperties(cmake *cm)
"for the named configuration.");
cm->DefineProperty
+ ("INTERFACE_INCLUDE_DIRECTORIES", cmProperty::TARGET,
+ "List of public include directories for a library.",
+ "Targets may populate this property to publish the include directories "
+ "required to compile against the headers for the target. Consuming "
+ "targets can add entries to their own INCLUDE_DIRECTORIES property such "
+ "as $<TARGET_PROPERTY:foo,INTERFACE_INCLUDE_DIRECTORIES> to use the "
+ "include directories specified in the interface of 'foo'."
+ "\n"
+ CM_DOCUMENT_COMMAND_GENERATOR_EXPRESSIONS);
+
+ cm->DefineProperty
+ ("INTERFACE_COMPILE_DEFINITIONS", cmProperty::TARGET,
+ "List of public compile definitions for a library.",
+ "Targets may populate this property to publish the compile definitions "
+ "required to compile against the headers for the target. Consuming "
+ "targets can add entries to their own COMPILE_DEFINITIONS property such "
+ "as $<TARGET_PROPERTY:foo,INTERFACE_COMPILE_DEFINITIONS> to use the "
+ "compile definitions specified in the interface of 'foo'."
+ "\n"
+ CM_DOCUMENT_COMMAND_GENERATOR_EXPRESSIONS);
+
+ cm->DefineProperty
("LINK_INTERFACE_MULTIPLICITY", cmProperty::TARGET,
"Repetition count for STATIC libraries with cyclic dependencies.",
"When linking to a STATIC library target with cyclic dependencies the "