Преглед изворни кода

Add CMAKE_SYSROOT variable to set --sysroot when cross compiling.

As CMAKE_ROOT_FIND_PATH can be a list, a new CMAKE_SYSROOT is
introduced, which is never a list.

The contents of this variable is passed to supporting compilers
as --sysroot. It is also accounted for when processing implicit
link directories reported by the compiler, and when generating
RPATH information.
Stephen Kelly пре 12 година
родитељ
комит
7cd65c97fa

+ 9 - 2
Help/command/FIND_XXX_ROOT.txt

@@ -1,10 +1,17 @@
 The CMake variable CMAKE_FIND_ROOT_PATH specifies one or more
 The CMake variable CMAKE_FIND_ROOT_PATH specifies one or more
 directories to be prepended to all other search directories.  This
 directories to be prepended to all other search directories.  This
 effectively "re-roots" the entire search under given locations.  By
 effectively "re-roots" the entire search under given locations.  By
-default it is empty.  It is especially useful when cross-compiling to
+default it is empty.
+
+The :variable:`CMAKE_SYSROOT` variable can also be used to specify exactly one
+directory to use as a prefix.  Setting :variable:`CMAKE_SYSROOT` also has other
+effects.  See the documentation for that variable for more.
+
+These variables are especially useful when cross-compiling to
 point to the root directory of the target environment and CMake will
 point to the root directory of the target environment and CMake will
 search there too.  By default at first the directories listed in
 search there too.  By default at first the directories listed in
-CMAKE_FIND_ROOT_PATH and then the non-rooted directories will be
+CMAKE_FIND_ROOT_PATH are searched, then the :variable:`CMAKE_SYSROOT` directory is
+searched, and then the non-rooted directories will be
 searched.  The default behavior can be adjusted by setting
 searched.  The default behavior can be adjusted by setting
 |CMAKE_FIND_ROOT_PATH_MODE_XXX|.  This behavior can be manually
 |CMAKE_FIND_ROOT_PATH_MODE_XXX|.  This behavior can be manually
 overridden on a per-call basis.  By using CMAKE_FIND_ROOT_PATH_BOTH
 overridden on a per-call basis.  By using CMAKE_FIND_ROOT_PATH_BOTH

+ 1 - 0
Help/manual/cmake-variables.7.rst

@@ -91,6 +91,7 @@ Variables that Change Behavior
    /variable/CMAKE_DISABLE_FIND_PACKAGE_PackageName
    /variable/CMAKE_DISABLE_FIND_PACKAGE_PackageName
    /variable/CMAKE_ERROR_DEPRECATED
    /variable/CMAKE_ERROR_DEPRECATED
    /variable/CMAKE_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION
    /variable/CMAKE_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION
+   /variable/CMAKE_SYSROOT
    /variable/CMAKE_FIND_LIBRARY_PREFIXES
    /variable/CMAKE_FIND_LIBRARY_PREFIXES
    /variable/CMAKE_FIND_LIBRARY_SUFFIXES
    /variable/CMAKE_FIND_LIBRARY_SUFFIXES
    /variable/CMAKE_FIND_PACKAGE_WARN_NO_MODULE
    /variable/CMAKE_FIND_PACKAGE_WARN_NO_MODULE

+ 12 - 0
Help/variable/CMAKE_SYSROOT.rst

@@ -0,0 +1,12 @@
+CMAKE_SYSROOT
+-------------
+
+Path to pass to the compiler in the ``--sysroot`` flag.
+
+The ``CMAKE_SYSROOT`` content is passed to the compiler in the ``--sysroot``
+flag, if supported.  The path is also stripped from the RPATH/RUNPATH if
+necessary on installation.  The ``CMAKE_SYSROOT`` is also used to prefix
+paths searched by the ``find_*`` commands.
+
+This variable may only be set in a toolchain file specified by
+the ``CMAKE_TOOLCHAIN_FILE`` variable.

+ 1 - 0
Modules/Compiler/GNU.cmake

@@ -30,6 +30,7 @@ macro(__compiler_gnu lang)
   endif()
   endif()
   set(CMAKE_SHARED_LIBRARY_${lang}_FLAGS "-fPIC")
   set(CMAKE_SHARED_LIBRARY_${lang}_FLAGS "-fPIC")
   set(CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS "-shared")
   set(CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS "-shared")
+  set(CMAKE_${lang}_COMPILE_OPTIONS_SYSROOT "--sysroot=")
 
 
   # Older versions of gcc (< 4.5) contain a bug causing them to report a missing
   # Older versions of gcc (< 4.5) contain a bug causing them to report a missing
   # header file as a warning if depfiles are enabled, causing check_header_file
   # header file as a warning if depfiles are enabled, causing check_header_file

