Search code examples
gccmakefileubuntu-20.04

Can't compile Super Mario 64 on Ubuntu 20.04.2 LTS


I'm having trouble compiling this github repo for Super Mario 64. I followed all of the steps.

  • I made sure I had all of the dependencies like build essential installed
  • I cloned the repo and copied a rom for asset extraction
  • I used the Makfile by running make VERSION=us -j4

The compiler did it's thing and gave a few warnings which is to be expected, but it didn't give any errors and make said the sha1 checksums matched. When I went into the build directory and tried executing sm64.us.bin, it gave this error: bash: ./sm64.us.bin: cannot execute binary file: Exec format error. When I googled the error, I found that some people got it when trying to run a 32 bit binary on a 64 bit OS, but that can't be it because I'm running a 64 bit kernel on a 64 bit machine and compiling it myself. I checked the permission bits and there don't seem to be any issues there. I even tried deleting the repo and cloning it again which didn't work. I then tried running different flags like -j5 or without the -j flag entirely (That shouldn't make a difference since I'm running a fairly zippy 12 core Ryzen 5 but I thought I'd try having GCC compile on a single core because I was running out of ideas). What am I doing wrong here? Is there a setting with GCC I should change or could there be a problem with the makefile?


UPDATE:

I checked the ELF file and it looks like it is 32 bit for some reason. I ran file sm64.us.elf and the output was sm64.us.elf: ELF 32-bit MSB executable, MIPS, MIPS-III version 1 (SYSV), statically linked, not stripped. Why is GCC doing that? How can I compile a 64 bit executable?


Solution

  • GCC can build 32bit or 64bit executables (on most systems). It all depends on what arguments you give it. If you look at the compile invocation that make is running you'll likely see that it passes the -m32 (or some similar) option, which tells the compiler and linker to create 32bit objects and binaries.

    If you want to build 64bit instead you'll have to find the arguments in your makefile or other configuration that select 32bit, and remove them (or change them to explicitly choose 64bit).

    I should warn you, this almost certainly won't work!! It's not the case that any old C program can be compiled as either 32bit or 64bit and continue to work identically. It is possible, but doing this requires that the programmer write their code carefully and with forethought. In my experience video game programs are almost always coded specifically for a given hardware target and little thought is given to making it portable to other hardware, and that includes 64bit versions of the "same" vendor.

    Instead of trying to make the code build for 64bit, a better use of your time is to investigate why your system is not able to run a 32bit executable and fix that. It's odd to me that you can compile for 32bit but not run 32bit: usually if you can build it then you have the proper libraries, etc. installed to run.