summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Source/CMakeVersion.cmake2
-rw-r--r--Source/cmDocumentGeneratorExpressions.h1
-rw-r--r--Source/cmGeneratorExpressionEvaluator.cxx18
-rw-r--r--Source/cmTarget.cxx83
-rw-r--r--Source/cmTarget.h2
-rw-r--r--Source/cmTargetCompileDefinitionsCommand.h3
-rw-r--r--Source/cmTargetIncludeDirectoriesCommand.h3
-rw-r--r--Source/cmTargetLinkLibrariesCommand.h7
-rw-r--r--Source/cmTargetPropCommandBase.h1
-rw-r--r--Source/cmake.cxx13
-rw-r--r--Source/cmake.h2
-rw-r--r--Tests/CMakeCommands/target_compile_definitions/CMakeLists.txt2
-rw-r--r--Tests/CMakeCommands/target_compile_definitions/consumer.cpp8
13 files changed, 144 insertions, 1 deletions
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index c71ba21..1e7fe50 100644
--- a/Source/CMakeVersion.cmake
+++ b/Source/CMakeVersion.cmake
@@ -2,5 +2,5 @@
set(CMake_VERSION_MAJOR 2)
set(CMake_VERSION_MINOR 8)
set(CMake_VERSION_PATCH 10)
-set(CMake_VERSION_TWEAK 20130111)
+set(CMake_VERSION_TWEAK 20130115)
#set(CMake_VERSION_RC 1)
diff --git a/Source/cmDocumentGeneratorExpressions.h b/Source/cmDocumentGeneratorExpressions.h
index b8889ac..fa21907 100644
--- a/Source/cmDocumentGeneratorExpressions.h
+++ b/Source/cmDocumentGeneratorExpressions.h
@@ -37,6 +37,7 @@
"target in the same buildsystem. Expands to the empty string " \
"otherwise.\n" \
" $<TARGET_FILE:tgt> = main file (.exe, .so.1.2, .a)\n" \
+ " $<TARGET_DEFINED:tgt> = '1' if tgt is a target, else '0'\n" \
" $<TARGET_LINKER_FILE:tgt> = file used to link (.a, .lib, .so)\n" \
" $<TARGET_SONAME_FILE:tgt> = file with soname (.so.3)\n" \
"where \"tgt\" is the name of a target. " \
diff --git a/Source/cmGeneratorExpressionEvaluator.cxx b/Source/cmGeneratorExpressionEvaluator.cxx
index f4e4131..8e40815a 100644
--- a/Source/cmGeneratorExpressionEvaluator.cxx
+++ b/Source/cmGeneratorExpressionEvaluator.cxx
@@ -289,6 +289,22 @@ static const struct ConfigurationTestNode : public cmGeneratorExpressionNode
} configurationTestNode;
+static const struct TargetDefinedNode : public cmGeneratorExpressionNode
+{
+ TargetDefinedNode() {}
+
+ virtual int NumExpectedParameters() const { return 1; }
+
+ std::string Evaluate(const std::vector<std::string> &parameters,
+ cmGeneratorExpressionContext *context,
+ const GeneratorExpressionContent *,
+ cmGeneratorExpressionDAGChecker *) const
+ {
+ return context->Makefile->FindTargetToUse(parameters.front().c_str())
+ ? "1" : "0";
+ }
+} targetDefinedNode;
+
//----------------------------------------------------------------------------
static const char* targetPropertyTransitiveWhitelist[] = {
"INTERFACE_INCLUDE_DIRECTORIES"
@@ -702,6 +718,8 @@ cmGeneratorExpressionNode* GetNode(const std::string &identifier)
return &buildInterfaceNode;
else if (identifier == "INSTALL_INTERFACE")
return &installInterfaceNode;
+ else if (identifier == "TARGET_DEFINED")
+ return &targetDefinedNode;
return 0;
}
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 9b50b8e..6f68140 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -892,6 +892,19 @@ void cmTarget::DefineProperties(cmake *cm)
"requirement for their INTERFACE_POSITION_INDEPENDENT_CODE property.");
cm->DefineProperty
+ ("COMPATIBLE_INTERFACE_BOOL", cmProperty::TARGET,
+ "Properties which must be compatible with their link interface",
+ "The COMPATIBLE_INTERFACE_BOOL property may contain a list of properties"
+ "for this target which must be consistent when evaluated as a boolean "
+ "in the INTERFACE of all linked dependencies. For example, if a "
+ "property \"FOO\" appears in the list, then the \"INTERFACE_FOO\" "
+ "property content in all dependencies must be consistent with each "
+ "other, and with the \"FOO\" property in this target. "
+ "Consistency in this sense has the meaning that if the property is set,"
+ "then it must have the same boolean value as all others, and if the "
+ "property is not set, then it is ignored.");
+
+ cm->DefineProperty
("POST_INSTALL_SCRIPT", cmProperty::TARGET,
"Deprecated install support.",
"The PRE_INSTALL_SCRIPT and POST_INSTALL_SCRIPT properties are the "
@@ -2233,6 +2246,14 @@ static std::string targetNameGenex(const char *lib)
}
//----------------------------------------------------------------------------
+static bool isGeneratorExpression(const std::string &lib)
+{
+ const std::string::size_type openpos = lib.find("$<");
+ return (openpos != std::string::npos)
+ && (lib.find(">", openpos) != std::string::npos);
+}
+
+//----------------------------------------------------------------------------
void cmTarget::AddLinkLibrary(cmMakefile& mf,
const char *target, const char* lib,
LinkLibraryType llt)
@@ -2254,6 +2275,11 @@ void cmTarget::AddLinkLibrary(cmMakefile& mf,
llt).c_str());
}
+ if (isGeneratorExpression(lib))
+ {
+ return;
+ }
+
cmTarget::LibraryID tmp;
tmp.first = lib;
tmp.second = llt;
@@ -5299,6 +5325,58 @@ std::string cmTarget::CheckCMP0004(std::string const& item)
}
//----------------------------------------------------------------------------
+void cmTarget::CheckPropertyCompatibility(cmComputeLinkInformation *info,
+ const char* config)
+{
+ const cmComputeLinkInformation::ItemVector &deps = info->GetItems();
+
+ std::set<cmStdString> emitted;
+
+ for(cmComputeLinkInformation::ItemVector::const_iterator li =
+ deps.begin();
+ li != deps.end(); ++li)
+ {
+ if (!li->Target)
+ {
+ continue;
+ }
+ const char *prop = li->Target->GetProperty("COMPATIBLE_INTERFACE_BOOL");
+ if (!prop)
+ {
+ continue;
+ }
+
+ std::vector<std::string> props;
+ cmSystemTools::ExpandListArgument(prop, props);
+
+ for(std::vector<std::string>::iterator pi = props.begin();
+ pi != props.end(); ++pi)
+ {
+ if (this->Makefile->GetCMakeInstance()
+ ->GetIsPropertyDefined(pi->c_str(),
+ cmProperty::TARGET))
+ {
+ cmOStringStream e;
+ e << "Target \"" << li->Target->GetName() << "\" has property \""
+ << *pi << "\" listed in its COMPATIBLE_INTERFACE_BOOL property. "
+ "This is not allowed. Only user-defined properties may appear "
+ "listed in the COMPATIBLE_INTERFACE_BOOL property.";
+ this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
+ return;
+ }
+ if(emitted.insert(*pi).second)
+ {
+ this->GetLinkInterfaceDependentBoolProperty(*pi, config);
+ if (cmSystemTools::GetErrorOccuredFlag())
+ {
+ return;
+ }
+ }
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
cmComputeLinkInformation*
cmTarget::GetLinkInformation(const char* config, cmTarget *head)
{
@@ -5319,6 +5397,11 @@ cmTarget::GetLinkInformation(const char* config, cmTarget *head)
info = 0;
}
+ if (info)
+ {
+ this->CheckPropertyCompatibility(info, config);
+ }
+
// Store the information for this configuration.
cmTargetLinkInformationMap::value_type entry(key, info);
i = this->LinkInformation.insert(entry).first;
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index b4d053d..0963c5c 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -626,6 +626,8 @@ private:
cmTarget *head);
cmTargetLinkInformationMap LinkInformation;
+ void CheckPropertyCompatibility(cmComputeLinkInformation *info,
+ const char* config);
bool ComputeLinkInterface(const char* config, LinkInterface& iface,
cmTarget *head);
diff --git a/Source/cmTargetCompileDefinitionsCommand.h b/Source/cmTargetCompileDefinitionsCommand.h
index 707610e..4b066b7a 100644
--- a/Source/cmTargetCompileDefinitionsCommand.h
+++ b/Source/cmTargetCompileDefinitionsCommand.h
@@ -69,6 +69,9 @@ public:
"INTERFACE_COMPILE_DEFINITIONS from. "
"Repeated calls for the same <target> append items in the order called."
"\n"
+ "Arguments to target_compile_definitions may use \"generator "
+ "expressions\" with the syntax \"$<...>\". "
+ CM_DOCUMENT_COMMAND_GENERATOR_EXPRESSIONS
;
}
diff --git a/Source/cmTargetIncludeDirectoriesCommand.h b/Source/cmTargetIncludeDirectoriesCommand.h
index c1957d6..90e039c 100644
--- a/Source/cmTargetIncludeDirectoriesCommand.h
+++ b/Source/cmTargetIncludeDirectoriesCommand.h
@@ -73,6 +73,9 @@ public:
"directories must be absolute paths, not relative paths. "
"Repeated calls for the same <target> append items in the order called."
"\n"
+ "Arguments to target_include_directories may use \"generator "
+ "expressions\" with the syntax \"$<...>\". "
+ CM_DOCUMENT_COMMAND_GENERATOR_EXPRESSIONS
;
}
diff --git a/Source/cmTargetLinkLibrariesCommand.h b/Source/cmTargetLinkLibrariesCommand.h
index 8e5823c..34fe54c 100644
--- a/Source/cmTargetLinkLibrariesCommand.h
+++ b/Source/cmTargetLinkLibrariesCommand.h
@@ -13,6 +13,7 @@
#define cmTargetLinkLibrariesCommand_h
#include "cmCommand.h"
+#include "cmDocumentGeneratorExpressions.h"
/** \class cmTargetLinkLibrariesCommand
* \brief Specify a list of libraries to link into executables.
@@ -141,6 +142,12 @@ public:
"However, if two archives are really so interdependent they should "
"probably be combined into a single archive."
")"
+ "\n"
+ "Arguments to target_link_libraries may use \"generator expressions\" "
+ "with the syntax \"$<...>\". Note however, that generator expressions "
+ "will not be used in OLD handling of CMP0003 or CMP0004."
+ "\n"
+ CM_DOCUMENT_COMMAND_GENERATOR_EXPRESSIONS
;
}
diff --git a/Source/cmTargetPropCommandBase.h b/Source/cmTargetPropCommandBase.h
index 90e3bbb..e757f9d 100644
--- a/Source/cmTargetPropCommandBase.h
+++ b/Source/cmTargetPropCommandBase.h
@@ -14,6 +14,7 @@
#define cmTargetPropCommandBase_h
#include "cmCommand.h"
+#include "cmDocumentGeneratorExpressions.h"
class cmTarget;
diff --git a/Source/cmake.cxx b/Source/cmake.cxx
index a44c825..2eecfba 100644
--- a/Source/cmake.cxx
+++ b/Source/cmake.cxx
@@ -3299,6 +3299,12 @@ int cmake::ExecuteLinkScript(std::vector<std::string>& args)
int result = 0;
while(result == 0 && cmSystemTools::GetLineFromStream(fin, command))
{
+ // Skip empty command lines.
+ if(command.find_first_not_of(" \t") == command.npos)
+ {
+ continue;
+ }
+
// Setup this command line.
const char* cmd[2] = {command.c_str(), 0};
cmsysProcess_SetCommand(cp, cmd);
@@ -3552,6 +3558,13 @@ void cmake::DefineProperty(const char *name, cmProperty::ScopeType scope,
chained);
}
+bool cmake::GetIsPropertyDefined(const char *name,
+ cmProperty::ScopeType scope)
+{
+ return this->PropertyDefinitions[scope].find(name) !=
+ this->PropertyDefinitions[scope].end();
+}
+
cmPropertyDefinition *cmake
::GetPropertyDefinition(const char *name,
cmProperty::ScopeType scope)
diff --git a/Source/cmake.h b/Source/cmake.h
index e5aa076..f6fe0d6 100644
--- a/Source/cmake.h
+++ b/Source/cmake.h
@@ -341,6 +341,8 @@ class cmake
bool chain = false,
const char *variableGroup = 0);
+ bool GetIsPropertyDefined(const char *name, cmProperty::ScopeType scope);
+
// get property definition
cmPropertyDefinition *GetPropertyDefinition
(const char *name, cmProperty::ScopeType scope);
diff --git a/Tests/CMakeCommands/target_compile_definitions/CMakeLists.txt b/Tests/CMakeCommands/target_compile_definitions/CMakeLists.txt
index 84a23ef..a37c597 100644
--- a/Tests/CMakeCommands/target_compile_definitions/CMakeLists.txt
+++ b/Tests/CMakeCommands/target_compile_definitions/CMakeLists.txt
@@ -23,4 +23,6 @@ add_executable(consumer
target_compile_definitions(consumer
PRIVATE target_compile_definitions importedlib
+ $<$<TARGET_DEFINED:notdefined>:SHOULD_NOT_BE_DEFINED>
+ $<$<TARGET_DEFINED:importedlib>:SHOULD_BE_DEFINED>
)
diff --git a/Tests/CMakeCommands/target_compile_definitions/consumer.cpp b/Tests/CMakeCommands/target_compile_definitions/consumer.cpp
index e3788dd..1ef657d 100644
--- a/Tests/CMakeCommands/target_compile_definitions/consumer.cpp
+++ b/Tests/CMakeCommands/target_compile_definitions/consumer.cpp
@@ -15,4 +15,12 @@
#error Expected MY_IMPORTEDINTERFACE_DEFINE
#endif
+#ifdef SHOULD_NOT_BE_DEFINED
+#error Unexpected SHOULD_NOT_BE_DEFINED
+#endif
+
+#ifndef SHOULD_BE_DEFINED
+#error Expected SHOULD_BE_DEFINED
+#endif
+
int main() { return 0; }