+ 16 - 4
Source/cmComputeLinkInformation.cxx

@@ -1901,6 +1901,8 @@ void cmComputeLinkInformation::GetRPath(std::vector<std::string>& runtimeDirs,
     }
     }
   if(use_build_rpath || use_link_rpath)
   if(use_build_rpath || use_link_rpath)
     {
     {
+    std::string rootPath = this->Makefile->GetSafeDefinition("CMAKE_SYSROOT");
+    cmSystemTools::ConvertToUnixSlashes(rootPath);
     std::vector<std::string> const& rdirs = this->GetRuntimeSearchPath();
     std::vector<std::string> const& rdirs = this->GetRuntimeSearchPath();
     for(std::vector<std::string>::const_iterator ri = rdirs.begin();
     for(std::vector<std::string>::const_iterator ri = rdirs.begin();
         ri != rdirs.end(); ++ri)
         ri != rdirs.end(); ++ri)
@@ -1909,9 +1911,14 @@ void cmComputeLinkInformation::GetRPath(std::vector<std::string>& runtimeDirs,
       // support or if using the link path as an rpath.
       // support or if using the link path as an rpath.
       if(use_build_rpath)
       if(use_build_rpath)
         {
         {
-        if(emitted.insert(*ri).second)
+        std::string d = *ri;
+        if (!rootPath.empty() && d.find(rootPath) == 0)
           {
           {
-          runtimeDirs.push_back(*ri);
+          d = d.substr(rootPath.size());
+          }
+        if(emitted.insert(d).second)
+          {
+          runtimeDirs.push_back(d);
           }
           }
         }
         }
       else if(use_link_rpath)
       else if(use_link_rpath)
@@ -1924,9 +1931,14 @@ void cmComputeLinkInformation::GetRPath(std::vector<std::string>& runtimeDirs,
            !cmSystemTools::IsSubDirectory(ri->c_str(), topSourceDir) &&
            !cmSystemTools::IsSubDirectory(ri->c_str(), topSourceDir) &&
            !cmSystemTools::IsSubDirectory(ri->c_str(), topBinaryDir))
            !cmSystemTools::IsSubDirectory(ri->c_str(), topBinaryDir))
           {
           {
-          if(emitted.insert(*ri).second)
+          std::string d = *ri;
+          if (!rootPath.empty() && d.find(rootPath) == 0)
+            {
+            d = d.substr(rootPath.size());
+            }
+          if(emitted.insert(d).second)
             {
             {
-            runtimeDirs.push_back(*ri);
+            runtimeDirs.push_back(d);
             }
             }
           }
           }
         }
         }

+ 7 - 0
Source/cmCoreTryCompile.cxx

@@ -433,6 +433,13 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv)
       flag += tcDef;
       flag += tcDef;
       cmakeFlags.push_back(flag);
       cmakeFlags.push_back(flag);
       }
       }
