Is it currently possible to use emacs on aarch64-darwin?

I use nix-darwin, and previously I used emacsMacport without any issues when I have a x86 mac.

I’ve switched to an aarch64 mac, and emacsMacport doesn’t work anymore: emacsMacport: build fails on aarch64-darwin · Issue #127902 · NixOS/nixpkgs · GitHub

I wonder if there is any workaround? Like maybe just use the official version of emacs? I tried this in my configuration.nix:

services.emacs = {
    enable = true;
    package = (pkgs.emacsPackagesFor pkgs.emacsNativeComp).emacsWithPackages (epkgs: [
      epkgs.vterm
    ]);
  };

But it didn’t link the GUI app to /Application/Nix Apps, I also tried this with home-manager:

programs.emacs = {
    enable = true;
    package = (pkgs.emacsPackagesFor pkgs.emacsNativeComp).emacsWithPackages (epkgs: [
      epkgs.vterm
    ]);
  };

The GUI app did get linked to ~/Applications/Home Manager Apps, but running it required rosetta, It seems somehow a x86 version was built.

I wonder how are people using an aarch64 mac install emacs with nix right now?

fwiw, for the time being I’ve simply installed Emacs through Brew (GitHub - d12frosted/homebrew-emacs-plus: Emacs Plus formulae for the Homebrew package manager) - it’s not the best solution, but the patches presented in the related GitHub issue didn’t work for me (I’ve had memory leaks & performance issues) :eyes:

@Patryk27 Thanks for the reply. Do you use homebrew directly or via homebrew.enable in nix-darwin?

Directly - I wasn’t aware of homebrew.enable; gotta check it out!

I’m not sure what you are doing but my ~/Applications/Home\ Manager\ Apps/Emacs.app/Contents/MacOS/Emacs installed via home-manager is Mach-O 64-bit executable arm64.

Could you post your config? We don’t need to see the parts configuring specific other stuff, just the parts setting generic options.

just the parts setting generic options

Sorry, not sure I understand what you mean by generic options, but in my nix-darwin’s configuration.nix, I have:

home-manager.users.hgl = (import ./home.nix);

Where home.nix contains:

  programs.emacs = {
    enable = true;
    package = (pkgs.emacsPackagesFor pkgs.emacsNativeComp).emacsWithPackages (epkgs: [
      epkgs.vterm
    ]);
  };

I have set system correctly to "aarch64-darwin" in my flake.nix’s darwinConfigurations, this can be proven by my programs.git.enable, which correctly installs arm64 git in the nix store.

I guess maybe pkgs.emacsNativeComp is not the right choice?

I mean general options. Anything that isn’t directly tied to some specific app like i.e. a vim config.

General setup like macOS settings, user settings that sort of thing.

It’s probably easiest you simply posted your whole config.

I don’t use nix-darwin, so I can’t help you with that but I can help you with your home-manager config to a degree.

Please post all of it, not just the section pertaining Emacs you already included in your OP.

Sorry, I thought you missed the code in my OP.

I created a small test flake.nix that can reproduce the issue. I also found out ~/Applications/Home Manager Apps/Emacs.app/Contents/MacOS/Emacs is actually a bash script, which calls:

/nix/store/b6nbzyagfbq2spg7fm62rqv3rpcs92rv-emacs-with-packages-28.2/Applications/Emacs.app/Contents/MacOS/Emacs

which in turn is a bash script that calls:

/nix/store/rf6l3szx7c0p876xdkr5pdjd6jx31bv1-emacs-28.2/Applications/Emacs.app/Contents/MacOS/Emacs

Which is an arm64 executable, and if I directly executes it, I can open emacs without the rosetta prompt.

flake.nix

