LnL7 / nix-darwin

nix modules for darwin
MIT License
2.79k stars 429 forks source link

Using the new native M1 support #334

Closed purcell closed 1 year ago

purcell commented 3 years ago

Apple M1 (aarch64-darwin) support just landed in Nixpkgs master, so I thought I'd open an issue here to describe/discuss how best to migrate to a nix-darwin setup which uses that system type by default.

I've had some luck with this, so I'll recount what I've done. Starting with a regular x86_64-darwin installation, on the nixpkgs-unstable channel, I added

      extra-platforms = x86_64-darwin aarch64-darwin

to nix.extraOptions and defined a package set like

  pkgsM1 = import <nixpkgs> { localSystem = "aarch64-darwin"; };

At this point, it's possible to set nix.pkg = pkgsM1.nix, and then after darwin-rebuild switch, the nix tools and overall system are switched to aarch64, and pkgs will yield aarch64 packages.

However, of course many packages in a user's configuration won't build on aarch64, so to get to this stage, you have to comment out those packages. After switching the nix installation to aarch64, the packages can be added back in, with a similar pkgs_x86.

Notable packages (for me) which don't yet build on aarch64 are nix-direnv and anything written in Haskell, like shellcheck, niv.

It's also possible to skip switching nix.pkg, and keep the overall system as x86_64 for now: then, packages can be included from pkgsM1 for installation as desired. This might be the best choice for most users until some of the rough edges are smoothed off.

Hope this helps some people. I'd be keen to hear tips and tricks from others.

hlolli commented 3 years ago

Thanks a lot for this tip. I've finally got the wheels running after mostly commenting out package overrides based on nixpkgs PR's. I went the other way around it. Instead of selecting the aarch64 packages, I overlay the x86_64's.

~/.nixpkgs/darwin-configuration.nix

I use with to thoroughly set the stdenv.

{ ... }:
# just a tarball of the latest master
with import (fetchTarball /. + "file:///Users/hlolli/nixpkgs-fork.tar.gz") { localSystem = "aarch64-darwin"; };

 {
  imports = [
    /Users/hlolli/nixos-configuration
  ];
}

/Users/hlolli/nixos-configuration/default.nix

I have the two versions

{ stdenv, config, pkgs, ... }:

let pkgsX86 = import <nixpkgs> { localSystem = "x86_64-darwin"; };
...

and overlay the unsupported packages

...
  nixpkgs.overlays = [
    (
    self: super: {
      inherit (pkgsX86) haskell haskellPackages openssl openssl_1_1;
    }
  )];
  ...

long rebuild ahead rn, praying for luck 🙏

LnL7 commented 3 years ago

I don't think that overlay will do what you want as it mixes x86 and arm libraries. To build a mixed system you most likely want to use the same overlays for both package sets and between the architecture at binary level.

{ config, lib, pkgs, ... }:
let pkgsX86 = import <nixpkgs> { localSystem = "x86_64-darwin"; overlays = config.nixpkgs.overlays; };
{
  environment.systemPackages =
    [ pkgs.curl
      pkgsX86.haskell
    ];
}
hlolli commented 3 years ago

Yes indeed, I should have known, but the rosetta2 magic has spelled my senses here. Bad idea I was suggesting there above.

ld: warning: ignoring file /nix/store/96j2ai9h4f5kaqcnp9kvgbp2srr79xhx-openssl-1.1.1k/lib/libcrypto.dylib, building for macOS-arm64 but attempting to link with file built for macOS-x86_64
Undefined symbols for architecture arm64:

Besides the fact that openssl compiles fine on aarch (so far so good after I removed it from the overlay), then I hope this adverts pitfalls for others.

hlolli commented 3 years ago

Maybe not the right place for it, but I have a PR for emacs fix for aarch64, if someone wants to review and test the fix https://github.com/NixOS/nixpkgs/pull/124888

antifuchs commented 3 years ago

I've gotten a flake.nix-based configuration working working, where I install the rosetta x86-64 packages by default and opt into arm64 packages on a case-by-case basis.

Here's the relevant flake.nix bits:

{
outputs = {self, nixpkgs, darwin, ...}: {
  darwinConfigs."my-machine" = darwin.lib.darwinSystem {
    modules = [
      { nix.extraOptions = ''extra-platforms = x86_64-darwin aarch64-darwin ''; }
      ./machine/my-machine.nix
    ];
    specialArgs = { 
      m1Ize = (pkgs: config: import nixpkgs {
        system = "aarch64-darwin";
        overlays = config.nixpkgs.overlays;
      });
    };
  };
};
}

