aboutsummaryrefslogtreecommitdiff
path: root/src/libstore/globals.cc
diff options
context:
space:
mode:
authorMatthew Bauer <mjbauer95@gmail.com>2020-12-03 15:35:38 -0600
committerMatthew Bauer <mjbauer95@gmail.com>2020-12-03 15:41:43 -0600
commit9b1824ecbd222b4bdc8fa2b6f345dc55ef4872d0 (patch)
tree1ad5f555cad53d7a1838931b903b14d575655353 /src/libstore/globals.cc
parent6ed09cb8c2c27f30bec1eccb153db80dc5a77520 (diff)
Add extraPlatforms for Rosetta 2 macOS
macOS systems with ARM64 can utilize a translation layer at /Library/Apple/usr/libexec/oah to run x86_64 binaries. This change makes Nix recognize that and it to "extra-platforms". Note that there are two cases here since Nix could be built for either x86_64 or aarch64. In either case, we can switch to the other architecture. Unfortunately there is not a good way to prevent aarch64 binaries from being run in x86_64 contexts or vice versa - programs can always execute programs for the other architecture.
Diffstat (limited to 'src/libstore/globals.cc')
-rw-r--r--src/libstore/globals.cc22
1 files changed, 22 insertions, 0 deletions
diff --git a/src/libstore/globals.cc b/src/libstore/globals.cc
index f38601d6d..59c49af8a 100644
--- a/src/libstore/globals.cc
+++ b/src/libstore/globals.cc
@@ -131,6 +131,28 @@ StringSet Settings::getDefaultSystemFeatures()
return features;
}
+StringSet Settings::getDefaultExtraPlatforms()
+{
+ if (std::string{SYSTEM} == "x86_64-linux" && !isWSL1())
+ return StringSet{"i686-linux"};
+#if __APPLE__
+ // Rosetta 2 emulation layer can run x86_64 binaries on aarch64
+ // machines. Note that we can’t force processes from executing
+ // x86_64 in aarch64 environments or vice versa since they can
+ // always exec with their own binary preferences.
+ else if (pathExists("/Library/Apple/usr/libexec/oah")) {
+ if (std::string{SYSTEM} == "x86_64-darwin")
+ return StringSet{"aarch64-darwin"};
+ else if (std::string{SYSTEM} == "aarch64-darwin")
+ return StringSet{"x86_64-darwin"};
+ else
+ return StringSet{};
+ }
+#endif
+ else
+ return StringSet{};
+}
+
bool Settings::isExperimentalFeatureEnabled(const std::string & name)
{
auto & f = experimentalFeatures.get();