+    if (const char *rootDef
+              = this->Makefile->GetDefinition("CMAKE_SYSROOT"))
+      {
+      std::string flag="-DCMAKE_SYSROOT=";
+      flag += rootDef;
+      cmakeFlags.push_back(flag);
+      }
     if(this->Makefile->GetDefinition("CMAKE_POSITION_INDEPENDENT_CODE")!=0)
     if(this->Makefile->GetDefinition("CMAKE_POSITION_INDEPENDENT_CODE")!=0)
       {
       {
       fprintf(fout, "set(CMAKE_POSITION_INDEPENDENT_CODE \"ON\")\n");
       fprintf(fout, "set(CMAKE_POSITION_INDEPENDENT_CODE \"ON\")\n");

+ 13 - 2
Source/cmFindCommon.cxx

@@ -138,16 +138,27 @@ void cmFindCommon::RerootPaths(std::vector<std::string>& paths)
     {
     {
     return;
     return;
     }
     }
+  const char* sysroot =
+    this->Makefile->GetDefinition("CMAKE_SYSROOT");
   const char* rootPath =
   const char* rootPath =
     this->Makefile->GetDefinition("CMAKE_FIND_ROOT_PATH");
     this->Makefile->GetDefinition("CMAKE_FIND_ROOT_PATH");
-  if((rootPath == 0) || (strlen(rootPath) == 0))
+  const bool noSysroot = !sysroot || !*sysroot;
+  const bool noRootPath = !rootPath || !*rootPath;
+  if(noSysroot && noRootPath)
     {
     {
     return;
     return;
     }
     }
 
 
   // Construct the list of path roots with no trailing slashes.
   // Construct the list of path roots with no trailing slashes.
   std::vector<std::string> roots;
   std::vector<std::string> roots;
-  cmSystemTools::ExpandListArgument(rootPath, roots);
+  if (rootPath)
+    {
+    cmSystemTools::ExpandListArgument(rootPath, roots);
+    }
+  if (sysroot)
+    {
+    roots.push_back(sysroot);
+    }
   for(std::vector<std::string>::iterator ri = roots.begin();
   for(std::vector<std::string>::iterator ri = roots.begin();
       ri != roots.end(); ++ri)
       ri != roots.end(); ++ri)
     {
     {

+ 19 - 1
Source/cmLocalGenerator.cxx

@@ -1047,6 +1047,8 @@ cmLocalGenerator::ExpandRuleVariable(std::string const& variable,
       const char* compilerOptionTarget = 0;
       const char* compilerOptionTarget = 0;
       const char* compilerExternalToolchain = 0;
       const char* compilerExternalToolchain = 0;
       const char* compilerOptionExternalToolchain = 0;
       const char* compilerOptionExternalToolchain = 0;
+      const char* compilerSysroot = 0;
+      const char* compilerOptionSysroot = 0;
       if(actualReplace == "CMAKE_${LANG}_COMPILER")
       if(actualReplace == "CMAKE_${LANG}_COMPILER")
         {
         {
         std::string arg1 = actualReplace + "_ARG1";
         std::string arg1 = actualReplace + "_ARG1";
@@ -1067,6 +1069,12 @@ cmLocalGenerator::ExpandRuleVariable(std::string const& variable,
               = this->Makefile->GetDefinition(
               = this->Makefile->GetDefinition(
                 (std::string("CMAKE_") + lang +
                 (std::string("CMAKE_") + lang +
                               "_COMPILE_OPTIONS_EXTERNAL_TOOLCHAIN").c_str());
                               "_COMPILE_OPTIONS_EXTERNAL_TOOLCHAIN").c_str());
+        compilerSysroot
+              = this->Makefile->GetDefinition("CMAKE_SYSROOT");
+        compilerOptionSysroot
+              = this->Makefile->GetDefinition(
+                (std::string("CMAKE_") + lang +
+                              "_COMPILE_OPTIONS_SYSROOT").c_str());
         }
         }
       if(actualReplace.find("${LANG}") != actualReplace.npos)
       if(actualReplace.find("${LANG}") != actualReplace.npos)
         {
         {
@@ -1099,6 +1107,12 @@ cmLocalGenerator::ExpandRuleVariable(std::string const& variable,
             ret += compilerOptionExternalToolchain;
             ret += compilerOptionExternalToolchain;
             ret += this->EscapeForShell(compilerExternalToolchain, true);
             ret += this->EscapeForShell(compilerExternalToolchain, true);
             }
             }
+          if (compilerSysroot && compilerOptionSysroot)
+            {
+            ret += " ";
+            ret += compilerOptionSysroot;
+            ret += this->EscapeForShell(compilerSysroot, true);
+            }
           return ret;
           return ret;
           }
           }
         return replace;
         return replace;
@@ -1493,6 +1507,8 @@ void cmLocalGenerator::GetIncludeDirectories(std::vector<std::string>& dirs,
     return;
     return;
     }
     }
 
 
+  std::string rootPath = this->Makefile->GetSafeDefinition("CMAKE_SYSROOT");
+
   std::vector<std::string> implicitDirs;
   std::vector<std::string> implicitDirs;
   // Load implicit include directories for this language.
   // Load implicit include directories for this language.
   std::string impDirVar = "CMAKE_";
   std::string impDirVar = "CMAKE_";
@@ -1505,7 +1521,9 @@ void cmLocalGenerator::GetIncludeDirectories(std::vector<std::string>& dirs,
     for(std::vector<std::string>::const_iterator i = impDirVec.begin();
     for(std::vector<std::string>::const_iterator i = impDirVec.begin();
         i != impDirVec.end(); ++i)
         i != impDirVec.end(); ++i)
       {
       {
-      emitted.insert(*i);
+      std::string d = rootPath + *i;
+      cmSystemTools::ConvertToUnixSlashes(d);
+      emitted.insert(d);
       if (!stripImplicitInclDirs)
       if (!stripImplicitInclDirs)
         {
         {
         implicitDirs.push_back(*i);
         implicitDirs.push_back(*i);