From 53e89b6ab0cae7b9ba0316b3806abd986794a22c Mon Sep 17 00:00:00 2001 From: Brad King Date: Tue, 9 May 2017 14:08:15 -0400 Subject: Add options for separate compile and link sysroots Add `CMAKE_SYSROOT_COMPILE` and `CMAKE_SYSROOT_LINK` variables to as operation-specific alternatives to `CMAKE_SYSROOT`. This will be useful for Android NDKs that compile and link with different sysroot values (e.g. `r14` with unified headers). Co-Author: Florent Castelli --- Help/manual/cmake-variables.7.rst | 2 ++ Help/release/dev/split-sysroot.rst | 5 +++++ Help/variable/CMAKE_SYSROOT.rst | 3 +++ Help/variable/CMAKE_SYSROOT_COMPILE.rst | 9 +++++++++ Help/variable/CMAKE_SYSROOT_LINK.rst | 9 +++++++++ Source/cmComputeLinkInformation.cxx | 8 +++++++- Source/cmCoreTryCompile.cxx | 4 ++++ Source/cmFindCommon.cxx | 14 +++++++++++++- Source/cmLocalGenerator.cxx | 25 ++++++++++++++++++++++--- Source/cmLocalGenerator.h | 1 + Source/cmLocalNinjaGenerator.cxx | 5 +++-- Source/cmRulePlaceholderExpander.cxx | 16 +++++++++++++--- Source/cmRulePlaceholderExpander.h | 3 ++- 13 files changed, 93 insertions(+), 11 deletions(-) create mode 100644 Help/release/dev/split-sysroot.rst create mode 100644 Help/variable/CMAKE_SYSROOT_COMPILE.rst create mode 100644 Help/variable/CMAKE_SYSROOT_LINK.rst diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst index 4317f67..6ee4257 100644 --- a/Help/manual/cmake-variables.7.rst +++ b/Help/manual/cmake-variables.7.rst @@ -171,6 +171,8 @@ Variables that Change Behavior /variable/CMAKE_SUBLIME_TEXT_2_ENV_SETTINGS /variable/CMAKE_SUBLIME_TEXT_2_EXCLUDE_BUILD_TREE /variable/CMAKE_SYSROOT + /variable/CMAKE_SYSROOT_COMPILE + /variable/CMAKE_SYSROOT_LINK /variable/CMAKE_SYSTEM_APPBUNDLE_PATH /variable/CMAKE_SYSTEM_FRAMEWORK_PATH /variable/CMAKE_SYSTEM_IGNORE_PATH diff --git a/Help/release/dev/split-sysroot.rst b/Help/release/dev/split-sysroot.rst new file mode 100644 index 0000000..8144e3f --- /dev/null +++ b/Help/release/dev/split-sysroot.rst @@ -0,0 +1,5 @@ +split-sysroot +------------- + +* The :variable:`CMAKE_SYSROOT_COMPILE` and :variable:`CMAKE_SYSROOT_LINK` + variables were added to use separate sysroots for compiling and linking. diff --git a/Help/variable/CMAKE_SYSROOT.rst b/Help/variable/CMAKE_SYSROOT.rst index 7aa0450..64f81bb 100644 --- a/Help/variable/CMAKE_SYSROOT.rst +++ b/Help/variable/CMAKE_SYSROOT.rst @@ -10,3 +10,6 @@ paths searched by the ``find_*`` commands. This variable may only be set in a toolchain file specified by the :variable:`CMAKE_TOOLCHAIN_FILE` variable. + +See also the :variable:`CMAKE_SYSROOT_COMPILE` and +:variable:`CMAKE_SYSROOT_LINK` variables. diff --git a/Help/variable/CMAKE_SYSROOT_COMPILE.rst b/Help/variable/CMAKE_SYSROOT_COMPILE.rst new file mode 100644 index 0000000..e96c62b --- /dev/null +++ b/Help/variable/CMAKE_SYSROOT_COMPILE.rst @@ -0,0 +1,9 @@ +CMAKE_SYSROOT_COMPILE +--------------------- + +Path to pass to the compiler in the ``--sysroot`` flag when compiling source +files. This is the same as :variable:`CMAKE_SYSROOT` but is used only for +compiling sources and not linking. + +This variable may only be set in a toolchain file specified by +the :variable:`CMAKE_TOOLCHAIN_FILE` variable. diff --git a/Help/variable/CMAKE_SYSROOT_LINK.rst b/Help/variable/CMAKE_SYSROOT_LINK.rst new file mode 100644 index 0000000..88b48ef --- /dev/null +++ b/Help/variable/CMAKE_SYSROOT_LINK.rst @@ -0,0 +1,9 @@ +CMAKE_SYSROOT_LINK +------------------ + +Path to pass to the compiler in the ``--sysroot`` flag when linking. This is +the same as :variable:`CMAKE_SYSROOT` but is used only for linking and not +compiling sources. + +This variable may only be set in a toolchain file specified by +the :variable:`CMAKE_TOOLCHAIN_FILE` variable. diff --git a/Source/cmComputeLinkInformation.cxx b/Source/cmComputeLinkInformation.cxx index b273443..c2ada43 100644 --- a/Source/cmComputeLinkInformation.cxx +++ b/Source/cmComputeLinkInformation.cxx @@ -1737,7 +1737,13 @@ void cmComputeLinkInformation::GetRPath(std::vector& runtimeDirs, } } if (use_build_rpath || use_link_rpath) { - std::string rootPath = this->Makefile->GetSafeDefinition("CMAKE_SYSROOT"); + std::string rootPath; + if (const char* sysrootLink = + this->Makefile->GetDefinition("CMAKE_SYSROOT_LINK")) { + rootPath = sysrootLink; + } else { + rootPath = this->Makefile->GetSafeDefinition("CMAKE_SYSROOT"); + } const char* stagePath = this->Makefile->GetDefinition("CMAKE_STAGING_PREFIX"); const char* installPrefix = diff --git a/Source/cmCoreTryCompile.cxx b/Source/cmCoreTryCompile.cxx index 2287bc2..d8ddf45 100644 --- a/Source/cmCoreTryCompile.cxx +++ b/Source/cmCoreTryCompile.cxx @@ -41,6 +41,8 @@ static std::string const kCMAKE_OSX_SYSROOT = "CMAKE_OSX_SYSROOT"; static std::string const kCMAKE_POSITION_INDEPENDENT_CODE = "CMAKE_POSITION_INDEPENDENT_CODE"; static std::string const kCMAKE_SYSROOT = "CMAKE_SYSROOT"; +static std::string const kCMAKE_SYSROOT_COMPILE = "CMAKE_SYSROOT_COMPILE"; +static std::string const kCMAKE_SYSROOT_LINK = "CMAKE_SYSROOT_LINK"; static std::string const kCMAKE_TRY_COMPILE_OSX_ARCHITECTURES = "CMAKE_TRY_COMPILE_OSX_ARCHITECTURES"; static std::string const kCMAKE_TRY_COMPILE_PLATFORM_VARIABLES = @@ -609,6 +611,8 @@ int cmCoreTryCompile::TryCompileCode(std::vector const& argv, vars.insert(kCMAKE_OSX_SYSROOT); vars.insert(kCMAKE_POSITION_INDEPENDENT_CODE); vars.insert(kCMAKE_SYSROOT); + vars.insert(kCMAKE_SYSROOT_COMPILE); + vars.insert(kCMAKE_SYSROOT_LINK); vars.insert(kCMAKE_WARN_DEPRECATED); if (const char* varListStr = this->Makefile->GetDefinition( diff --git a/Source/cmFindCommon.cxx b/Source/cmFindCommon.cxx index 110195c..5d46674 100644 --- a/Source/cmFindCommon.cxx +++ b/Source/cmFindCommon.cxx @@ -154,10 +154,16 @@ void cmFindCommon::RerootPaths(std::vector& paths) } const char* sysroot = this->Makefile->GetDefinition("CMAKE_SYSROOT"); + const char* sysrootCompile = + this->Makefile->GetDefinition("CMAKE_SYSROOT_COMPILE"); + const char* sysrootLink = + this->Makefile->GetDefinition("CMAKE_SYSROOT_LINK"); const char* rootPath = this->Makefile->GetDefinition("CMAKE_FIND_ROOT_PATH"); const bool noSysroot = !sysroot || !*sysroot; + const bool noCompileSysroot = !sysrootCompile || !*sysrootCompile; + const bool noLinkSysroot = !sysrootLink || !*sysrootLink; const bool noRootPath = !rootPath || !*rootPath; - if (noSysroot && noRootPath) { + if (noSysroot && noCompileSysroot && noLinkSysroot && noRootPath) { return; } @@ -166,6 +172,12 @@ void cmFindCommon::RerootPaths(std::vector& paths) if (rootPath) { cmSystemTools::ExpandListArgument(rootPath, roots); } + if (sysrootCompile) { + roots.push_back(sysrootCompile); + } + if (sysrootLink) { + roots.push_back(sysrootLink); + } if (sysroot) { roots.push_back(sysroot); } diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index 0ab6e89..f584753 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -88,7 +88,19 @@ cmLocalGenerator::cmLocalGenerator(cmGlobalGenerator* gg, cmMakefile* makefile) std::vector enabledLanguages = this->GetState()->GetEnabledLanguages(); - this->CompilerSysroot = this->Makefile->GetSafeDefinition("CMAKE_SYSROOT"); + if (const char* sysrootCompile = + this->Makefile->GetDefinition("CMAKE_SYSROOT_COMPILE")) { + this->CompilerSysroot = sysrootCompile; + } else { + this->CompilerSysroot = this->Makefile->GetSafeDefinition("CMAKE_SYSROOT"); + } + + if (const char* sysrootLink = + this->Makefile->GetDefinition("CMAKE_SYSROOT_LINK")) { + this->LinkerSysroot = sysrootLink; + } else { + this->LinkerSysroot = this->Makefile->GetSafeDefinition("CMAKE_SYSROOT"); + } for (std::vector::iterator i = enabledLanguages.begin(); i != enabledLanguages.end(); ++i) { @@ -142,7 +154,8 @@ cmRulePlaceholderExpander* cmLocalGenerator::CreateRulePlaceholderExpander() const { return new cmRulePlaceholderExpander(this->Compilers, this->VariableMappings, - this->CompilerSysroot); + this->CompilerSysroot, + this->LinkerSysroot); } cmLocalGenerator::~cmLocalGenerator() @@ -843,7 +856,13 @@ void cmLocalGenerator::GetIncludeDirectories(std::vector& dirs, return; } - std::string rootPath = this->Makefile->GetSafeDefinition("CMAKE_SYSROOT"); + std::string rootPath; + if (const char* sysrootCompile = + this->Makefile->GetDefinition("CMAKE_SYSROOT_COMPILE")) { + rootPath = sysrootCompile; + } else { + rootPath = this->Makefile->GetSafeDefinition("CMAKE_SYSROOT"); + } std::vector implicitDirs; // Load implicit include directories for this language. diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h index e888094..9f78be4 100644 --- a/Source/cmLocalGenerator.h +++ b/Source/cmLocalGenerator.h @@ -362,6 +362,7 @@ protected: std::map Compilers; std::map VariableMappings; std::string CompilerSysroot; + std::string LinkerSysroot; bool EmitUniversalBinaryFlags; diff --git a/Source/cmLocalNinjaGenerator.cxx b/Source/cmLocalNinjaGenerator.cxx index e0e3e54..35960d4 100644 --- a/Source/cmLocalNinjaGenerator.cxx +++ b/Source/cmLocalNinjaGenerator.cxx @@ -37,8 +37,9 @@ cmLocalNinjaGenerator::cmLocalNinjaGenerator(cmGlobalGenerator* gg, cmRulePlaceholderExpander* cmLocalNinjaGenerator::CreateRulePlaceholderExpander() const { - cmRulePlaceholderExpander* ret = new cmRulePlaceholderExpander( - this->Compilers, this->VariableMappings, this->CompilerSysroot); + cmRulePlaceholderExpander* ret = + new cmRulePlaceholderExpander(this->Compilers, this->VariableMappings, + this->CompilerSysroot, this->LinkerSysroot); ret->SetTargetImpLib("$TARGET_IMPLIB"); return ret; } diff --git a/Source/cmRulePlaceholderExpander.cxx b/Source/cmRulePlaceholderExpander.cxx index f190a5c..d5d2f67 100644 --- a/Source/cmRulePlaceholderExpander.cxx +++ b/Source/cmRulePlaceholderExpander.cxx @@ -12,10 +12,11 @@ cmRulePlaceholderExpander::cmRulePlaceholderExpander( std::map const& compilers, std::map const& variableMappings, - std::string const& compilerSysroot) + std::string const& compilerSysroot, std::string const& linkerSysroot) : Compilers(compilers) , VariableMappings(variableMappings) , CompilerSysroot(compilerSysroot) + , LinkerSysroot(linkerSysroot) { } @@ -249,10 +250,19 @@ std::string cmRulePlaceholderExpander::ExpandRuleVariable( ret += compilerOptionExternalToolchain; ret += outputConverter->EscapeForShell(compilerExternalToolchain, true); } - if (!this->CompilerSysroot.empty() && !compilerOptionSysroot.empty()) { + std::string sysroot; + // Some platforms may use separate sysroots for compiling and linking. + // If we detect link flags, then we pass the link sysroot instead. + // FIXME: Use a more robust way to detect link line expansion. + if (replaceValues.LinkFlags) { + sysroot = this->LinkerSysroot; + } else { + sysroot = this->CompilerSysroot; + } + if (!sysroot.empty() && !compilerOptionSysroot.empty()) { ret += " "; ret += compilerOptionSysroot; - ret += outputConverter->EscapeForShell(this->CompilerSysroot, true); + ret += outputConverter->EscapeForShell(sysroot, true); } return ret; } diff --git a/Source/cmRulePlaceholderExpander.h b/Source/cmRulePlaceholderExpander.h index 90b4119..7b19210 100644 --- a/Source/cmRulePlaceholderExpander.h +++ b/Source/cmRulePlaceholderExpander.h @@ -17,7 +17,7 @@ public: cmRulePlaceholderExpander( std::map const& compilers, std::map const& variableMappings, - std::string const& compilerSysroot); + std::string const& compilerSysroot, std::string const& linkerSysroot); void SetTargetImpLib(std::string const& targetImpLib) { @@ -76,6 +76,7 @@ private: std::map Compilers; std::map VariableMappings; std::string CompilerSysroot; + std::string LinkerSysroot; }; #endif -- cgit v0.12