浏览代码

Merge topic 'LINK_INTERFACE_LIBRARIES-genex'

77d2646 Allow generator expressions in LINK_INTERFACE_LIBRARIES.
94aeaf7 Split LINK_INTERFACE_LIBRARIES export handling into dedicated method.
a3aedb8 Split the generator expression before extracting targets.
b6036d1 Extract the AddTargetNamespace method.
cb1afbf Don't pass a position when determining if a target name is a literal.
f99196d Add cmGeneratorExpression::Split() API.
Brad King 13 年之前
父节点
当前提交
c0c8ef85fc

+ 4 - 0
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

+ 153 - 99
Source/cmExportFileGenerator.cxx

@@ -183,9 +183,89 @@ 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;
+}
+
+//----------------------------------------------------------------------------
+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(*li))
+      {
+      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)
@@ -212,45 +292,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 +319,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("$<", lastPos) != input.npos)
+    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())
     {
@@ -319,6 +344,64 @@ cmExportFileGenerator::ResolveTargetsInGeneratorExpressions(
     }
 }
 
+//----------------------------------------------------------------------------
+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;
+    }
+
+  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;
+    }
+}
+
 //----------------------------------------------------------------------------
 void
 cmExportFileGenerator
@@ -363,9 +446,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);
@@ -397,9 +478,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 +488,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.

+ 20 - 2
Source/cmExportFileGenerator.h

@@ -102,9 +102,20 @@ 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,
+    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;
@@ -128,6 +139,13 @@ private:
                                  cmGeneratorExpression::PreprocessContext,
                                  ImportPropertyMap &properties,
                                  std::vector<std::string> &missingTargets);
+
+  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

+ 4 - 0
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.

+ 61 - 0
Source/cmGeneratorExpression.cxx

@@ -250,6 +250,67 @@ static std::string stripExportInterface(const std::string &input,
   return result;
 }
 
+//----------------------------------------------------------------------------
+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)

+ 3 - 0
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 &);

+ 38 - 12
Source/cmTarget.cxx

@@ -4896,16 +4896,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);
     }
   }
 
@@ -5019,18 +5033,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());
       }
     }
 
@@ -5048,7 +5064,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)
       {
@@ -5091,6 +5116,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)

+ 3 - 1
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

+ 10 - 0
Tests/CMakeCommands/target_link_libraries/CMakeLists.txt

@@ -80,3 +80,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)

+ 13 - 0
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;
+}

+ 11 - 0
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();
+};

+ 10 - 0
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();
+}

+ 32 - 1
Tests/ExportImport/Export/CMakeLists.txt

@@ -158,6 +158,36 @@ set_property(TARGET testLibRequired APPEND PROPERTY
     $<INSTALL_INTERFACE:InstallOnly_DEFINE>
 )
 
