How to create custom cross-compile overlay?

I’d like to be able to specify a cross-compile target like lib.system.examples.iphone64 , so it would be possible to do nix-build -A pkgsCross.someNewThing.hello . I tried adding an overlay to my project that would override lib, merging with existing examples using // but this didn’t seem to add a new cross-compile overlay.

Is it explained anywhere how to do this?

1 Like

If I understand you correctly, you’ll probably want to pass the system as the cross target into nixpkgs, eg.

nix-build -E 'let lib = import ./lib; in with import ./. { crossSystem = lib.systems.examples.iphone64; }; pkgs.hello'
1 Like

No, I mean like adding another thing to lib.systems.examples so I could use iphone64New instead of iphone64. I submitted a PR some time ago to update things to current versions but this hasn’t moved since then (darwin: update xcode versions by spease · Pull Request #100687 · NixOS/nixpkgs · GitHub) so I’m just working around it with an overlay now.

I have a video demonstrating overlays here.

However, if you’re doing a packages set like darwin, you’ll want to do something like:

# xcode_overlay
final: prev: {
  darwin = prev.darwin // {
    xcode_10_2 = .... ;
    ...
  }
  lib = prev.lib // {
    systems.examples.iphone64 = prev.lib.systems.examples.iphone64 // {
      sdk = "...";
    };
    ...
  };
}

maybe you could also use lib.recusiveUpdate. Which should make this a little nicer as the // operator will only overwrite top-level attributes.

@jonringer I’m not sure that would work, as pkgsCross are populated via the lib argument that is passed into the lib stage function, which is imported directly relatively to pkgs:

My understanding thus far is that overlaying the lib like you propose would have no relevance when the stdenv is constructed, hence would not produce a new, functioning cross target.

I didn’t realize it had that behavior, you’re likely correct that it wouldn’t work.

@jonringer Your example is very close to what I was trying initially, except I was going through each level of the hierarchy and using //. But yeah, I tried your approach too and it didn’t seem to change anything.

EDIT: But thanks for the suggestion.

You could probably construct something like

# xcode_overlay
final: prev: {
  pkgsCross.iphone64New = import path { 
    overlays = [(final: prev: { darwin= prev.darwin // {
      xcode_10_2 = .... ;
  })]; 
    crossSystem = lib.systems.examples.iphone64 // {
      sdk = "...";
    };
    inherit localSystem;
  };
}

From the top of my head though so untested and probably some parans are just plain wrong :smiley:

1 Like

What’s path in that case?

Sorry, I can see how that is not obvious.
path in this case is not a placeholder but actually https://github.com/NixOS/nixpkgs/blob/ec5994ce9409a0866bb76f1ff6a343f77c905ad8/pkgs/top-level/all-packages.nix#L57

More precisely, pkgs.path points to the root of the nixpkgs filesystem three you are currently in.
(Actually, it might have to be prev.path in the code sample above)

2 Likes

Sorry I didn’t reply to this - I ended up having to abandon nix as a solution for management of the iPhone apps for this project. My PR did eventually get accepted however. Though, then there were more obstacles as I don’t think anyone has really been maintaining iPhone development.