Explorar o código

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 %!s(int64=12) %!d(string=hai) anos
pai
achega
7cd65c97fa

+ 9 - 2
Help/command/FIND_XXX_ROOT.txt

@@ -1,10 +1,17 @@
 The CMake variable CMAKE_FIND_ROOT_PATH specifies one or more
 directories to be prepended to all other search directories.  This
 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
 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
 |CMAKE_FIND_ROOT_PATH_MODE_XXX|.  This behavior can be manually
 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_ERROR_DEPRECATED
    /variable/CMAKE_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION
+   /variable/CMAKE_SYSROOT
    /variable/CMAKE_FIND_LIBRARY_PREFIXES
    /variable/CMAKE_FIND_LIBRARY_SUFFIXES
    /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()
   set(CMAKE_SHARED_LIBRARY_${lang}_FLAGS "-fPIC")
   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
   # 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)
     {
+    std::string rootPath = this->Makefile->GetSafeDefinition("CMAKE_SYSROOT");
+    cmSystemTools::ConvertToUnixSlashes(rootPath);
     std::vector<std::string> const& rdirs = this->GetRuntimeSearchPath();
     for(std::vector<std::string>::const_iterator ri = rdirs.begin();
         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.
       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)
@@ -1924,9 +1931,14 @@ void cmComputeLinkInformation::GetRPath(std::vector<std::string>& runtimeDirs,
            !cmSystemTools::IsSubDirectory(ri->c_str(), topSourceDir) &&
            !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;
       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)
       {
       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;
     }
+  const char* sysroot =
+    this->Makefile->GetDefinition("CMAKE_SYSROOT");
   const char* rootPath =
     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;
     }
 
   // Construct the list of path roots with no trailing slashes.
   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();
       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* compilerExternalToolchain = 0;
       const char* compilerOptionExternalToolchain = 0;
+      const char* compilerSysroot = 0;
+      const char* compilerOptionSysroot = 0;
       if(actualReplace == "CMAKE_${LANG}_COMPILER")
         {
         std::string arg1 = actualReplace + "_ARG1";
@@ -1067,6 +1069,12 @@ cmLocalGenerator::ExpandRuleVariable(std::string const& variable,
               = this->Makefile->GetDefinition(
                 (std::string("CMAKE_") + lang +
                               "_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)
         {
@@ -1099,6 +1107,12 @@ cmLocalGenerator::ExpandRuleVariable(std::string const& variable,
             ret += compilerOptionExternalToolchain;
             ret += this->EscapeForShell(compilerExternalToolchain, true);
             }
+          if (compilerSysroot && compilerOptionSysroot)
+            {
+            ret += " ";
+            ret += compilerOptionSysroot;
+            ret += this->EscapeForShell(compilerSysroot, true);
+            }
           return ret;
           }
         return replace;
@@ -1493,6 +1507,8 @@ void cmLocalGenerator::GetIncludeDirectories(std::vector<std::string>& dirs,
     return;
     }
 
+  std::string rootPath = this->Makefile->GetSafeDefinition("CMAKE_SYSROOT");
+
   std::vector<std::string> implicitDirs;
   // Load implicit include directories for this language.
   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();
         i != impDirVec.end(); ++i)
       {
-      emitted.insert(*i);
+      std::string d = rootPath + *i;
+      cmSystemTools::ConvertToUnixSlashes(d);
+      emitted.insert(d);
       if (!stripImplicitInclDirs)
         {
         implicitDirs.push_back(*i);