{
  inputs = {
    nixpkgs.url = "nixpkgs";
    utils.url = "flake-utils";
    home-manager = {
      url = "home-manager";
      inputs.nixpkgs.follows = "nixpkgs";
    };
    nix-darwin = {
      url = "github:lnl7/nix-darwin";
      inputs.nixpkgs.follows = "nixpkgs";
    };
  };

  outputs = { nix-darwin, home-manager, ... }: {
    darwinConfigurations."hgl-laptop" = nix-darwin.lib.darwinSystem {
      modules = [
        home-manager.darwinModules.home-manager
        ({ pkgs, lib, config, ... }: {
          nix.settings.auto-optimise-store = true;
          nix.extraOptions = ''
            keep-outputs = true
            keep-derivations = true
            experimental-features = nix-command flakes
          '';
          services.nix-daemon.enable = true;
          nixpkgs.hostPlatform = "aarch64-darwin";
          system.stateVersion = 4;

          programs.fish = {
            enable = true;
            useBabelfish = true;
            babelfishPackage = pkgs.babelfish;
          };
          environment.shells = with pkgs; [ bashInteractive fish ];
          programs.fish.shellInit = ''
            for p in (string split : ${config.environment.systemPath})
              if not contains $p $fish_user_paths
                set -g fish_user_paths $fish_user_paths $p
              end
            end
          '';
          users.users.hgl = {
            description = "Glen Huang";
            home = "/Users/hgl";
            shell = pkgs.fish;
          };
          home-manager.users.hgl = { pkgs, lib, config, ... }: {
            programs.emacs = {
              enable = true;
              package =
                (pkgs.emacsPackagesFor pkgs.emacsNativeComp).emacsWithPackages
                (epkgs: [ epkgs.vterm ]);
            };
            home.stateVersion = "22.11";
          };
        })
      ];
    };
  };
}

And flake.lock:

{
  "nodes": {
    "home-manager": {
      "inputs": {
        "nixpkgs": [
          "nixpkgs"
        ]
      },
      "locked": {
        "lastModified": 1691672736,
        "narHash": "sha256-HNPA/dKHerA0p4OsToEcW/DtTSXBcK5gFRsy/yPgV/Y=",
        "owner": "nix-community",
        "repo": "home-manager",
        "rev": "6e1eff9aac0e8d84bda7f2d60ba6108eea9b7e79",
        "type": "github"
      },
      "original": {
        "id": "home-manager",
        "type": "indirect"
      }
    },
    "nix-darwin": {
      "inputs": {
        "nixpkgs": [
          "nixpkgs"
        ]
      },
      "locked": {
        "lastModified": 1691640097,
        "narHash": "sha256-6vPsJYjtt2hs4mkiR46yt8c/Spdm/UiUKoSCIlc7iJw=",
        "owner": "lnl7",
        "repo": "nix-darwin",
        "rev": "426d38710b656b0a31f8eaae6e0002206a3b96d7",
        "type": "github"
      },
      "original": {
        "owner": "lnl7",
        "repo": "nix-darwin",
        "type": "github"
      }
    },
    "nixpkgs": {
      "locked": {
        "lastModified": 1691625043,
        "narHash": "sha256-IiiOwgRTQm9W1QHe8qme7qYxDbAT2MYxbIJMfPEltN0=",
        "owner": "NixOS",
        "repo": "nixpkgs",
        "rev": "3d6ebeb283be256f008541ce2b089eb5fb0e4e01",
        "type": "github"
      },
      "original": {
        "id": "nixpkgs",
        "type": "indirect"
      }
    },
    "root": {
      "inputs": {
        "home-manager": "home-manager",
        "nix-darwin": "nix-darwin",
        "nixpkgs": "nixpkgs",
        "utils": "utils"
      }
    },
    "systems": {
      "locked": {
        "lastModified": 1681028828,
        "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
        "owner": "nix-systems",
        "repo": "default",
        "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
        "type": "github"
      },
      "original": {
        "owner": "nix-systems",
        "repo": "default",
        "type": "github"
      }
    },
    "utils": {
      "inputs": {
        "systems": "systems"
      },
      "locked": {
        "lastModified": 1689068808,
        "narHash": "sha256-6ixXo3wt24N/melDWjq70UuHQLxGV8jZvooRanIHXw0=",
        "owner": "numtide",
        "repo": "flake-utils",
        "rev": "919d646de7be200f3bf08cb76ae1f09402b6f9b4",
        "type": "github"
      },
      "original": {
        "id": "flake-utils",
        "type": "indirect"
      }
    }
  },
  "root": "root",
  "version": 7
}

