[Cmake-commits] CMake branch, next, updated. v2.8.12-4860-g2e2047b

Stephen Kelly steveire at gmail.com
Mon Nov 4 10:16:45 EST 2013


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  2e2047be1371469be2449b96720ee372d30ce76d (commit)
       via  e27f90430f75a2d3d0957d26ac38432c27725c16 (commit)
       via  1abe6cf39a5b5d4a564a1a535337f91b64709ff9 (commit)
      from  9027cc39da581e6f17f87bc4bd63898e66ec96f3 (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=2e2047be1371469be2449b96720ee372d30ce76d
commit 2e2047be1371469be2449b96720ee372d30ce76d
Merge: 9027cc3 e27f904
Author:     Stephen Kelly <steveire at gmail.com>
AuthorDate: Mon Nov 4 10:16:39 2013 -0500
Commit:     CMake Topic Stage <kwrobot at kitware.com>
CommitDate: Mon Nov 4 10:16:39 2013 -0500

    Merge topic 'target_compile_features' into next
    
    e27f904 Base the target_compile_features command on cmTargetPropCommandBase.
    1abe6cf cmTarget: Transitively evaluate compiler features.


http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=e27f90430f75a2d3d0957d26ac38432c27725c16
commit e27f90430f75a2d3d0957d26ac38432c27725c16
Author:     Stephen Kelly <steveire at gmail.com>
AuthorDate: Wed Oct 30 21:13:44 2013 +0100
Commit:     Stephen Kelly <steveire at gmail.com>
CommitDate: Mon Nov 4 16:16:01 2013 +0100

    Base the target_compile_features command on cmTargetPropCommandBase.
    
    This gives us 'free' handling of IMPORTED, ALIAS, INTERFACE,
    non-compilable and missing targets.

diff --git a/Source/cmTargetCompileFeaturesCommand.cxx b/Source/cmTargetCompileFeaturesCommand.cxx
index 4217eb3..6948717 100644
--- a/Source/cmTargetCompileFeaturesCommand.cxx
+++ b/Source/cmTargetCompileFeaturesCommand.cxx
@@ -15,51 +15,50 @@ bool cmTargetCompileFeaturesCommand::InitialPass(
   std::vector<std::string> const& args,
   cmExecutionStatus &)
 {
-  if (args.size() < 3)
-    {
-      this->SetError("called with wrong number of arguments.");
-      return false;
-    }
-  cmTarget *target = this->Makefile->FindTargetToUse(args[0].c_str());
+  return this->HandleArguments(args, "COMPILE_FEATURES", NO_FLAGS);
+}
 
-  if(!target)
-    {
-    this->SetError("specified invalid target.");
-    return false;
-    }
+void cmTargetCompileFeaturesCommand
+::HandleImportedTarget(const std::string &tgt)
+{
+  cmOStringStream e;
+  e << "Cannot specify compile features for imported target \""
+    << tgt << "\".";
+  this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
+}
 
-  if(target->IsImported())
-    {
-    this->SetError("may not be used with an IMPORTED target.");
-    return false;
-    }
+void cmTargetCompileFeaturesCommand
+::HandleMissingTarget(const std::string &name)
+{
+  cmOStringStream e;
+  e << "Cannot specify compile features for target \"" << name << "\" "
+       "which is not built by this project.";
+  this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
+}
 
-  const bool interfaceOnly = args[1] == "INTERFACE";
-  if(args[1] != "PRIVATE" && args[1] != "PUBLIC" && !interfaceOnly)
+//----------------------------------------------------------------------------
+std::string cmTargetCompileFeaturesCommand
+::Join(const std::vector<std::string> &content)
+{
+  std::string defs;
+  std::string sep;
+  for(std::vector<std::string>::const_iterator it = content.begin();
+    it != content.end(); ++it)
     {
-    this->SetError("called with invalid arguments.");
-    return false;
+    defs += sep + *it;
+    sep = ";";
     }
+  return defs;
+}
 
-  for (size_t i = 2; i < args.size(); ++i)
+//----------------------------------------------------------------------------
+void cmTargetCompileFeaturesCommand
+::HandleDirectContent(cmTarget *tgt, const std::vector<std::string> &content,
+                                   bool, bool)
+{
+  for(std::vector<std::string>::const_iterator it = content.begin();
+    it != content.end(); ++it)
     {
-    std::string feature = args[i];
-
-    if (!interfaceOnly)
-      {
-      bool result = this->Makefile->AddRequiredTargetFeature(target,
-                                                            feature.c_str());
-
-      if (!result)
-        {
-        this->SetError("specified unknown feature.");
-        return false;
-        }
-      }
-    if (interfaceOnly || args[1] == "PUBLIC")
-      {
-      target->AppendProperty("INTERFACE_COMPILE_FEATURES", feature.c_str());
-      }
+    this->Makefile->AddRequiredTargetFeature(tgt, it->c_str());
     }
-  return true;
 }
diff --git a/Source/cmTargetCompileFeaturesCommand.h b/Source/cmTargetCompileFeaturesCommand.h
index 63beeca..9386c84 100644
--- a/Source/cmTargetCompileFeaturesCommand.h
+++ b/Source/cmTargetCompileFeaturesCommand.h
@@ -12,9 +12,9 @@
 #ifndef cmTargetCompileFeaturesCommand_h
 #define cmTargetCompileFeaturesCommand_h
 
-#include "cmCommand.h"
+#include "cmTargetPropCommandBase.h"
 
-class cmTargetCompileFeaturesCommand : public cmCommand
+class cmTargetCompileFeaturesCommand : public cmTargetPropCommandBase
 {
   virtual cmCommand* Clone()
     {
@@ -26,7 +26,16 @@ class cmTargetCompileFeaturesCommand : public cmCommand
 
   virtual const char* GetName() const { return "target_compile_features";}
 
-  cmTypeMacro(cmTargetCompileFeaturesCommand, cmCommand);
+  cmTypeMacro(cmTargetCompileFeaturesCommand, cmTargetPropCommandBase);
+
+private:
+  virtual void HandleImportedTarget(const std::string &tgt);
+  virtual void HandleMissingTarget(const std::string &name);
+
+  virtual void HandleDirectContent(cmTarget *tgt,
+                                   const std::vector<std::string> &content,
+                                   bool prepend, bool system);
+  virtual std::string Join(const std::vector<std::string> &content);
 };
 
 #endif

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=1abe6cf39a5b5d4a564a1a535337f91b64709ff9
commit 1abe6cf39a5b5d4a564a1a535337f91b64709ff9
Author:     Stephen Kelly <steveire at gmail.com>
AuthorDate: Tue Oct 22 01:40:47 2013 +0200
Commit:     Stephen Kelly <steveire at gmail.com>
CommitDate: Mon Nov 4 16:16:01 2013 +0100

    cmTarget: Transitively evaluate compiler features.
    
    Extend the interface of the target_compile_features command with
    PUBLIC and INTERFACE keywords. Populate the INTERFACE_COMPILER_FEATURES
    target property if they are set. Consume the INTERFACE_COMPILER_FEATURES
    target property from linked dependent targets to determine the final
    required compiler features and the compile flag, if needed.

diff --git a/Help/command/target_compile_features.rst b/Help/command/target_compile_features.rst
index ebd9611..e33ba4e 100644
--- a/Help/command/target_compile_features.rst
+++ b/Help/command/target_compile_features.rst
@@ -5,7 +5,7 @@ Add expected compiler features to a target.
 
 ::
 
-  target_compile_features(<target> PRIVATE <feature> [...])
+  target_compile_features(<target> <PRIVATE|PUBLIC|INTERFACE> <feature> [...])
 
 Specify compiler features required when compiling a given target.  If the
 feature is not listed in the :variable:`CMAKE_CXX_COMPILE_FEATURES` variable,
@@ -13,6 +13,12 @@ then an error will be reported by CMake.  If the use of the feature requires
 an additional compiler flag, such as --std=c++11, the flag will be added
 automatically.
 
+The INTERFACE, PUBLIC and PRIVATE keywords are required to specify the
+scope of the features.  PRIVATE and PUBLIC items will
+populate the :prop_tgt:`COMPILE_FEATURES` property of <target>.  PUBLIC and
+INTERFACE items will populate the :prop_tgt:`INTERFACE_COMPILE_FEATURES` property
+of <target>.  Repeated calls for the same <target> append items in the order called.
+
 The named <target> must have been created by a command such as
 add_executable or add_library and must not be an IMPORTED target.
 
diff --git a/Source/cmGeneratorExpressionDAGChecker.cxx b/Source/cmGeneratorExpressionDAGChecker.cxx
index 92dc054..cfcaa70 100644
--- a/Source/cmGeneratorExpressionDAGChecker.cxx
+++ b/Source/cmGeneratorExpressionDAGChecker.cxx
@@ -210,3 +210,11 @@ bool cmGeneratorExpressionDAGChecker::EvaluatingCompileOptions() const
   return (strcmp(prop, "COMPILE_OPTIONS") == 0
        || strcmp(prop, "INTERFACE_COMPILE_OPTIONS") == 0 );
 }
+
+//----------------------------------------------------------------------------
+bool cmGeneratorExpressionDAGChecker::EvaluatingCompileFeatures() const
+{
+  const char *prop = this->Property.c_str();
+  return (strcmp(prop, "COMPILE_FEATURES") == 0
+       || strcmp(prop, "INTERFACE_COMPILE_FEATURES") == 0);
+}
diff --git a/Source/cmGeneratorExpressionDAGChecker.h b/Source/cmGeneratorExpressionDAGChecker.h
index c8594e7..0502430 100644
--- a/Source/cmGeneratorExpressionDAGChecker.h
+++ b/Source/cmGeneratorExpressionDAGChecker.h
@@ -20,13 +20,15 @@
   F(EvaluatingIncludeDirectories) \
   F(EvaluatingSystemIncludeDirectories) \
   F(EvaluatingCompileDefinitions) \
-  F(EvaluatingCompileOptions)
+  F(EvaluatingCompileOptions) \
+  F(EvaluatingCompileFeatures)
 
 #define CM_FOR_EACH_TRANSITIVE_PROPERTY_NAME(F) \
   F(INCLUDE_DIRECTORIES) \
   F(SYSTEM_INCLUDE_DIRECTORIES) \
   F(COMPILE_DEFINITIONS) \
-  F(COMPILE_OPTIONS)
+  F(COMPILE_OPTIONS) \
+  F(COMPILE_FEATURES)
 
 //----------------------------------------------------------------------------
 struct cmGeneratorExpressionDAGChecker
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index f091765..edbcfc6 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -140,6 +140,7 @@ public:
   };
   std::vector<TargetPropertyEntry*> IncludeDirectoriesEntries;
   std::vector<TargetPropertyEntry*> CompileOptionsEntries;
