From f41ecd1db4341a9ab6087e6959993f4384eb6c53 Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Sat, 16 Nov 2013 16:53:26 +0100 Subject: [PATCH 1/4] CMakeDetermineCompilerId: Look for internal file only on host The find_file this module uses to locate the compiler id source file must always look on the host and never in CMAKE_FIND_ROOT_PATH, even when a toolchain file has set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) Add NO_CMAKE_FIND_ROOT_PATH to the find_file call to avoid rerooting. --- Modules/CMakeDetermineCompilerId.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/CMakeDetermineCompilerId.cmake b/Modules/CMakeDetermineCompilerId.cmake index 7fa45340c..efb06c094 100644 --- a/Modules/CMakeDetermineCompilerId.cmake +++ b/Modules/CMakeDetermineCompilerId.cmake @@ -85,7 +85,7 @@ endfunction() #----------------------------------------------------------------------------- # Function to write the compiler id source file. 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) unset(src_in CACHE) string(CONFIGURE "${ID_CONTENT_IN}" ID_CONTENT_OUT @ONLY) From 76552d595db509d47e9bf179aac7a00e2f1fcfae Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Sun, 19 May 2013 19:18:01 +0200 Subject: [PATCH 2/4] Add compiler target compile options. For clang, this allows passing -target to the compiler, and for qcc, -V using toolchain files containing something like set(triple arm-linux-gnueabihf) set(CMAKE_C_COMPILER "/usr/bin/clang") set(CMAKE_C_COMPILER_TARGET ${triple}) set(CMAKE_CXX_COMPILER "/usr/bin/clang++") set(CMAKE_CXX_COMPILER_TARGET ${triple}) or set(arch gcc_ntoarmv7le) set(CMAKE_C_COMPILER /opt/qnx650/host/linux/x86/usr/bin/qcc) set(CMAKE_C_COMPILER_TARGET ${arch}) set(CMAKE_CXX_COMPILER /opt/qnx650/host/linux/x86/usr/bin/QCC) set(CMAKE_CXX_COMPILER_TARGET ${arch}) Both clang and qcc are inherently cross compiler( driver)s. When cross-compiling with clang, use the CMAKE_${lang}_COMPILER_TARGET as the _CMAKE_TOOLCHAIN_PREFIX to find the appropriate binutils. When cross-compiling with QNX qcc, use the CMAKE_${lang}_COMPILER_TARGET to set the appropriate _CMAKE_TOOLCHAIN_PREFIX. --- Help/manual/cmake-variables.7.rst | 1 + Help/variable/CMAKE_LANG_COMPILER_TARGET.rst | 11 +++++++++++ Modules/CMakeDetermineCCompiler.cmake | 6 ++++++ Modules/CMakeDetermineCXXCompiler.cmake | 6 ++++++ Modules/Compiler/Clang.cmake | 1 + Modules/Platform/QNX.cmake | 3 +++ Source/cmCoreTryCompile.cxx | 14 ++++++++++++++ Source/cmLocalGenerator.cxx | 15 +++++++++++++++ 8 files changed, 57 insertions(+) create mode 100644 Help/variable/CMAKE_LANG_COMPILER_TARGET.rst diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst index 59e806443..c2af59601 100644 --- a/Help/manual/cmake-variables.7.rst +++ b/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_TARGET /variable/CMAKE_LANG_COMPILER_VERSION /variable/CMAKE_LANG_CREATE_SHARED_LIBRARY /variable/CMAKE_LANG_CREATE_SHARED_MODULE diff --git a/Help/variable/CMAKE_LANG_COMPILER_TARGET.rst b/Help/variable/CMAKE_LANG_COMPILER_TARGET.rst new file mode 100644 index 000000000..7c8efee9b --- /dev/null +++ b/Help/variable/CMAKE_LANG_COMPILER_TARGET.rst @@ -0,0 +1,11 @@ +CMAKE__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. diff --git a/Modules/CMakeDetermineCCompiler.cmake b/Modules/CMakeDetermineCCompiler.cmake index 0d47a60a9..438a98a5d 100644 --- a/Modules/CMakeDetermineCCompiler.cmake +++ b/Modules/CMakeDetermineCCompiler.cmake @@ -158,6 +158,12 @@ if (CMAKE_CROSSCOMPILING AND NOT _CMAKE_TOOLCHAIN_PREFIX) get_filename_component(COMPILER_BASENAME "${CMAKE_C_COMPILER}" NAME) if (COMPILER_BASENAME MATCHES "^(.+-)(clang|g?cc)(-[0-9]+\\.[0-9]+\\.[0-9]+)?(\\.exe)?$") 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 () # if "llvm-" is part of the prefix, remove it, since llvm doesn't have its own binutils diff --git a/Modules/CMakeDetermineCXXCompiler.cmake b/Modules/CMakeDetermineCXXCompiler.cmake index e88218922..5f9d9bf60 100644 --- a/Modules/CMakeDetermineCXXCompiler.cmake +++ b/Modules/CMakeDetermineCXXCompiler.cmake @@ -156,6 +156,12 @@ if (CMAKE_CROSSCOMPILING AND NOT _CMAKE_TOOLCHAIN_PREFIX) get_filename_component(COMPILER_BASENAME "${CMAKE_CXX_COMPILER}" NAME) if (COMPILER_BASENAME MATCHES "^(.+-)(clan)?[gc]\\+\\+(-[0-9]+\\.[0-9]+\\.[0-9]+)?(\\.exe)?$") 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 () # if "llvm-" is part of the prefix, remove it, since llvm doesn't have its own binutils diff --git a/Modules/Compiler/Clang.cmake b/Modules/Compiler/Clang.cmake index 7d7be5c4b..f0ea2f802 100644 --- a/Modules/Compiler/Clang.cmake +++ b/Modules/Compiler/Clang.cmake @@ -30,5 +30,6 @@ else() set(CMAKE_${lang}_COMPILE_OPTIONS_PIE "-fPIE") set(CMAKE_INCLUDE_SYSTEM_FLAG_${lang} "-isystem ") set(CMAKE_${lang}_COMPILE_OPTIONS_VISIBILITY "-fvisibility=") + set(CMAKE_${lang}_COMPILE_OPTIONS_TARGET "-target ") endmacro() endif() diff --git a/Modules/Platform/QNX.cmake b/Modules/Platform/QNX.cmake index 068799f91..9afde0557 100644 --- a/Modules/Platform/QNX.cmake +++ b/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_SONAME_C_FLAG "-Wl,-soname,") 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 # specifying the file path. diff --git a/Source/cmCoreTryCompile.cxx b/Source/cmCoreTryCompile.cxx index 479a6995c..5bf8ce58b 100644 --- a/Source/cmCoreTryCompile.cxx +++ b/Source/cmCoreTryCompile.cxx @@ -405,6 +405,20 @@ int cmCoreTryCompile::TryCompileCode(std::vector const& argv) flag += this->Makefile->GetSafeDefinition("CMAKE_OSX_DEPLOYMENT_TARGET"); 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(this->Makefile->GetDefinition("CMAKE_POSITION_INDEPENDENT_CODE")!=0) { fprintf(fout, "set(CMAKE_POSITION_INDEPENDENT_CODE \"ON\")\n"); diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index 63ec576d8..c308ba85c 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -1043,11 +1043,20 @@ cmLocalGenerator::ExpandRuleVariable(std::string const& variable, // If this is the compiler then look for the extra variable // _COMPILER_ARG1 which must be the first argument to the compiler const char* compilerArg1 = 0; + const char* compilerTarget = 0; + const char* compilerOptionTarget = 0; if(actualReplace == "CMAKE_${LANG}_COMPILER") { std::string arg1 = actualReplace + "_ARG1"; cmSystemTools::ReplaceString(arg1, "${LANG}", lang); 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()); } if(actualReplace.find("${LANG}") != actualReplace.npos) { @@ -1068,6 +1077,12 @@ cmLocalGenerator::ExpandRuleVariable(std::string const& variable, ret += " "; ret += compilerArg1; } + if (compilerTarget && compilerOptionTarget) + { + ret += " "; + ret += compilerOptionTarget; + ret += compilerTarget; + } return ret; } return replace; From 5096967ecd443f3d7477d823e7ffdffcc15a8ed1 Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Thu, 8 Aug 2013 17:36:36 +0200 Subject: [PATCH 3/4] 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. --- Help/manual/cmake-variables.7.rst | 1 + .../CMAKE_LANG_COMPILER_EXTERNAL_TOOLCHAIN.rst | 13 +++++++++++++ Modules/CMakeFindBinUtils.cmake | 7 ++++++- Modules/Compiler/Clang.cmake | 1 + Source/cmCoreTryCompile.cxx | 14 ++++++++++++++ Source/cmLocalGenerator.cxx | 16 ++++++++++++++++ 6 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 Help/variable/CMAKE_LANG_COMPILER_EXTERNAL_TOOLCHAIN.rst diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst index c2af59601..ada9647e2 100644 --- a/Help/manual/cmake-variables.7.rst +++ b/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 diff --git a/Help/variable/CMAKE_LANG_COMPILER_EXTERNAL_TOOLCHAIN.rst b/Help/variable/CMAKE_LANG_COMPILER_EXTERNAL_TOOLCHAIN.rst new file mode 100644 index 000000000..86c0b0e42 --- /dev/null +++ b/Help/variable/CMAKE_LANG_COMPILER_EXTERNAL_TOOLCHAIN.rst @@ -0,0 +1,13 @@ +CMAKE__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__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. diff --git a/Modules/CMakeFindBinUtils.cmake b/Modules/CMakeFindBinUtils.cmake index 315d57ec3..829b6ffd4 100644 --- a/Modules/CMakeFindBinUtils.cmake +++ b/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}) diff --git a/Modules/Compiler/Clang.cmake b/Modules/Compiler/Clang.cmake index f0ea2f802..055aad639 100644 --- a/Modules/Compiler/Clang.cmake +++ b/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() diff --git a/Source/cmCoreTryCompile.cxx b/Source/cmCoreTryCompile.cxx index 5bf8ce58b..900f09f8c 100644 --- a/Source/cmCoreTryCompile.cxx +++ b/Source/cmCoreTryCompile.cxx @@ -419,6 +419,20 @@ int cmCoreTryCompile::TryCompileCode(std::vector 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"); diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index c308ba85c..582ad0e05 100644 --- a/Source/cmLocalGenerator.cxx +++ b/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; From 7cd65c97fabd9f3249739a81dd1260a1e0b59ee1 Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Sat, 13 Apr 2013 14:46:57 +0200 Subject: [PATCH 4/4] 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. --- Help/command/FIND_XXX_ROOT.txt | 11 +++++++++-- Help/manual/cmake-variables.7.rst | 1 + Help/variable/CMAKE_SYSROOT.rst | 12 ++++++++++++ Modules/Compiler/GNU.cmake | 1 + Source/cmComputeLinkInformation.cxx | 20 ++++++++++++++++---- Source/cmCoreTryCompile.cxx | 7 +++++++ Source/cmFindCommon.cxx | 15 +++++++++++++-- Source/cmLocalGenerator.cxx | 20 +++++++++++++++++++- 8 files changed, 78 insertions(+), 9 deletions(-) create mode 100644 Help/variable/CMAKE_SYSROOT.rst diff --git a/Help/command/FIND_XXX_ROOT.txt b/Help/command/FIND_XXX_ROOT.txt index 407375a03..7f80dcb10 100644 --- a/Help/command/FIND_XXX_ROOT.txt +++ b/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 diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst index ada9647e2..dd82b409d 100644 --- a/Help/manual/cmake-variables.7.rst +++ b/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 diff --git a/Help/variable/CMAKE_SYSROOT.rst b/Help/variable/CMAKE_SYSROOT.rst new file mode 100644 index 000000000..e42e63a22 --- /dev/null +++ b/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. diff --git a/Modules/Compiler/GNU.cmake b/Modules/Compiler/GNU.cmake index 504704dad..f01255cf6 100644 --- a/Modules/Compiler/GNU.cmake +++ b/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 diff --git a/Source/cmComputeLinkInformation.cxx b/Source/cmComputeLinkInformation.cxx index d4644c3cc..3152c2a0b 100644 --- a/Source/cmComputeLinkInformation.cxx +++ b/Source/cmComputeLinkInformation.cxx @@ -1901,6 +1901,8 @@ void cmComputeLinkInformation::GetRPath(std::vector& runtimeDirs, } if(use_build_rpath || use_link_rpath) { + std::string rootPath = this->Makefile->GetSafeDefinition("CMAKE_SYSROOT"); + cmSystemTools::ConvertToUnixSlashes(rootPath); std::vector const& rdirs = this->GetRuntimeSearchPath(); for(std::vector::const_iterator ri = rdirs.begin(); ri != rdirs.end(); ++ri) @@ -1909,9 +1911,14 @@ void cmComputeLinkInformation::GetRPath(std::vector& 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& 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) { - runtimeDirs.push_back(*ri); + d = d.substr(rootPath.size()); + } + if(emitted.insert(d).second) + { + runtimeDirs.push_back(d); } } } diff --git a/Source/cmCoreTryCompile.cxx b/Source/cmCoreTryCompile.cxx index 900f09f8c..bbfc427a4 100644 --- a/Source/cmCoreTryCompile.cxx +++ b/Source/cmCoreTryCompile.cxx @@ -433,6 +433,13 @@ int cmCoreTryCompile::TryCompileCode(std::vector 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"); diff --git a/Source/cmFindCommon.cxx b/Source/cmFindCommon.cxx index 7beeda097..8c4281113 100644 --- a/Source/cmFindCommon.cxx +++ b/Source/cmFindCommon.cxx @@ -138,16 +138,27 @@ void cmFindCommon::RerootPaths(std::vector& 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 roots; - cmSystemTools::ExpandListArgument(rootPath, roots); + if (rootPath) + { + cmSystemTools::ExpandListArgument(rootPath, roots); + } + if (sysroot) + { + roots.push_back(sysroot); + } for(std::vector::iterator ri = roots.begin(); ri != roots.end(); ++ri) { diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index 582ad0e05..d2784a927 100644 --- a/Source/cmLocalGenerator.cxx +++ b/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& dirs, return; } + std::string rootPath = this->Makefile->GetSafeDefinition("CMAKE_SYSROOT"); + std::vector implicitDirs; // Load implicit include directories for this language. std::string impDirVar = "CMAKE_"; @@ -1505,7 +1521,9 @@ void cmLocalGenerator::GetIncludeDirectories(std::vector& dirs, for(std::vector::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);