[Cmake-commits] CMake branch, next, updated. v2.8.12.1-6726-g4bd19c5

Stephen Kelly steveire at gmail.com
Mon Jan 6 11:23:53 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  4bd19c5f2e3d39a70531d9f8690a153c0c3a08c6 (commit)
       via  f71ed5751391b128f8cf6fa9c18afc75d41af0aa (commit)
       via  137c78374ede920587726fcf6fe734a34a2ffa03 (commit)
       via  6b54182bab523455aa439c90d3b221342a448a75 (commit)
       via  7ec34794a556be67eea2addf35900f685ef8b31a (commit)
       via  257a79f663abda7d35e34a7e3e521e4a1454c78c (commit)
       via  5a2ed996f66737e9862f059eca85d541bc1983c5 (commit)
       via  a48f90f76c750355dcd3df36bdd224e941aa8420 (commit)
       via  2e01c3f9914f057792a107d4695d264179a0d232 (commit)
       via  bb67fc4edeebd6457523a0f76ec0a5be6a246696 (commit)
       via  799365dfbd0240c6cd54e2e745d18b36a3d51996 (commit)
       via  050ab5d274ec1e72cb848ef0ea276cc46259a835 (commit)
       via  a67335de19ef9248d0483c80bfa50edd3393444b (commit)
       via  eeae2e873d4a5e67d3b352322b9f78e3d3783ed1 (commit)
       via  274ce58b8adb79e1edc01043d50de25bb23c1cba (commit)
      from  6ecb24df904e230a820b87d7f503780dc38d6e14 (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=4bd19c5f2e3d39a70531d9f8690a153c0c3a08c6
commit 4bd19c5f2e3d39a70531d9f8690a153c0c3a08c6
Merge: 6ecb24d f71ed57
Author:     Stephen Kelly <steveire at gmail.com>
AuthorDate: Mon Jan 6 11:23:51 2014 -0500
Commit:     CMake Topic Stage <kwrobot at kitware.com>
CommitDate: Mon Jan 6 11:23:51 2014 -0500

    Merge topic 'minor-cleanups' into next
    
    f71ed57 Don't allow include() of export(EXPORT) file at configure time.
    137c783 cmTarget: Fix system include annotation propagation.
    6b54182 add_library: Disallow invalid signatures for INTERFACE_LIBRARY.
    7ec3479 cmTarget: Move a variable initialization closer to where it is used.
    257a79f Undefine local preprocessor loop variables.
    5a2ed99 Genex: Reform error-checking for nullary/unary expressions.
    a48f90f cmTarget: Remove some of the INTERFACE_LIBRARY whitelisted properties.
    2e01c3f cmTarget: INTERFACE_LIBRARY is always EXCLUDE_FROM_ALL.
    bb67fc4 export: Rename some variables to reflect content type.
    799365d cmTarget: Enable convenient include dir handling for INTERFACE_LIBRARY.
    050ab5d cmTarget: Remove dead code.
    a67335d Genex: Add EQUAL expression.
    eeae2e8 cmTarget: Use strtol for numeric parsing.
    274ce58 Add cmHasLiteralSuffix API.


http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=f71ed5751391b128f8cf6fa9c18afc75d41af0aa
commit f71ed5751391b128f8cf6fa9c18afc75d41af0aa
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:23:16 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=137c78374ede920587726fcf6fe734a34a2ffa03
commit 137c78374ede920587726fcf6fe734a34a2ffa03
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:23:16 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=6b54182bab523455aa439c90d3b221342a448a75
commit 6b54182bab523455aa439c90d3b221342a448a75
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:23:15 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=7ec34794a556be67eea2addf35900f685ef8b31a
commit 7ec34794a556be67eea2addf35900f685ef8b31a
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:23:15 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=257a79f663abda7d35e34a7e3e521e4a1454c78c
commit 257a79f663abda7d35e34a7e3e521e4a1454c78c
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:23:15 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=5a2ed996f66737e9862f059eca85d541bc1983c5
commit 5a2ed996f66737e9862f059eca85d541bc1983c5
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:23:15 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=a48f90f76c750355dcd3df36bdd224e941aa8420
commit a48f90f76c750355dcd3df36bdd224e941aa8420
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:23:15 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=2e01c3f9914f057792a107d4695d264179a0d232
commit 2e01c3f9914f057792a107d4695d264179a0d232
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:23:15 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=bb67fc4edeebd6457523a0f76ec0a5be6a246696
commit bb67fc4edeebd6457523a0f76ec0a5be6a246696
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:23:15 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=799365dfbd0240c6cd54e2e745d18b36a3d51996
commit 799365dfbd0240c6cd54e2e745d18b36a3d51996
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:23:14 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=050ab5d274ec1e72cb848ef0ea276cc46259a835
commit 050ab5d274ec1e72cb848ef0ea276cc46259a835
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:23:14 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=a67335de19ef9248d0483c80bfa50edd3393444b
commit a67335de19ef9248d0483c80bfa50edd3393444b
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:23:14 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=eeae2e873d4a5e67d3b352322b9f78e3d3783ed1
commit eeae2e873d4a5e67d3b352322b9f78e3d3783ed1
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:23:14 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"

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=274ce58b8adb79e1edc01043d50de25bb23c1cba
commit 274ce58b8adb79e1edc01043d50de25bb23c1cba
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:23:14 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");
 }
 
 

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

Summary of changes:


hooks/post-receive
-- 
CMake


More information about the Cmake-commits mailing list