Installing the MIPS binutils toolchain?

I’m a computer scientist / high school volunteer working on a (hopfully) fun extra-ciricular project for high school CS students. This project will involve building the sm64 C project on Replit (as that is the platform the kids already use and have general access to) and modifying it. Given their binaries I would load them into my Everdrive and the group would try to play them on real hardware. My thought is that this would be a complex “real-world” codebase with a tangable output, but lightweight enough to do with limited compute resources.

The problem is: I can’t seem to build it myself :face_with_spiral_eyes: on this platform. I think its a dependency issue. Specifically: I’m missing the MIPS binutils toolchain for tools like ld, gcc, ar, objdump, etc… but this might not be the only problem.

However, to keep the question focused, I’m wondering if there is a way to do the equivalent of what I would do in Ubuntu (i.e.apt install binutils-mips-linux-gnu), but in Replit’s Nix environment?

For context, I’ve documented the steps I’ve taken and the errors I’ve gotten so far here:
sm64-random-assets-replit-instructions.

In short, when building the code I get:

gcc: fatal error: Killed signal terminated program cc1

and I think this is because the Makefile is expecting one of mips-linux-gnu-ld, mips64-linux-gnu-ld, or mips64-elf-ld (and the other corresponding binutils) to exist. The x86-64 variants do exist, but I believe I need the ones that can cross-compile for the N64’s MIPS instruction set.

1 Like

~I’m not sure how to edit my post (I guess I need to ping a moderator?), but it looks like I messed up the URL to the docs:~

1 Like

Click the pencil icon at the three dots of your message.

If I am not wrong, Nix runs on Linux and not Ubuntu.

Yes. To clarify I meant: On Ubuntu I can install the MIPS toolchain like:

sudo apt install binutils-mips-linux-gnu

And I’m wondering what the equivalent way of doing this in NIX is (or if there is a way to do it)? I’ve checked: NixOS Search and I’ve been unable to find any packages that seem correct.

My current .replit.nix file looks like this:

    { pkgs }: {
      deps = [
        pkgs.python310Full
        pkgs.replitPackages.prybar-python310
        pkgs.replitPackages.stderred
        pkgs.capstone
        pkgs.pkg-config
        pkgs.python310Packages.pkgconfig
        pkgs.binutils
        pkgs.binutils-unwrapped-all-targets
      ];
      env = {
        PYTHON_LD_LIBRARY_PATH = pkgs.lib.makeLibraryPath [
          # Needed for pandas / numpy
          pkgs.stdenv.cc.cc.lib
          pkgs.zlib
          # Needed for pygame
          pkgs.glib
          # Needed for matplotlib
          pkgs.xorg.libX11
        ];
        PYTHONHOME = "${pkgs.python310Full}";
        PYTHONBIN = "${pkgs.python310Full}/bin/python3.10";
        LANG = "en_US.UTF-8";
        STDERREDBIN = "${pkgs.replitPackages.stderred}/bin/stderred";
        PRYBAR_PYTHON_BIN = "${pkgs.replitPackages.prybar-python310}/bin/prybar-python310";
      };
    }

(Also, I don’t see a pencil icon after expanding the menu. Perhaps this is because I’m a new user? It’s not that important, but it would be nice to clarify or reword my phrasing - EDIT: It seems I have it now!)

1 Like

On the #nix matrix channel I got some information that has helped.

Adding:

pkgs.pkgsCross.mipsel-linux-gnu.buildPackages.bintools

to my replit.nix deps has provided mipsel-unknown-linux-gnu-ld, which is really close to what I need. (It may actually work if I modify the sm64 Makefile, but I haven’t tested yet, I’m expecting it not to work because the N64’s R4000 process is big-endian, but maybe that’s correctable with post-processing?)

I learned that pkgsCross is a special shortcut to compile packages, although I don’t entirely understand the details yet.

