diff --git a/Modules/Compiler/GNU.cmake b/Modules/Compiler/GNU.cmake index 504704dad..e5e10c3ab 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_SYSROOT_FLAG "--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 02495c43d..b378391bf 100644 --- a/Source/cmComputeLinkInformation.cxx +++ b/Source/cmComputeLinkInformation.cxx @@ -1884,6 +1884,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) @@ -1907,9 +1909,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 (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/cmDocumentVariables.cxx b/Source/cmDocumentVariables.cxx index 689508f5a..4499cbd3e 100644 --- a/Source/cmDocumentVariables.cxx +++ b/Source/cmDocumentVariables.cxx @@ -560,6 +560,16 @@ void cmDocumentVariables::DefineVariables(cmake* cm) false, "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 ("CMAKE_FIND_LIBRARY_PREFIXES", cmProperty::VARIABLE, "Prefixes to prepend when looking for libraries.", diff --git a/Source/cmFindCommon.cxx b/Source/cmFindCommon.cxx index b44864e13..5daa47d6f 100644 --- a/Source/cmFindCommon.cxx +++ b/Source/cmFindCommon.cxx @@ -62,10 +62,15 @@ void cmFindCommon::GenerateDocumentation() "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 " + "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 " "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. " "The default behavior can be adjusted by setting " "CMAKE_FIND_ROOT_PATH_MODE_XXX. This behavior can be manually " @@ -187,16 +192,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 (sysroot) + { + roots.push_back(sysroot); + } + if (rootPath) + { + cmSystemTools::ExpandListArgument(rootPath, roots); + } for(std::vector::iterator ri = roots.begin(); ri != roots.end(); ++ri) { diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index c2da4a9ae..1563860db 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -1425,6 +1425,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_"; @@ -1437,7 +1439,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); diff --git a/Source/cmMakefileExecutableTargetGenerator.cxx b/Source/cmMakefileExecutableTargetGenerator.cxx index e4219a945..271183e70 100644 --- a/Source/cmMakefileExecutableTargetGenerator.cxx +++ b/Source/cmMakefileExecutableTargetGenerator.cxx @@ -365,6 +365,22 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink) vars.TargetVersionMajor = targetVersionMajor.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.Flags = flags.c_str(); vars.LinkFlags = linkFlags.c_str(); diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx index 347f26d26..36d1a5a4a 100644 --- a/Source/cmMakefileLibraryTargetGenerator.cxx +++ b/Source/cmMakefileLibraryTargetGenerator.cxx @@ -589,6 +589,26 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules cmLocalGenerator::SHELL); vars.ObjectDir = objdir.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.ObjectsQuoted = buildObjs.c_str(); if (this->Target->HasSOName(this->ConfigName)) diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx index 10b784993..f31b1a804 100644 --- a/Source/cmMakefileTargetGenerator.cxx +++ b/Source/cmMakefileTargetGenerator.cxx @@ -686,6 +686,23 @@ cmMakefileTargetGenerator cmLocalGenerator::START_OUTPUT, cmLocalGenerator::SHELL); 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(); std::string definesString = "$("; diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx index 1bc4302c5..0a2a75f25 100644 --- a/Source/cmNinjaNormalTargetGenerator.cxx +++ b/Source/cmNinjaNormalTargetGenerator.cxx @@ -223,7 +223,27 @@ cmNinjaNormalTargetGenerator vars.TargetVersionMajor = targetVersionMajor.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"; std::string langFlags; diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx index ae18a4887..43b7baa1c 100644 --- a/Source/cmNinjaTargetGenerator.cxx +++ b/Source/cmNinjaTargetGenerator.cxx @@ -414,7 +414,23 @@ cmNinjaTargetGenerator cmSystemTools::ReplaceString(depFlagsStr, "", mf->GetDefinition("CMAKE_C_COMPILER")); 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();