note the specialArgs.m1Ize function; that will be passed down to the modules, e.g. to my development system config module:

{ pkgs, config, lib, m1Ize, ... }:
let
  m1Pkgs = m1Ize pkgs config;
in
{
  environment.systemPackages = with m1Pkgs; [
    cmake
    llvm
    openssl
    gnumake
    postgresql_13
  ];
}

You have to use that let binding in all the modules where you intend to use it, but it's about as short as it gets. Hope this helps fellow flake-ers (:

lloeki commented 3 years ago

For those that stumble on this and, like me, use a pure nixpkgs install (i.e don't use nix-darwin, flakes, or whatever), I'm popping up a nix-shell with arm64 derivations quite easily:

$ sh <(curl -L https://nixos.org/nix/install) --daemon  # install as usual
$ cat /etc/nix/nix.conf                                 # add extra-platforms

build-users-group = nixbld
extra-platforms = x86_64-darwin aarch64-darwin
$ cat shell.nix
{
  pkgs ? import <nixpkgs> { localSystem = "aarch64-darwin"; },
}:
let
  ruby = pkgs.ruby_3_0;
in pkgs.mkShell {
  buildInputs = [
    pkgs.openssl
    ruby
  ];
}
$ nix-shell
nix$ which ruby
/nix/store/sc54smx4gqa80nxwpfvpxfw8slh7fgyd-ruby-3.0.1/bin/ruby
nix$ file $(which ruby)
/nix/store/sc54smx4gqa80nxwpfvpxfw8slh7fgyd-ruby-3.0.1/bin/ruby: Mach-O 64-bit executable arm64

Now I'm a complete beginner, so if only I knew how to pivot the nixpkgs install into arm64 😅 I'd rather be arm64 first and fill in the blanks with x86_64 on a case by case basis with an additional pkgs_x86_64 ? import <nixpkgs> { localSystem = "x86_64-darwin"; }, in shell.nix:

{
  pkgs ? import <nixpkgs> { localSystem = "aarch64-darwin"; },
  pkgs_x86_64 ? import <nixpkgs> { localSystem = "x86_64-darwin"; },
}:
let
  ruby = pkgs.ruby_3_0;
in pkgs.mkShell {
  buildInputs = [
    pkgs.openssl
    ruby
    pkgs_x86_64.shellcheck
  ];
}
LnL7 commented 3 years ago

@lloeki By default the nix client evaluates using the system it was built with. So upgrading you nix installation to the arm build will also change the default.

lloeki commented 3 years ago

Thanks @LnL7, I think I managed to do it:

$ sudo su -l
# cat /etc/nix/nix.conf 
build-users-group = nixbld
system = aarch64-darwin
extra-platforms = x86_64-darwin aarch64-darwin
#  launchctl unload /Library/LaunchDaemons/org.nixos.nix-daemon.plist
#  launchctl load /Library/LaunchDaemons/org.nixos.nix-daemon.plist
# nix-env -iA nixpkgs.nix
replacing old 'nix-2.3.12'
installing 'nix-2.3.12'
-----8<------
# file $(which nix-shell)
/var/root/.nix-profile/bin/nix-shell: Mach-O 64-bit executable arm64
# file /nix/var/nix/profiles/default/bin/nix-daemon
/nix/var/nix/profiles/default/bin/nix-daemon: Mach-O 64-bit executable arm64
# launchctl unload /Library/LaunchDaemons/org.nixos.nix-daemon.plist
# launchctl load /Library/LaunchDaemons/org.nixos.nix-daemon.plist

From there I think I can remove system = aarch64-darwin from /etc/nix/nix.conf, but everything seems alright nonetheless.

shaunsingh commented 3 years ago

Hi, I'm having an error with installing nix-darwin using my configuration.nix. My configuration.nix can be found here: https://github.com/shaunsingh/vimrc-dotfiles/blob/main/.nixpkgs/darwin-configuration.nix

Please let me know if you need any other information that may help with solving the issue. Thank you for the amazing project and your time!

Edit: Sorry for cluttering up the thread. The error in question was due to a package not cooperating with aarch64 (Neovim-nightly), nix-darwin itself was/is working fine. I apologize for my noob behavior. Thanks for the great project once again!

BaoPham92 commented 3 years ago

Thanks @LnL7, I think I managed to do it:

$ sudo su -l
# cat /etc/nix/nix.conf 
build-users-group = nixbld
system = aarch64-darwin
extra-platforms = x86_64-darwin aarch64-darwin
#  launchctl unload /Library/LaunchDaemons/org.nixos.nix-daemon.plist
#  launchctl load /Library/LaunchDaemons/org.nixos.nix-daemon.plist
# nix-env -iA nixpkgs.nix
replacing old 'nix-2.3.12'
installing 'nix-2.3.12'
-----8<------
# file $(which nix-shell)
/var/root/.nix-profile/bin/nix-shell: Mach-O 64-bit executable arm64
# file /nix/var/nix/profiles/default/bin/nix-daemon
/nix/var/nix/profiles/default/bin/nix-daemon: Mach-O 64-bit executable arm64
# launchctl unload /Library/LaunchDaemons/org.nixos.nix-daemon.plist
# launchctl load /Library/LaunchDaemons/org.nixos.nix-daemon.plist

From there I think I can remove system = aarch64-darwin from /etc/nix/nix.conf, but everything seems alright nonetheless.

I followed both of your above approach while being on macOS Big Sur.

So far I was able to follow the steps, but activating "nix-shell" within the plutus project would give me the following:

error: cannot coerce null to a string, at /nix/store/sdjxjsd5phr225rs2qzklj2xci0c9gr0-source/pkgs/stdenv/generic/make-derivation.nix:192:19

I tried:

error: Package ‘ghc-8.10.4’ in /nix/store/9jyvfa211fxvwyd79vz5ydak07q52y5w-nixexprs.tar.xz/pkgs/development/compilers/ghc/8.10.4.nix:267 is not supported on ‘aarch64-darwin’, refusing to evaluate.

a) To temporarily allow packages that are unsupported for this system, you can use an environment variable
   for a single invocation of the nix tools.

     $ export NIXPKGS_ALLOW_UNSUPPORTED_SYSTEM=1

b) For `nixos-rebuild` you can set
  { nixpkgs.config.allowUnsupportedSystem = true; }
