瀏覽代碼

Merge topic 'cross-compiling-toolchain-variables'

7cd65c9 Add CMAKE_SYSROOT variable to set --sysroot when cross compiling.
5096967 Allow toolchain files to specify an external toolchain.
76552d5 Add compiler target compile options.
f41ecd1 CMakeDetermineCompilerId: Look for internal file only on host
Brad King 12 年之前
父節點
當前提交
46ec48c93d

+ 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

+ 3 - 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
@@ -234,6 +235,8 @@ Variables for Languages
    /variable/CMAKE_LANG_COMPILER_ID
    /variable/CMAKE_LANG_COMPILER_ID
    /variable/CMAKE_LANG_COMPILER_LOADED
    /variable/CMAKE_LANG_COMPILER_LOADED
    /variable/CMAKE_LANG_COMPILER
    /variable/CMAKE_LANG_COMPILER
+   /variable/CMAKE_LANG_COMPILER_EXTERNAL_TOOLCHAIN
+   /variable/CMAKE_LANG_COMPILER_TARGET
    /variable/CMAKE_LANG_COMPILER_VERSION
    /variable/CMAKE_LANG_COMPILER_VERSION
    /variable/CMAKE_LANG_CREATE_SHARED_LIBRARY
    /variable/CMAKE_LANG_CREATE_SHARED_LIBRARY
    /variable/CMAKE_LANG_CREATE_SHARED_MODULE
    /variable/CMAKE_LANG_CREATE_SHARED_MODULE

+ 13 - 0
Help/variable/CMAKE_LANG_COMPILER_EXTERNAL_TOOLCHAIN.rst

@@ -0,0 +1,13 @@
+CMAKE_<LANG>_COMPILER_EXTERNAL_TOOLCHAIN
+----------------------------------------
+
+The external toolchain for cross-compiling, if supported.
+
+Some compiler toolchains do not ship their own auxilliary utilities such as
+archivers and linkers.  The compiler driver may support a command-line argument
+to specify the location of such tools.  CMAKE_<LANG>_COMPILER_EXTERNAL_TOOLCHAIN
+may be set to a path to a path to the external toolchain and will be passed
+to the compiler driver if supported.
+
+This variable may only be set in a toolchain file specified by
+the ``CMAKE_TOOLCHAIN_FILE`` variable.

+ 11 - 0
Help/variable/CMAKE_LANG_COMPILER_TARGET.rst

@@ -0,0 +1,11 @@
+CMAKE_<LANG>_COMPILER_TARGET
+----------------------------
+
+The target for cross-compiling, if supported.
+
+Some compiler drivers are inherently cross-compilers, such as clang and
+QNX qcc. These compiler drivers support a command-line argument to specify
+the target to cross-compile for.
+
+This variable may only be set in a toolchain file specified by
+the ``CMAKE_TOOLCHAIN_FILE`` variable.

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

+ 6 - 0
Modules/CMakeDetermineCCompiler.cmake

@@ -158,6 +158,12 @@ if (CMAKE_CROSSCOMPILING  AND NOT _CMAKE_TOOLCHAIN_PREFIX)
     get_filename_component(COMPILER_BASENAME "${CMAKE_C_COMPILER}" NAME)
     get_filename_component(COMPILER_BASENAME "${CMAKE_C_COMPILER}" NAME)
     if (COMPILER_BASENAME MATCHES "^(.+-)(clang|g?cc)(-[0-9]+\\.[0-9]+\\.[0-9]+)?(\\.exe)?$")
     if (COMPILER_BASENAME MATCHES "^(.+-)(clang|g?cc)(-[0-9]+\\.[0-9]+\\.[0-9]+)?(\\.exe)?$")
       set(_CMAKE_TOOLCHAIN_PREFIX ${CMAKE_MATCH_1})
       set(_CMAKE_TOOLCHAIN_PREFIX ${CMAKE_MATCH_1})
