Переглянути джерело

ENH: If CMAKE_NO_AUTOMATIC_INCLUDE_DIRECTORIES is not set try to approximate in-source build include file behavior in an out-of-source build by adding the build tree directory corresponding to a source tree directory at the beginning of the include path. Also fixed VS6 and VS7 generators to use cmLocalGenerator's computation of include paths. The VS6 generator will now short-path the include directories if the total length is too long in order to try to avoid its truncation limit.

Brad King 19 роки тому
батько
коміт
9ba0283870

+ 53 - 18
Source/cmLocalGenerator.cxx

@@ -1129,22 +1129,20 @@ const char* cmLocalGenerator::GetIncludeFlags(const char* lang)
 //----------------------------------------------------------------------------
 void cmLocalGenerator::GetIncludeDirectories(std::vector<std::string>& dirs)
 {
-  // Output Include paths
-  std::set<cmStdString> implicitIncludes;
-
   // CMake versions below 2.0 would add the source tree to the -I path
   // automatically.  Preserve compatibility.
   bool includeSourceDir = false;
   const char* versionValue =
     m_Makefile->GetDefinition("CMAKE_BACKWARDS_COMPATIBILITY");
-  if(versionValue)
+  int major = 0;
+  int minor = 0;
+  if(versionValue && sscanf(versionValue, "%d.%d", &major, &minor) != 2)
     {
-    int major = 0;
-    int minor = 0;
-    if(sscanf(versionValue, "%d.%d", &major, &minor) == 2 && major < 2)
-      {
-      includeSourceDir = true;
-      }
+    versionValue = 0;
+    }
+  if(versionValue && major < 2)
+    {
+    includeSourceDir = true;
     }
   const char* vtkSourceDir =
     m_Makefile->GetDefinition("VTK_SOURCE_DIR");
@@ -1164,23 +1162,59 @@ void cmLocalGenerator::GetIncludeDirectories(std::vector<std::string>& dirs)
       }
     }
 
+  // If this is not an in-source build then include the binary
+  // directory at the beginning of the include path to approximate
+  // include file behavior for an in-source build.  This does not
+  // account for the case of a source file in a subdirectory of the
+  // current source directory but we cannot fix this because not all
+  // native build tools support per-source-file include paths.  Allow
+  // the behavior to be disabled by the project.
+  bool includeBinaryDir =
+    !cmSystemTools::ComparePath(m_Makefile->GetStartDirectory(),
+                                m_Makefile->GetStartOutputDirectory());
+  if(m_Makefile->IsOn("CMAKE_NO_AUTOMATIC_INCLUDE_DIRECTORIES"))
+    {
+    includeSourceDir = false;
+    includeBinaryDir = false;
+    }
+
+  // CMake versions 2.2 and earlier did not add the binary directory
+  // automatically.
+  if(versionValue && ((major < 2) || major == 2 && minor < 3))
+    {
+    includeBinaryDir = false;
+    }
+
+  // Do not repeat an include path.
+  std::set<cmStdString> emitted;
+
+  // Store the automatic include paths.
+  if(includeBinaryDir)
+    {
+    dirs.push_back(m_Makefile->GetStartOutputDirectory());
+    emitted.insert(m_Makefile->GetStartOutputDirectory());
+    }
   if(includeSourceDir)
     {
-    dirs.push_back(m_Makefile->GetStartDirectory());
+    if(emitted.find(m_Makefile->GetStartDirectory()) == emitted.end())
+      {
+      dirs.push_back(m_Makefile->GetStartDirectory());
+      emitted.insert(m_Makefile->GetStartDirectory());
+      }
     }
 
   // Do not explicitly add the standard include path "/usr/include".
   // This can cause problems with certain standard library
   // implementations because the wrong headers may be found first.
