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.
This commit is contained in:
Stephen Kelly 2013-04-13 14:46:57 +02:00 committed by Brad King
parent 5096967ecd
commit 7cd65c97fa
8 changed files with 78 additions and 9 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

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

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

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

@ -433,6 +433,13 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv)
flag += tcDef; flag += tcDef;
cmakeFlags.push_back(flag); 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;
if (rootPath)
{
cmSystemTools::ExpandListArgument(rootPath, roots); 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

@ -1047,6 +1047,8 @@ cmLocalGenerator::ExpandRuleVariable(std::string const& variable,
const char* compilerOptionTarget = 0; const char* compilerOptionTarget = 0;
const char* compilerExternalToolchain = 0; const char* compilerExternalToolchain = 0;
const char* compilerOptionExternalToolchain = 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";
@ -1067,6 +1069,12 @@ cmLocalGenerator::ExpandRuleVariable(std::string const& variable,
= this->Makefile->GetDefinition( = this->Makefile->GetDefinition(
(std::string("CMAKE_") + lang + (std::string("CMAKE_") + lang +
"_COMPILE_OPTIONS_EXTERNAL_TOOLCHAIN").c_str()); "_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)
{ {
@ -1099,6 +1107,12 @@ cmLocalGenerator::ExpandRuleVariable(std::string const& variable,
ret += compilerOptionExternalToolchain; ret += compilerOptionExternalToolchain;
ret += this->EscapeForShell(compilerExternalToolchain, true); ret += this->EscapeForShell(compilerExternalToolchain, true);
} }
if (compilerSysroot && compilerOptionSysroot)
{
ret += " ";
ret += compilerOptionSysroot;
ret += this->EscapeForShell(compilerSysroot, true);
}
return ret; return ret;
} }
return replace; return replace;
@ -1493,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_";
@ -1505,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);