Use --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
parent bb879bcf2d
commit de4da665d3
10 changed files with 136 additions and 9 deletions

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_SYSROOT_FLAG "--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

@ -1884,6 +1884,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)
@ -1907,9 +1909,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 (d.find(rootPath) == 0)
{ {
runtimeDirs.push_back(*ri); d = d.substr(rootPath.size());
}
if(emitted.insert(d).second)
{
runtimeDirs.push_back(d);
} }
} }
} }

View File

@ -560,6 +560,16 @@ void cmDocumentVariables::DefineVariables(cmake* cm)
false, false,
"Variables That Change Behavior"); "Variables That Change Behavior");
cm->DefineProperty
("CMAKE_SYSROOT", cmProperty::VARIABLE,
"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 if "
"necessary on installation. The CMAKE_SYSROOT is also used to prefix "
"paths searched by the find_* commands.",
false,
"Variables That Change Behavior");
cm->DefineProperty cm->DefineProperty
("CMAKE_FIND_LIBRARY_PREFIXES", cmProperty::VARIABLE, ("CMAKE_FIND_LIBRARY_PREFIXES", cmProperty::VARIABLE,
"Prefixes to prepend when looking for libraries.", "Prefixes to prepend when looking for libraries.",

View File

@ -62,10 +62,15 @@ void cmFindCommon::GenerateDocumentation()
"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. " "directories to be prepended to all other search directories. "
"This effectively \"re-roots\" the entire search under given locations. " "This effectively \"re-roots\" the entire search under given locations. "
"By default it is empty. It is especially useful when " "By default it is empty. "
"The variable CMAKE_SYSROOT can also be used to specify exactly one "
"directory to use as a prefix. Setting CMAKE_SYSROOT also has other "
"effects. See the documentation for that variable for more. "
"These are especially useful when "
"cross-compiling to point to the root directory of the " "cross-compiling to point to the root directory of the "
"target environment and CMake will search there too. By default at first " "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 " "the CMAKE_SYSROOT directory is searched, then the directories listed in "
"CMAKE_FIND_ROOT_PATH and then the non-rooted "
"directories will be searched. " "directories will be searched. "
"The default behavior can be adjusted by setting " "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 "
@ -187,16 +192,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 (sysroot)
{
roots.push_back(sysroot);
}
if (rootPath)
{
cmSystemTools::ExpandListArgument(rootPath, roots);
}
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

@ -1425,6 +1425,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_";
@ -1437,7 +1439,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);

View File

@ -365,6 +365,22 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
vars.TargetVersionMajor = targetVersionMajor.c_str(); vars.TargetVersionMajor = targetVersionMajor.c_str();
vars.TargetVersionMinor = targetVersionMinor.c_str(); vars.TargetVersionMinor = targetVersionMinor.c_str();
if (const char *rootPath =
this->Makefile->GetDefinition("CMAKE_SYSROOT"))
{
if (*rootPath)
{
if (const char *sysrootFlag =
this->Makefile->GetDefinition("CMAKE_SYSROOT_FLAG"))
{
flags += " ";
flags += sysrootFlag;
flags += this->LocalGenerator->EscapeForShell(rootPath);
flags += " ";
}
}
}
vars.LinkLibraries = linkLibs.c_str(); vars.LinkLibraries = linkLibs.c_str();
vars.Flags = flags.c_str(); vars.Flags = flags.c_str();
vars.LinkFlags = linkFlags.c_str(); vars.LinkFlags = linkFlags.c_str();

View File

@ -589,6 +589,26 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules
cmLocalGenerator::SHELL); cmLocalGenerator::SHELL);
vars.ObjectDir = objdir.c_str(); vars.ObjectDir = objdir.c_str();
vars.Target = targetOutPathReal.c_str(); vars.Target = targetOutPathReal.c_str();
if(this->Target->GetType() == cmTarget::SHARED_LIBRARY)
{
if (const char *rootPath =
this->Makefile->GetSafeDefinition("CMAKE_SYSROOT"))
{
if (*rootPath)
{
if (const char *sysrootFlag =
this->Makefile->GetDefinition("CMAKE_SYSROOT_FLAG"))
{
linkFlags += " ";
linkFlags += sysrootFlag;
linkFlags += this->LocalGenerator->EscapeForShell(rootPath);
linkFlags += " ";
}
}
}
}
vars.LinkLibraries = linkLibs.c_str(); vars.LinkLibraries = linkLibs.c_str();
vars.ObjectsQuoted = buildObjs.c_str(); vars.ObjectsQuoted = buildObjs.c_str();
if (this->Target->HasSOName(this->ConfigName)) if (this->Target->HasSOName(this->ConfigName))

View File

@ -686,6 +686,23 @@ cmMakefileTargetGenerator
cmLocalGenerator::START_OUTPUT, cmLocalGenerator::START_OUTPUT,
cmLocalGenerator::SHELL); cmLocalGenerator::SHELL);
vars.ObjectDir = objectDir.c_str(); vars.ObjectDir = objectDir.c_str();
if (const char *rootPath =
this->Makefile->GetSafeDefinition("CMAKE_SYSROOT"))
{
if (*rootPath)
{
if (const char *sysrootFlag =
this->Makefile->GetDefinition("CMAKE_SYSROOT_FLAG"))
{
flags += " ";
flags += sysrootFlag;
flags += this->LocalGenerator->EscapeForShell(rootPath);
flags += " ";
}
}
}
vars.Flags = flags.c_str(); vars.Flags = flags.c_str();
std::string definesString = "$("; std::string definesString = "$(";

View File

@ -223,7 +223,27 @@ cmNinjaNormalTargetGenerator
vars.TargetVersionMajor = targetVersionMajor.c_str(); vars.TargetVersionMajor = targetVersionMajor.c_str();
vars.TargetVersionMinor = targetVersionMinor.c_str(); vars.TargetVersionMinor = targetVersionMinor.c_str();
vars.Flags = "$FLAGS";
std::string flags = "$FLAGS";
if (const char *rootPath =
this->GetMakefile()->GetSafeDefinition("CMAKE_SYSROOT"))
{
if (*rootPath)
{
if (const char *sysrootFlag =
this->GetMakefile()->GetDefinition("CMAKE_SYSROOT_FLAG"))
{
flags += " ";
flags += sysrootFlag;
flags += this->GetLocalGenerator()->EscapeForShell(rootPath);
flags += " ";
}
}
}
vars.Flags = flags.c_str();
vars.LinkFlags = "$LINK_FLAGS"; vars.LinkFlags = "$LINK_FLAGS";
std::string langFlags; std::string langFlags;

View File

@ -414,7 +414,23 @@ cmNinjaTargetGenerator
cmSystemTools::ReplaceString(depFlagsStr, "<CMAKE_C_COMPILER>", cmSystemTools::ReplaceString(depFlagsStr, "<CMAKE_C_COMPILER>",
mf->GetDefinition("CMAKE_C_COMPILER")); mf->GetDefinition("CMAKE_C_COMPILER"));
flags += " " + depFlagsStr; flags += " " + depFlagsStr;
}
if (const char *rootPath =
this->Makefile->GetSafeDefinition("CMAKE_SYSROOT"))
{
if (*rootPath)
{
if (const char *sysrootFlag =
this->Makefile->GetDefinition("CMAKE_SYSROOT_FLAG"))
{
flags += " ";
flags += sysrootFlag;
flags += this->LocalGenerator->EscapeForShell(rootPath);
flags += " ";
}
}
}
}
vars.Flags = flags.c_str(); vars.Flags = flags.c_str();