And the rosetta message

I found out if I directly open

/nix/store/rf6l3szx7c0p876xdkr5pdjd6jx31bv1-emacs-28.2/Applications/Emacs.app

It’s opened without rosetta prompt. Looks like arm Mac doesn’t support Emacs.app/Contents/MacOS/Emacs being a bash script?

I use emacs daily on aarch64-darwin without issue. My relevant config is following. Keep in mind that I adapted it from multiple others found on github so it may not be the most optimal way to do things.

My main flake.nix:

{
  description = "Alex's darwin system";

  inputs = {
    # Package sets
    nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-23.05-darwin";
    nixpkgs-unstable.url = github:NixOS/nixpkgs/nixpkgs-unstable;

    # Environment/system management
    darwin.url = "github:lnl7/nix-darwin/master";
    darwin.inputs.nixpkgs.follows = "nixpkgs";
    home-manager.url = "github:nix-community/home-manager/release-23.05";
    home-manager.inputs.nixpkgs.follows = "nixpkgs";

    # Extras
    emacs-overlay.url = "github:nix-community/emacs-overlay";
  };

  outputs = {
    self,
    darwin,
    nixpkgs,
    nixpkgs-unstable,
    home-manager,
    ...
  } @ inputs: let
    inherit (darwin.lib) darwinSystem;
    inherit (inputs.nixpkgs.lib) attrValues makeOverridable optionalAttrs singleton;

    system = "aarch64-darwin";
    pkgs = nixpkgs.legacyPackages.${system};
    pkgs-unstable = nixpkgs-unstable.legacyPackages.${system};

    # Configuration for `nixpkgs`
    nixpkgsConfig = {
      config = {allowUnfree = true;};
    };
  in {
    # My `nix-darwin` configs
    darwinConfigurations = rec {
      mbp = darwinSystem {
        system = system;
        specialArgs = {inherit pkgs pkgs-unstable;};
        modules = [
          # Main `nix-darwin` config
          ./configuration.nix
          # `home-manager` module
          home-manager.darwinModules.home-manager
          {
            nixpkgs = nixpkgsConfig;
            # `home-manager` config
            home-manager.useGlobalPkgs = true;
            home-manager.useUserPackages = true;
            home-manager.users.afoulon = import ./home.nix;
          }
        ];
      };
    };
  };
}

In configuration.nix,

{
  pkgs,
  pkgs-unstable,
  lib,
  ...
}: {

  # Skipped most parts for brevity ...

  nixpkgs.overlays = [
    #TODO    (import emacs-overlay)
  ];

  # Enable emacs daemon
  # PROBLEMS with visual themes between GUI and emacsclient
  #  services.emacs = {
  #    enable = true;
  #    package = pkgs.emacsNativeComp;
  #  };

  # Apps
  # `home-manager` currently has issues adding them to `~/Applications`
  # Issue: https://github.com/nix-community/home-manager/issues/1341
  environment.systemPackages = with pkgs; [
    # ...

    ## Emacs itself
    binutils # native-comp needs 'as', provided by this

    ((emacsPackagesFor emacs).emacsWithPackages (epkgs: [
      epkgs.vterm
      # LSP python
      epkgs.lsp-pyright
    ]))

    ## Doom dependencies not covered above
    (ripgrep.override {withPCRE2 = true;})
    gnutls # for TLS connectivity

    ## Optional dependencies
    imagemagick # for image-dired
    cmake
    fontconfig

    ## Module dependencies
    # :checkers spell
    (aspellWithDicts (ds:
      with ds; [
        en
        en-computers
        en-science
      ]))
    # :tools editorconfig
    editorconfig-core-c # per-project style config
    # :tools lookup & :lang org +roam
    sqlite
    # LSP pyright
    nodejs
  ];

  # Fonts
  fonts.fontDir.enable = true;
  fonts.fonts = [
    pkgs.emacs-all-the-icons-fonts
    (pkgs.nerdfonts.override { fonts = [ "Hack" ]; })
    #pkgs.hack-font
  ];

  # Add doom path to env.path
  environment.variables.PATH = ["$HOME/.emacs.d/bin:$PATH"];

  system.activationScripts = {
    installDoomEmacs.text = ''
      if [ ! -d "$HOME/.emacs.d" ]; then
      git clone --depth=1 --single-branch "https://github.com/hlissner/doom-emacs" "$HOME/.emacs.d"
      fi
    '';
  };
}

