Răsfoiți Sursa

Make the BUILD_INTERFACE of export()ed targets work.

The existing BUILD_INTERFACE code is executed at generate time, which
is too late for export().
Stephen Kelly 12 ani în urmă
părinte
comite
4ee872cb99

+ 2 - 0
Source/cmExportBuildFileGenerator.cxx

@@ -62,6 +62,8 @@ bool cmExportBuildFileGenerator::GenerateMainFile(std::ostream& os)
     cmTarget* te = *tei;
     this->GenerateImportTargetCode(os, te);
 
+    te->AppendBuildInterfaceIncludes();
+
     ImportPropertyMap properties;
 
     this->PopulateInterfaceProperty("INTERFACE_INCLUDE_DIRECTORIES", te,

+ 1 - 13
Source/cmGlobalGenerator.cxx

@@ -941,19 +941,7 @@ void cmGlobalGenerator::Generate()
 
     for ( tit = targets->begin(); tit != targets->end(); ++ tit )
       {
-      if (mf->IsOn("CMAKE_BUILD_INTERFACE_INCLUDES"))
-        {
-        const char *binDir = mf->GetStartOutputDirectory();
-        const char *srcDir = mf->GetStartDirectory();
-        const std::string dirs = std::string(binDir ? binDir : "")
-                                + std::string(binDir ? ";" : "")
-                                + std::string(srcDir ? srcDir : "");
-        if (!dirs.empty())
-          {
-          tit->second.AppendProperty("INTERFACE_INCLUDE_DIRECTORIES",
-                                ("$<BUILD_INTERFACE:" + dirs + ">").c_str());
-          }
-        }
+        tit->second.AppendBuildInterfaceIncludes();
       }
     }
 

+ 25 - 0
Source/cmTarget.cxx

@@ -150,6 +150,7 @@ cmTarget::cmTarget()
   this->DLLPlatform = false;
   this->IsApple = false;
   this->IsImportedTarget = false;
+  this->BuildInterfaceIncludesAppended = false;
 }
 
 //----------------------------------------------------------------------------
@@ -2654,6 +2655,30 @@ void cmTarget::AppendProperty(const char* prop, const char* value,
   this->MaybeInvalidatePropertyCache(prop);
 }
 
+//----------------------------------------------------------------------------
+void cmTarget::AppendBuildInterfaceIncludes()
+{
+  if (this->BuildInterfaceIncludesAppended)
+    {
+    return;
+    }
+  this->BuildInterfaceIncludesAppended = true;
+
+  if (this->Makefile->IsOn("CMAKE_BUILD_INTERFACE_INCLUDES"))
+    {
+    const char *binDir = this->Makefile->GetStartOutputDirectory();
+    const char *srcDir = this->Makefile->GetStartDirectory();
+    const std::string dirs = std::string(binDir ? binDir : "")
+                            + std::string(binDir ? ";" : "")
+                            + std::string(srcDir ? srcDir : "");
+    if (!dirs.empty())
+      {
+      this->AppendProperty("INTERFACE_INCLUDE_DIRECTORIES",
+                            ("$<BUILD_INTERFACE:" + dirs + ">").c_str());
+      }
+    }
+}
+
 //----------------------------------------------------------------------------
 void cmTarget::InsertInclude(const cmMakefileIncludeDirectoriesEntry &entry,
                      bool before)

+ 3 - 0
Source/cmTarget.h

@@ -490,6 +490,8 @@ public:
   void InsertInclude(const cmMakefileIncludeDirectoriesEntry &entry,
                      bool before = false);
 
+  void AppendBuildInterfaceIncludes();
+
   void GetLinkDependentTargetsForProperty(const std::string &p,
                                        std::set<std::string> &targets);
   bool IsNullImpliedByLinkLibraries(const std::string &p);
@@ -611,6 +613,7 @@ private:
   mutable std::map<cmStdString, std::set<std::string> >
                                                       LinkDependentProperties;
   mutable std::set<std::string> LinkImplicitNullProperties;
+  bool BuildInterfaceIncludesAppended;
 
   // Cache target output paths for each configuration.
   struct OutputInfo;

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

@@ -247,9 +247,11 @@ if(WIN32)
   install(TARGETS testLib5 RUNTIME DESTINATION bin)
 endif()
 
+add_subdirectory(sublib) # For CMAKE_BUILD_INTERFACE_INCLUDES test.
+
 # Export from build tree.
 export(TARGETS testExe1 testLib1 testLib2 testLib3
-  testExe2libImp testLib3Imp testLib3ImpDep
+  testExe2libImp testLib3Imp testLib3ImpDep subdirlib
   testSharedLibRequired testSharedLibDepends
   NAMESPACE bld_
   FILE ExportBuildTree.cmake

+ 6 - 0
Tests/ExportImport/Export/sublib/CMakeLists.txt

@@ -0,0 +1,6 @@
+
+set(CMAKE_BUILD_INTERFACE_INCLUDES ON)
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+add_library(subdirlib SHARED subdir.cpp)
+generate_export_header(subdirlib)

+ 7 - 0
Tests/ExportImport/Export/sublib/subdir.cpp

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

+ 12 - 0
Tests/ExportImport/Export/sublib/subdir.h

@@ -0,0 +1,12 @@
+
+#ifndef SUBDIR_H
+#define SUBDIR_H
+
+#include "subdirlib_export.h"
+
+struct SUBDIRLIB_EXPORT SubDirObject
+{
+  int foo();
+};
+
+#endif

+ 5 - 3
Tests/ExportImport/Import/A/CMakeLists.txt

@@ -172,6 +172,8 @@ target_compile_definitions(deps_shared_iface PRIVATE testSharedLibDepends)
 # evaluated correctly. The above already tests the same for the install tree.
 
 add_executable(deps_shared_iface2 deps_shared_iface.cpp)
-target_link_libraries(deps_shared_iface2 bld_testSharedLibDepends)
-target_include_directories(deps_shared_iface2 PRIVATE bld_testSharedLibDepends)
-target_compile_definitions(deps_shared_iface2 PRIVATE bld_testSharedLibDepends)
+target_link_libraries(deps_shared_iface2 bld_testSharedLibDepends bld_subdirlib)
+target_include_directories(deps_shared_iface2 PRIVATE bld_testSharedLibDepends bld_subdirlib)
+target_compile_definitions(deps_shared_iface2
+  PRIVATE bld_testSharedLibDepends TEST_SUBDIR_LIB
+)

+ 13 - 1
Tests/ExportImport/Import/A/deps_shared_iface.cpp

@@ -2,10 +2,22 @@
 
 #include "testSharedLibDepends.h"
 
+#ifdef TEST_SUBDIR_LIB
+#include "subdir.h"
+#endif
+
 int main(int,char **)
 {
   TestSharedLibDepends dep;
   TestSharedLibRequired req;
 
-  return dep.foo() + req.foo();
+#ifdef TEST_SUBDIR_LIB
+  SubDirObject sdo;
+#endif
+
+  return dep.foo() + req.foo()
+#ifdef TEST_SUBDIR_LIB
+                   + sdo.foo()
+#endif
+                              ;
 }