[Cmake-commits] CMake branch, next, updated. v2.8.12.1-6741-g9255d92

Stephen Kelly steveire at gmail.com
Mon Jan 6 11:28:47 EST 2014


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "CMake".

The branch, next has been updated
       via  9255d92137021c8ea6dbb50a8b2a983b8aecfb06 (commit)
       via  a44aa2ac1afe27469b5b93f91c04102910899772 (commit)
       via  84fac67f90b275116efa9ec25f5fcb2c2bf7f6b4 (commit)
       via  faedd2bea9c98fddd9e9f70deebdb53f8f369124 (commit)
       via  9eb06d0dde52203d3f8ac91ea9a1c5396a09f8af (commit)
       via  10d65d50195e0183120e102c043cc9c96a16a36b (commit)
       via  0f3e8e957f20c0e7c2ad4da326c073c94d7a5816 (commit)
       via  9ba47ee49b41569555f0ef85d7a5fce7ad09f0dc (commit)
       via  fa651c7a198d5c20e2bcb06df4673ec1a270d4d3 (commit)
       via  61d138aea2df9df2da7fa817b47131c73557fbdb (commit)
       via  3429541e1c853207ae77ac033f04888e6c84ebf8 (commit)
       via  7461d67cf37a40ce5a6c20e8eaf4cbfff1c7d27e (commit)
       via  7fc6e3d607c79c1124b2ac93fac0dcddc326ef66 (commit)
       via  2af966d9ab37cb22bd6173f938e83cc710923c3c (commit)
       via  2d6638008c2aeba6015d45160e52d78d92daf57d (commit)
      from  4bd19c5f2e3d39a70531d9f8690a153c0c3a08c6 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=9255d92137021c8ea6dbb50a8b2a983b8aecfb06
commit 9255d92137021c8ea6dbb50a8b2a983b8aecfb06
Merge: 4bd19c5 a44aa2a
Author:     Stephen Kelly <steveire at gmail.com>
AuthorDate: Mon Jan 6 11:28:45 2014 -0500
Commit:     CMake Topic Stage <kwrobot at kitware.com>
CommitDate: Mon Jan 6 11:28:45 2014 -0500

    Merge topic 'minor-cleanups' into next
    
    a44aa2a Add cmHasLiteralSuffix API.
    84fac67 Don't allow include() of export(EXPORT) file at configure time.
    faedd2b cmTarget: Fix system include annotation propagation.
    9eb06d0 add_library: Disallow invalid signatures for INTERFACE_LIBRARY.
    10d65d5 cmTarget: Move a variable initialization closer to where it is used.
    0f3e8e9 Undefine local preprocessor loop variables.
    9ba47ee Genex: Reform error-checking for nullary/unary expressions.
    fa651c7 cmTarget: Remove some of the INTERFACE_LIBRARY whitelisted properties.
    61d138a cmTarget: INTERFACE_LIBRARY is always EXCLUDE_FROM_ALL.
    3429541 export: Rename some variables to reflect content type.
    7461d67 cmTarget: Enable convenient include dir handling for INTERFACE_LIBRARY.
    7fc6e3d cmTarget: Remove dead code.
    2af966d Genex: Add EQUAL expression.
    2d66380 cmTarget: Use strtol for numeric parsing.


http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=a44aa2ac1afe27469b5b93f91c04102910899772
commit a44aa2ac1afe27469b5b93f91c04102910899772
Author:     Stephen Kelly <steveire at gmail.com>
AuthorDate: Mon Dec 30 16:09:46 2013 +0100
Commit:     Stephen Kelly <steveire at gmail.com>
CommitDate: Mon Jan 6 17:25:11 2014 +0100

    Add cmHasLiteralSuffix API.

diff --git a/Source/cmFindPackageCommand.cxx b/Source/cmFindPackageCommand.cxx
index 55c20d6..3329f8a 100644
--- a/Source/cmFindPackageCommand.cxx
+++ b/Source/cmFindPackageCommand.cxx
@@ -1151,8 +1151,8 @@ void cmFindPackageCommand::AddPrefixesSystemEnvironment()
       std::string const& d = *i;
 
       // If the path is a PREFIX/bin case then add its parent instead.
-      if((d.size() >= 4 && strcmp(d.c_str()+d.size()-4, "/bin") == 0) ||
-         (d.size() >= 5 && strcmp(d.c_str()+d.size()-5, "/sbin") == 0))
+      if((d.size() >= 4 && cmHasLiteralSuffix(d, "/bin")) ||
+         (d.size() >= 5 && cmHasLiteralSuffix(d, "/sbin")))
         {
         this->AddPathInternal(cmSystemTools::GetFilenamePath(d), EnvPath);
         }
diff --git a/Source/cmStandardIncludes.h b/Source/cmStandardIncludes.h
index eb6e52f..ebfa8f9 100644
--- a/Source/cmStandardIncludes.h
+++ b/Source/cmStandardIncludes.h
@@ -391,6 +391,22 @@ inline bool cmHasLiteralPrefixImpl(const char* str1,
   return strncmp(str1, str2, N) == 0;
 }
 
+inline bool cmHasLiteralSuffixImpl(const std::string &str1,
+                                   const char *str2,
+                                   size_t N)
+{
+  size_t len = str1.size();
+  return len >= N && strcmp(str1.c_str() + len - N, str2) == 0;
+}
+
+inline bool cmHasLiteralSuffixImpl(const char* str1,
+                                   const char* str2,
+                                   size_t N)
+{
+  size_t len = strlen(str1);
+  return len >= N && strcmp(str1 + len - N, str2) == 0;
+}
+
 #if defined(_MSC_VER) && _MSC_VER < 1300 \
   || defined(__GNUC__) && __GNUC__ < 3 \
   || defined(__BORLANDC__)
@@ -402,6 +418,9 @@ inline bool cmHasLiteralPrefixImpl(const char* str1,
 #define cmHasLiteralPrefix(STR1, STR2) \
   cmHasLiteralPrefixImpl(STR1, "" STR2 "", sizeof(STR2) - 1)
 
+#define cmHasLiteralSuffix(STR1, STR2) \
+  cmHasLiteralSuffixImpl(STR1, "" STR2 "", sizeof(STR2) - 1)
+
 #else
 
 template<typename T, size_t N>
@@ -417,6 +436,12 @@ bool cmHasLiteralPrefix(T str1, const char (&str2)[N])
   return cmHasLiteralPrefixImpl(str1, str2, N - 1);
 }
 
+template<typename T, size_t N>
+bool cmHasLiteralSuffix(T str1, const char (&str2)[N])
+{
+  return cmHasLiteralSuffixImpl(str1, str2, N - 1);
+}
+
 #endif
 
 struct cmStrCmp {
diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx
index b8163c8..1de2358 100644
--- a/Source/cmSystemTools.cxx
+++ b/Source/cmSystemTools.cxx
@@ -359,18 +359,11 @@ bool cmSystemTools::IsOn(const char* val)
 
 bool cmSystemTools::IsNOTFOUND(const char* val)
 {
-  size_t len = strlen(val);
-  const char* notfound = "-NOTFOUND";
-  const size_t lenNotFound = 9;
-  if(len < lenNotFound-1)
+  if(strcmp(val, "NOTFOUND") == 0)
     {
-    return false;
-    }
-  if(len == lenNotFound-1)
-    {
-    return ( strcmp(val, "NOTFOUND") == 0);
+    return true;
     }
-  return ((strncmp((val + (len - lenNotFound)), notfound, lenNotFound) == 0));
+  return cmHasLiteralSuffix(val, "-NOTFOUND");
 }
 
 

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=84fac67f90b275116efa9ec25f5fcb2c2bf7f6b4
commit 84fac67f90b275116efa9ec25f5fcb2c2bf7f6b4
Author:     Stephen Kelly <steveire at gmail.com>
AuthorDate: Thu Dec 26 14:34:27 2013 +0100
Commit:     Stephen Kelly <steveire at gmail.com>
CommitDate: Mon Jan 6 17:25:11 2014 +0100

    Don't allow include() of export(EXPORT) file at configure time.
    
    As a new feature it does not need to participate in CMP0024.
    
    Store cmExportBuildFileGenerator instances which correspond to the
    export(EXPORT) signature in a second map which does not own the
    pointers.  This avoids the need to add cmExportBuildFileGenerator
    and dependencies to the bootstrap system.

diff --git a/Source/cmExportCommand.cxx b/Source/cmExportCommand.cxx
index b6bf870..7c97d8d 100644
--- a/Source/cmExportCommand.cxx
+++ b/Source/cmExportCommand.cxx
@@ -236,8 +236,14 @@ bool cmExportCommand
     {
     ebfg->AddConfiguration("");
     }
-
-  gg->AddBuildExportSet(ebfg);
+  if (this->ExportSet)
+    {
+    gg->AddBuildExportExportSet(ebfg);
+    }
+  else
+    {
+    gg->AddBuildExportSet(ebfg);
+    }
 
   return true;
 }
diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx
index 226a45a..eef8d6d 100644
--- a/Source/cmGlobalGenerator.cxx
+++ b/Source/cmGlobalGenerator.cxx
@@ -187,6 +187,13 @@ void cmGlobalGenerator::AddBuildExportSet(cmExportBuildFileGenerator* gen)
   this->BuildExportSets[gen->GetMainExportFileName()] = gen;
 }
 