+    elseif("${CMAKE_C_COMPILER_ID}" MATCHES "Clang")
+      set(_CMAKE_TOOLCHAIN_PREFIX ${CMAKE_C_COMPILER_TARGET}-)
+    elseif(COMPILER_BASENAME MATCHES "qcc(\\.exe)?$")
+      if(CMAKE_C_COMPILER_TARGET MATCHES "gcc_nto([^_le]+)(le)?.*$")
+        set(_CMAKE_TOOLCHAIN_PREFIX nto${CMAKE_MATCH_1}-)
+      endif()
     endif ()
     endif ()
 
 
     # if "llvm-" is part of the prefix, remove it, since llvm doesn't have its own binutils
     # if "llvm-" is part of the prefix, remove it, since llvm doesn't have its own binutils

+ 6 - 0
Modules/CMakeDetermineCXXCompiler.cmake

@@ -156,6 +156,12 @@ if (CMAKE_CROSSCOMPILING  AND NOT  _CMAKE_TOOLCHAIN_PREFIX)
     get_filename_component(COMPILER_BASENAME "${CMAKE_CXX_COMPILER}" NAME)
     get_filename_component(COMPILER_BASENAME "${CMAKE_CXX_COMPILER}" NAME)
     if (COMPILER_BASENAME MATCHES "^(.+-)(clan)?[gc]\\+\\+(-[0-9]+\\.[0-9]+\\.[0-9]+)?(\\.exe)?$")
     if (COMPILER_BASENAME MATCHES "^(.+-)(clan)?[gc]\\+\\+(-[0-9]+\\.[0-9]+\\.[0-9]+)?(\\.exe)?$")
       set(_CMAKE_TOOLCHAIN_PREFIX ${CMAKE_MATCH_1})
       set(_CMAKE_TOOLCHAIN_PREFIX ${CMAKE_MATCH_1})