+  std::vector<TargetPropertyEntry*> CompileFeaturesEntries;
   std::vector<TargetPropertyEntry*> CompileDefinitionsEntries;
   std::vector<cmValueWithOrigin> LinkInterfacePropertyEntries;
 
@@ -148,11 +149,14 @@ public:
   std::map<std::string, std::vector<TargetPropertyEntry*> >
                                 CachedLinkInterfaceCompileOptionsEntries;
   std::map<std::string, std::vector<TargetPropertyEntry*> >
+                                CachedLinkInterfaceCompileFeaturesEntries;
+  std::map<std::string, std::vector<TargetPropertyEntry*> >
                                 CachedLinkInterfaceCompileDefinitionsEntries;
 
   std::map<std::string, bool> CacheLinkInterfaceIncludeDirectoriesDone;
   std::map<std::string, bool> CacheLinkInterfaceCompileDefinitionsDone;
   std::map<std::string, bool> CacheLinkInterfaceCompileOptionsDone;
+  std::map<std::string, bool> CacheLinkInterfaceCompileFeaturesDone;
 };
 
 //----------------------------------------------------------------------------
@@ -210,6 +214,7 @@ cmTarget::cmTarget()
   this->BuildInterfaceIncludesAppended = false;
   this->DebugIncludesDone = false;
   this->DebugCompileOptionsDone = false;