Now, some notes on this:

What this gives when built:

~
❯ ll /run/current-system/sw/bin/emacs
lrwxr-xr-x  1 root  wheel    78B Jan  1  1970 /run/current-system/sw/bin/emacs -> /nix/store/l9572gp0ddzanl8dzyp264r5ysgc2xcv-emacs-with-packages-28.2/bin/emacs

~
❯ ll /Applications/Nix\ Apps/
total 0
lrwxr-xr-x  1 root  wheel    91B Jan  1  1970 Emacs.app -> /nix/store/l9572gp0ddzanl8dzyp264r5ysgc2xcv-emacs-with-packages-28.2/Applications/Emacs.app

So far so good, emacs invoked by cli or Launchpad seems to link to the same place in the store. Let’s check:

❯ diff /nix/store/l9572gp0ddzanl8dzyp264r5ysgc2xcv-emacs-with-packages-28.2/bin/emacs /nix/store/l9572gp0ddzanl8dzyp264r5ysgc2xcv-emacs-with-packages-28.2/Applications/Emacs.app/Contents/MacOS/Emacs
47c47
< exec /nix/store/0837jf3z6vfrjqn94hil9yz9rr00fyq2-emacs-28.2/bin/emacs "$@"
---
> exec /nix/store/0837jf3z6vfrjqn94hil9yz9rr00fyq2-emacs-28.2/Applications/Emacs.app/Contents/MacOS/Emacs "$@"

Both are shell scripts, the only difference being the exec at the end. Now, let’s find what these are.

❯ file /nix/store/0837jf3z6vfrjqn94hil9yz9rr00fyq2-emacs-28.2/bin/emacs
/nix/store/0837jf3z6vfrjqn94hil9yz9rr00fyq2-emacs-28.2/bin/emacs: Mach-O 64-bit executable arm64

~
❯ file /nix/store/0837jf3z6vfrjqn94hil9yz9rr00fyq2-emacs-28.2/Applications/Emacs.app/Contents/MacOS/Emacs
/nix/store/0837jf3z6vfrjqn94hil9yz9rr00fyq2-emacs-28.2/Applications/Emacs.app/Contents/MacOS/Emacs: Mach-O 64-bit executable arm64

Everything seems fine, we have arm64 executables, and launching them doesn’t prompt me for rosetta.

So, either its an issue with the way emacs is installed by home-manager, or you have an error in your config and the system variable is not set correctly in the darwinConfiguration.

Hope this helps.

2 Likes

@kaelnor thanks for sharing your config.

The result is actually the same as mine if you check my previous reply. I can run the inner most Emacs.app without rosetta prompt, but directly running /Applications/Nix Apps/Emacs.app does prompt.

I also tried your config, by using emacs directly in configuration.nix’s environment.systemPackages, same result.

Do you have rosetta already installed? If so, you won’t get the prompt. You can confirm by checking if there is an Rosetta Stone app in /Application.

My guess is that Emacs.app/Contents/MacOS/Emacs being a bash script will cause the rosetta prompt.

No, I don’t have Rosetta installed.

But, your reply made me think of something. Can you open the shell script and check the shebang ?

Mine is #!/nix/store/7avcas47b0g25c9bk7m4xb7p5p636qs7-bash-5.2-p15/bin/bash and its bash compiled for aarch64-darwin.