+    elseif("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
+      set(_CMAKE_TOOLCHAIN_PREFIX ${CMAKE_CXX_COMPILER_TARGET}-)
+    elseif(COMPILER_BASENAME MATCHES "QCC(\\.exe)?$")
+      if(CMAKE_CXX_COMPILER_TARGET MATCHES "gcc_nto([^_le]+)(le)?.*$")
+        set(_CMAKE_TOOLCHAIN_PREFIX nto${CMAKE_MATCH_1}-)
+      endif()
     endif ()
     endif ()
 
 
     # if "llvm-" is part of the prefix, remove it, since llvm doesn't have its own binutils
     # if "llvm-" is part of the prefix, remove it, since llvm doesn't have its own binutils

+ 1 - 1
Modules/CMakeDetermineCompilerId.cmake

@@ -85,7 +85,7 @@ endfunction()
 #-----------------------------------------------------------------------------
 #-----------------------------------------------------------------------------
 # Function to write the compiler id source file.
 # Function to write the compiler id source file.
 function(CMAKE_DETERMINE_COMPILER_ID_WRITE lang src)
 function(CMAKE_DETERMINE_COMPILER_ID_WRITE lang src)
-  find_file(src_in ${src}.in PATHS ${CMAKE_ROOT}/Modules ${CMAKE_MODULE_PATH} NO_DEFAULT_PATH)
+  find_file(src_in ${src}.in PATHS ${CMAKE_ROOT}/Modules ${CMAKE_MODULE_PATH} NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH)
   file(READ ${src_in} ID_CONTENT_IN)
   file(READ ${src_in} ID_CONTENT_IN)
   unset(src_in CACHE)
   unset(src_in CACHE)
   string(CONFIGURE "${ID_CONTENT_IN}" ID_CONTENT_OUT @ONLY)
   string(CONFIGURE "${ID_CONTENT_IN}" ID_CONTENT_OUT @ONLY)

+ 6 - 1
Modules/CMakeFindBinUtils.cmake

@@ -43,7 +43,12 @@ if("${CMAKE_C_SIMULATE_ID}" STREQUAL "MSVC"
 
 
 # in all other cases search for ar, ranlib, etc.
 # in all other cases search for ar, ranlib, etc.
 else()
 else()
-
+  if(CMAKE_C_COMPILER_EXTERNAL_TOOLCHAIN)
+    set(_CMAKE_TOOLCHAIN_LOCATION ${_CMAKE_TOOLCHAIN_LOCATION} ${CMAKE_C_COMPILER_EXTERNAL_TOOLCHAIN}/bin)
+  endif()
+  if(CMAKE_CXX_COMPILER_EXTERNAL_TOOLCHAIN)
+    set(_CMAKE_TOOLCHAIN_LOCATION ${_CMAKE_TOOLCHAIN_LOCATION} ${CMAKE_CXX_COMPILER_EXTERNAL_TOOLCHAIN}/bin)
+  endif()
   find_program(CMAKE_AR NAMES ${_CMAKE_TOOLCHAIN_PREFIX}ar${_CMAKE_TOOLCHAIN_SUFFIX} HINTS ${_CMAKE_TOOLCHAIN_LOCATION})
   find_program(CMAKE_AR NAMES ${_CMAKE_TOOLCHAIN_PREFIX}ar${_CMAKE_TOOLCHAIN_SUFFIX} HINTS ${_CMAKE_TOOLCHAIN_LOCATION})
 
 
   find_program(CMAKE_RANLIB NAMES ${_CMAKE_TOOLCHAIN_PREFIX}ranlib HINTS ${_CMAKE_TOOLCHAIN_LOCATION})
   find_program(CMAKE_RANLIB NAMES ${_CMAKE_TOOLCHAIN_PREFIX}ranlib HINTS ${_CMAKE_TOOLCHAIN_LOCATION})

+ 2 - 0
Modules/Compiler/Clang.cmake

@@ -30,5 +30,7 @@ else()
     set(CMAKE_${lang}_COMPILE_OPTIONS_PIE "-fPIE")
     set(CMAKE_${lang}_COMPILE_OPTIONS_PIE "-fPIE")
     set(CMAKE_INCLUDE_SYSTEM_FLAG_${lang} "-isystem ")
     set(CMAKE_INCLUDE_SYSTEM_FLAG_${lang} "-isystem ")
     set(CMAKE_${lang}_COMPILE_OPTIONS_VISIBILITY "-fvisibility=")
     set(CMAKE_${lang}_COMPILE_OPTIONS_VISIBILITY "-fvisibility=")
+    set(CMAKE_${lang}_COMPILE_OPTIONS_TARGET "-target ")
+    set(CMAKE_${lang}_COMPILE_OPTIONS_EXTERNAL_TOOLCHAIN "-gcc-toolchain ")
   endmacro()
   endmacro()
 endif()
 endif()

+ 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

+ 3 - 0
Modules/Platform/QNX.cmake

@@ -16,6 +16,9 @@ set(CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG_SEP ":")
 set(CMAKE_SHARED_LIBRARY_RPATH_LINK_C_FLAG "-Wl,-rpath-link,")
 set(CMAKE_SHARED_LIBRARY_RPATH_LINK_C_FLAG "-Wl,-rpath-link,")
 set(CMAKE_SHARED_LIBRARY_SONAME_C_FLAG "-Wl,-soname,")
 set(CMAKE_SHARED_LIBRARY_SONAME_C_FLAG "-Wl,-soname,")
 set(CMAKE_EXE_EXPORTS_C_FLAG "-Wl,--export-dynamic")
 set(CMAKE_EXE_EXPORTS_C_FLAG "-Wl,--export-dynamic")
+# http://www.qnx.com/developers/docs/6.4.0/neutrino/utilities/q/qcc.html#examples
+set(CMAKE_C_COMPILE_OPTIONS_TARGET "-V")
+set(CMAKE_CXX_COMPILE_OPTIONS_TARGET "-V")
 
 
 # Shared libraries with no builtin soname may not be linked safely by
 # Shared libraries with no builtin soname may not be linked safely by
 # specifying the file path.
 # specifying the file path.

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

+ 35 - 0
Source/cmCoreTryCompile.cxx

@@ -405,6 +405,41 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv)
       flag += this->Makefile->GetSafeDefinition("CMAKE_OSX_DEPLOYMENT_TARGET");
       flag += this->Makefile->GetSafeDefinition("CMAKE_OSX_DEPLOYMENT_TARGET");
       cmakeFlags.push_back(flag);
       cmakeFlags.push_back(flag);
       }
       }
