1
0
Эх сурвалжийг харах

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 <[email protected]>
Brad King 8 жил өмнө
parent
commit
53e89b6ab0

+ 2 - 0
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

+ 5 - 0
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.

+ 3 - 0
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.

+ 9 - 0
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.

+ 9 - 0
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.

+ 7 - 1
Source/cmComputeLinkInformation.cxx

@@ -1737,7 +1737,13 @@ void cmComputeLinkInformation::GetRPath(std::vector<std::string>& 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 =

+ 4 - 0
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<std::string> 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(

+ 13 - 1
Source/cmFindCommon.cxx

@@ -154,10 +154,16 @@ void cmFindCommon::RerootPaths(std::vector<std::string>& 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<std::string>& 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);
   }

+ 22 - 3
Source/cmLocalGenerator.cxx

@@ -88,7 +88,19 @@ cmLocalGenerator::cmLocalGenerator(cmGlobalGenerator* gg, cmMakefile* makefile)
   std::vector<std::string> 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<std::string>::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<std::string>& 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<std::string> implicitDirs;
   // Load implicit include directories for this language.

+ 1 - 0
Source/cmLocalGenerator.h

@@ -362,6 +362,7 @@ protected:
   std::map<std::string, std::string> Compilers;
   std::map<std::string, std::string> VariableMappings;
   std::string CompilerSysroot;
+  std::string LinkerSysroot;
 
   bool EmitUniversalBinaryFlags;
 

+ 3 - 2
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;
 }

+ 13 - 3
Source/cmRulePlaceholderExpander.cxx

@@ -12,10 +12,11 @@
 cmRulePlaceholderExpander::cmRulePlaceholderExpander(
   std::map<std::string, std::string> const& compilers,
   std::map<std::string, std::string> 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;
   }

+ 2 - 1
Source/cmRulePlaceholderExpander.h

@@ -17,7 +17,7 @@ public:
   cmRulePlaceholderExpander(
     std::map<std::string, std::string> const& compilers,
     std::map<std::string, std::string> 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<std::string, std::string> Compilers;
   std::map<std::string, std::string> VariableMappings;
   std::string CompilerSysroot;
+  std::string LinkerSysroot;
 };
 
 #endif