I was shown the page: nixpkgs/lib/systems/examples.nix at d6784f25a2c0ee72d83e6783061c52b1c9254aa8 · NixOS/nixpkgs · GitHub which defines a recursive set of arch names. The ones that look interesting are:

  # can execute on 32bit chip
  mips-linux-gnu           = { config = "mips-unknown-linux-gnu";           } // platforms.gcc_mips32r2_o32;
  mipsel-linux-gnu         = { config = "mipsel-unknown-linux-gnu";         } // platforms.gcc_mips32r2_o32;

  # require 64bit chip (for more registers, 64-bit floating point, 64-bit "long long") but use 32bit pointers
  mips64-linux-gnuabin32   = { config = "mips64-unknown-linux-gnuabin32";   } // platforms.gcc_mips64r2_n32;
  mips64el-linux-gnuabin32 = { config = "mips64el-unknown-linux-gnuabin32"; } // platforms.gcc_mips64r2_n32;

  # 64bit pointers
  mips64-linux-gnuabi64    = { config = "mips64-unknown-linux-gnuabi64";    } // platforms.gcc_mips64r2_64;
  mips64el-linux-gnuabi64  = { config = "mips64el-unknown-linux-gnuabi64";  } // platforms.gcc_mips64r2_64;

I’ve tried adding each of:

    pkgs.pkgsCross.mips-linux-gnu.buildPackages.bintools
    pkgs.pkgsCross.mipsel-linux-gnu.buildPackages.bintools
    pkgs.pkgsCross.mips64-linux-gnuabin32.buildPackages.bintools
    pkgs.pkgsCross.mips64el-linux-gnuabin32.buildPackages.bintools
    pkgs.pkgsCross.mips64-linux-gnuabi64.buildPackages.bintools
    pkgs.pkgsCross.mips64el-linux-gnuabi64.buildPackages.bintools

to my deps, but only

  • mipsel-linux-gnu and
  • mips64el-unknown-linux-gnuabin32

have seemed to give me any new commands in my shell. (not sure why replit likes the little endian variants).

The packages:

  • pkgs.pkgsCross.mips64-linux-gnuabin32.buildPackages.bintools and
  • pkgs.pkgsCross.mips64-linux-gnuabi64.buildPackages.bintools and
  • pkgs.pkgsCross.mips64el-linux-gnuabi64.buildPackages.bintools

didn’t throw an error, but I didn’t have any mips prefixed executables in my PATH

Lastly, the mips-linux-gnu raised a nix error when reloading the shell:

Detected change in environment, reloading shell...
nix error: building nix env: exit status 1
Output has been trimmed to the last 20 lines

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
     
 Note: For `nix shell`, `nix build`, `nix develop` or any other Nix 2.4+
 (Flake) command, `--impure` must be passed in order to read this
 environment variable.
    
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.

(use '--show-trace' to show detailed location information)

which is a real shame considering that’s the one that would probably work for me. Does anyone have tips on how to further debug this? (I did try defining the environment variable in the error message both in the shell with export and in the env section of replit.nix)

2 Likes

You can’t use sudo to install. Use pip instead.

That error implies that the package is unsupported, but you can probably bypass it by adding

To the replit.nix file.

1 Like

I tried to add it like this:


{ pkgs }: {
  allowUnsupportedSystem = true;
  deps = [
    pkgs.python310Full
    pkgs.replitPackages.prybar-python310
    pkgs.replitPackages.stderred
    pkgs.capstone
    pkgs.pkg-config
    #pkgs.python310Packages.pkgconfig
    #pkgs.binutils
    #pkgs.pkgsCross.mips-linux-gnu
    pkgs.pkgsCross.mips-linux-gnu.buildPackages.bintools
    #pkgs.pkgsCross.mipsel-linux-gnu.buildPackages.bintools
    #pkgs.pkgsCross.mips64-linux-gnuabin32.buildPackages.bintools
    #pkgs.pkgsCross.mips64el-linux-gnuabin32.buildPackages.bintools
    #pkgs.pkgsCross.mips64-linux-gnuabi64.buildPackages.bintools
    #pkgs.pkgsCross.mips64el-linux-gnuabi64.buildPackages.bintools
  ];
  env = {
    NIXPKGS_ALLOW_UNSUPPORTED_SYSTEM=1;
    PYTHON_LD_LIBRARY_PATH = pkgs.lib.makeLibraryPath [
      # Needed for pandas / numpy
      pkgs.stdenv.cc.cc.lib
      pkgs.zlib
      # Needed for pygame
      pkgs.glib
      # Needed for matplotlib
      pkgs.xorg.libX11
    ];
    PYTHONHOME = "${pkgs.python310Full}";
    PYTHONBIN = "${pkgs.python310Full}/bin/python3.10";
    LANG = "en_US.UTF-8";
    STDERREDBIN = "${pkgs.replitPackages.stderred}/bin/stderred";
    PRYBAR_PYTHON_BIN = "${pkgs.replitPackages.prybar-python310}/bin/prybar-python310";
  };
}

But I got the same error. Is that the correct syntax?