+    if (const char *cxxDef
+              = this->Makefile->GetDefinition("CMAKE_CXX_COMPILER_TARGET"))
+      {
+      std::string flag="-DCMAKE_CXX_COMPILER_TARGET=";
+      flag += cxxDef;
+      cmakeFlags.push_back(flag);
+      }
+    if (const char *cDef
+                = this->Makefile->GetDefinition("CMAKE_C_COMPILER_TARGET"))
+      {
+      std::string flag="-DCMAKE_C_COMPILER_TARGET=";
+      flag += cDef;
+      cmakeFlags.push_back(flag);
+      }
+    if (const char *tcxxDef = this->Makefile->GetDefinition(
+                                  "CMAKE_CXX_COMPILER_EXTERNAL_TOOLCHAIN"))
+      {
+      std::string flag="-DCMAKE_CXX_COMPILER_EXTERNAL_TOOLCHAIN=";
+      flag += tcxxDef;
+      cmakeFlags.push_back(flag);
+      }
+    if (const char *tcDef = this->Makefile->GetDefinition(
+                                    "CMAKE_C_COMPILER_EXTERNAL_TOOLCHAIN"))
+      {
+      std::string flag="-DCMAKE_C_COMPILER_EXTERNAL_TOOLCHAIN=";
+      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)
     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)
     {
     {

+ 50 - 1
Source/cmLocalGenerator.cxx

@@ -1043,11 +1043,38 @@ cmLocalGenerator::ExpandRuleVariable(std::string const& variable,
       // If this is the compiler then look for the extra variable
       // If this is the compiler then look for the extra variable
       // _COMPILER_ARG1 which must be the first argument to the compiler
       // _COMPILER_ARG1 which must be the first argument to the compiler
       const char* compilerArg1 = 0;
       const char* compilerArg1 = 0;
+      const char* compilerTarget = 0;
+      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")
       if(actualReplace == "CMAKE_${LANG}_COMPILER")
         {
         {
         std::string arg1 = actualReplace + "_ARG1";
         std::string arg1 = actualReplace + "_ARG1";
         cmSystemTools::ReplaceString(arg1, "${LANG}", lang);
         cmSystemTools::ReplaceString(arg1, "${LANG}", lang);
         compilerArg1 = this->Makefile->GetDefinition(arg1.c_str());
         compilerArg1 = this->Makefile->GetDefinition(arg1.c_str());
+        compilerTarget
+              = this->Makefile->GetDefinition(
+                (std::string("CMAKE_") + lang + "_COMPILER_TARGET").c_str());
+        compilerOptionTarget
+              = this->Makefile->GetDefinition(
+                (std::string("CMAKE_") + lang +
+                                          "_COMPILE_OPTIONS_TARGET").c_str());
+        compilerExternalToolchain
+              = this->Makefile->GetDefinition(
+                (std::string("CMAKE_") + lang +
+                                    "_COMPILER_EXTERNAL_TOOLCHAIN").c_str());
+        compilerOptionExternalToolchain
+              = 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)
       if(actualReplace.find("${LANG}") != actualReplace.npos)
         {
         {
@@ -1068,6 +1095,24 @@ cmLocalGenerator::ExpandRuleVariable(std::string const& variable,
             ret += " ";
             ret += " ";
             ret += compilerArg1;
             ret += compilerArg1;
             }
             }
+          if (compilerTarget && compilerOptionTarget)
+            {
+            ret += " ";
+            ret += compilerOptionTarget;
+            ret += compilerTarget;
+            }
+          if (compilerExternalToolchain && compilerOptionExternalToolchain)
+            {
+            ret += " ";
+            ret += compilerOptionExternalToolchain;
+            ret += this->EscapeForShell(compilerExternalToolchain, true);
+            }
+          if (compilerSysroot && compilerOptionSysroot)
+            {
+            ret += " ";
+            ret += compilerOptionSysroot;
+            ret += this->EscapeForShell(compilerSysroot, true);
+            }
           return ret;
           return ret;
           }
           }
         return replace;
         return replace;
@@ -1462,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_";
@@ -1474,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);