in configuration.nix to override this.

c) For `nix-env`, `nix-build`, `nix-shell` or any other Nix command you can add
  { allowUnsupportedSystem = true; }
to ~/.config/nixpkgs/config.nix.

Each options of a - c, so far the same error reappears.

I've also attempted your approach as clean installs.

yisraeldov commented 3 years ago

@purcell , Steve what is your current setup for getting things working on the M1 ?

domenkozar commented 3 years ago

Note that ghc builds as of today on master. More package fixes are pending in haskell-updates (including cachix).

domenkozar commented 3 years ago

Flake.nix needs to pass the correct system to https://github.com/LnL7/nix-darwin/blob/a7492a8c76dcc702d0a65cd820a5f9baa8702684/eval-config.nix#L1

dhess commented 3 years ago

https://github.com/LnL7/nix-darwin/pull/317

shaunsingh commented 2 years ago

Anyone have a sample darwin-configuration.nix setup for m1 that they would like to share? Its hard to follow along with the thread, and I'm quite new to nix-darwin

lilyball commented 2 years ago

In order to get this working I had to darwin-rebuild switch with extra-platforms = x86_64-darwin aarch64-darwin set first, before I could then build any x86_64 packages (pkgs is aarch64-darwin). Is there any way to avoid this two-phase configuration? I've got this machine setup now, but I don't want to run into this again the next time I set up a new machine.

srid commented 2 years ago

Anyone have a sample darwin-configuration.nix setup for m1 that they would like to share? Its hard to follow along with the thread, and I'm quite new to nix-darwin

@shaunsingh Add this to your darwin-configuration.nix during install:

  nix.extraOptions = ''
    extra-platforms = aarch64-darwin x86_64-darwin
    experimental-features = nix-command flakes
  '';
masaeedu commented 2 years ago

@domenkozar in your comment here you mention that:

GHC has been fixed just last week, with now over 25000 packages building on aarch64-darwin.

Presumably this fix is for the "cannot coerce null to a string" bug. Would you happen to recall what PR/commit introduced this fix and what the problem was (I'm wondering if I can backport the fix to an older nixpkgs). Thanks in advance.

domenkozar commented 2 years ago

This was related to signing and process getting killed, so your error message is something different/new.

yacinehmito commented 1 year ago

Is there still an issue with native M1 support? I installed nix-darwin recently on an M1 and I seem to get everything on aarch64-darwin without having done anything special.

purcell commented 1 year ago

Agree, I'll go ahead and close this: I opened it mainly to share info, and there's indeed no current issue on these machines.