Bläddra i källkod

Allow toolchain files to specify an external toolchain.

Clang can compile code, but uses the gcc tools for other tasks such
as linking. The -gcc-toolchain option can be used for that, but
generalize so that other compilers can be treated the same.

If such a location is specified, use it as a hint for finding
the binutils executables.
Stephen Kelly 12 år sedan
förälder
incheckning
5096967ecd

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

@@ -234,6 +234,7 @@ Variables for Languages
    /variable/CMAKE_LANG_COMPILER_ID
    /variable/CMAKE_LANG_COMPILER_LOADED
    /variable/CMAKE_LANG_COMPILER
+   /variable/CMAKE_LANG_COMPILER_EXTERNAL_TOOLCHAIN
    /variable/CMAKE_LANG_COMPILER_TARGET
    /variable/CMAKE_LANG_COMPILER_VERSION
    /variable/CMAKE_LANG_CREATE_SHARED_LIBRARY

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

+ 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.
 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_RANLIB NAMES ${_CMAKE_TOOLCHAIN_PREFIX}ranlib HINTS ${_CMAKE_TOOLCHAIN_LOCATION})

+ 1 - 0
Modules/Compiler/Clang.cmake

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

+ 14 - 0
Source/cmCoreTryCompile.cxx

@@ -419,6 +419,20 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv)
       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(this->Makefile->GetDefinition("CMAKE_POSITION_INDEPENDENT_CODE")!=0)
       {
       fprintf(fout, "set(CMAKE_POSITION_INDEPENDENT_CODE \"ON\")\n");

+ 16 - 0
Source/cmLocalGenerator.cxx

@@ -1045,6 +1045,8 @@ cmLocalGenerator::ExpandRuleVariable(std::string const& variable,
       const char* compilerArg1 = 0;
       const char* compilerTarget = 0;
       const char* compilerOptionTarget = 0;
+      const char* compilerExternalToolchain = 0;
+      const char* compilerOptionExternalToolchain = 0;
       if(actualReplace == "CMAKE_${LANG}_COMPILER")
         {
         std::string arg1 = actualReplace + "_ARG1";
@@ -1057,6 +1059,14 @@ cmLocalGenerator::ExpandRuleVariable(std::string const& variable,
               = 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());
         }
       if(actualReplace.find("${LANG}") != actualReplace.npos)
         {
@@ -1083,6 +1093,12 @@ cmLocalGenerator::ExpandRuleVariable(std::string const& variable,
             ret += compilerOptionTarget;
             ret += compilerTarget;
             }
+          if (compilerExternalToolchain && compilerOptionExternalToolchain)
+            {
+            ret += " ";
+            ret += compilerOptionExternalToolchain;
+            ret += this->EscapeForShell(compilerExternalToolchain, true);
+            }
           return ret;
           }
         return replace;