+include(GenerateExportHeader)
+
+add_library(testSharedLibRequired SHARED testSharedLibRequired.cpp)
+generate_export_header(testSharedLibRequired)
+set_property(TARGET testSharedLibRequired APPEND PROPERTY
+  INCLUDE_DIRECTORIES "${CMAKE_CURRENT_BINARY_DIR}"
+)
+set_property(TARGET testSharedLibRequired APPEND PROPERTY
+  INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_BINARY_DIR}"
+                                "${CMAKE_CURRENT_SOURCE_DIR}"
+)
+
+add_library(testSharedLibDepends SHARED testSharedLibDepends.cpp)
+set_property(TARGET testSharedLibDepends APPEND PROPERTY
+  INCLUDE_DIRECTORIES "${CMAKE_CURRENT_BINARY_DIR}"
+)
+generate_export_header(testSharedLibDepends)
+
+set_property(TARGET testSharedLibDepends APPEND PROPERTY
+  INTERFACE_INCLUDE_DIRECTORIES
+    $<TARGET_PROPERTY:testSharedLibRequired,INTERFACE_INCLUDE_DIRECTORIES>
+)
+set_property(TARGET testSharedLibDepends APPEND PROPERTY
+  LINK_INTERFACE_LIBRARIES
+    $<1:$<TARGET_NAME:testSharedLibRequired>>
+)
+
+# LINK_PRIVATE because the LINK_INTERFACE_LIBRARIES is specified above.
+target_link_libraries(testSharedLibDepends LINK_PRIVATE testSharedLibRequired)
+
 install(TARGETS testLibRequired
                 testLibIncludeRequired1
                 testLibIncludeRequired2
@@ -165,10 +195,11 @@ install(TARGETS testLibRequired
                 testLibIncludeRequired4
                 testLibIncludeRequired5
                 testLibIncludeRequired6
+                testSharedLibRequired
         EXPORT RequiredExp DESTINATION lib )
 install(EXPORT RequiredExp NAMESPACE Req:: FILE testLibRequiredConfig.cmake DESTINATION lib/cmake/testLibRequired)
 
-install(TARGETS testLibDepends EXPORT DependsExp DESTINATION lib )
+install(TARGETS testLibDepends testSharedLibDepends EXPORT DependsExp DESTINATION lib )
 install(EXPORT DependsExp FILE testLibDependsConfig.cmake DESTINATION lib/cmake/testLibDepends)
 
 

+ 8 - 0
Tests/ExportImport/Export/testSharedLibDepends.cpp

@@ -0,0 +1,8 @@
+
+#include "testSharedLibDepends.h"
+
+int TestSharedLibDepends::foo()
+{
+  TestSharedLibRequired req;
+  return req.foo();
+}

+ 14 - 0
Tests/ExportImport/Export/testSharedLibDepends.h

@@ -0,0 +1,14 @@
+
+#ifndef TESTSHAREDLIBDEPENDS_H
+#define TESTSHAREDLIBDEPENDS_H
+
+#include "testsharedlibdepends_export.h"
+
+#include "testSharedLibRequired.h"
+
+struct TESTSHAREDLIBDEPENDS_EXPORT TestSharedLibDepends
+{
+  int foo();
+};
+
+#endif

+ 7 - 0
Tests/ExportImport/Export/testSharedLibRequired.cpp

@@ -0,0 +1,7 @@
+
+#include "testSharedLibRequired.h"
+
+int TestSharedLibRequired::foo()
+{
+  return 0;
+}

+ 12 - 0
Tests/ExportImport/Export/testSharedLibRequired.h

@@ -0,0 +1,12 @@
+
+#ifndef TESTSHAREDLIBREQUIRED_H
+#define TESTSHAREDLIBREQUIRED_H
+
+#include "testsharedlibrequired_export.h"
+
+struct TESTSHAREDLIBREQUIRED_EXPORT TestSharedLibRequired
+{
+  int foo();
+};
+
+#endif

+ 11 - 0
Tests/ExportImport/Import/A/CMakeLists.txt

@@ -167,3 +167,14 @@ set_property(TARGET deps_iface APPEND PROPERTY
   INCLUDE_DIRECTORIES
     $<TARGET_PROPERTY:testLibDepends,INTERFACE_INCLUDE_DIRECTORIES>
 )
+
+add_executable(deps_shared_iface deps_shared_iface.cpp)
+target_link_libraries(deps_shared_iface testSharedLibDepends)
+set_property(TARGET deps_shared_iface APPEND PROPERTY
+  COMPILE_DEFINITIONS
+    $<TARGET_PROPERTY:testSharedLibDepends,INTERFACE_COMPILE_DEFINITIONS>
+)
+set_property(TARGET deps_shared_iface APPEND PROPERTY
+  INCLUDE_DIRECTORIES
+    $<TARGET_PROPERTY:testSharedLibDepends,INTERFACE_INCLUDE_DIRECTORIES>
+)

+ 11 - 0
Tests/ExportImport/Import/A/deps_shared_iface.cpp

@@ -0,0 +1,11 @@
+
+
+#include "testSharedLibDepends.h"
+
+int main(int,char **)
+{
+  TestSharedLibDepends dep;
+  TestSharedLibRequired req;
+
+  return dep.foo() + req.foo();
+}