+  this->DebugCompileFeaturesDone = false;
   this->DebugCompileDefinitionsDone = false;
 }
 
@@ -2542,6 +2547,121 @@ void cmTarget::GetCompileDefinitions(std::vector<std::string> &list,
 }
 
 //----------------------------------------------------------------------------
+static void processCompileFeatures(cmTarget *tgt,
+      const std::vector<cmTargetInternals::TargetPropertyEntry*> &entries,
+      std::vector<std::string> &options,
+      std::set<std::string> &uniqueOptions,
+      cmGeneratorExpressionDAGChecker *dagChecker,
+      const char *config, bool debugOptions)
+{
+  processCompileOptionsInternal(tgt, entries, options, uniqueOptions,
+                                dagChecker, config, debugOptions, "features");
+}
+
+//----------------------------------------------------------------------------
+void cmTarget::GetCompileFeatures(std::vector<std::string> &result,
+                                 const char *config)
+{
+  std::set<std::string> uniqueFeatures;
+  cmListFileBacktrace lfbt;
+
+  cmGeneratorExpressionDAGChecker dagChecker(lfbt,
+                                             this->GetName(),
+                                             "COMPILE_FEATURES",
+                                             0, 0);
+
+  std::vector<std::string> debugProperties;
+  const char *debugProp =
+              this->Makefile->GetDefinition("CMAKE_DEBUG_TARGET_PROPERTIES");
+  if (debugProp)
+    {
+    cmSystemTools::ExpandListArgument(debugProp, debugProperties);
+    }
+
+  bool debugFeatures = !this->DebugCompileFeaturesDone
+                    && std::find(debugProperties.begin(),
+                                 debugProperties.end(),
+                                 "COMPILE_FEATURES")
+                        != debugProperties.end();
+
+  if (this->Makefile->IsGeneratingBuildSystem())
+    {
+    this->DebugCompileFeaturesDone = true;
+    }
+
+  processCompileFeatures(this,
+                            this->Internal->CompileFeaturesEntries,
+                            result,
+                            uniqueFeatures,
+                            &dagChecker,
+                            config,
+                            debugFeatures);
+
+  std::string configString = config ? config : "";
+  if (!this->Internal->CacheLinkInterfaceCompileFeaturesDone[configString])
+    {
+
+    for (std::vector<cmValueWithOrigin>::const_iterator
+        it = this->Internal->LinkInterfacePropertyEntries.begin(),
+        end = this->Internal->LinkInterfacePropertyEntries.end();
+        it != end; ++it)
+      {
+      if (!cmGeneratorExpression::IsValidTargetName(it->Value)
+          && cmGeneratorExpression::Find(it->Value) == std::string::npos)
+        {
+        continue;
+        }
+      {
+      cmGeneratorExpression ge(lfbt);
+      cmsys::auto_ptr<cmCompiledGeneratorExpression> cge =
+                                                        ge.Parse(it->Value);
+      std::string targetResult = cge->Evaluate(this->Makefile, config,
+                                        false, this, 0, 0);
+      if (!this->Makefile->FindTargetToUse(targetResult.c_str()))
+        {
+        continue;
+        }
+      }
+      std::string featureGenex = "$<TARGET_PROPERTY:" +
+                              it->Value + ",INTERFACE_COMPILE_FEATURES>";
+      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.
+        featureGenex = "$<$<BOOL:" + it->Value + ">:" + featureGenex + ">";
+        }
+      cmGeneratorExpression ge(it->Backtrace);
+      cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(
+                                                                featureGenex);
+
+      this->Internal
+        ->CachedLinkInterfaceCompileFeaturesEntries[configString].push_back(
+                        new cmTargetInternals::TargetPropertyEntry(cge,
+                                                              it->Value));
+      }
+    }
+
+  processCompileFeatures(this,
+    this->Internal->CachedLinkInterfaceCompileFeaturesEntries[configString],
+                            result,
+                            uniqueFeatures,
+                            &dagChecker,
+                            config,
+                            debugFeatures);
+
+  if (!this->Makefile->IsGeneratingBuildSystem())
+    {
+    deleteAndClear(this->Internal->CachedLinkInterfaceCompileFeaturesEntries);
+    }
+  else
+    {
+    this->Internal->CacheLinkInterfaceCompileFeaturesDone[configString]
+                                                                      = true;
+    }
+}
+
+//----------------------------------------------------------------------------
 void cmTarget::MaybeInvalidatePropertyCache(const char* prop)
 {
   // Wipe out maps caching information affected by this property.
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index 9d62f5f..7663d38 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -530,6 +530,8 @@ public:
 
   void GetCompileOptions(std::vector<std::string> &result,
                          const char *config);
+  void GetCompileFeatures(std::vector<std::string> &result,
+                           const char *config);
 
   bool IsNullImpliedByLinkLibraries(const std::string &p);
   bool IsLinkInterfaceDependentBoolProperty(const std::string &p,
@@ -688,6 +690,7 @@ private:
   bool IsImportedTarget;
   bool DebugIncludesDone;
   bool DebugCompileOptionsDone;
+  bool DebugCompileFeaturesDone;
   bool DebugCompileDefinitionsDone;
   mutable std::set<std::string> LinkImplicitNullProperties;
   bool BuildInterfaceIncludesAppended;
diff --git a/Source/cmTargetCompileFeaturesCommand.cxx b/Source/cmTargetCompileFeaturesCommand.cxx
index 7004865..4217eb3 100644
--- a/Source/cmTargetCompileFeaturesCommand.cxx
+++ b/Source/cmTargetCompileFeaturesCommand.cxx
@@ -34,7 +34,8 @@ bool cmTargetCompileFeaturesCommand::InitialPass(
     return false;
     }
 
-  if(args[1] != "PRIVATE")
+  const bool interfaceOnly = args[1] == "INTERFACE";
+  if(args[1] != "PRIVATE" && args[1] != "PUBLIC" && !interfaceOnly)
     {
     this->SetError("called with invalid arguments.");
     return false;
@@ -44,13 +45,20 @@ bool cmTargetCompileFeaturesCommand::InitialPass(
     {
     std::string feature = args[i];
 
-    bool result = this->Makefile->AddRequiredTargetFeature(target,
-                                                          feature.c_str());
+    if (!interfaceOnly)
+      {
+      bool result = this->Makefile->AddRequiredTargetFeature(target,
+                                                            feature.c_str());
 
-    if (!result)
+      if (!result)
+        {
+        this->SetError("specified unknown feature.");
+        return false;
+        }
+      }
+    if (interfaceOnly || args[1] == "PUBLIC")
       {
-      this->SetError("specified unknown feature.");
-      return false;
+      target->AppendProperty("INTERFACE_COMPILE_FEATURES", feature.c_str());
       }
     }
   return true;
diff --git a/Tests/CMakeCommands/target_compile_features/CMakeLists.txt b/Tests/CMakeCommands/target_compile_features/CMakeLists.txt
index 73e22e0..3d10f24 100644
--- a/Tests/CMakeCommands/target_compile_features/CMakeLists.txt
+++ b/Tests/CMakeCommands/target_compile_features/CMakeLists.txt
@@ -11,3 +11,11 @@ add_executable(target_compile_features main.cpp)
 target_compile_features(target_compile_features
   PRIVATE cxx_delegating_constructors
 )
+
+add_library(lib_delegating_constructors lib_delegating_constructors.cpp)
+target_compile_features(lib_delegating_constructors
+  PUBLIC cxx_delegating_constructors
+)
+
+add_executable(lib_user lib_user.cpp)
+target_link_libraries(lib_user lib_delegating_constructors)
diff --git a/Tests/CMakeCommands/target_compile_features/lib_delegating_constructors.cpp b/Tests/CMakeCommands/target_compile_features/lib_delegating_constructors.cpp
new file mode 100644
index 0000000..e597acd
--- /dev/null
+++ b/Tests/CMakeCommands/target_compile_features/lib_delegating_constructors.cpp
@@ -0,0 +1,8 @@
+
+#include "lib_delegating_constructors.h"
+
+Foo::Foo(int i)
+  : m_i(i)
+{
+
+}
diff --git a/Tests/CMakeCommands/target_compile_features/lib_delegating_constructors.h b/Tests/CMakeCommands/target_compile_features/lib_delegating_constructors.h
new file mode 100644
index 0000000..75be701
--- /dev/null
+++ b/Tests/CMakeCommands/target_compile_features/lib_delegating_constructors.h
@@ -0,0 +1,17 @@
+
+#include <cstring>
+
+class Foo
+{
+public:
+  Foo(int i);
+
+  Foo(const char *a)
+    : Foo(strlen(a))
+  {
+
+  }
+
+private:
+  int m_i;
+};
diff --git a/Tests/CMakeCommands/target_compile_features/lib_user.cpp b/Tests/CMakeCommands/target_compile_features/lib_user.cpp
new file mode 100644
index 0000000..83ad51e
--- /dev/null
+++ b/Tests/CMakeCommands/target_compile_features/lib_user.cpp
@@ -0,0 +1,27 @@
+
+#include "lib_delegating_constructors.h"
+
+class Bar
+{
+  Bar(int i)
+    :m_i(i)
+  {
+
+  }
+
+  Bar(const char *a)
+    : Bar(strlen(a))
+  {
+
+  }
+
+private:
+  int m_i;
+};
+
+int main(int argc, char **argv)
+{
+  Foo f("hello");
+  Foo b("world");
+  return 0;
+}

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

Summary of changes:


hooks/post-receive
-- 
CMake


More information about the Cmake-commits mailing list