+void
+cmGlobalGenerator::AddBuildExportExportSet(cmExportBuildFileGenerator* gen)
+{
+  this->BuildExportSets[gen->GetMainExportFileName()] = gen;
+  this->BuildExportExportSets[gen->GetMainExportFileName()] = gen;
+}
+
 bool cmGlobalGenerator::GenerateImportFile(const std::string &file)
 {
   std::map<std::string, cmExportBuildFileGenerator*>::iterator it
@@ -207,7 +214,12 @@ cmGlobalGenerator::IsExportedTargetsFile(const std::string &filename) const
 {
   const std::map<std::string, cmExportBuildFileGenerator*>::const_iterator it
                                       = this->BuildExportSets.find(filename);
-  return it != this->BuildExportSets.end();
+  if (it == this->BuildExportSets.end())
+    {
+    return false;
+    }
+  return this->BuildExportExportSets.find(filename)
+                                        == this->BuildExportExportSets.end();
 }
 
 // Find the make program for the generator, required for try compiles
diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h
index 049b0e6..fc5cab9 100644
--- a/Source/cmGlobalGenerator.h
+++ b/Source/cmGlobalGenerator.h
@@ -311,6 +311,7 @@ public:
   std::map<std::string, cmExportBuildFileGenerator*>& GetBuildExportSets()
     {return this->BuildExportSets;}
   void AddBuildExportSet(cmExportBuildFileGenerator*);
+  void AddBuildExportExportSet(cmExportBuildFileGenerator*);
   bool IsExportedTargetsFile(const std::string &filename) const;
   bool GenerateImportFile(const std::string &file);
   cmExportBuildFileGenerator*
@@ -375,6 +376,7 @@ protected:
   // Sets of named target exports
   cmExportSetMap ExportSets;
   std::map<std::string, cmExportBuildFileGenerator*> BuildExportSets;
+  std::map<std::string, cmExportBuildFileGenerator*> BuildExportExportSets;
 
   // Manifest of all targets that will be built for each configuration.
   // This is computed just before local generators generate.
diff --git a/Tests/RunCMake/include/ExportExportInclude-result.txt b/Tests/RunCMake/include/ExportExportInclude-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/include/ExportExportInclude-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/include/ExportExportInclude-stderr.txt b/Tests/RunCMake/include/ExportExportInclude-stderr.txt
new file mode 100644
index 0000000..70d013c
--- /dev/null
+++ b/Tests/RunCMake/include/ExportExportInclude-stderr.txt
@@ -0,0 +1,6 @@
+CMake Error at ExportExportInclude.cmake:6 \(include\):
+  include could not find load file:
+
+    .*/Tests/RunCMake/include/ExportExportInclude-build/theTargets.cmake
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/include/ExportExportInclude.cmake b/Tests/RunCMake/include/ExportExportInclude.cmake
new file mode 100644
index 0000000..14e5d91
--- /dev/null
+++ b/Tests/RunCMake/include/ExportExportInclude.cmake
@@ -0,0 +1,6 @@
+
+add_library(iface INTERFACE)
+install(TARGETS iface EXPORT ifaceExport)
+
+export(EXPORT ifaceExport FILE "${CMAKE_CURRENT_BINARY_DIR}/theTargets.cmake")
+include("${CMAKE_CURRENT_BINARY_DIR}/theTargets.cmake")
diff --git a/Tests/RunCMake/include/RunCMakeTest.cmake b/Tests/RunCMake/include/RunCMakeTest.cmake
index 7fc9a12..bea7d5c 100644
--- a/Tests/RunCMake/include/RunCMakeTest.cmake
+++ b/Tests/RunCMake/include/RunCMakeTest.cmake
@@ -4,3 +4,4 @@ run_cmake(EmptyString)
 run_cmake(EmptyStringOptional)
 run_cmake(CMP0024-WARN)
 run_cmake(CMP0024-NEW)
+run_cmake(ExportExportInclude)

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=faedd2bea9c98fddd9e9f70deebdb53f8f369124
commit faedd2bea9c98fddd9e9f70deebdb53f8f369124
Author:     Stephen Kelly <steveire at gmail.com>
AuthorDate: Wed Jan 1 15:49:05 2014 +0100
Commit:     Stephen Kelly <steveire at gmail.com>
CommitDate: Mon Jan 6 17:25:10 2014 +0100

    cmTarget: Fix system include annotation propagation.
    
    Direct users of IMPORTED targets treat INTERFACE_INCLUDE_DIRECTORIES
    as SYSTEM, after commit a63fcbcb (Always consider includes from IMPORTED
    targets to be SYSTEM., 2013-08-29).  It was intended that transitive
    use of an IMPORTED target would have the same behavior, but that
    did not work.  The implementation processed only direct dependencies
    in cmTarget::FinalizeSystemIncludeDirectories.
    
    Implement transitive evaluation of dependencies by traversing the
    link interface of each target in the link implementation.

diff --git a/Source/cmGeneratorExpressionDAGChecker.cxx b/Source/cmGeneratorExpressionDAGChecker.cxx
index 84d7735..c2c4e20 100644
--- a/Source/cmGeneratorExpressionDAGChecker.cxx
+++ b/Source/cmGeneratorExpressionDAGChecker.cxx
@@ -192,7 +192,8 @@ bool
 cmGeneratorExpressionDAGChecker::EvaluatingSystemIncludeDirectories() const
 {
   const char *prop = this->Property.c_str();
-  return strcmp(prop, "INTERFACE_SYSTEM_INCLUDE_DIRECTORIES") == 0;
+  return (strcmp(prop, "SYSTEM_INCLUDE_DIRECTORIES") == 0
+       || strcmp(prop, "INTERFACE_SYSTEM_INCLUDE_DIRECTORIES") == 0);
 }
 
 //----------------------------------------------------------------------------
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index fdd4e6d..6894cfc 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -18,9 +18,12 @@
 #include "cmSourceFile.h"
 #include "cmGeneratorExpression.h"
 #include "cmGeneratorExpressionDAGChecker.h"
+#include "cmComputeLinkInformation.h"
 
 #include <queue>
 
+#include "assert.h"
+
 //----------------------------------------------------------------------------
 cmGeneratorTarget::cmGeneratorTarget(cmTarget* t): Target(t)
 {
@@ -59,10 +62,50 @@ cmGeneratorTarget::GetSourceDepends(cmSourceFile* sf) const
   return 0;
 }
 
+static void handleSystemIncludesDep(cmMakefile *mf, const std::string &name,
+                                  const char *config, cmTarget *headTarget,
+                                  cmGeneratorExpressionDAGChecker *dagChecker,
+                                  std::vector<std::string>& result)
+{
+  cmTarget* depTgt = mf->FindTargetToUse(name.c_str());
+
+  if (!depTgt)
+    {
+    return;
+    }
+
+  cmListFileBacktrace lfbt;
+
+  if (const char* dirs =
+          depTgt->GetProperty("INTERFACE_SYSTEM_INCLUDE_DIRECTORIES"))
+    {
+    cmGeneratorExpression ge(lfbt);
+    cmSystemTools::ExpandListArgument(ge.Parse(dirs)
+                                      ->Evaluate(mf,
+                                      config, false, headTarget,
+                                      depTgt, dagChecker), result);
+    }
+  if (!depTgt->IsImported())
+    {
+    return;
+    }
+
+  if (const char* dirs =
+                depTgt->GetProperty("INTERFACE_INCLUDE_DIRECTORIES"))
+    {
+    cmGeneratorExpression ge(lfbt);
+    cmSystemTools::ExpandListArgument(ge.Parse(dirs)
+                                      ->Evaluate(mf,
+                                      config, false, headTarget,
+                                      depTgt, dagChecker), result);
+    }
+}
+
 //----------------------------------------------------------------------------
 bool cmGeneratorTarget::IsSystemIncludeDirectory(const char *dir,
                                                  const char *config) const
 {
+  assert(this->GetType() != cmTarget::INTERFACE_LIBRARY);
   std::string config_upper;
   if(config && *config)
     {
@@ -75,39 +118,81 @@ bool cmGeneratorTarget::IsSystemIncludeDirectory(const char *dir,
 
   if (iter == this->SystemIncludesCache.end())
     {
+    cmTarget::LinkImplementation const* impl
+                  = this->Target->GetLinkImplementation(config, this->Target);
+    if(!impl)
+      {
+      return false;
+      }
+
+    cmListFileBacktrace lfbt;
+    cmGeneratorExpressionDAGChecker dagChecker(lfbt,
+                                        this->GetName(),
+                                        "SYSTEM_INCLUDE_DIRECTORIES", 0, 0);
+
     std::vector<std::string> result;
     for (std::set<cmStdString>::const_iterator
         it = this->Target->GetSystemIncludeDirectories().begin();
         it != this->Target->GetSystemIncludeDirectories().end(); ++it)
       {
-      cmListFileBacktrace lfbt;
       cmGeneratorExpression ge(lfbt);
+      cmSystemTools::ExpandListArgument(ge.Parse(*it)
+                                          ->Evaluate(this->Makefile,
+                                          config, false, this->Target,
+                                          &dagChecker), result);
+      }
+
+    std::set<cmStdString> uniqueDeps;
+    for(std::vector<std::string>::const_iterator li = impl->Libraries.begin();
+        li != impl->Libraries.end(); ++li)
+      {
+      if (uniqueDeps.insert(*li).second)
+        {
+        cmTarget* tgt = this->Makefile->FindTargetToUse(li->c_str());
 
-      cmGeneratorExpressionDAGChecker dagChecker(lfbt,
-                                                this->GetName(),
-                                "INTERFACE_SYSTEM_INCLUDE_DIRECTORIES", 0, 0);
+        if (!tgt)
+          {
+          continue;
+          }
 
-      cmSystemTools::ExpandListArgument(ge.Parse(*it)
-                                        ->Evaluate(this->Makefile,
-                                        config, false, this->Target,
-                                        &dagChecker), result);
+        handleSystemIncludesDep(this->Makefile, *li, config, this->Target,
+                                &dagChecker, result);
+
+        std::vector<std::string> deps;
+        tgt->GetTransitivePropertyLinkLibraries(config, this->Target, deps);
+
+        for(std::vector<std::string>::const_iterator di = deps.begin();
+            di != deps.end(); ++di)
+          {
+          if (uniqueDeps.insert(*di).second)
+            {
+            handleSystemIncludesDep(this->Makefile, *di, config, this->Target,
+                                    &dagChecker, result);
+            }
+          }
+        }
       }
+    std::set<cmStdString> unique;
     for(std::vector<std::string>::iterator li = result.begin();
         li != result.end(); ++li)
       {
       cmSystemTools::ConvertToUnixSlashes(*li);
+      unique.insert(*li);
+      }
+    result.clear();
+    for(std::set<cmStdString>::iterator li = unique.begin();
+        li != unique.end(); ++li)
+      {
+      result.push_back(*li);
       }
 
     IncludeCacheType::value_type entry(config_upper, result);
     iter = this->SystemIncludesCache.insert(entry).first;
     }
 
-  if (std::find(iter->second.begin(),
-                iter->second.end(), dir) != iter->second.end())
-    {
-    return true;
-    }
-  return false;
+  std::string dirString = dir;
+  return std::binary_search(iter->second.begin(), iter->second.end(),
+                            dirString);
 }
 
 //----------------------------------------------------------------------------
diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx
index 0a56771..226a45a 100644
--- a/Source/cmGlobalGenerator.cxx
+++ b/Source/cmGlobalGenerator.cxx
@@ -1164,17 +1164,6 @@ void cmGlobalGenerator::Generate()
   // it builds by default.
   this->FillLocalGeneratorToTargetMap();
 
-  for (i = 0; i < this->LocalGenerators.size(); ++i)
-    {
-    cmMakefile* mf = this->LocalGenerators[i]->GetMakefile();
-    cmTargets* targets = &(mf->GetTargets());
-    for ( cmTargets::iterator it = targets->begin();
-        it != targets->end(); ++ it )
-      {
-      it->second.FinalizeSystemIncludeDirectories();
-      }
-    }
-
   // Generate project files
   for (i = 0; i < this->LocalGenerators.size(); ++i)
     {
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 4b7bd3b..b06480b 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -1042,62 +1042,6 @@ cmTarget::AddSystemIncludeDirectories(const std::vector<std::string> &incs)
 }
 
 //----------------------------------------------------------------------------
-void cmTarget::FinalizeSystemIncludeDirectories()
-{
-  for (std::vector<cmValueWithOrigin>::const_iterator
-      it = this->Internal->LinkImplementationPropertyEntries.begin(),
-      end = this->Internal->LinkImplementationPropertyEntries.end();
-      it != end; ++it)
-    {
-    if (!cmGeneratorExpression::IsValidTargetName(it->Value)
-        && cmGeneratorExpression::Find(it->Value) == std::string::npos)
-      {
-      continue;
-      }
-    {
-    cmListFileBacktrace lfbt;
-    cmGeneratorExpression ge(lfbt);
-    cmsys::auto_ptr<cmCompiledGeneratorExpression> cge =
-                                                      ge.Parse(it->Value);
-    std::string targetName = cge->Evaluate(this->Makefile, 0,
-                                      false, this, 0, 0);
-    cmTarget *tgt = this->Makefile->FindTargetToUse(targetName.c_str());
-    if (!tgt || tgt == this)
-      {
-      continue;
-      }
-    if (tgt->IsImported()
-        && tgt->GetProperty("INTERFACE_INCLUDE_DIRECTORIES")
-        && !this->GetPropertyAsBool("NO_SYSTEM_FROM_IMPORTED"))
-      {
-      std::string includeGenex = "$<TARGET_PROPERTY:" +
-                                it->Value + ",INTERFACE_INCLUDE_DIRECTORIES>";
-      if (cmGeneratorExpression::Find(it->Value) != std::string::npos)
-        {
-        // Because it->Value is a generator expression, ensure that it
-        // evaluates to the non-empty string before being used in the
-        // TARGET_PROPERTY expression.
-        includeGenex = "$<$<BOOL:" + it->Value + ">:" + includeGenex + ">";
-        }
-      this->SystemIncludeDirectories.insert(includeGenex);
-      return; // The INTERFACE_SYSTEM_INCLUDE_DIRECTORIES are a subset
-              // of the INTERFACE_INCLUDE_DIRECTORIES
-      }
-    }
-    std::string includeGenex = "$<TARGET_PROPERTY:" +
-                        it->Value + ",INTERFACE_SYSTEM_INCLUDE_DIRECTORIES>";
-    if (cmGeneratorExpression::Find(it->Value) != std::string::npos)
-      {
-      // Because it->Value is a generator expression, ensure that it
-      // evaluates to the non-empty string before being used in the
-      // TARGET_PROPERTY expression.
-      includeGenex = "$<$<BOOL:" + it->Value + ">:" + includeGenex + ">";
-      }
-    this->SystemIncludeDirectories.insert(includeGenex);
-    }
-}
-
-//----------------------------------------------------------------------------
 void
 cmTarget::AnalyzeLibDependencies( const cmMakefile& mf )
 {
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index e026c59..4916648 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -568,8 +568,6 @@ public:
   std::set<cmStdString> const & GetSystemIncludeDirectories() const
     { return this->SystemIncludeDirectories; }
 
-  void FinalizeSystemIncludeDirectories();
-
   bool LinkLanguagePropagatesToDependents() const
   { return this->TargetTypeValue == STATIC_LIBRARY; }
 
diff --git a/Tests/IncludeDirectories/SystemIncludeDirectories/CMakeLists.txt b/Tests/IncludeDirectories/SystemIncludeDirectories/CMakeLists.txt
index 1f5c93b..abe9f74 100644
--- a/Tests/IncludeDirectories/SystemIncludeDirectories/CMakeLists.txt
+++ b/Tests/IncludeDirectories/SystemIncludeDirectories/CMakeLists.txt
@@ -25,6 +25,10 @@ add_library(imported_consumer imported_consumer.cpp)
 target_link_libraries(imported_consumer iface)
 target_compile_options(imported_consumer PRIVATE -Werror=unused-variable)
 
+add_library(imported_consumer2 imported_consumer.cpp)
+target_link_libraries(imported_consumer2 imported_consumer)
+target_compile_options(imported_consumer2 PRIVATE -Werror=unused-variable)
+
 macro(do_try_compile error_option)
   set(TC_ARGS
     IFACE_TRY_COMPILE_${error_option}

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=9eb06d0dde52203d3f8ac91ea9a1c5396a09f8af
commit 9eb06d0dde52203d3f8ac91ea9a1c5396a09f8af
Author:     Stephen Kelly <steveire at gmail.com>
AuthorDate: Tue Dec 31 14:52:07 2013 +0100
Commit:     Stephen Kelly <steveire at gmail.com>
CommitDate: Mon Jan 6 17:25:10 2014 +0100

    add_library: Disallow invalid signatures for INTERFACE_LIBRARY.
    
    Document the valid signatures. Add a test for the IMPORTED GLOBAL
    signature.

diff --git a/Help/command/add_library.rst b/Help/command/add_library.rst
index 45f1102..2d69c89 100644
--- a/Help/command/add_library.rst
+++ b/Help/command/add_library.rst
@@ -109,12 +109,21 @@ The signature
 
 ::
 
-  add_library(<name> INTERFACE)
+  add_library(<name> INTERFACE [IMPORTED [GLOBAL]])
 
 creates an interface target.  An interface target does not directly
 create build output, though it may have properties set on it and it
 may be installed, exported and imported.  Typically the INTERFACE_*
 properties are populated on the interface target using the
-set_property(), target_link_libraries(), target_include_directories()
-and target_compile_defintions() commands, and then it is used as an
-argument to target_link_libraries() like any other target.
+:command:`set_property`, :command:`target_link_libraries`,
+:command:`target_include_directories`
+and :command:`target_compile_defintions` commands, and then it is used as an
+argument to :command:`target_link_libraries` like any other target.
+
+An ``INTERFACE`` :prop_tgt:`IMPORTED` target may also be created with this
+signature.  An :prop_tgt:`IMPORTED` library target references a library defined
+outside the project.  The target name has scope in the directory in which it is
+created and below, but the ``GLOBAL`` option extends visibility.  It may be
+referenced like any target built within the project.  :prop_tgt:`IMPORTED`
+libraries are useful for convenient reference from commands like
+:command:`target_link_libraries`.
diff --git a/Source/cmAddLibraryCommand.cxx b/Source/cmAddLibraryCommand.cxx
index 0f98f35..2627445 100644
--- a/Source/cmAddLibraryCommand.cxx
+++ b/Source/cmAddLibraryCommand.cxx
@@ -49,47 +49,117 @@ bool cmAddLibraryCommand
     std::string libType = *s;
     if(libType == "STATIC")
       {
+      if (type == cmTarget::INTERFACE_LIBRARY)
+        {
+        cmOStringStream e;
+        e << "INTERFACE library specified with conflicting STATIC type.";
+        this->SetError(e.str().c_str());
+        return false;
+        }
       ++s;
       type = cmTarget::STATIC_LIBRARY;
       haveSpecifiedType = true;
       }
     else if(libType == "SHARED")
       {
+      if (type == cmTarget::INTERFACE_LIBRARY)
+        {
+        cmOStringStream e;
+        e << "INTERFACE library specified with conflicting SHARED type.";
+        this->SetError(e.str().c_str());
+        return false;
+        }
       ++s;
       type = cmTarget::SHARED_LIBRARY;
       haveSpecifiedType = true;
       }
     else if(libType == "MODULE")
       {
+      if (type == cmTarget::INTERFACE_LIBRARY)
+        {
+        cmOStringStream e;
+        e << "INTERFACE library specified with conflicting MODULE type.";
+        this->SetError(e.str().c_str());
+        return false;
+        }
       ++s;
       type = cmTarget::MODULE_LIBRARY;
       haveSpecifiedType = true;
       }
     else if(libType == "OBJECT")
       {
+      if (type == cmTarget::INTERFACE_LIBRARY)
+        {
+        cmOStringStream e;
+        e << "INTERFACE library specified with conflicting OBJECT type.";
+        this->SetError(e.str().c_str());
+        return false;
+        }
       ++s;
       type = cmTarget::OBJECT_LIBRARY;
       haveSpecifiedType = true;
       }
     else if(libType == "UNKNOWN")
       {
+      if (type == cmTarget::INTERFACE_LIBRARY)
+        {
+        cmOStringStream e;
+        e << "INTERFACE library specified with conflicting UNKNOWN type.";
+        this->SetError(e.str().c_str());
+        return false;
+        }
       ++s;
       type = cmTarget::UNKNOWN_LIBRARY;
       haveSpecifiedType = true;
       }
     else if(libType == "ALIAS")
       {
+      if (type == cmTarget::INTERFACE_LIBRARY)
+        {
+        cmOStringStream e;
+        e << "INTERFACE library specified with conflicting ALIAS type.";
+        this->SetError(e.str().c_str());
+        return false;
+        }
       ++s;
       isAlias = true;
       }
     else if(libType == "INTERFACE")
       {
+      if (haveSpecifiedType)
+        {
+        cmOStringStream e;
+        e << "INTERFACE library specified with conflicting/multiple types.";
+        this->SetError(e.str().c_str());
+        return false;
+        }
+      if (isAlias)
+        {
+        cmOStringStream e;
+        e << "INTERFACE library specified with conflicting ALIAS type.";
+        this->SetError(e.str().c_str());
+        return false;
+        }
+      if (excludeFromAll)
+        {
+        cmOStringStream e;
+        e << "INTERFACE library may not be used with EXCLUDE_FROM_ALL.";
+        this->SetError(e.str().c_str());
+        return false;
+        }
       ++s;
       type = cmTarget::INTERFACE_LIBRARY;
       haveSpecifiedType = true;
       }
     else if(*s == "EXCLUDE_FROM_ALL")
       {
+      if (type == cmTarget::INTERFACE_LIBRARY)
+        {
+        cmOStringStream e;
+        e << "INTERFACE library may not be used with EXCLUDE_FROM_ALL.";
+        this->SetError(e.str().c_str());
+        return false;
+        }
       ++s;
       excludeFromAll = true;
       }
@@ -109,6 +179,24 @@ bool cmAddLibraryCommand
       }
     }
 
+  if (type == cmTarget::INTERFACE_LIBRARY)
+    {
+    if (s != args.end())
+      {
+      cmOStringStream e;
+      e << "INTERFACE library requires no source arguments.";
+      this->SetError(e.str().c_str());
+      return false;
+      }
+    if (importGlobal && !importTarget)
+      {
+      cmOStringStream e;
+      e << "INTERFACE library specified as GLOBAL, but not as IMPORTED.";
+      this->SetError(e.str().c_str());
+      return false;
+      }
+    }
+
   bool nameOk = cmGeneratorExpression::IsValidTargetName(libName) &&
     !cmGlobalGenerator::IsReservedTarget(libName);
 
diff --git a/Tests/InterfaceLibrary/CMakeLists.txt b/Tests/InterfaceLibrary/CMakeLists.txt
index 396a84a..b396eb6 100644
--- a/Tests/InterfaceLibrary/CMakeLists.txt
+++ b/Tests/InterfaceLibrary/CMakeLists.txt
@@ -14,7 +14,7 @@ target_link_libraries(InterfaceLibrary iface_nodepends headeriface)
 add_subdirectory(libsdir)
 
 add_executable(sharedlibtestexe sharedlibtestexe.cpp)
-target_link_libraries(sharedlibtestexe shared_iface)
+target_link_libraries(sharedlibtestexe shared_iface imported::iface)
 
 add_library(broken EXCLUDE_FROM_ALL broken.cpp)
 
diff --git a/Tests/InterfaceLibrary/libsdir/CMakeLists.txt b/Tests/InterfaceLibrary/libsdir/CMakeLists.txt
index 6999646..4e529df 100644
--- a/Tests/InterfaceLibrary/libsdir/CMakeLists.txt
+++ b/Tests/InterfaceLibrary/libsdir/CMakeLists.txt
@@ -24,3 +24,5 @@ target_compile_definitions(shareddependlib
 
 add_library(shared_iface INTERFACE)
 target_link_libraries(shared_iface INTERFACE sharedlib)
+
+add_library(imported::iface INTERFACE IMPORTED GLOBAL)
diff --git a/Tests/RunCMake/interface_library/RunCMakeTest.cmake b/Tests/RunCMake/interface_library/RunCMakeTest.cmake
index d76600c..9ca9a77 100644
--- a/Tests/RunCMake/interface_library/RunCMakeTest.cmake
+++ b/Tests/RunCMake/interface_library/RunCMakeTest.cmake
@@ -4,5 +4,6 @@ run_cmake(invalid_name)
 run_cmake(target_commands)
 run_cmake(no_shared_libs)
 run_cmake(whitelist)
+run_cmake(invalid_signature)
 run_cmake(genex_link)
 run_cmake(add_dependencies)
diff --git a/Tests/RunCMake/interface_library/invalid_signature-result.txt b/Tests/RunCMake/interface_library/invalid_signature-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/interface_library/invalid_signature-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/interface_library/invalid_signature-stderr.txt b/Tests/RunCMake/interface_library/invalid_signature-stderr.txt
new file mode 100644
index 0000000..701586a
--- /dev/null
+++ b/Tests/RunCMake/interface_library/invalid_signature-stderr.txt
@@ -0,0 +1,89 @@
+CMake Error at invalid_signature.cmake:2 \(add_library\):
+  add_library INTERFACE library requires no source arguments.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
++
+CMake Error at invalid_signature.cmake:3 \(add_library\):
+  add_library INTERFACE library specified with conflicting/multiple types.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
++
+CMake Error at invalid_signature.cmake:4 \(add_library\):
+  add_library INTERFACE library specified with conflicting/multiple types.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
++
+CMake Error at invalid_signature.cmake:5 \(add_library\):
+  add_library INTERFACE library specified with conflicting/multiple types.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
++
+CMake Error at invalid_signature.cmake:6 \(add_library\):
+  add_library INTERFACE library specified with conflicting/multiple types.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
++
+CMake Error at invalid_signature.cmake:7 \(add_library\):
+  add_library INTERFACE library specified with conflicting/multiple types.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
++
+CMake Error at invalid_signature.cmake:8 \(add_library\):
+  add_library INTERFACE library specified with conflicting/multiple types.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
++
+CMake Error at invalid_signature.cmake:9 \(add_library\):
+  add_library INTERFACE library specified with conflicting STATIC type.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
++
+CMake Error at invalid_signature.cmake:10 \(add_library\):
+  add_library INTERFACE library specified with conflicting SHARED type.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
++
+CMake Error at invalid_signature.cmake:11 \(add_library\):
+  add_library INTERFACE library specified with conflicting MODULE type.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
++
+CMake Error at invalid_signature.cmake:12 \(add_library\):
+  add_library INTERFACE library specified with conflicting OBJECT type.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
++
+CMake Error at invalid_signature.cmake:13 \(add_library\):
+  add_library INTERFACE library specified with conflicting UNKNOWN type.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
++
+CMake Error at invalid_signature.cmake:14 \(add_library\):
+  add_library INTERFACE library specified with conflicting ALIAS type.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
++
+CMake Error at invalid_signature.cmake:15 \(add_library\):
+  add_library INTERFACE library specified with conflicting ALIAS type.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
++
+CMake Error at invalid_signature.cmake:16 \(add_library\):
+  add_library INTERFACE library specified with conflicting/multiple types.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
++
+CMake Error at invalid_signature.cmake:17 \(add_library\):
+  add_library INTERFACE library may not be used with EXCLUDE_FROM_ALL.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
++
+CMake Error at invalid_signature.cmake:18 \(add_library\):
+  add_library INTERFACE library may not be used with EXCLUDE_FROM_ALL.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
++
+CMake Error at invalid_signature.cmake:20 \(add_library\):
+  add_library INTERFACE library requires no source arguments.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/interface_library/invalid_signature.cmake b/Tests/RunCMake/interface_library/invalid_signature.cmake
new file mode 100644
index 0000000..67e3267
--- /dev/null
+++ b/Tests/RunCMake/interface_library/invalid_signature.cmake
@@ -0,0 +1,20 @@
+
+add_library(iface1 INTERFACE empty.cpp)
+add_library(iface3 STATIC INTERFACE)
+add_library(iface4 STATIC INTERFACE empty.cpp)
+add_library(iface5 SHARED INTERFACE)
+add_library(iface6 MODULE INTERFACE)
+add_library(iface7 OBJECT INTERFACE)
+add_library(iface8 UNKNOWN INTERFACE)
+add_library(iface9 INTERFACE STATIC)
+add_library(iface10 INTERFACE SHARED)
+add_library(iface11 INTERFACE MODULE)
+add_library(iface12 INTERFACE OBJECT)
+add_library(iface13 INTERFACE UNKNOWN)
+add_library(iface14 INTERFACE ALIAS)
+add_library(iface15 ALIAS INTERFACE)
+add_library(iface16 INTERFACE INTERFACE)
+add_library(iface17 INTERFACE EXCLUDE_FROM_ALL)
+add_library(iface18 EXCLUDE_FROM_ALL INTERFACE)
+add_library(iface19 GLOBAL INTERFACE)
+add_library(iface20 INTERFACE GLOBAL)

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=10d65d50195e0183120e102c043cc9c96a16a36b
commit 10d65d50195e0183120e102c043cc9c96a16a36b
Author:     Stephen Kelly <steveire at gmail.com>
AuthorDate: Tue Dec 31 14:35:14 2013 +0100
Commit:     Stephen Kelly <steveire at gmail.com>
CommitDate: Mon Jan 6 17:25:10 2014 +0100

    cmTarget: Move a variable initialization closer to where it is used.
    
    This is more readable and easier to reason about.

diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 3d1a4d4..4b7bd3b 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -5592,9 +5592,6 @@ void cmTarget::ComputeLinkImplementation(const char* config,
                                          LinkImplementation& impl,
                                          cmTarget const* head) const
 {
-  // Compute which library configuration to link.
-  cmTarget::LinkLibraryType linkType = this->ComputeLinkType(config);
-
   // Collect libraries directly linked in this configuration.
   std::vector<std::string> llibs;
   this->GetDirectLinkLibraries(config, llibs, head);
@@ -5687,6 +5684,7 @@ void cmTarget::ComputeLinkImplementation(const char* config,
     impl.Libraries.push_back(item);
     }
 
+  cmTarget::LinkLibraryType linkType = this->ComputeLinkType(config);
   LinkLibraryVectorType const& oldllibs = this->GetOriginalLinkLibraries();
   for(cmTarget::LinkLibraryVectorType::const_iterator li = oldllibs.begin();
       li != oldllibs.end(); ++li)

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=0f3e8e957f20c0e7c2ad4da326c073c94d7a5816
commit 0f3e8e957f20c0e7c2ad4da326c073c94d7a5816
Author:     Stephen Kelly <steveire at gmail.com>
AuthorDate: Tue Dec 31 14:34:16 2013 +0100
Commit:     Stephen Kelly <steveire at gmail.com>
CommitDate: Mon Jan 6 17:25:10 2014 +0100

    Undefine local preprocessor loop variables.
    
    Most occurances of this pattern already contain the undef, so add it to
    the rest too.

diff --git a/Source/cmExportTryCompileFileGenerator.cxx b/Source/cmExportTryCompileFileGenerator.cxx
index d9bc04c..8d37b62 100644
--- a/Source/cmExportTryCompileFileGenerator.cxx
+++ b/Source/cmExportTryCompileFileGenerator.cxx
@@ -36,6 +36,8 @@ bool cmExportTryCompileFileGenerator::GenerateMainFile(std::ostream& os)
 
       CM_FOR_EACH_TRANSITIVE_PROPERTY_NAME(FIND_TARGETS)
 
+#undef FIND_TARGETS
+
       this->PopulateProperties(te, properties, emittedDeps);
 
       this->GenerateInterfaceProperties(te, os, properties);
diff --git a/Source/cmGeneratorExpressionDAGChecker.cxx b/Source/cmGeneratorExpressionDAGChecker.cxx
index 92f74f3..84d7735 100644
--- a/Source/cmGeneratorExpressionDAGChecker.cxx
+++ b/Source/cmGeneratorExpressionDAGChecker.cxx
@@ -40,6 +40,7 @@ cmGeneratorExpressionDAGChecker::cmGeneratorExpressionDAGChecker(
       CM_FOR_EACH_TRANSITIVE_PROPERTY_METHOD(TEST_TRANSITIVE_PROPERTY_METHOD)
       false)
      )
+#undef TEST_TRANSITIVE_PROPERTY_METHOD
     {
     std::map<cmStdString, std::set<cmStdString> >::const_iterator it
                                                     = top->Seen.find(target);
diff --git a/Source/cmGeneratorExpressionDAGChecker.h b/Source/cmGeneratorExpressionDAGChecker.h
index fd47ad7..98ffd36 100644
--- a/Source/cmGeneratorExpressionDAGChecker.h
+++ b/Source/cmGeneratorExpressionDAGChecker.h
@@ -56,7 +56,9 @@ struct cmGeneratorExpressionDAGChecker
 #define DECLARE_TRANSITIVE_PROPERTY_METHOD(METHOD) \
   bool METHOD () const;
 
-CM_FOR_EACH_TRANSITIVE_PROPERTY_METHOD(DECLARE_TRANSITIVE_PROPERTY_METHOD)
+  CM_FOR_EACH_TRANSITIVE_PROPERTY_METHOD(DECLARE_TRANSITIVE_PROPERTY_METHOD)
+
+#undef DECLARE_TRANSITIVE_PROPERTY_METHOD
 
   bool GetTransitivePropertiesOnly();
   void SetTransitivePropertiesOnly()
diff --git a/Source/cmGeneratorExpressionEvaluator.cxx b/Source/cmGeneratorExpressionEvaluator.cxx
index 1ddafca..f0e40ea 100644
--- a/Source/cmGeneratorExpressionEvaluator.cxx
+++ b/Source/cmGeneratorExpressionEvaluator.cxx
@@ -772,6 +772,8 @@ static const char* targetPropertyTransitiveWhitelist[] = {
   CM_FOR_EACH_TRANSITIVE_PROPERTY_NAME(TRANSITIVE_PROPERTY_NAME)
 };
 
+#undef TRANSITIVE_PROPERTY_NAME
+
 std::string getLinkedTargetsContent(const std::vector<std::string> &libraries,
                                   cmTarget const* target,
                                   cmTarget const* headTarget,
@@ -999,6 +1001,7 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
                                             ASSERT_TRANSITIVE_PROPERTY_METHOD)
           false);
         }
+#undef ASSERT_TRANSITIVE_PROPERTY_METHOD
       }
 
     std::string linkedTargetsContent;

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=9ba47ee49b41569555f0ef85d7a5fce7ad09f0dc
commit 9ba47ee49b41569555f0ef85d7a5fce7ad09f0dc
Author:     Stephen Kelly <steveire at gmail.com>
AuthorDate: Tue Dec 31 14:28:52 2013 +0100
Commit:     Stephen Kelly <steveire at gmail.com>
CommitDate: Mon Jan 6 17:25:10 2014 +0100

    Genex: Reform error-checking for nullary/unary expressions.
    
    The error messages were incorrect (reporting that the expression
    requires one or two parameters), and repeated.  Remove the now-unused
    ZeroOrMoreParameters enum value.

diff --git a/Source/cmGeneratorExpressionEvaluator.cxx b/Source/cmGeneratorExpressionEvaluator.cxx
index 83d341e..1ddafca 100644
--- a/Source/cmGeneratorExpressionEvaluator.cxx
+++ b/Source/cmGeneratorExpressionEvaluator.cxx
@@ -49,7 +49,7 @@ struct cmGeneratorExpressionNode
   enum {
     DynamicParameters = 0,
     OneOrMoreParameters = -1,
-    ZeroOrMoreParameters = -2
+    OneOrZeroParameters = -2
   };
   virtual ~cmGeneratorExpressionNode() {}
 
@@ -384,7 +384,7 @@ struct CompilerIdNode : public cmGeneratorExpressionNode
 {
   CompilerIdNode() {}
 
-  virtual int NumExpectedParameters() const { return ZeroOrMoreParameters; }
+  virtual int NumExpectedParameters() const { return OneOrZeroParameters; }
 
   std::string EvaluateWithLanguage(const std::vector<std::string> &parameters,
                        cmGeneratorExpressionContext *context,
@@ -430,12 +430,6 @@ static const struct CCompilerIdNode : public CompilerIdNode
                        const GeneratorExpressionContent *content,
                        cmGeneratorExpressionDAGChecker *dagChecker) const
   {
-    if (parameters.size() != 0 && parameters.size() != 1)
-      {
-      reportError(context, content->GetOriginalExpression(),
-          "$<C_COMPILER_ID> expression requires one or two parameters");
-      return std::string();
-      }
     if (!context->HeadTarget)
       {
       reportError(context, content->GetOriginalExpression(),
@@ -458,12 +452,6 @@ static const struct CXXCompilerIdNode : public CompilerIdNode
                        const GeneratorExpressionContent *content,
                        cmGeneratorExpressionDAGChecker *dagChecker) const
   {
-    if (parameters.size() != 0 && parameters.size() != 1)
-      {
-      reportError(context, content->GetOriginalExpression(),
-          "$<CXX_COMPILER_ID> expression requires one or two parameters");
-      return std::string();
-      }
     if (!context->HeadTarget)
       {
       reportError(context, content->GetOriginalExpression(),
@@ -481,7 +469,7 @@ struct CompilerVersionNode : public cmGeneratorExpressionNode
 {
   CompilerVersionNode() {}
 
-  virtual int NumExpectedParameters() const { return ZeroOrMoreParameters; }
+  virtual int NumExpectedParameters() const { return OneOrZeroParameters; }
 
   std::string EvaluateWithLanguage(const std::vector<std::string> &parameters,
                        cmGeneratorExpressionContext *context,
@@ -526,12 +514,6 @@ static const struct CCompilerVersionNode : public CompilerVersionNode
                        const GeneratorExpressionContent *content,
                        cmGeneratorExpressionDAGChecker *dagChecker) const
   {
-    if (parameters.size() != 0 && parameters.size() != 1)
-      {
-      reportError(context, content->GetOriginalExpression(),
-          "$<C_COMPILER_VERSION> expression requires one or two parameters");
-      return std::string();
-      }
     if (!context->HeadTarget)
       {
       reportError(context, content->GetOriginalExpression(),
@@ -554,13 +536,6 @@ static const struct CxxCompilerVersionNode : public CompilerVersionNode
                        const GeneratorExpressionContent *content,
                        cmGeneratorExpressionDAGChecker *dagChecker) const
   {
-    if (parameters.size() != 0 && parameters.size() != 1)
-      {
-      reportError(context, content->GetOriginalExpression(),
-          "$<CXX_COMPILER_VERSION> expression requires one or two "
-          "parameters");
-      return std::string();
-      }
     if (!context->HeadTarget)
       {
       reportError(context, content->GetOriginalExpression(),
@@ -579,7 +554,7 @@ struct PlatformIdNode : public cmGeneratorExpressionNode
 {
   PlatformIdNode() {}
 
-  virtual int NumExpectedParameters() const { return ZeroOrMoreParameters; }
+  virtual int NumExpectedParameters() const { return OneOrZeroParameters; }
 
   std::string Evaluate(const std::vector<std::string> &parameters,
                        cmGeneratorExpressionContext *context,
@@ -1822,6 +1797,12 @@ std::string GeneratorExpressionContent::EvaluateParameters(
     reportError(context, this->GetOriginalExpression(), "$<" + identifier
                       + "> expression requires at least one parameter.");
     }
+  if (numExpected == cmGeneratorExpressionNode::OneOrZeroParameters
+      && parameters.size() > 2)
+    {
+    reportError(context, this->GetOriginalExpression(), "$<" + identifier
+                      + "> expression requires one or zero parameters.");
+    }
   return std::string();
 }
 

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=fa651c7a198d5c20e2bcb06df4673ec1a270d4d3
commit fa651c7a198d5c20e2bcb06df4673ec1a270d4d3
Author:     Stephen Kelly <steveire at gmail.com>
AuthorDate: Mon Dec 30 22:05:55 2013 +0100
Commit:     Stephen Kelly <steveire at gmail.com>
CommitDate: Mon Jan 6 17:25:10 2014 +0100

    cmTarget: Remove some of the INTERFACE_LIBRARY whitelisted properties.
    
    There is no need to allow EXCLUDE_* properties, because an
    INTERFACE_LIBRARY has no direct build output.
    
    IMPORTED_LINK_INTERFACE_LANGUAGES are relevant only to static
    libraries.
    
    VERSION is relevant only to the filename of direct build outputs,
    which INTERFACE_LIBRARY does not have.

diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx
index b5a46d0..381c1f5 100644
--- a/Source/cmGlobalXCodeGenerator.cxx
+++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -488,7 +488,8 @@ cmGlobalXCodeGenerator::AddExtraTargets(cmLocalGenerator* root,
                                                     dir.c_str());
         }
 
-      if(!target.GetPropertyAsBool("EXCLUDE_FROM_ALL"))
+      if(target.GetType() != cmTarget::INTERFACE_LIBRARY
+          && !target.GetPropertyAsBool("EXCLUDE_FROM_ALL"))
         {
         allbuild->AddUtility(target.GetName());
         }
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 91bd90f..3d1a4d4 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -1403,14 +1403,10 @@ static bool whiteListedInterfaceProperty(const char *prop)
     "COMPATIBLE_INTERFACE_NUMBER_MAX",
     "COMPATIBLE_INTERFACE_NUMBER_MIN",
     "COMPATIBLE_INTERFACE_STRING",
-    "EXCLUDE_FROM_ALL",
-    "EXCLUDE_FROM_DEFAULT_BUILD",
     "EXPORT_NAME",
-    "IMPORTED_LINK_INTERFACE_LANGUAGES",
     "IMPORTED",
     "NAME",
-    "TYPE",
-    "VERSION"
+    "TYPE"
   };
 
   if (std::binary_search(cmArrayBegin(builtIns),
@@ -1421,9 +1417,7 @@ static bool whiteListedInterfaceProperty(const char *prop)
     return true;
     }
 
-  if (cmHasLiteralPrefix(prop, "EXCLUDE_FROM_DEFAULT_BUILD_")
-      || cmHasLiteralPrefix(prop, "IMPORTED_LINK_INTERFACE_LANGUAGES_")
-      || cmHasLiteralPrefix(prop, "MAP_IMPORTED_CONFIG_"))
+  if (cmHasLiteralPrefix(prop, "MAP_IMPORTED_CONFIG_"))
     {
     return true;
     }
@@ -2576,6 +2570,8 @@ void cmTarget::GetTargetVersion(bool soversion,
   minor = 0;
   patch = 0;
 
+  assert(this->GetType() != INTERFACE_LIBRARY);
+
   // Look for a VERSION or SOVERSION property.
   const char* prop = soversion? "SOVERSION" : "VERSION";
   if(const char* version = this->GetProperty(prop))
@@ -3588,6 +3584,8 @@ void cmTarget::GetLibraryNames(std::string& name,
     return;
     }
 
+  assert(this->GetType() != INTERFACE_LIBRARY);
+
   // Check for library version properties.
   const char* version = this->GetProperty("VERSION");
   const char* soversion = this->GetProperty("SOVERSION");
@@ -4163,6 +4161,8 @@ std::string cmTarget::GetOutputName(const char* config, bool implib) const
 //----------------------------------------------------------------------------
 std::string cmTarget::GetFrameworkVersion() const
 {
+  assert(this->GetType() != INTERFACE_LIBRARY);
+
   if(const char* fversion = this->GetProperty("FRAMEWORK_VERSION"))
     {
     return fversion;

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=61d138aea2df9df2da7fa817b47131c73557fbdb
commit 61d138aea2df9df2da7fa817b47131c73557fbdb
Author:     Stephen Kelly <steveire at gmail.com>
AuthorDate: Mon Dec 30 22:12:30 2013 +0100
Commit:     Stephen Kelly <steveire at gmail.com>
CommitDate: Mon Jan 6 17:25:10 2014 +0100

    cmTarget: INTERFACE_LIBRARY is always EXCLUDE_FROM_ALL.

diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx
index 0b58a45..0a56771 100644
--- a/Source/cmGlobalGenerator.cxx
+++ b/Source/cmGlobalGenerator.cxx
@@ -1908,7 +1908,8 @@ bool cmGlobalGenerator::IsExcluded(cmLocalGenerator* root,
 bool cmGlobalGenerator::IsExcluded(cmLocalGenerator* root,
                                    cmTarget& target)
 {
-  if(target.GetPropertyAsBool("EXCLUDE_FROM_ALL"))
+  if(target.GetType() == cmTarget::INTERFACE_LIBRARY
+      || target.GetPropertyAsBool("EXCLUDE_FROM_ALL"))
     {
     // This target is excluded from its directory.
     return true;

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=3429541e1c853207ae77ac033f04888e6c84ebf8
commit 3429541e1c853207ae77ac033f04888e6c84ebf8
Author:     Stephen Kelly <steveire at gmail.com>
AuthorDate: Mon Dec 30 22:01:02 2013 +0100
Commit:     Stephen Kelly <steveire at gmail.com>
CommitDate: Mon Jan 6 17:25:10 2014 +0100

    export: Rename some variables to reflect content type.
    
    This method is used with a list of languages.

diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx
index 2a87e4f..4543f79 100644
--- a/Source/cmExportFileGenerator.cxx
+++ b/Source/cmExportFileGenerator.cxx
@@ -825,36 +825,36 @@ cmExportFileGenerator
 ::SetImportLinkProperty(std::string const& suffix,
                         cmTarget* target,
                         const char* propName,
-                        std::vector<std::string> const& libs,
+                        std::vector<std::string> const& entries,
                         ImportPropertyMap& properties,
                         std::vector<std::string>& missingTargets
                        )
 {
-  // Skip the property if there are no libraries.
-  if(libs.empty())
+  // Skip the property if there are no entries.
+  if(entries.empty())
     {
     return;
     }
 
   // Construct the property value.
-  std::string link_libs;
+  std::string link_entries;
   const char* sep = "";
-  for(std::vector<std::string>::const_iterator li = libs.begin();
-      li != libs.end(); ++li)
+  for(std::vector<std::string>::const_iterator li = entries.begin();
+      li != entries.end(); ++li)
     {
     // Separate this from the previous entry.
-    link_libs += sep;
+    link_entries += sep;
     sep = ";";
 
     std::string temp = *li;
     this->AddTargetNamespace(temp, target, missingTargets);
-    link_libs += temp;
+    link_entries += temp;
     }
 
   // Store the property.
   std::string prop = propName;
   prop += suffix;
-  properties[prop] = link_libs;
+  properties[prop] = link_entries;
 }
 
 
diff --git a/Source/cmExportFileGenerator.h b/Source/cmExportFileGenerator.h
index 6fd23b0..1438f4d 100644
--- a/Source/cmExportFileGenerator.h
+++ b/Source/cmExportFileGenerator.h
@@ -82,7 +82,7 @@ protected:
                                  std::vector<std::string>& missingTargets);
   void SetImportLinkProperty(std::string const& suffix,
                              cmTarget* target, const char* propName,
-                             std::vector<std::string> const& libs,
+                             std::vector<std::string> const& entries,
                              ImportPropertyMap& properties,
                              std::vector<std::string>& missingTargets);
 

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=7461d67cf37a40ce5a6c20e8eaf4cbfff1c7d27e
commit 7461d67cf37a40ce5a6c20e8eaf4cbfff1c7d27e
Author:     Stephen Kelly <steveire at gmail.com>
AuthorDate: Mon Dec 30 14:35:08 2013 +0100
Commit:     Stephen Kelly <steveire at gmail.com>
CommitDate: Mon Jan 6 17:25:10 2014 +0100

    cmTarget: Enable convenient include dir handling for INTERFACE_LIBRARY.
    
    Make the CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE variable affect
    INTERFACE_LIBRARY targets.

diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx
index 3b858af..0b58a45 100644
--- a/Source/cmGlobalGenerator.cxx
+++ b/Source/cmGlobalGenerator.cxx
@@ -1337,13 +1337,13 @@ void cmGlobalGenerator::FinalizeTargetCompileInfo()
       {
       cmTarget* t = &ti->second;
 
+      t->AppendBuildInterfaceIncludes();
+
       if (t->GetType() == cmTarget::INTERFACE_LIBRARY)
         {
         continue;
         }
 
-      t->AppendBuildInterfaceIncludes();
-
       for (std::vector<cmValueWithOrigin>::const_iterator it
                                       = noconfig_compile_definitions.begin();
           it != noconfig_compile_definitions.end(); ++it)
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index b51ea2a..91bd90f 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -1606,6 +1606,7 @@ void cmTarget::AppendBuildInterfaceIncludes()
   if(this->GetType() != cmTarget::SHARED_LIBRARY &&
      this->GetType() != cmTarget::STATIC_LIBRARY &&
      this->GetType() != cmTarget::MODULE_LIBRARY &&
+     this->GetType() != cmTarget::INTERFACE_LIBRARY &&
      !this->IsExecutableWithExports())
     {
     return;
diff --git a/Tests/InterfaceLibrary/CMakeLists.txt b/Tests/InterfaceLibrary/CMakeLists.txt
index 8154ced..396a84a 100644
--- a/Tests/InterfaceLibrary/CMakeLists.txt
+++ b/Tests/InterfaceLibrary/CMakeLists.txt
@@ -6,8 +6,10 @@ project(InterfaceLibrary)
 add_library(iface_nodepends INTERFACE)
 target_compile_definitions(iface_nodepends INTERFACE IFACE_DEFINE)
 
+add_subdirectory(headerdir)
+
 add_executable(InterfaceLibrary definetestexe.cpp)
-target_link_libraries(InterfaceLibrary iface_nodepends)
+target_link_libraries(InterfaceLibrary iface_nodepends headeriface)
 
 add_subdirectory(libsdir)
 
diff --git a/Tests/InterfaceLibrary/definetestexe.cpp b/Tests/InterfaceLibrary/definetestexe.cpp
index decd37c..e7a10c1 100644
--- a/Tests/InterfaceLibrary/definetestexe.cpp
+++ b/Tests/InterfaceLibrary/definetestexe.cpp
@@ -3,6 +3,18 @@
 #error Expected IFACE_DEFINE
 #endif
 
+#include "iface_header.h"
+
+#ifndef IFACE_HEADER_SRCDIR
+#error Expected IFACE_HEADER_SRCDIR
+#endif
+
+#include "iface_header_builddir.h"
+
+#ifndef IFACE_HEADER_BUILDDIR
+#error Expected IFACE_HEADER_BUILDDIR
+#endif
+
 int main(int,char**)
 {
   return 0;
diff --git a/Tests/InterfaceLibrary/headerdir/CMakeLists.txt b/Tests/InterfaceLibrary/headerdir/CMakeLists.txt
new file mode 100644
index 0000000..98f521e
--- /dev/null
+++ b/Tests/InterfaceLibrary/headerdir/CMakeLists.txt
@@ -0,0 +1,8 @@
+
+set(CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE ON)
+
+add_library(headeriface INTERFACE)
+
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/iface_header_builddir.h"
+  "#define IFACE_HEADER_BUILDDIR\n"
+)
diff --git a/Tests/InterfaceLibrary/headerdir/iface_header.h b/Tests/InterfaceLibrary/headerdir/iface_header.h
new file mode 100644
index 0000000..82dd157
--- /dev/null
+++ b/Tests/InterfaceLibrary/headerdir/iface_header.h
@@ -0,0 +1 @@
+#define IFACE_HEADER_SRCDIR

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=7fc6e3d607c79c1124b2ac93fac0dcddc326ef66
commit 7fc6e3d607c79c1124b2ac93fac0dcddc326ef66
Author:     Stephen Kelly <steveire at gmail.com>
AuthorDate: Mon Dec 30 20:35:15 2013 +0100
Commit:     Stephen Kelly <steveire at gmail.com>
CommitDate: Mon Jan 6 17:25:09 2014 +0100

    cmTarget: Remove dead code.
    
    Whitelisting of properties already ensures that the LOCATION
    property will not be read from an INTERFACE_LIBRARY.

diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 472f87d..b51ea2a 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -2688,7 +2688,6 @@ const char *cmTarget::GetProperty(const char* prop,
      this->GetType() == cmTarget::STATIC_LIBRARY ||
      this->GetType() == cmTarget::SHARED_LIBRARY ||
      this->GetType() == cmTarget::MODULE_LIBRARY ||
-     this->GetType() == cmTarget::INTERFACE_LIBRARY ||
      this->GetType() == cmTarget::UNKNOWN_LIBRARY)
     {
     if(strcmp(prop,"LOCATION") == 0)

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=2af966d9ab37cb22bd6173f938e83cc710923c3c
commit 2af966d9ab37cb22bd6173f938e83cc710923c3c
Author:     Stephen Kelly <steveire at gmail.com>
AuthorDate: Fri Dec 27 12:42:37 2013 +0100
Commit:     Stephen Kelly <steveire at gmail.com>
CommitDate: Mon Jan 6 17:25:09 2014 +0100

    Genex: Add EQUAL expression.
    
    Support decimal, hex, octal and binary literals.

diff --git a/Help/manual/cmake-generator-expressions.7.rst b/Help/manual/cmake-generator-expressions.7.rst
index ed28abd..12cfaf8 100644
--- a/Help/manual/cmake-generator-expressions.7.rst
+++ b/Help/manual/cmake-generator-expressions.7.rst
@@ -55,6 +55,8 @@ otherwise expands to nothing.
   ``0`` if ``?`` is ``1``, else ``1``
 ``$<STREQUAL:a,b>``
   ``1`` if ``a`` is STREQUAL ``b``, else ``0``
+``$<EQUAL:a,b>``
+  ``1`` if ``a`` is EQUAL ``b`` in a numeric comparison, else ``0``
 ``$<CONFIG:cfg>``
   ``1`` if config is ``cfg``, else ``0``. This is a case-insensitive comparison.
   The mapping in :prop_tgt:`MAP_IMPORTED_CONFIG_<CONFIG>` is also considered by
diff --git a/Source/cmGeneratorExpressionEvaluator.cxx b/Source/cmGeneratorExpressionEvaluator.cxx
index c8010d0..83d341e 100644
--- a/Source/cmGeneratorExpressionEvaluator.cxx
+++ b/Source/cmGeneratorExpressionEvaluator.cxx
@@ -19,6 +19,7 @@
 #include <cmsys/String.h>
 
 #include <assert.h>
+#include <errno.h>
 
 //----------------------------------------------------------------------------
 #if !defined(__SUNPRO_CC) || __SUNPRO_CC > 0x510
@@ -197,6 +198,92 @@ static const struct StrEqualNode : public cmGeneratorExpressionNode
 } strEqualNode;
 
 //----------------------------------------------------------------------------
+static const struct EqualNode : public cmGeneratorExpressionNode
+{
+  EqualNode() {}
+
+  virtual int NumExpectedParameters() const { return 2; }
+
+  std::string Evaluate(const std::vector<std::string> &parameters,
+                       cmGeneratorExpressionContext *context,
+                       const GeneratorExpressionContent *content,
+                       cmGeneratorExpressionDAGChecker *) const
+  {
+    char *pEnd;
+
+    int base = 0;
+    bool flipSign = false;
+
+    const char *lhs = parameters[0].c_str();
+    if (cmHasLiteralPrefix(lhs, "0b"))
+      {
+      base = 2;
+      lhs += 2;
+      }
+    if (cmHasLiteralPrefix(lhs, "-0b"))
+      {
+      base = 2;
+      lhs += 3;
+      flipSign = true;
+      }
+    if (cmHasLiteralPrefix(lhs, "+0b"))
+      {
+      base = 2;
+      lhs += 3;
+      }
+
+    long lnum = strtol(lhs, &pEnd, base);
+    if (pEnd == lhs || *pEnd != '\0' || errno == ERANGE)
+      {
+      reportError(context, content->GetOriginalExpression(),
+          "$<EQUAL> parameter " + parameters[0] + " is not a valid integer.");
+      return std::string();
+      }
+
+    if (flipSign)
+      {
+      lnum = -lnum;
+      }
+
+    base = 0;
+    flipSign = false;
+
+    const char *rhs = parameters[1].c_str();
+    if (cmHasLiteralPrefix(rhs, "0b"))
+      {
+      base = 2;
+      rhs += 2;
+      }
+    if (cmHasLiteralPrefix(rhs, "-0b"))
+      {
+      base = 2;
+      rhs += 3;
+      flipSign = true;
+      }
+    if (cmHasLiteralPrefix(rhs, "+0b"))
+      {
+      base = 2;
+      rhs += 3;
+      }
+
+    long rnum = strtol(rhs, &pEnd, base);
+    if (pEnd == rhs || *pEnd != '\0' || errno == ERANGE)
+      {
+      reportError(context, content->GetOriginalExpression(),
+          "$<EQUAL> parameter " + parameters[1] + " is not a valid integer.");
+      return std::string();
+      }
+
+    if (flipSign)
+      {
+      rnum = -rnum;
+      }
+
+    return lnum == rnum ? "1" : "0";
+  }
+} equalNode;
+
+//----------------------------------------------------------------------------
 static const struct LowerCaseNode : public cmGeneratorExpressionNode
 {
   LowerCaseNode() {}
@@ -1492,6 +1579,8 @@ cmGeneratorExpressionNode* GetNode(const std::string &identifier)
     return &targetSoNameFileDirNode;
   else if (identifier == "STREQUAL")
     return &strEqualNode;
+  else if (identifier == "EQUAL")
+    return &equalNode;
   else if (identifier == "LOWER_CASE")
     return &lowerCaseNode;
   else if (identifier == "UPPER_CASE")
diff --git a/Tests/CompatibleInterface/CMakeLists.txt b/Tests/CompatibleInterface/CMakeLists.txt
index 47e974a..350b518 100644
--- a/Tests/CompatibleInterface/CMakeLists.txt
+++ b/Tests/CompatibleInterface/CMakeLists.txt
@@ -60,7 +60,7 @@ set_property(TARGET CompatibleInterface PROPERTY STRING_PROP2 prop2)
 set_property(TARGET CompatibleInterface PROPERTY STRING_PROP3 prop3)
 set_property(TARGET CompatibleInterface PROPERTY NUMBER_MIN_PROP1 50)
 set_property(TARGET CompatibleInterface PROPERTY NUMBER_MIN_PROP2 250)
-set_property(TARGET CompatibleInterface PROPERTY NUMBER_MIN_PROP3 0xA)
+set_property(TARGET CompatibleInterface PROPERTY NUMBER_MIN_PROP3 0xa)
 set_property(TARGET CompatibleInterface PROPERTY NUMBER_MIN_PROP4 0x1A)
 set_property(TARGET CompatibleInterface PROPERTY NUMBER_MAX_PROP1 50)
 set_property(TARGET CompatibleInterface PROPERTY NUMBER_MAX_PROP2 250)
@@ -75,7 +75,7 @@ target_compile_definitions(CompatibleInterface
     $<$<STREQUAL:$<TARGET_PROPERTY:STRING_PROP3>,prop3>:STRING_PROP3>
     $<$<STREQUAL:$<TARGET_PROPERTY:NUMBER_MIN_PROP1>,50>:NUMBER_MIN_PROP1=50>
     $<$<STREQUAL:$<TARGET_PROPERTY:NUMBER_MIN_PROP2>,200>:NUMBER_MIN_PROP2=200>
-    $<$<STREQUAL:$<TARGET_PROPERTY:NUMBER_MIN_PROP3>,0xA>:NUMBER_MIN_PROP3=0xA>
+    $<$<EQUAL:$<TARGET_PROPERTY:NUMBER_MIN_PROP3>,0xA>:NUMBER_MIN_PROP3=0xA>
     $<$<STREQUAL:$<TARGET_PROPERTY:NUMBER_MIN_PROP4>,0x10>:NUMBER_MIN_PROP4=0x10>
     $<$<STREQUAL:$<TARGET_PROPERTY:NUMBER_MAX_PROP1>,100>:NUMBER_MAX_PROP1=100>
     $<$<STREQUAL:$<TARGET_PROPERTY:NUMBER_MAX_PROP2>,250>:NUMBER_MAX_PROP2=250>
diff --git a/Tests/GeneratorExpression/CMakeLists.txt b/Tests/GeneratorExpression/CMakeLists.txt
index 892f80f..4fb7ecd 100644
--- a/Tests/GeneratorExpression/CMakeLists.txt
+++ b/Tests/GeneratorExpression/CMakeLists.txt
@@ -196,6 +196,27 @@ add_custom_target(check-part3 ALL
     -Dlower_case=$<LOWER_CASE:Mi,XeD>
     -Dupper_case=$<UPPER_CASE:MiX,eD>
     -Dmake_c_identifier=$<MAKE_C_IDENTIFIER:4f,oo:+bar-$>
+    -Dequal1=$<EQUAL:1,2>
+    -Dequal2=$<EQUAL:1,1>
+    -Dequal3=$<EQUAL:0x1,1>
+    -Dequal4=$<EQUAL:0x1,2>
+    -Dequal5=$<EQUAL:0xA,0xa>
+    -Dequal6=$<EQUAL:0xA,10>
+    -Dequal7=$<EQUAL:0xA,012>
+    -Dequal8=$<EQUAL:10,012>
+    -Dequal9=$<EQUAL:10,010>
+    -Dequal10=$<EQUAL:10,0b1010>
+    -Dequal11=$<EQUAL:-10,-0xa>
+    -Dequal12=$<EQUAL:10,+0xa>
+    -Dequal13=$<EQUAL:+10,+0xa>
+    -Dequal14=$<EQUAL:+10,0xa>
+    -Dequal15=$<EQUAL:-10,-0xa>
+    -Dequal16=$<EQUAL:-10,-0b1010>
+    -Dequal17=$<EQUAL:-10,+0b1010>
+    -Dequal18=$<EQUAL:10,+0b1010>
+    -Dequal19=$<EQUAL:10,+012>
+    -Dequal20=$<EQUAL:10,-012>
+    -Dequal21=$<EQUAL:-10,-012>
     -P ${CMAKE_CURRENT_SOURCE_DIR}/check-part3.cmake
   COMMAND ${CMAKE_COMMAND} -E echo "check done (part 3 of 3)"
   VERBATIM
diff --git a/Tests/GeneratorExpression/check-part3.cmake b/Tests/GeneratorExpression/check-part3.cmake
index 3361eeb..2c6bf49 100644
--- a/Tests/GeneratorExpression/check-part3.cmake
+++ b/Tests/GeneratorExpression/check-part3.cmake
@@ -37,3 +37,24 @@ endforeach()
 check(lower_case "mi,xed")
 check(upper_case "MIX,ED")
 check(make_c_identifier "_4f_oo__bar__")
+check(equal1 "0")
+check(equal2 "1")
+check(equal3 "1")
+check(equal4 "0")
+check(equal5 "1")
+check(equal6 "1")
+check(equal7 "1")
+check(equal8 "1")
+check(equal9 "0")
+check(equal10 "1")
+check(equal11 "1")
+check(equal12 "1")
+check(equal13 "1")
+check(equal14 "1")
+check(equal15 "1")
+check(equal16 "1")
+check(equal17 "0")
+check(equal18 "1")
+check(equal19 "1")
+check(equal20 "0")
+check(equal21 "1")

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=2d6638008c2aeba6015d45160e52d78d92daf57d
commit 2d6638008c2aeba6015d45160e52d78d92daf57d
Author:     Stephen Kelly <steveire at gmail.com>
AuthorDate: Thu Dec 26 16:04:58 2013 +0100
Commit:     Stephen Kelly <steveire at gmail.com>
CommitDate: Mon Jan 6 17:25:09 2014 +0100

    cmTarget: Use strtol for numeric parsing.
    
    On Windows apparently sscanf can not handle hex numbers.
    
    Test that numeric comparison works with hex numbers.

diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index ead48b9..472f87d 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -24,6 +24,7 @@
 #include <set>
 #include <stdlib.h> // required for atof
 #include <assert.h>
+#include <errno.h>
 
 const char* cmTarget::GetTargetTypeName(TargetType targetType)
 {
@@ -4274,6 +4275,7 @@ std::pair<bool, const char*> consistentNumberProperty(const char *lhs,
                                                       const char *rhs,
                                                       CompatibleType t)
 {
+  char *pEnd;
 
 #if defined(_MSC_VER)
   static const char* const null_ptr = 0;
@@ -4281,10 +4283,14 @@ std::pair<bool, const char*> consistentNumberProperty(const char *lhs,
 # define null_ptr 0
 #endif
 
-  double lnum;
-  double rnum;
-  if(sscanf(lhs, "%lg", &lnum) != 1 ||
-      sscanf(rhs, "%lg", &rnum) != 1)
+  long lnum = strtol(lhs, &pEnd, 0);
+  if (pEnd == lhs || *pEnd != '\0' || errno == ERANGE)
+    {
+    return std::pair<bool, const char*>(false, null_ptr);
+    }
+
+  long rnum = strtol(rhs, &pEnd, 0);
+  if (pEnd == rhs || *pEnd != '\0' || errno == ERANGE)
     {
     return std::pair<bool, const char*>(false, null_ptr);
     }
diff --git a/Tests/CompatibleInterface/CMakeLists.txt b/Tests/CompatibleInterface/CMakeLists.txt
index 5e64d2a..47e974a 100644
--- a/Tests/CompatibleInterface/CMakeLists.txt
+++ b/Tests/CompatibleInterface/CMakeLists.txt
@@ -24,6 +24,8 @@ set_property(TARGET iface1 APPEND PROPERTY
   COMPATIBLE_INTERFACE_NUMBER_MIN
     NUMBER_MIN_PROP1
     NUMBER_MIN_PROP2
+    NUMBER_MIN_PROP3
+    NUMBER_MIN_PROP4
 )
 set_property(TARGET iface1 APPEND PROPERTY
   COMPATIBLE_INTERFACE_NUMBER_MAX
@@ -34,7 +36,7 @@ set_property(TARGET iface1 APPEND PROPERTY
 set(CMAKE_DEBUG_TARGET_PROPERTIES
   BOOL_PROP1 BOOL_PROP2 BOOL_PROP3 BOOL_PROP4
   STRING_PROP1 STRING_PROP2 STRING_PROP3
-  NUMBER_MIN_PROP1 NUMBER_MIN_PROP2
+  NUMBER_MIN_PROP1 NUMBER_MIN_PROP2 NUMBER_MIN_PROP3 NUMBER_MIN_PROP4
   NUMBER_MAX_PROP1 NUMBER_MAX_PROP2
 )
 
@@ -44,6 +46,8 @@ set_property(TARGET iface1 PROPERTY INTERFACE_STRING_PROP1 prop1)
 set_property(TARGET iface1 PROPERTY INTERFACE_STRING_PROP2 prop2)
 set_property(TARGET iface1 PROPERTY INTERFACE_NUMBER_MIN_PROP1 100)
 set_property(TARGET iface1 PROPERTY INTERFACE_NUMBER_MIN_PROP2 200)
+set_property(TARGET iface1 PROPERTY INTERFACE_NUMBER_MIN_PROP3 0x10)
+set_property(TARGET iface1 PROPERTY INTERFACE_NUMBER_MIN_PROP4 0x10)
 set_property(TARGET iface1 PROPERTY INTERFACE_NUMBER_MAX_PROP1 100)
 set_property(TARGET iface1 PROPERTY INTERFACE_NUMBER_MAX_PROP2 200)
 
@@ -56,6 +60,8 @@ set_property(TARGET CompatibleInterface PROPERTY STRING_PROP2 prop2)
 set_property(TARGET CompatibleInterface PROPERTY STRING_PROP3 prop3)
 set_property(TARGET CompatibleInterface PROPERTY NUMBER_MIN_PROP1 50)
 set_property(TARGET CompatibleInterface PROPERTY NUMBER_MIN_PROP2 250)
+set_property(TARGET CompatibleInterface PROPERTY NUMBER_MIN_PROP3 0xA)
+set_property(TARGET CompatibleInterface PROPERTY NUMBER_MIN_PROP4 0x1A)
 set_property(TARGET CompatibleInterface PROPERTY NUMBER_MAX_PROP1 50)
 set_property(TARGET CompatibleInterface PROPERTY NUMBER_MAX_PROP2 250)
 
@@ -69,6 +75,8 @@ target_compile_definitions(CompatibleInterface
     $<$<STREQUAL:$<TARGET_PROPERTY:STRING_PROP3>,prop3>:STRING_PROP3>
     $<$<STREQUAL:$<TARGET_PROPERTY:NUMBER_MIN_PROP1>,50>:NUMBER_MIN_PROP1=50>
     $<$<STREQUAL:$<TARGET_PROPERTY:NUMBER_MIN_PROP2>,200>:NUMBER_MIN_PROP2=200>
+    $<$<STREQUAL:$<TARGET_PROPERTY:NUMBER_MIN_PROP3>,0xA>:NUMBER_MIN_PROP3=0xA>
+    $<$<STREQUAL:$<TARGET_PROPERTY:NUMBER_MIN_PROP4>,0x10>:NUMBER_MIN_PROP4=0x10>
     $<$<STREQUAL:$<TARGET_PROPERTY:NUMBER_MAX_PROP1>,100>:NUMBER_MAX_PROP1=100>
     $<$<STREQUAL:$<TARGET_PROPERTY:NUMBER_MAX_PROP2>,250>:NUMBER_MAX_PROP2=250>
 )
diff --git a/Tests/CompatibleInterface/main.cpp b/Tests/CompatibleInterface/main.cpp
index fa299e9..e23625a 100644
--- a/Tests/CompatibleInterface/main.cpp
+++ b/Tests/CompatibleInterface/main.cpp
@@ -33,7 +33,9 @@ enum {
   NumericMaxTest1 = sizeof(CMakeStaticAssert<NUMBER_MAX_PROP1 == 100>),
   NumericMaxTest2 = sizeof(CMakeStaticAssert<NUMBER_MAX_PROP2 == 250>),
   NumericMinTest1 = sizeof(CMakeStaticAssert<NUMBER_MIN_PROP1 == 50>),
-  NumericMinTest2 = sizeof(CMakeStaticAssert<NUMBER_MIN_PROP2 == 200>)
+  NumericMinTest2 = sizeof(CMakeStaticAssert<NUMBER_MIN_PROP2 == 200>),
+  NumericMinTest3 = sizeof(CMakeStaticAssert<NUMBER_MIN_PROP3 == 0xA>),
+  NumericMinTest4 = sizeof(CMakeStaticAssert<NUMBER_MIN_PROP4 == 0x10>)
 };
 
 #include "iface2.h"

-----------------------------------------------------------------------

Summary of changes:


hooks/post-receive
-- 
CMake


More information about the Cmake-commits mailing list