❯ file /nix/store/7avcas47b0g25c9bk7m4xb7p5p636qs7-bash-5.2-p15/bin/bash
/nix/store/7avcas47b0g25c9bk7m4xb7p5p636qs7-bash-5.2-p15/bin/bash: Mach-O 64-bit executable arm64

My guess is yours is an x86_64 shell, triggering the rosetta prompt.

It’s really strange that you don’t get the prompt. The bash is arm64:

$ cat /Applications/Nix\ Apps/Emacs.app/Contents/MacOS/Emacs
#!/nix/store/rz0xwswp80pjyn8sf2vz3xlv67sfiyns-bash-5.2-p15/bin/bash
$ file /nix/store/rz0xwswp80pjyn8sf2vz3xlv67sfiyns-bash-5.2-p15/bin/bash                                                                                                           
/nix/store/rz0xwswp80pjyn8sf2vz3xlv67sfiyns-bash-5.2-p15/bin/bash: Mach-O 64-bit executable arm64

And if I use open to open the app

$ open /Applications/Nix\ Apps/Emacs.app                                                                                                                                          
The application cannot be opened for an unexpected reason, error=Error Domain=NSOSStatusErrorDomain Code=-10669 "(null)" UserInfo={_LSLine=4101, _LSFunction=_LSOpenStuffCallLocal}

Double click in finder gives the rosetta prompt.

Somehow, something is triggering rosetta at some point when calling the bin even though it is arm64.

You can check in macos Console the logs to see if you have more information on what happens when you try to launch emacs. Also, you could try installing rosetta, launch emacs, and check in Activity Monitor if any app has a Kind value different that “Apple”.

Hopefully this would give you more clues because I’m out of ideas right now.

1 Like

Could you run nix-instantiate --eval -E builtins.currentSystem?

Try enabling Emacs without vterm.

$ nix-instantiate --eval -E builtins.currentSystem                                                                                                            ~/d/lab/openwrt (main) 09:39:49
"aarch64-darwin"

Enabling Emacs without vterm also tried, still getting the rosetta prompt.

Since I can run the inner most Emacs.app without issues, I think the problem probably lies along the wrapper path. I’ll try to isolate it.

I installed emacs29 (no macport and no emacWithPackages) on aarch64 darwin and found the aarch64 .app in `/Applications/Nix Apps.

Is it possible emacs is properly on aarch64 but something it installed in .emacs.d from when you migrated isn’t? You can confirm this with file or the get info dialog on the .app.

1 Like

After some more research, I don’t really think it’s some x86-accidentally-compiled issue. If I show the package content of Emacs.app, and double click Contents/MacOS/Emacs, it uses Terminal to open Emacs GUI, without showing the rosetta prompt, but clicking Emacs.app directly does.

Someone else also encountered this issue, and I had exactly the same console error message:

error	12:30:59.157670-0700	Finder	LAUNCH: User preference exists for x86_64 but runtime support is not installed.
error	12:30:59.157774-0700	Finder	LAUNCH: Launch failure with -10669/ <private>

My guess is that Emacs.app’s user preference plist contained some legacy option, but I’m unable to identify which.

I’ve just given in and installed rosetta, but strangely I don’t see any rosetta app in my /Applications. I wonder if you guys actually installed it too?

I have a M2 Mac, macOS 13.5.2, not sure if anyone is with the same spec but doesn’t have the rosetta prompt with a fresh install?

I ran into exactly this a month ago!

The culprit is apparently the emacsWithPackages function - using just the package worked fine!

…but then I had to “manually” add vterm, with the following additions:

On home-manager’s config:

  home.packages = with pkgs; [
+    emacsPackages.vterm
  ]

On nix-darwin’s config (since I use home-manager through it):

+  # HACK: Required to add vterm to user profile
+  environment.pathsToLink = [ "/share/emacs" ];

On emacs’ config/init file:

+;;  Vterm hack for Darwin's ARM
+(add-load-path! "/etc/profiles/per-user/aisamu/share/emacs/site-lisp/elpa/vterm-20230417.424")

I’m not skilled enough to fix it and wasn’t super sure where to report it (since it’s a Darwin issue), but perhaps it’s warranted!