[Cmake-commits] CMake branch, next, updated. v2.8.10.2-1501-g873239a

Stephen Kelly steveire at gmail.com
Tue Jan 8 15:19:33 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  873239a43e9f5b8fa5f93269e10c27f5636581d8 (commit)
       via  ae55193591fde3e68f312552a6ebcc2900eafec8 (commit)
       via  20e6dafa379aa6cae864304da8ee44729a4781ac (commit)
       via  c110bd199b1b9c3dc9b56b7e3679c2688ae6a6bc (commit)
       via  d0094bda8f11367db281ddfdc9b844e6515d974b (commit)
       via  9305c9f21c399a078d899bb9249cb4bb9087d756 (commit)
       via  b36471bc4f47bd590885f0d013ee38d34bac96a8 (commit)
      from  636f4f4325d21ed078b8fac0c57c24ac58a69271 (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=873239a43e9f5b8fa5f93269e10c27f5636581d8
commit 873239a43e9f5b8fa5f93269e10c27f5636581d8
Merge: 636f4f4 ae55193
Author:     Stephen Kelly <steveire at gmail.com>
AuthorDate: Tue Jan 8 15:19:27 2013 -0500
Commit:     CMake Topic Stage <kwrobot at kitware.com>
CommitDate: Tue Jan 8 15:19:27 2013 -0500

    Merge topic 'LINK_INTERFACE_LIBRARIES-genex' into next
    
    ae55193 Allow generator expressions in LINK_INTERFACE_LIBRARIES.
    20e6daf Split LINK_INTERFACE_LIBRARIES export handling into dedicated method.
    c110bd1 Split the generator expression before extracting targets.
    d0094bd Extract the AddTargetNamespace method.
    9305c9f Don't pass a position when determining if a target name is a literal.
    b36471b Add cmGeneratorExpression::Split() API.


http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=ae55193591fde3e68f312552a6ebcc2900eafec8
commit ae55193591fde3e68f312552a6ebcc2900eafec8
Author:     Stephen Kelly <steveire at gmail.com>
AuthorDate: Fri Jan 4 13:36:18 2013 +0100
Commit:     Stephen Kelly <steveire at gmail.com>
CommitDate: Tue Jan 8 21:16:08 2013 +0100

    Allow generator expressions in LINK_INTERFACE_LIBRARIES.
    
    The Config and IMPORTED_ variants may also contain generator
    expressions.
    
    If 'the implementation is the interface', then the result of
    evaluating the expressions at generate time is used to populate
    the IMPORTED_LINK_INTERFACE_LIBRARIES property.
    
    1) In the case of non-static libraries, this is fine because the
      user still has the option to populate the LINK_INTERFACE_LIBRARIES
      with generator expressions if that is what is wanted.
    
    2) In the case of static libraries, this prevents a footgun,
      enforcing that the interface and the implementation are really
      the same.
    
      Otherwise, the LINK_LIBRARIES could contain a generator
      expression which is evaluated with a different context at build
      time, and when used as an imported target. That would mean that the
      result of evaluating the INTERFACE_LINK_LIBRARIES property for
      a static library would not necessarily be the 'link implementation'.
    
      For example:
    
        add_library(libone STATIC libone.cpp)
        add_library(libtwo STATIC libtwo.cpp)
        add_library(libthree STATIC libthree.cpp)
    
        target_link_libraries(libtwo
          $<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,STATIC_LIBRARY>:libone>)
        target_link_libraries(libthree libtwo)
    
      If the LINK_LIBRARIES content was simply copied to the
      IMPORTED_LINK_INTERFACE_LIBRARIES, then libthree links to libone, but
      executables linking to libthree will not link to libone.
    
    3) As the 'implementation is the interface' concept is to be
      deprecated in the future anyway, this should be fine.

diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx
index 3f5525a..6ed0af7 100644
--- a/Source/cmExportFileGenerator.cxx
+++ b/Source/cmExportFileGenerator.cxx
@@ -359,9 +359,47 @@ cmExportFileGenerator
     {
     return;
     }
