aboutsummaryrefslogtreecommitdiff
path: root/src/libstore
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
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')
-rw-r--r--src/libstore/globals.cc22
-rw-r--r--src/libstore/globals.hh4
2 files changed, 25 insertions, 1 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();
diff --git a/src/libstore/globals.hh b/src/libstore/globals.hh
index 4655ca058..8666a7d28 100644
--- a/src/libstore/globals.hh
+++ b/src/libstore/globals.hh
@@ -34,6 +34,8 @@ class Settings : public Config {
StringSet getDefaultSystemFeatures();
+ StringSet getDefaultExtraPlatforms();
+
bool isWSL1();
public:
@@ -545,7 +547,7 @@ public:
Setting<StringSet> extraPlatforms{
this,
- std::string{SYSTEM} == "x86_64-linux" && !isWSL1() ? StringSet{"i686-linux"} : StringSet{},
+ getDefaultExtraPlatforms(),
"extra-platforms",
R"(
Platforms other than the native one which this machine is capable of