morph icon indicating copy to clipboard operation
morph copied to clipboard

Building for other architecture is unintuitive

Open fooker opened this issue 5 years ago • 8 comments

Building for different architectures on a per deployment base feels not very intuitive.

I got it working by setting network.pkgs to an instance of nixpkgs with no further configuration while setting nixpkgs.pkgs in the relevant deployments to a nixpkgs called with system = "...". In addition, I have to set nixpkgs.localSystem.system to the architecture, too.

I'm not even sure, if this is the right way to do it. If so, I feel like this needs some documentation / examples (which I'm happy to contribute).

fooker avatar Jan 29 '20 09:01 fooker

An example of a currently working version can be found here: https://github.com/fooker/nixcfg/blob/363d14b53ef17c01e66fa086ce21ca7039f628b5/deployment.nix

fooker avatar Jan 29 '20 09:01 fooker

The example is a bit complicated, but getting morph to work that way is really just about setting nixpkgs.pkgs.system and nixpkgs.localSystem.system for each machine in deployment.nix, isn't it?

flokli avatar Mar 08 '20 22:03 flokli

I also don't fully understand @fooker's example, but I think this could be solved reasonably well by just specifying distinct nixpkgs for each machine. The best way to do this, however, is unclear to me.

Maybe @johanot can give us some ideas?

lovesegfault avatar Mar 08 '20 23:03 lovesegfault

For those who come across this in the future here's my hacky solution to the issue: https://github.com/lovesegfault/nix-config/blob/e7bd275a37b2268978bb875cedb47aac41482d34/deployment.nix

It amounts to:

  1. not setting network.pkgs
  2. setting nixpkgs.pkgs for each machine individually through a small function
cfg: system:
    let
      pkgs = import ./nix/nixpkgs.nix { inherit system; config.allowUnfree = true; };
    in
      { lib, ... }: {
        imports = [ cfg ];
        nixpkgs.pkgs = lib.mkForce pkgs;
      }

lovesegfault avatar Mar 11 '20 01:03 lovesegfault

The example is a bit complicated, but getting morph to work that way is really just about setting [...] nixpkgs.localSystem.system for each machine in deployment.nix, isn't it?

That doesn't work, as morph sets nixpkgs.pkgsto the value of network.pkgs, in which case nixpkgs.localSystem/nixpkgs.crossSystem is ignored. I think if you set evalConfig instead of pkgs, you could then set nixpkgs.localSysetm and it would build the pkgs argument from the nixpkgs that evalConfig comes from and nixpkgs.localSystem etc.

tomprince avatar Sep 06 '21 23:09 tomprince

@tomprince https://github.com/DBCDK/morph/issues/104#issuecomment-589954838 is what most of us with that use case use.

mweinelt avatar Sep 07 '21 00:09 mweinelt

That doesn't work, as morph sets nixpkgs.pkgsto the value of network.pkgs, in which case nixpkgs.localSystem/nixpkgs.crossSystem is ignored.

This doesn't appear to be true. I managed to get a working configuration like @lovesegfault described, with

config = {
  nixpkgs.system = "aarch64-linux";
  nixpkgs.pkgs = import sources.pkgs {
    system = "aarch64-linux";
  };
};

However, one indeed requires the evalConfig hack for anything that involves more than simply building packages, i.e. using a different channel or overriding modules.

piegamesde avatar Sep 11 '21 03:09 piegamesde

Share a setup which works in my daily usage.


I'm using morph on macOS for building software on my x86_64-linux machines.

The core idea is simple:

  1. run a x86_64-linux machine on macOS (virtual machine or docker container)
  2. set the machine as the build machine for Nix.
  3. let morph know you are building for x86_64-linux.

For 1 / 2, checkout a possible guide which can be found at Provisioning a NixOS server from macOS. In the article, docker container is used. But, you can also use a virtual machine.

For 3, there's a possible network.nix:

let
  pkgs = import <nixpkgs> {
    system = "x86_64-linux"; # a. eval pkgs with right `system`
  };
in
{
  network = {
    inherit pkgs; # b. use the pkgs for morph.
    description = "your network name";
  };

  machine-n = {
    deployment.targetHost = "...";

    # nix 2 is using `nixpkgs.localSystem.system`, not `nixpkgs.system`
    nixpkgs.localSystem.system = "x86_64-linux";  # c. declare the machine's system

    # ...
  };

  # ...
}

Then, morph it. Enjoy yourself.


If you care about clean code, checkout the solution of lovesegfault, which is a higher abstraction of above code.

c4710n avatar Mar 11 '22 06:03 c4710n