-  this->SetImportLinkProperty(suffix, target,
-                              "IMPORTED_LINK_INTERFACE_LIBRARIES",
-                              iface->Libraries, properties, missingTargets);
+
+  if (iface->ImplementationIsInterface)
+    {
+    this->SetImportLinkProperty(suffix, target,
+                                "IMPORTED_LINK_INTERFACE_LIBRARIES",
+                                iface->Libraries, properties, missingTargets);
+    return;
+    }
+
+  const char *propContent;
+
+  if (const char *prop_suffixed = target->GetProperty(
+                    ("LINK_INTERFACE_LIBRARIES" + suffix).c_str()))
+    {
+    propContent = prop_suffixed;
+    }
+  else if (const char *prop = target->GetProperty(
+                    "LINK_INTERFACE_LIBRARIES"))
+    {
+    propContent = prop;
+    }
+  else
+    {
+    return;
+    }
+
+  if (!*propContent)
+    {
+    properties["IMPORTED_LINK_INTERFACE_LIBRARIES" + suffix] = "";
+    return;
+    }
+
+  std::string prepro = cmGeneratorExpression::Preprocess(propContent,
+                                                         preprocessRule);
+  if (!prepro.empty())
+    {
+    this->ResolveTargetsInGeneratorExpressions(prepro, target,
+                                               missingTargets,
+                                               ReplaceFreeTargets);
+    properties["IMPORTED_LINK_INTERFACE_LIBRARIES" + suffix] = prepro;
+    }
 }
 
 //----------------------------------------------------------------------------
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 25054c5..d325dc5 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -4714,16 +4714,30 @@ void cmTarget::ComputeImportInfo(std::string const& desired_config,
   {
   std::string linkProp = "IMPORTED_LINK_INTERFACE_LIBRARIES";
   linkProp += suffix;
-  if(const char* config_libs = this->GetProperty(linkProp.c_str()))
+
+  const char *propertyLibs = this->GetProperty(linkProp.c_str());
+
+  if(!propertyLibs)
     {
-    cmSystemTools::ExpandListArgument(config_libs,
-                                      info.LinkInterface.Libraries);
+    linkProp = "IMPORTED_LINK_INTERFACE_LIBRARIES";
+    propertyLibs = this->GetProperty(linkProp.c_str());
     }
-  else if(const char* libs =
-          this->GetProperty("IMPORTED_LINK_INTERFACE_LIBRARIES"))
+  if(propertyLibs)
     {
-    cmSystemTools::ExpandListArgument(libs,
-                                      info.LinkInterface.Libraries);
+    cmListFileBacktrace lfbt;
+    cmGeneratorExpression ge(lfbt);
+
+    cmGeneratorExpressionDAGChecker dagChecker(lfbt,
+                                        this->GetName(),
+                                        linkProp, 0, 0);
+    cmSystemTools::ExpandListArgument(ge.Parse(propertyLibs)
+                                       ->Evaluate(this->Makefile,
+                                                  desired_config.c_str(),
+                                                  false,
+                                                  headTarget,
+                                                  this,
+                                                  &dagChecker),
+                                    info.LinkInterface.Libraries);
     }
   }
 
@@ -4837,18 +4851,20 @@ bool cmTarget::ComputeLinkInterface(const char* config, LinkInterface& iface,
   // An explicit list of interface libraries may be set for shared
   // libraries and executables that export symbols.
   const char* explicitLibraries = 0;
+  std::string linkIfaceProp;
   if(this->GetType() == cmTarget::SHARED_LIBRARY ||
      this->IsExecutableWithExports())
     {
     // Lookup the per-configuration property.
-    std::string propName = "LINK_INTERFACE_LIBRARIES";
-    propName += suffix;
-    explicitLibraries = this->GetProperty(propName.c_str());
+    linkIfaceProp = "LINK_INTERFACE_LIBRARIES";
+    linkIfaceProp += suffix;
+    explicitLibraries = this->GetProperty(linkIfaceProp.c_str());
 
     // If not set, try the generic property.
     if(!explicitLibraries)
       {
-      explicitLibraries = this->GetProperty("LINK_INTERFACE_LIBRARIES");
+      linkIfaceProp = "LINK_INTERFACE_LIBRARIES";
+      explicitLibraries = this->GetProperty(linkIfaceProp.c_str());
       }
     }
 
@@ -4866,7 +4882,16 @@ bool cmTarget::ComputeLinkInterface(const char* config, LinkInterface& iface,
   if(explicitLibraries)
     {
     // The interface libraries have been explicitly set.
-    cmSystemTools::ExpandListArgument(explicitLibraries, iface.Libraries);
+    cmListFileBacktrace lfbt;
+    cmGeneratorExpression ge(lfbt);
+    cmGeneratorExpressionDAGChecker dagChecker(lfbt, this->GetName(),
+                                               linkIfaceProp, 0, 0);
+    cmSystemTools::ExpandListArgument(ge.Parse(explicitLibraries)->Evaluate(
+                                        this->Makefile,
+                                        config,
+                                        false,
+                                        headTarget,
+                                        this, &dagChecker), iface.Libraries);
 
     if(this->GetType() == cmTarget::SHARED_LIBRARY)
       {
@@ -4909,6 +4934,7 @@ bool cmTarget::ComputeLinkInterface(const char* config, LinkInterface& iface,
     // The link implementation is the default link interface.
     LinkImplementation const* impl = this->GetLinkImplementation(config,
                                                               headTarget);
+    iface.ImplementationIsInterface = true;
     iface.Libraries = impl->Libraries;
     iface.WrongConfigLibraries = impl->WrongConfigLibraries;
     if(this->GetType() == cmTarget::STATIC_LIBRARY)
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index d4069fa..d70da62 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -258,7 +258,9 @@ public:
     // Needed only for OLD behavior of CMP0003.
     std::vector<std::string> WrongConfigLibraries;
 
-    LinkInterface(): Multiplicity(0) {}
+    bool ImplementationIsInterface;
+
+    LinkInterface(): Multiplicity(0), ImplementationIsInterface(false) {}
   };
 
   /** Get the link interface for the given configuration.  Returns 0
diff --git a/Tests/CMakeCommands/target_link_libraries/CMakeLists.txt b/Tests/CMakeCommands/target_link_libraries/CMakeLists.txt
index 6ffef3f..1d0e342 100644
--- a/Tests/CMakeCommands/target_link_libraries/CMakeLists.txt
+++ b/Tests/CMakeCommands/target_link_libraries/CMakeLists.txt
@@ -77,3 +77,13 @@ assert_property(targetA LINK_INTERFACE_LIBRARIES "")
 add_library(depIfaceOnly SHARED EXCLUDE_FROM_ALL depIfaceOnly.cpp)
 generate_export_header(depIfaceOnly)
 set_property(TARGET depB APPEND PROPERTY LINK_INTERFACE_LIBRARIES depIfaceOnly)
+
+add_library(depD SHARED depD.cpp)
+generate_export_header(depD)
+set_property(TARGET depD APPEND PROPERTY
+  LINK_INTERFACE_LIBRARIES
+    $<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,EXECUTABLE>:depA>
+)
+
+add_executable(targetB targetB.cpp)
+target_link_libraries(targetB depD)
diff --git a/Tests/CMakeCommands/target_link_libraries/depD.cpp b/Tests/CMakeCommands/target_link_libraries/depD.cpp
new file mode 100644
index 0000000..b02c76c
--- /dev/null
+++ b/Tests/CMakeCommands/target_link_libraries/depD.cpp
@@ -0,0 +1,13 @@
+
+#include "depD.h"
+
+int DepD::foo()
+{
+  return 0;
+}
+
+DepA DepD::getA()
+{
+  DepA a;
+  return a;
+}
diff --git a/Tests/CMakeCommands/target_link_libraries/depD.h b/Tests/CMakeCommands/target_link_libraries/depD.h
new file mode 100644
index 0000000..d24ff5f
--- /dev/null
+++ b/Tests/CMakeCommands/target_link_libraries/depD.h
@@ -0,0 +1,11 @@
+
+#include "depd_export.h"
+
+#include "depA.h"
+
+struct DEPD_EXPORT DepD
+{
+  int foo();
+
+  DepA getA();
+};
diff --git a/Tests/CMakeCommands/target_link_libraries/targetB.cpp b/Tests/CMakeCommands/target_link_libraries/targetB.cpp
new file mode 100644
index 0000000..063d63a
--- /dev/null
+++ b/Tests/CMakeCommands/target_link_libraries/targetB.cpp
@@ -0,0 +1,10 @@
+
+#include "depD.h"
+
+int main(int argc, char **argv)
+{
+  DepD d;
+  DepA a = d.getA();
+
+  return d.foo() + a.foo();
+}
diff --git a/Tests/ExportImport/Export/CMakeLists.txt b/Tests/ExportImport/Export/CMakeLists.txt
index 569845a..fb17791 100644
--- a/Tests/ExportImport/Export/CMakeLists.txt
+++ b/Tests/ExportImport/Export/CMakeLists.txt
@@ -149,6 +149,7 @@ set_property(TARGET testLibRequired APPEND PROPERTY
     $<BUILD_INTERFACE:$<TARGET_PROPERTY:testLibIncludeRequired4,INTERFACE_INCLUDE_DIRECTORIES>>
     $<BUILD_INTERFACE:$<TARGET_PROPERTY:testLibIncludeRequired5,INTERFACE_INCLUDE_DIRECTORIES>>
     $<INSTALL_INTERFACE:$<TARGET_PROPERTY:testLibIncludeRequired6,INTERFACE_INCLUDE_DIRECTORIES>>
+    $<TARGET_PROPERTY:testLibLibraryRequired,INTERFACE_INCLUDE_DIRECTORIES>
 )
 
 set_property(TARGET testLibRequired APPEND PROPERTY
@@ -158,6 +159,22 @@ set_property(TARGET testLibRequired APPEND PROPERTY
     $<INSTALL_INTERFACE:InstallOnly_DEFINE>
 )
 
+include(GenerateExportHeader)
+add_library(testLibLibraryRequired SHARED testLibLibraryRequired.cpp)
+generate_export_header(testLibLibraryRequired)
+set_property(TARGET testLibLibraryRequired APPEND PROPERTY
+  INCLUDE_DIRECTORIES "${CMAKE_CURRENT_BINARY_DIR}"
+)
+set_property(TARGET testLibLibraryRequired APPEND PROPERTY
+  INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_BINARY_DIR}"
+                                "${CMAKE_CURRENT_SOURCE_DIR}"
+)
+
+set_property(TARGET testLibRequired APPEND PROPERTY
+  LINK_INTERFACE_LIBRARIES
+    $<1:testLibLibraryRequired>
+)
+
 install(TARGETS testLibRequired
                 testLibIncludeRequired1
                 testLibIncludeRequired2
@@ -165,6 +182,7 @@ install(TARGETS testLibRequired
                 testLibIncludeRequired4
                 testLibIncludeRequired5
                 testLibIncludeRequired6
+                testLibLibraryRequired
         EXPORT RequiredExp DESTINATION lib )
 install(EXPORT RequiredExp NAMESPACE Req:: FILE testLibRequiredConfig.cmake DESTINATION lib/cmake/testLibRequired)
 
diff --git a/Tests/ExportImport/Export/testLibLibraryRequired.cpp b/Tests/ExportImport/Export/testLibLibraryRequired.cpp
new file mode 100644
index 0000000..4d48a26
--- /dev/null
+++ b/Tests/ExportImport/Export/testLibLibraryRequired.cpp
@@ -0,0 +1,7 @@
+
+#include "testLibLibraryRequired.h"
+
+int TestLibLibraryRequired::foo()
+{
+  return 0;
+}
diff --git a/Tests/ExportImport/Export/testLibLibraryRequired.h b/Tests/ExportImport/Export/testLibLibraryRequired.h
new file mode 100644
index 0000000..89bc945
--- /dev/null
+++ b/Tests/ExportImport/Export/testLibLibraryRequired.h
@@ -0,0 +1,12 @@
+
+#ifndef TESTLIBLIBRARYREQUIRED_H
+#define TESTLIBLIBRARYREQUIRED_H
+
+#include "testliblibraryrequired_export.h"
+
+struct TESTLIBLIBRARYREQUIRED_EXPORT TestLibLibraryRequired
+{
+  int foo();
+};
+
+#endif
diff --git a/Tests/ExportImport/Import/A/deps_iface.cpp b/Tests/ExportImport/Import/A/deps_iface.cpp
index 7190b92..c0d9735 100644
--- a/Tests/ExportImport/Import/A/deps_iface.cpp
+++ b/Tests/ExportImport/Import/A/deps_iface.cpp
@@ -3,6 +3,8 @@
 #include "testLibIncludeRequired2.h"
 #include "testLibIncludeRequired6.h"
 
+#include "testLibLibraryRequired.h"
+
 #ifndef testLibRequired_IFACE_DEFINE
 #error Expected testLibRequired_IFACE_DEFINE
 #endif
@@ -20,5 +22,7 @@ extern int testLibDepends(void);
 
 int main(int,char **)
 {
-  return testLibDepends();
+  TestLibLibraryRequired ifaceDep;
+
+  return testLibDepends() + ifaceDep.foo();
 }

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=20e6dafa379aa6cae864304da8ee44729a4781ac
commit 20e6dafa379aa6cae864304da8ee44729a4781ac
Author:     Stephen Kelly <steveire at gmail.com>
AuthorDate: Fri Jan 4 15:58:16 2013 +0100
Commit:     Stephen Kelly <steveire at gmail.com>
CommitDate: Tue Jan 8 21:16:08 2013 +0100

    Split LINK_INTERFACE_LIBRARIES export handling into dedicated method.

diff --git a/Source/cmExportBuildFileGenerator.cxx b/Source/cmExportBuildFileGenerator.cxx
index 9533319..29f6743 100644
--- a/Source/cmExportBuildFileGenerator.cxx
+++ b/Source/cmExportBuildFileGenerator.cxx
@@ -107,6 +107,10 @@ cmExportBuildFileGenerator
       std::vector<std::string> missingTargets;
       this->SetImportDetailProperties(config, suffix,
                                       target, properties, missingTargets);
+      this->SetImportLinkInterface(config, suffix,
+                                   cmGeneratorExpression::BuildInterface,
+                                   target, properties, missingTargets);
+
 
       // TOOD: PUBLIC_HEADER_LOCATION
       // This should wait until the build feature propagation stuff
diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx
index 2ba5978..3f5525a 100644
--- a/Source/cmExportFileGenerator.cxx
+++ b/Source/cmExportFileGenerator.cxx
@@ -347,6 +347,26 @@ cmExportFileGenerator::ResolveTargetsInGeneratorExpression(
 //----------------------------------------------------------------------------
 void
 cmExportFileGenerator
+::SetImportLinkInterface(const char* config, std::string const& suffix,
+                    cmGeneratorExpression::PreprocessContext preprocessRule,
+                    cmTarget* target, ImportPropertyMap& properties,
+                    std::vector<std::string>& missingTargets)
+{
+  // Add the transitive link dependencies for this configuration.
+  cmTarget::LinkInterface const* iface = target->GetLinkInterface(config,
+                                                                  target);
+  if (!iface)
+    {
+    return;
+    }
+  this->SetImportLinkProperty(suffix, target,
+                              "IMPORTED_LINK_INTERFACE_LIBRARIES",
+                              iface->Libraries, properties, missingTargets);
+}
+
+//----------------------------------------------------------------------------
+void
+cmExportFileGenerator
 ::SetImportDetailProperties(const char* config, std::string const& suffix,
                             cmTarget* target, ImportPropertyMap& properties,
                             std::vector<std::string>& missingTargets
@@ -388,9 +408,7 @@ cmExportFileGenerator
     this->SetImportLinkProperty(suffix, target,
                                 "IMPORTED_LINK_INTERFACE_LANGUAGES",
                                 iface->Languages, properties, missingTargets);
-    this->SetImportLinkProperty(suffix, target,
-                                "IMPORTED_LINK_INTERFACE_LIBRARIES",
-                                iface->Libraries, properties, missingTargets);
+
     this->SetImportLinkProperty(suffix, target,
                                 "IMPORTED_LINK_DEPENDENT_LIBRARIES",
                                 iface->SharedDeps, properties, missingTargets);
diff --git a/Source/cmExportFileGenerator.h b/Source/cmExportFileGenerator.h
index 866806b..4d97a63 100644
--- a/Source/cmExportFileGenerator.h
+++ b/Source/cmExportFileGenerator.h
@@ -102,6 +102,10 @@ protected:
   void GenerateInterfaceProperties(cmTarget *target, std::ostream& os,
                                    const ImportPropertyMap &properties);
 
+  void SetImportLinkInterface(const char* config, std::string const& suffix,
+                    cmGeneratorExpression::PreprocessContext preprocessRule,
+                    cmTarget* target, ImportPropertyMap& properties,
+                    std::vector<std::string>& missingTargets);
 
   enum FreeTargetsReplace {
     ReplaceFreeTargets,
diff --git a/Source/cmExportInstallFileGenerator.cxx b/Source/cmExportInstallFileGenerator.cxx
index bc953c9..68881a1 100644
--- a/Source/cmExportInstallFileGenerator.cxx
+++ b/Source/cmExportInstallFileGenerator.cxx
@@ -229,6 +229,10 @@ cmExportInstallFileGenerator
       this->SetImportDetailProperties(config, suffix,
                                       te->Target, properties, missingTargets);
 
+      this->SetImportLinkInterface(config, suffix,
+                                   cmGeneratorExpression::InstallInterface,
+                                   te->Target, properties, missingTargets);
+
       // TOOD: PUBLIC_HEADER_LOCATION
       // This should wait until the build feature propagation stuff
       // is done.  Then this can be a propagated include directory.

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=c110bd199b1b9c3dc9b56b7e3679c2688ae6a6bc
commit c110bd199b1b9c3dc9b56b7e3679c2688ae6a6bc
Author:     Stephen Kelly <steveire at gmail.com>
AuthorDate: Fri Jan 4 15:56:13 2013 +0100
Commit:     Stephen Kelly <steveire at gmail.com>
CommitDate: Tue Jan 8 21:16:08 2013 +0100

    Split the generator expression before extracting targets.
    
    Now that we're processing a LINK_INTERFACE_LIBRARIES string, it
    can contain targets. Make sure they are extracted for
    namespacing purposes.
    
    This needs to be restricted to strings which can actually have
    targets named in them. For example, this is not done for
    INTERFACE_COMPILE_DEFINITIONS, because even if there is a target
    named 'foo', the string 'foo' in that property means that '-Dfoo'
    will be set when compiling.

diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx
index da18856..2ba5978 100644
--- a/Source/cmExportFileGenerator.cxx
+++ b/Source/cmExportFileGenerator.cxx
@@ -219,10 +219,55 @@ cmExportFileGenerator::AddTargetNamespace(std::string &input,
 }
 
 //----------------------------------------------------------------------------
+static bool isGeneratorExpression(const std::string &lib)
+{
+  const std::string::size_type openpos = lib.find("$<");
+  return (openpos != std::string::npos)
+      && (lib.find(">", openpos) != std::string::npos);
+}
+
+//----------------------------------------------------------------------------
 void
 cmExportFileGenerator::ResolveTargetsInGeneratorExpressions(
                                     std::string &input,
                                     cmTarget* target,
+                                    std::vector<std::string> &missingTargets,
+                                    FreeTargetsReplace replace)
+{
+  if (replace == NoReplaceFreeTargets)
+    {
+    this->ResolveTargetsInGeneratorExpression(input, target, missingTargets);
+    return;
+    }
+  std::vector<std::string> parts;
+  cmGeneratorExpression::Split(input, parts);
+
+  std::string sep;
+  input = "";
+  for(std::vector<std::string>::iterator li = parts.begin();
+      li != parts.end(); ++li)
+    {
+    if (!isGeneratorExpression(input))
+      {
+      this->AddTargetNamespace(*li, target, missingTargets);
+      }
+    else
+      {
+      this->ResolveTargetsInGeneratorExpression(
+                                    *li,
+                                    target,
+                                    missingTargets);
+      }
+    input += sep + *li;
+    sep = ";";
+    }
+}
+
+//----------------------------------------------------------------------------
+void
+cmExportFileGenerator::ResolveTargetsInGeneratorExpression(
+                                    std::string &input,
+                                    cmTarget* target,
                                     std::vector<std::string> &missingTargets)
 {
   std::string::size_type pos = 0;
diff --git a/Source/cmExportFileGenerator.h b/Source/cmExportFileGenerator.h
index a5b25f4..866806b 100644
--- a/Source/cmExportFileGenerator.h
+++ b/Source/cmExportFileGenerator.h
@@ -102,9 +102,16 @@ protected:
   void GenerateInterfaceProperties(cmTarget *target, std::ostream& os,
                                    const ImportPropertyMap &properties);
 
+
+  enum FreeTargetsReplace {
+    ReplaceFreeTargets,
+    NoReplaceFreeTargets
+  };
+
   void ResolveTargetsInGeneratorExpressions(std::string &input,
-                                    cmTarget* target,
-                                    std::vector<std::string> &missingTargets);
+                          cmTarget* target,
+                          std::vector<std::string> &missingTargets,
+                          FreeTargetsReplace replace = NoReplaceFreeTargets);
 
   // The namespace in which the exports are placed in the generated file.
   std::string Namespace;
@@ -132,6 +139,9 @@ private:
   bool AddTargetNamespace(std::string &input, cmTarget* target,
                           std::vector<std::string> &missingTargets);
 
+  void ResolveTargetsInGeneratorExpression(std::string &input,
+                                    cmTarget* target,
+                                    std::vector<std::string> &missingTargets);
 };
 
 #endif

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=d0094bda8f11367db281ddfdc9b844e6515d974b
commit d0094bda8f11367db281ddfdc9b844e6515d974b
Author:     Stephen Kelly <steveire at gmail.com>
AuthorDate: Tue Jan 8 20:58:33 2013 +0100
Commit:     Stephen Kelly <steveire at gmail.com>
CommitDate: Tue Jan 8 21:16:07 2013 +0100

    Extract the AddTargetNamespace method.

diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx
index 56b088e..da18856 100644
--- a/Source/cmExportFileGenerator.cxx
+++ b/Source/cmExportFileGenerator.cxx
@@ -184,6 +184,41 @@ void cmExportFileGenerator::GenerateInterfaceProperties(cmTarget *target,
 }
 
 //----------------------------------------------------------------------------
+bool
+cmExportFileGenerator::AddTargetNamespace(std::string &input,
+                                    cmTarget* target,
+                                    std::vector<std::string> &missingTargets)
+{
+  cmMakefile *mf = target->GetMakefile();
+
+  cmTarget *tgt = mf->FindTargetToUse(input.c_str());
+  if (!tgt)
+    {
+    return false;
+    }
+
+  if(tgt->IsImported())
+    {
+    return true;
+    }
+  if(this->ExportedTargets.find(tgt) != this->ExportedTargets.end())
+    {
+    input = this->Namespace + input;
+    }
+  else
+    {
+    std::string namespacedTarget;
+    this->HandleMissingTarget(namespacedTarget, missingTargets,
+                              mf, target, tgt);
+    if (!namespacedTarget.empty())
+      {
+      input = namespacedTarget;
+      }
+    }
+  return true;
+}
+
+//----------------------------------------------------------------------------
 void
 cmExportFileGenerator::ResolveTargetsInGeneratorExpressions(
                                     std::string &input,
@@ -212,45 +247,17 @@ cmExportFileGenerator::ResolveTargetsInGeneratorExpressions(
       continue;
       }
 
-    const std::string targetName = input.substr(nameStartPos,
+    std::string targetName = input.substr(nameStartPos,
                                                 commaPos - nameStartPos);
 
-    pos = nameStartPos; // We're not going to replace the entire expression,
-                        // but only the target parameter.
-    if (cmTarget *tgt = mf->FindTargetToUse(targetName.c_str()))
-      {
-      if(tgt->IsImported())
-        {
-        pos += targetName.size();
-        }
-      else if(this->ExportedTargets.find(tgt) != this->ExportedTargets.end())
-        {
-        input.replace(pos, targetName.size(),
-                      this->Namespace + targetName);
-        pos += this->Namespace.size() + targetName.size();
-        }
-      else
-        {
-        std::string namespacedTarget;
-        this->HandleMissingTarget(namespacedTarget, missingTargets,
-                                  mf, target, tgt);
-        if (!namespacedTarget.empty())
-          {
-          input.replace(pos, targetName.size(), namespacedTarget);
-          pos += namespacedTarget.size();
-          }
-        }
-      }
-    else
+    if (!this->AddTargetNamespace(targetName, target, missingTargets))
       {
       errorString = "$<TARGET_PROPERTY:" + targetName + ",prop> requires "
                     "its first parameter to be a reachable target.";
-      }
-    lastPos = pos;
-    if (!errorString.empty())
-      {
       break;
       }
+    input.replace(nameStartPos, commaPos - nameStartPos, targetName);
+    lastPos = pos + targetName.size();
     }
   if (!errorString.empty())
     {
@@ -267,51 +274,24 @@ cmExportFileGenerator::ResolveTargetsInGeneratorExpressions(
     if (endPos == input.npos)
       {
       errorString = "$<TARGET_NAME:...> expression incomplete";
+      break;
       }
-    const std::string targetName = input.substr(nameStartPos,
+    std::string targetName = input.substr(nameStartPos,
                                                 endPos - nameStartPos);
     if(targetName.find("$<") != input.npos)
       {
       errorString = "$<TARGET_NAME:...> requires its parameter to be a "
                     "literal.";
+      break;
       }
-    if (cmTarget *tgt = mf->FindTargetToUse(targetName.c_str()))
-      {
-      if(tgt->IsImported())
-        {
-        input.replace(pos, sizeof("$<TARGET_NAME:") + targetName.size(),
-                      targetName);
-        pos += sizeof("$<TARGET_NAME:") + targetName.size();
-        }
-      else if(this->ExportedTargets.find(tgt) != this->ExportedTargets.end())
-        {
-        input.replace(pos, sizeof("$<TARGET_NAME:") + targetName.size(),
-                      this->Namespace + targetName);
-        pos += sizeof("$<TARGET_NAME:") + targetName.size();
-        }
-      else
-        {
-        std::string namespacedTarget;
-        this->HandleMissingTarget(namespacedTarget, missingTargets,
-                                  mf, target, tgt);
-        if (!namespacedTarget.empty())
-          {
-          input.replace(pos, sizeof("$<TARGET_NAME:") + targetName.size(),
-                        namespacedTarget);
-          pos += sizeof("$<TARGET_NAME:") + targetName.size();
-          }
-        }
-      }
-    else
+    if (!this->AddTargetNamespace(targetName, target, missingTargets))
       {
       errorString = "$<TARGET_NAME:...> requires its parameter to be a "
                     "reachable target.";
-      }
-    lastPos = pos;
-    if (!errorString.empty())
-      {
       break;
       }
+    input.replace(pos, endPos - pos + 1, targetName);
+    lastPos = endPos;
     }
   if (!errorString.empty())
     {
@@ -397,9 +377,6 @@ cmExportFileGenerator
     return;
     }
 
-  // Get the makefile in which to lookup target information.
-  cmMakefile* mf = target->GetMakefile();
-
   // Construct the property value.
   std::string link_libs;
   const char* sep = "";
@@ -410,33 +387,9 @@ cmExportFileGenerator
     link_libs += sep;
     sep = ";";
 
-    // Append this entry.
-    if(cmTarget* tgt = mf->FindTargetToUse(li->c_str()))
-      {
-      // This is a target.
-      if(tgt->IsImported())
-        {
-        // The target is imported (and therefore is not in the
-        // export).  Append the raw name.
-        link_libs += *li;
-        }
-      else if(this->ExportedTargets.find(tgt) != this->ExportedTargets.end())
-        {
-        // The target is in the export.  Append it with the export
-        // namespace.
-        link_libs += this->Namespace;
-        link_libs += *li;
-        }
-      else
-        {
-        this->HandleMissingTarget(link_libs, missingTargets, mf, target, tgt);
-        }
-      }
-    else
-      {
-      // Append the raw name.
-      link_libs += *li;
-      }
+    std::string temp = *li;
+    this->AddTargetNamespace(temp, target, missingTargets);
+    link_libs += temp;
     }
 
   // Store the property.
diff --git a/Source/cmExportFileGenerator.h b/Source/cmExportFileGenerator.h
index 7c58ad8..a5b25f4 100644
--- a/Source/cmExportFileGenerator.h
+++ b/Source/cmExportFileGenerator.h
@@ -128,6 +128,10 @@ private:
                                  cmGeneratorExpression::PreprocessContext,
                                  ImportPropertyMap &properties,
                                  std::vector<std::string> &missingTargets);
+
+  bool AddTargetNamespace(std::string &input, cmTarget* target,
+                          std::vector<std::string> &missingTargets);
+
 };
 
 #endif

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=9305c9f21c399a078d899bb9249cb4bb9087d756
commit 9305c9f21c399a078d899bb9249cb4bb9087d756
Author:     Stephen Kelly <steveire at gmail.com>
AuthorDate: Tue Jan 8 21:06:24 2013 +0100
Commit:     Stephen Kelly <steveire at gmail.com>
CommitDate: Tue Jan 8 21:06:24 2013 +0100

    Don't pass a position when determining if a target name is a literal.
    
    The lastPos refers to a position in a different string.

diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx
index 90c0c41..56b088e 100644
--- a/Source/cmExportFileGenerator.cxx
+++ b/Source/cmExportFileGenerator.cxx
@@ -270,7 +270,7 @@ cmExportFileGenerator::ResolveTargetsInGeneratorExpressions(
       }
     const std::string targetName = input.substr(nameStartPos,
                                                 endPos - nameStartPos);
-    if(targetName.find("$<", lastPos) != input.npos)
+    if(targetName.find("$<") != input.npos)
       {
       errorString = "$<TARGET_NAME:...> requires its parameter to be a "
                     "literal.";

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=b36471bc4f47bd590885f0d013ee38d34bac96a8
commit b36471bc4f47bd590885f0d013ee38d34bac96a8
Author:     Stephen Kelly <steveire at gmail.com>
AuthorDate: Mon Dec 10 12:00:34 2012 +0100
Commit:     Stephen Kelly <steveire at gmail.com>
CommitDate: Tue Jan 8 20:34:17 2013 +0100

    Add cmGeneratorExpression::Split() API.
    
    It can split a string like
    
     "A;$<1:B>;$<1:C>;D;E;$<1:F;G;H>;$<1:I>;J"
    
    into
    
     "A" "$<1:B>" "$<1:C>" "D" "E" "$<1:F;G;H>" "$<1:I>" "J"

diff --git a/Source/cmGeneratorExpression.cxx b/Source/cmGeneratorExpression.cxx
index 6d003e1..9b04e6a 100644
--- a/Source/cmGeneratorExpression.cxx
+++ b/Source/cmGeneratorExpression.cxx
@@ -243,6 +243,67 @@ static std::string stripExportInterface(const std::string &input,
 }
 
 //----------------------------------------------------------------------------
+void cmGeneratorExpression::Split(const std::string &input,
+                                  std::vector<std::string> &output)
+{
+  std::string::size_type pos = 0;
+  std::string::size_type lastPos = pos;
+  while((pos = input.find("$<", lastPos)) != input.npos)
+    {
+    std::string part = input.substr(lastPos, pos - lastPos);
+    std::string preGenex;
+    if (!part.empty())
+      {
+      std::string::size_type startPos = input.rfind(";", pos);
+      if (startPos != pos - 1 && startPos >= lastPos)
+        {
+        part = input.substr(lastPos, startPos - lastPos);
+        preGenex = input.substr(startPos + 1, pos - startPos - 1);
+        }
+      cmSystemTools::ExpandListArgument(part.c_str(), output);
+      }
+    pos += 2;
+    int nestingLevel = 1;
+    const char *c = input.c_str() + pos;
+    const char * const cStart = c;
+    for ( ; *c; ++c)
+      {
+      if(c[0] == '$' && c[1] == '<')
+        {
+        ++nestingLevel;
+        ++c;
+        continue;
+        }
+      if(c[0] == '>')
+        {
+        --nestingLevel;
+        if (nestingLevel == 0)
+          {
+          break;
+          }
+        }
+      }
+    for ( ; *c; ++c)
+      {
+      // Capture the part after the genex and before the next ';'
+      if(c[0] == ';')
+        {
+        --c;
+        break;
+        }
+      }
+    const std::string::size_type traversed = (c - cStart) + 1;
+    output.push_back(preGenex + "$<" + input.substr(pos, traversed));
+    pos += traversed;
+    lastPos = pos;
+    }
+  if (lastPos < input.size())
+    {
+    cmSystemTools::ExpandListArgument(input.substr(lastPos), output);
+    }
+}
+
+//----------------------------------------------------------------------------
 std::string cmGeneratorExpression::Preprocess(const std::string &input,
                                               PreprocessContext context)
 {
diff --git a/Source/cmGeneratorExpression.h b/Source/cmGeneratorExpression.h
index dcdfefb..4e60fb0 100644
--- a/Source/cmGeneratorExpression.h
+++ b/Source/cmGeneratorExpression.h
@@ -59,6 +59,9 @@ public:
   static std::string Preprocess(const std::string &input,
                                 PreprocessContext context);
 
+  static void Split(const std::string &input,
+                    std::vector<std::string> &output);
+
 private:
   cmGeneratorExpression(const cmGeneratorExpression &);
   void operator=(const cmGeneratorExpression &);

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

Summary of changes:
 Source/cmExportBuildFileGenerator.cxx              |    4 +
 Source/cmExportFileGenerator.cxx                   |  252 ++++++++++++--------
 Source/cmExportFileGenerator.h                     |   22 ++-
 Source/cmExportInstallFileGenerator.cxx            |    4 +
 Source/cmGeneratorExpression.cxx                   |   61 +++++
 Source/cmGeneratorExpression.h                     |    3 +
 Source/cmTarget.cxx                                |   50 +++-
 Source/cmTarget.h                                  |    4 +-
 .../target_link_libraries/CMakeLists.txt           |   10 +
 Tests/CMakeCommands/target_link_libraries/depD.cpp |   13 +
 .../target_link_libraries/{depC.h => depD.h}       |    5 +-
 .../target_link_libraries/targetB.cpp              |   10 +
 Tests/ExportImport/Export/CMakeLists.txt           |   18 ++
 .../ExportImport/Export/testLibLibraryRequired.cpp |    7 +
 Tests/ExportImport/Export/testLibLibraryRequired.h |   12 +
 Tests/ExportImport/Import/A/deps_iface.cpp         |    6 +-
 16 files changed, 363 insertions(+), 118 deletions(-)
 create mode 100644 Tests/CMakeCommands/target_link_libraries/depD.cpp
 copy Tests/CMakeCommands/target_link_libraries/{depC.h => depD.h} (52%)
 create mode 100644 Tests/CMakeCommands/target_link_libraries/targetB.cpp
 create mode 100644 Tests/ExportImport/Export/testLibLibraryRequired.cpp
 create mode 100644 Tests/ExportImport/Export/testLibLibraryRequired.h


hooks/post-receive
-- 
CMake


More information about the Cmake-commits mailing list