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
This commit is contained in:
Brad King 2013-11-19 12:41:57 -05:00 committed by CMake Topic Stage
commit 46ec48c93d
16 changed files with 187 additions and 11 deletions

View File

@ -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

View File

@ -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

View File

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

View File

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

View File

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

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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})

View File

@ -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()

View File

@ -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

View File

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

View File

@ -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)
{ {
runtimeDirs.push_back(*ri); d = d.substr(rootPath.size());
}
if(emitted.insert(d).second)
{
runtimeDirs.push_back(d);
} }
} }
} }

View File

@ -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");

View File

@ -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)
{ {

View File

@ -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);