-  implicitIncludes.insert("/usr/include");
-  if(m_Makefile->GetDefinition("CMAKE_PLATFORM_IMPLICIT_INCLUDE_DIRECTORIES"))
+  emitted.insert("/usr/include");
+  if(const char* implicitIncludes =
+     m_Makefile->GetDefinition("CMAKE_PLATFORM_IMPLICIT_INCLUDE_DIRECTORIES"))
     {
-    std::string arg = m_Makefile->GetDefinition("CMAKE_PLATFORM_IMPLICIT_INCLUDE_DIRECTORIES");
     std::vector<std::string> implicitIncludeVec;
-    cmSystemTools::ExpandListArgument(arg, implicitIncludeVec);
-    for(unsigned int k =0; k < implicitIncludeVec.size(); k++)
+    cmSystemTools::ExpandListArgument(implicitIncludes, implicitIncludeVec);
+    for(unsigned int k = 0; k < implicitIncludeVec.size(); ++k)
       {
-      implicitIncludes.insert(implicitIncludeVec[k]);
+      emitted.insert(implicitIncludeVec[k]);
       }
     }
 
@@ -1189,9 +1223,10 @@ void cmLocalGenerator::GetIncludeDirectories(std::vector<std::string>& dirs)
   for(std::vector<std::string>::iterator i = includes.begin();
       i != includes.end(); ++i)
     {
-    if(implicitIncludes.find(*i) == implicitIncludes.end())
+    if(emitted.find(*i) == emitted.end())
       {
       dirs.push_back(*i);
+      emitted.insert(*i);
       }
     }
 }

+ 33 - 12
Source/cmLocalVisualStudio6Generator.cxx

@@ -55,24 +55,45 @@ void cmLocalVisualStudio6Generator::OutputDSPFile()
       }
     }
 
-  // Setup /I and /LIBPATH options for the resulting DSP file
-  std::vector<std::string>& includes = m_Makefile->GetIncludeDirectories();
-  std::vector<std::string>::iterator i;
-  for(i = includes.begin(); i != includes.end(); ++i)
+  // Setup /I and /LIBPATH options for the resulting DSP file.  VS 6
+  // truncates long include paths so make it as short as possible if
+  // the length threatents this problem.
+  unsigned int maxIncludeLength = 3000;
+  bool useShortPath = false;
+  for(int j=0; j < 2; ++j)
     {
-    m_IncludeOptions +=  " /I ";
-    std::string tmp = this->ConvertToOptionallyRelativeOutputPath(i->c_str());
+    std::vector<std::string> includes;
+    this->GetIncludeDirectories(includes);
+    std::vector<std::string>::iterator i;
+    for(i = includes.begin(); i != includes.end(); ++i)
+      {
+      std::string tmp = this->ConvertToOptionallyRelativeOutputPath(i->c_str());
+      if(useShortPath)
+        {
+        cmSystemTools::GetShortPath(tmp.c_str(), tmp);
+        }
+      m_IncludeOptions +=  " /I ";
 
-    // quote if not already quoted
-    if (tmp[0] != '"')
+      // quote if not already quoted
+      if (tmp[0] != '"')
+        {
+        m_IncludeOptions += "\"";
+        m_IncludeOptions += tmp;
+        m_IncludeOptions += "\"";
+        }
+      else
+        {
+        m_IncludeOptions += tmp;
+        }
+      }
+    if(j == 0 && m_IncludeOptions.size() > maxIncludeLength)
       {
-      m_IncludeOptions += "\"";
-      m_IncludeOptions += tmp;
-      m_IncludeOptions += "\"";
+      m_IncludeOptions = "";
+      useShortPath = true;
       }
     else
       {
-      m_IncludeOptions += tmp;
+      break;
       }
     }
   

+ 2 - 1
Source/cmLocalVisualStudio7Generator.cxx

@@ -566,7 +566,8 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout,
   fout << " -DCMAKE_INTDIR=\\&quot;" << configName << "\\&quot;" 
        << "\"\n";
   fout << "\t\t\t\tAdditionalIncludeDirectories=\"";
-  std::vector<std::string>& includes = m_Makefile->GetIncludeDirectories();
+  std::vector<std::string> includes;
+  this->GetIncludeDirectories(includes);
   std::vector<std::string>::iterator i = includes.begin();
   for(;i != includes.end(); ++i)
     {