Install tools on MacOS

  1. Install Xcode. You need Xcode for gcc and libncurses. This should be straightforward. Just Google it. These instructions were tested with Xcode 7.2. If your Xcode version is older, upgrade it first.
  2. Install homebrew. Homebrew is a package management system for MacOS. To install it, run the following in bash:
      ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" < /dev/null
    
  3. Install tools and libraries
    brew install bmake
    brew install libmpc
    brew install gmp
    brew install wget
    
    Alternative instructions for installing bmake are here.
  4. Build the os161 tools
    mkdir ~/tools
    wget https://people.ece.ubc.ca/os161/download/cs161-ubuntu-darwin.sh
    bash ./cs161-ubuntu-darwin.sh
    
    Note: the only difference between the tool-building script for Ubuntu and Darwin is the if-statement in the GDB build step that passes the --disable-sim option to configure on Darwin, to work around a known bug.

    Make sure that the tools have been built correctly. Go into the ~/tools directory and look for the log files corresponding to the four tools that were built by the script (sys161, binutils, gcc and gdb). Check these log files to make sure that there have not been any errors.

    After this step, you can continue to download the os161 code and to build it as described on the previous page, but the first tip in the following Troubleshooting section may come handy if you get build errors on the base os161.

    Troubleshooting

    Tip #1: If you get ntohll redefinition errors when you build os161:

    When trying to build os161, you might get an error, when the hostcompat library is built, about a redefinition of ntohll in sys/_endian.h. In that case, use the following hack. Open the configure script in the top level of the os161 tree and find the following lines:

    #include 
    int 
    main() 
    { 
          return ntohll(0xbeefbeefbeefbeefULL) != 0; 
    }
    

    Change them to:

    #include 
    int 
    main() 
    { 
          return ntohll(0xbeefbeefbeefbeefULL) == 0; 
    }
    

    Now re-run the configure script. You may need to delete the defs.mk file before configuring/building the tree.

    Tip #2: If your build fails because bmake cannot find mips-harvard-os161-gcc:

    1. First, check the ~/tools/os161/bin directory. Is mips-harvard-os161-gcc there? If it is, then bmake cannot find it, because it is not in your path. Run the following command to see what your path looks like:
        $ echo $PATH
      
      The location of OS161 tools should be included in the list of directories that were printed. For example, your path could look like this:
      /usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/X11/bin:/Users/UBC-home/bin:/Users/UBC-home/bin:/Users/UBC-home/tools/os161/bin:/Users/UBC-home/tools/sys161/bin
      
      Notice that /Users/UBC-home/tools/os161/bin, which is where the tools for this user are installed is in the path. If your directory is not in the path, you need to add it. Normally, the s161-ubuntu-darwin.sh script would do it for you, but if for some reason it has not, do this manually.
    2. If the binary mips-harvard-os161-gcc is not in ~/tools/os161/bin, then it was not built successfully. Go through gcc.log in the ~/tools directory and find out why. A very common problem is the error generated by the configure script that looks like this:
        configure: error: Building GCC requires GMP 4.2+, MPFR 2.4.0+ and MPC 0.8.0+.
      
      Try the --with-gmp, --with-mpfr and/or --with-mpc options to specify their locations. First, make sure that the libraries that the configure script complains about are installed. To find out, type:
      brew info gmp
      brew info libmpc
      brew info mpfr
      
      If they are not installed, go to Step 4 above and install them.

      If the configure script still complains that it cannot find them, then use the suggestion in the error message above and point the script to the location of these libraries. Find out where these libraries are installed by running brew info. For instance, to find out the location of gmp:

        brew info gmp
      
      You will see output that looks something like this:
      sasha-imac:~/Work/os161/root$ brew info gmp
      gmp: stable 6.1.0 (bottled)
      GNU multiple precision arithmetic library
      https://gmplib.org/
      /usr/local/Cellar/gmp/6.1.0 (15 files, 3.2M) *
        Poured from bottle
      From: https://github.com/Homebrew/homebrew/blob/master/Library/Formula/gmp.rb
      ==> Dependencies
      Build: xz ✘
      ==> Options
      --32-bit
       Build 32-bit only
      --c++11
          Build using C++11 mode
      
      You can see that the gmp library is installed in /usr/local/Cellar/gmp/6.1.0. Open the cs161-ubuntu-darwin.sh script that you downloaded, find the part that builds gcc and finally find the line that calls the configure script:
        ../$GCC161/configure --enable-languages=c,lto -nfp --disable-shared --disable-threads --disable-libmudflap --disable-libssp --disable-libstdcxx --disable-nls --target=mips-harvard-os161 --prefix=$HOME/tools/os161 2>&1 | tee ../gcc.log
      
      Add the --with-gmp to the list of options. For example:
        ../$GCC161/configure --enable-languages=c,lto -nfp --disable-shared --disable-threads --disable-libmudflap --disable-libssp --disable-libstdcxx --disable-nls --target=mips-harvard-os161 --prefix=$HOME/tools/os161 --with-gmp=/usr/local/Cellar/gmp/6.1.0 2>&1 | tee ../gcc.log 
      
      Now re-run the cs161-ubuntu-darwin.sh script. If the build still fails, add similar options for the remaining libraries: mpc and mpfr.
      Instead of modifying re-running the orginial script, you can use this trimmed-down script that builds only the GCC. Open this script in the editor and set the values of variables GMP, MPFR and LIBMPC to the output directory shown by brew info gmp, brew info mpfr and brew info libmpc on your system. Then re-run the script.
    3. If you are building on a new MacBook with arm64 architecture, you are also likely to run into the following problem. GCC will fail to build due to pre-compiled headers (PCH), like this:
        Undefined symbols for architecture arm64:
        "_host_hooks", referenced from:
        gt_pch_save(__sFILE*) in libbackend.a(ggc-common.o)
        gt_pch_restore(__sFILE*) in libbackend.a(ggc-common.o)
        toplev::main(int, char**) in libbackend.a(toplev.o)
        ld: symbol(s) not found for architecture arm64
      
      The solution is to disable pre-compiled headers. To do so, edit this trimmed-down script (that builds only GCC) to run lines 1 through 18. This will download and unpack the GCC distribution. Then open the following file in the editor (use any editor you like instead of gedit):
        $ gedit gcc-4.8.3+os161-2.1/gcc/config.host
      
      In that file, comment out lines 96 and 97, like so:
        # out_host_hook_obj=host-darwin.o
        # host_xmake_file="${host_xmake_file} x-darwin"
      
      Now re-run the trimmed-down gcc-building script to execute only starting from line 18.

      The solution was proposed in this github issue.

    Tip #3. If the build of OS161 gdb tool fails:

    1. Search the ~/tools/gdb.log file for the string disable-sim. The configure command run prior to building gdb must be run with the following string:
        ./configure --target=mips-harvard-os161 --prefix=$HOME/tools/os161 --disable-werror --disable-sim
      
    2. If you encounter an error due to a missing ioctl, such as:
        rltty.c: In function 'set_winsize':
        rltty.c:83:7: error: implicit declaration of function 'ioctl' is invalid in C99
      
      please use another GDB distribution that fixes this error. Open the script cs161-ubuntu-darwin.sh in the editor and replace the line
      GDB161="gdb-7.8+os161-2.1"
      
      with
        GDB161="gdb-7.8+os161-2.1-MacOS-Monterey-arm64"
      
      and re-run the script. The alternative distribution provides a modified readline/configure script that results in always running the steps to define GWINSZ_IN_SYS_IOCTL. With this variable defined, the compiler includes the file sys/ioctl, which has the missing function.