MIPS binutils on NixOS?

Is there a way to get the binutils toolchain on NixOS that can cross compile code for a mips64 chip? (i.e. the tools that would be installed by apt install binutils-mips-linux-gnu on Ubuntu)?

I’ve searched the NixOS Search package library, and I’m starting to think the answer is no.

For context, I’m trying to build the sm64 decomp on Replit with the goal of using it to teach high school CS students. I have more details in my question on the Replit forums: Installing the MIPS binutils toolchain? - #5 by JonathanCrall - Replit Help - Replit Ask

1 Like

The sm64 project seems to be forked - which one are you trying to compile?

In any case, n64decomp/sm64 builds fine for me using the following shell.nix on NixOS 23.05:

  crossPkgs = import <nixpkgs> { crossSystem = { config = "mips64-elf"; }; };
  pkgs = import <nixpkgs> {};
pkgs.mkShell {
  packages = [

Clone, drop in baserom.eu.z64 from your genuine N64 dump, then run make CROSS=mips64-elf- VERSION=eu -j16.

Note you don’t actually need a full toolchain - just binutils is sufficient. Using binutilsNoLibc avoids running into the unsupported system error.

1 Like

This is very helpful. Based on this and other answers I’m convinced getting this to work is possible.

The repo I’m using is called sm64-random-assets, and it contains two git submodules in the tpl directory. The sm64 one points to the official sm64 decomp. The parent repo (which I wrote) just contains logic to populate the assets without relying on a pre-existing baserom.

My current issue is that I have to do this in a Replit enviornment (which is somewhat beyond the scope of this forum), and I’m trying to figure out the relationship with shell.nix and replit.nix. It doesn’t appear to work the same way, and I’m having a hard time susing out all the details.

What I tried so far is to start a new Replit “nix derivation” project, which I think gives me a fairly clean starting point. I deleted the “default.nix” that it prepopulates with and added a “shell.nix” with the above content.

I tried to run nix-shell shell.nix --show-trace, but got the error:

error: while evaluating the attribute 'nativeBuildInputs' of the derivation 'nix-shell' at /nix/store/x8dbrija74rnw16hrbw5r5apx9k81giz-nixpkgs-21.11-src/pkgs/stdenv/generic/make-derivation.nix:205:7:
while evaluating 'getOutput' at /nix/store/x8dbrija74rnw16hrbw5r5apx9k81giz-nixpkgs-21.11-src/lib/attrsets.nix:489:23, called from undefined position:
while evaluating anonymous function at /nix/store/x8dbrija74rnw16hrbw5r5apx9k81giz-nixpkgs-21.11-src/pkgs/stdenv/generic/make-derivation.nix:147:13, called from undefined position:
anonymous function at /nix/store/67ls7gqys2krv5880a72q7m9vgc51jk5-nixpkgs-stable-21_11-21.11.tar.gz/nixpkgs-stable-21_11/default.nix:1:1 called with unexpected argument 'crossSystem', at /home/runner/HorizontalEmbellishedDownload/shell.nix:2:15

Is this the correct way to start a new “nix shell” if you don’t have an existing “shell.nix” file? I’m really not sure what replit is doing to give you a shell without a “shell.nix”, nor do I see a way to insert contents of a shell.nix file into a replit.nix file, but maybe there is a way?

1 Like

I don’t think your invocation of nix-shell is wrong here - rather, the <nixpkgs> path within the Replit environment refers to Replit’s nixpkgs tree instead of the upstream nixpkgs repository.

Have a look at their default.nix, they seem to support multiple (upstream) nixpkgs channels with their own packages spliced in using an overlay. The main issue I see is that their default.nix imports the upstream nixpkgs channel without any ability for your to pass the crossSystem argument.

Either way, there are many ways to refer to upstream nixpkgs - see the examples here - the very last one should work in an inline let ... in block.

Or, if you want to get creative, you can dig up the exact nixpkgs tree they use. I experimented for a bit on Replit, this expression works:

  nixpkgs = import (import <nixpkgs-stable-23_05/nix/sources.nix>)."nixpkgs-23.05";

Then just substitute <nixpkgs> for nixpkgs in the sample shell.nix. Something similar should work in your replit.nix if you wrap in in a let ... in.

Not entirely sure this is the best or cleanest solution. Hope you don’t run into resource constraints (because MIPS binutils isn’t cached you might end up having to build it every time).

Guess it doesn’t hurt to tag @ryantm who seems to be involved with Replit…