p1-stats

Setting Up Your Computer

This how-to will walk you through setting up your computer for EECS 280. At the end, you’ll have the starter files for a project compiling on your own computer. You’ll have both command line tools and a visual debugger ready to go. We’ll also walk you through how to build and test with make, version control with git, and testing on a remote CAEN Linux computer.

Command line tools

First, we’ll install a shell (AKA command line). The command line interface (CLI) lets us interact with the computer using the keyboard instead of the mouse. Once you get used to it, it’s very powerful and very fast.

When you see $ in this tutorial, you should type into your shell the command that comes after the $.

macOS

macOS has a built-in shell. Open the “Terminal” application.

Install a compiler.

$ xcode-select --install

Notice that this compiler is really Apple LLVM pretending to be g++.

$ g++ --version
Configured with: --prefix=/Library/Developer/CommandLineTools/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 9.0.0 (clang-900.0.38)
Target: x86_64-apple-darwin16.7.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin

Install the Homebrew package manager.

$ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"

Apple Silicon users (“M1”) only. At the time of this writing (2021), Homebrew has partial support for Apple Silicon. It installs to a non-standard location, /opt/homebrew.

Add Homebrew to your path.

$ echo 'eval $(/opt/homebrew/bin/brew shellenv)' >> ~/.zprofile

Close your terminal and reopen your terminal. Your version might be different.

$ which brew
/opt/homebrew/bin/brew
$ brew --version
Homebrew 3.2.0

Use Homebrew to install a few command line programs that we’ll use later. Your versions might be different.

$ brew install wget git tree

Windows

On Windows, we recommend the Windows 10 Subsystem for Linux (WSL). WSL runs native Linux command-line tools directly on Windows and includes:

You can follow the WSL Tutorial here.

Additionally, a free Windows 10 upgrade is available to UM students via the Computer Showcase, since Windows 10 is required to run WSL.

If you are running a version of Windows prior to Windows 10, you can install Cygwin, a collection of Linux programs compiled for Windows, with the Cygwin Tutorial. However, we strongly advise using WSL if at all possible.

Linux

These instructions work for Ubuntu systems. Linux systems come with a built-in shell. Open the “Terminal” application.

$ sudo apt-get install g++ make rsync wget git ssh gdb valgrind tree

Check your tools

After you’ve installed a command line interface, you should have all these command line programs installed. Your versions might be different.

$ g++ --version
g++ (GCC) 6.4.0
$ make --version
GNU Make 4.2.1
$ gdb --version   # Windows and Linux only
GNU gdb (Ubuntu 8.1-0ubuntu3) 8.1.0.20180409-git
$ lldb --version  # macOS only
lldb-900.0.64
$ rsync --version
rsync  version 3.1.2  protocol version 31
$ wget --version
GNU Wget 1.19.4 built on linux-gnu.
$ git --version
git version 2.15.1
$ ssh -V
OpenSSH_7.6p1, OpenSSL 1.0.2m  2 Nov 2017
$ tree --version
tree v1.7.0 (c) 1996 - 2014 by Steve Baker, Thomas Moore, Francesc Rocher, Florian Sesser, Kyosuke Tokoro 

Starter files

In this section, we’ll download the starter files and get our project to compile by adding function stubs.

Open your shell for this step. On macOS and Linux, that’s the Terminal application. On Windows, it’s either Cygwin or “Bash on Ubuntu on Windows”.

Create a folder

Decide where to store your EECS 280 projects. For reference, here are some common locations. You might want to use your Desktop, Documents or Dropbox.

System Desktop Documents
macOS /Users/awdeorio/Desktop/ /Users/awdeorio/Documents/
Windows/WSL /mnt/c/Users/awdeorio/Desktop/ /mnt/c/Users/awdeorio/Documents/
Windows/Cygwin /cygdrive/c/Users/awdeorio/Desktop/ /cygdrive/c/Users/awdeorio/Documents/
Linux /home/awdeorio/Desktop/ /home/awdeorio/Documents/

Navigate to a directory where you will store your EECS 280 projects. (awdeorio likes to use a directory called src in his home directory.)

$ cd /Users/awdeorio/src/

A note about file paths that contain spaces. There are two options:

$ cd /Users/awdeorio/Desktop/EECS\ 280/   # escape with a backslash
$ cd "/Users/awdeorio/Desktop/EECS 280/"  # enclose with quotes

List what’s in this directory. It looks like awdeorio has some old files from EECS 485 laying around.

$ ls
eecs485

You can create a directory like this.

$ mkdir eecs280
$ ls
eecs280  eecs485

Change directory and create another directory for this project.

$ cd eecs280
$ mkdir p1-stats
$ cd p1-stats

If you ever get lost at the command line, you can ask “where am I?” That’s called the Present Working Directory, or pwd.

$ pwd
/Users/awdeorio/src/eecs280/p1-stats

Download and unpack starter files

Download the starter files

$ pwd
/Users/awdeorio/src/eecs280/p1-stats
$ wget https://eecs280staff.github.io/p1-stats/starter-files.tar.gz
$ ls
starter-files.tar.gz

Unpack the starter files

$ tar -xvzf starter-files.tar.gz
starter-files/
starter-files/Makefile
starter-files/main_test.in
starter-files/main_test.out.correct
starter-files/main_test_data.tsv
starter-files/p1_library.cpp
starter-files/p1_library.h
starter-files/stats.h
starter-files/stats_public_test.cpp
starter-files/stats_tests.cpp.starter
$ ls
starter-files  starter-files.tar.gz

Move the starter files from starter-files/ to your present working directory (denoted by the dot .). Note that the asterisk in starter-files/* means “all the files inside the starter-files/ directory”.

$ mv starter-files/* .
$ ls
Makefile               p1_library.cpp        stats.h
main_test.in           p1_library.h          stats_public_test.cpp
main_test.out.correct  starter-files         stats_tests.cpp.starter
main_test_data.tsv     starter-files.tar.gz

Now that we’ve moved the files, we can remove the directory and the tarball.

$ rm -rf starter-files/
$ rm starter-files.tar.gz
$ ls
Makefile               main_test_data.tsv  stats.h
main_test.in           p1_library.cpp      stats_public_test.cpp
main_test.out.correct  p1_library.h        stats_tests.cpp.starter

Rename any .starter files.

$ mv stats_tests.cpp.starter stats_tests.cpp
$ ls
Makefile               main_test_data.tsv  stats.h
main_test.in           p1_library.cpp      stats_public_test.cpp
main_test.out.correct  p1_library.h        stats_tests.cpp

Visual debugger

We’ll walk you through setting up a visual debugger on your local machine (your laptop). Select one.

  Visual Studio Code Visual Studio Xcode
Operating system macOS, Windows, Linux Windows macOS
Easy to install :white_check_mark: :large_orange_diamond: :white_check_mark:
Easy project setup :white_check_mark: :large_orange_diamond: :large_orange_diamond:
Integrated autocomplete :white_check_mark: :white_check_mark: :white_check_mark:
Integrated build (compile) :white_check_mark: :white_check_mark: :white_check_mark:
Integrated debugger :white_check_mark: :white_check_mark: :white_check_mark:
Industry use :large_orange_diamond: :white_check_mark: :white_check_mark:
Detection of undefined behavior :large_orange_diamond: :white_check_mark: :large_orange_diamond:
  VS Code Tutorial Visual Studio Tutorial Xcode Tutorial

After finishing the visual debugger instructions, you should have added two new files, stats.cpp and main.cpp. Double check that you have these files.

$ pwd
/Users/awdeorio/src/eecs280/p1-stats
$ ls
Makefile      main_test.out.correct  p1_library.h  stats_public_test.cpp
main.cpp      main_test_data.tsv     stats.cpp     stats_tests.cpp
main_test.in  p1_library.cpp         stats.h

You can view the content of a file at the command line using the cat command.

$ cat main.cpp
// main.cpp
// Project UID 5366c7e2b77742d5b2142097e51561a5

#include "stats.h"
#include "p1_library.h"
#include <iostream>
using namespace std;

int main() {
  cout << "hello from main!\n";
}

main.cpp should look like this:

// main.cpp
// Project UID 5366c7e2b77742d5b2142097e51561a5

#include "stats.h"
#include "p1_library.h"
#include <iostream>
using namespace std;

int main() {
  cout << "hello from main!\n";
}

stats.cpp should look like this:

// stats.cpp
// Project UID 5366c7e2b77742d5b2142097e51561a5

#include "stats.h"
#include <cassert>
#include <vector>
using namespace std;

vector<vector<double> > summarize(vector<double> v) {
  assert(false);
}

int count(vector<double> v) {
  assert(false);
}

double sum(vector<double> v) {
  assert(false);
}

double mean(vector<double> v) {
  assert(false);
}

double median(vector<double> v) {
  assert(false);
}

double mode(vector<double> v) {
  assert(false);
}

double min(vector<double> v) {
  assert(false);
}

double max(vector<double> v) {
  assert(false);
}

double stdev(vector<double> v) {
  assert(false);
}

double percentile(vector<double> v, double p) {
  assert(false);
}

Text editor and debugger

This section is optional. If you’re interested in learning more about the command line, you can also learn a debugger and text editor.

Why learn a text editor like Emacs or Vim?

First, complete the GDB Tutorial (WSL or Linux) or the LLDB Tutorial (macOS).

Then, move on to the Emacs Tutorial, where you’ll use GDB or LLDB inside Emacs.

Makefiles

Makefiles automate building and testing an application. They provide shortcuts for long commands.

Makefile tutorial

After you’re done, you should be comfortable using the make command to clean up and run a regression test. Remember, your regression test will fail at this point because you haven’t finished the project yet.

$ make clean
rm -rvf *.exe *~ *.out *.dSYM *.stackdump
$ make test
g++ -Wall -Werror -pedantic -g --std=c++11 stats_tests.cpp stats.cpp p1_library.cpp -o stats_tests.exe
g++ -Wall -Werror -pedantic -g --std=c++11 stats_public_test.cpp stats.cpp p1_library.cpp -o stats_public_test.exe
g++ -Wall -Werror -pedantic -g --std=c++11 main.cpp stats.cpp p1_library.cpp -o main.exe
./stats_public_test.exe
stats_public_test.exe: stats.cpp:12: int count(std::vector<double>): Assertion `false' failed.
make: *** [test] Aborted

Version control

This how-to will walk you through setting up a Git repository. The repo will serve as a backup for your code and a way to undo mistakes.

Version control set up

After you’re done, you should have a local repository with a “clean” status and your local repository should be connected to a remote GitLab repository.

$ pwd
/Users/awdeorio/src/eecs280/p1-stats
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.

nothing to commit, working tree clean
$ git remote -v
origin	https://gitlab.eecs.umich.edu/awdeorio/p1-stats.git (fetch)
origin	https://gitlab.eecs.umich.edu/awdeorio/p1-stats.git (push)

You’ve made a few commits that show up in the log. It’s OK if your commits are different.

$ git log
commit 4d375b45357b4b39822ad48c62c6988910258370 (HEAD -> master, origin/master)
Author: Andrew DeOrio <awdeorio@umich.edu>
Date:   Fri Jan 12 16:14:02 2018 -0500

    Added quick start to README

commit e016bfad5a6371097ea00380aedd3e22ee63f754
Author: Andrew DeOrio <awdeorio@umich.edu>
Date:   Fri Jan 12 16:07:36 2018 -0500

    Added README

commit a13e2521fab6488458c912f598d6d5f89d429484
Author: Andrew DeOrio <awdeorio@umich.edu>
Date:   Fri Jan 12 15:59:25 2018 -0500

    Initial commit.  Starter files with function stubs.

CAEN Linux

This how-to will help you log in to a Linux computer operated by the College of Engineering using ssh at the command line. We’ll make sure our code works on a computer that is a lot like the autograder.

CAEN Linux set up

After you’re done, you should be able to copy files from your local computer to a CAEN Linux machine using rsync.

$ pwd
/Users/awdeorio/src/eecs280/p1-stats
$ rsync -rtv --exclude '.git*' ../p1-stats/ awdeorio@login.engin.umich.edu:p1-stats-copy/

Then you should be able to connect to a CAEN Linux machine with SSH and run your tests. Remember, your regression test will fail at this point because you haven’t finished the project yet.

$ ssh awdeorio@login.engin.umich.edu
Success. Logging you in...
...
$ ls
p1-stats-copy
$ cd p1-stats-copy
$ make clean
rm -rvf *.exe *~ *.out *.dSYM *.stackdump
$ make test
g++ -Wall -Werror -pedantic -g --std=c++11 stats_tests.cpp stats.cpp p1_library.cpp -o stats_tests.exe
g++ -Wall -Werror -pedantic -g --std=c++11 stats_public_test.cpp stats.cpp p1_library.cpp -o stats_public_test.exe
g++ -Wall -Werror -pedantic -g --std=c++11 main.cpp stats.cpp p1_library.cpp -o main.exe
./stats_public_test.exe
stats_public_test.exe: stats.cpp:12: int count(std::vector<double>): Assertion `false' failed.
make: *** [test] Aborted

Check style

This how-to will show you how to check the style of your code automatically. Before using the automated tools, check out the EECS 280 C++ Style Guide.

Style checking tutorial

After you’re done, you should be able to quickly copy files from your local computer to a CAEN Linux machine using a Makefile target.

$ make sync
rsync \
  -rtv \
  --delete \
  --exclude '.git*' \
  --filter=':- .gitignore' \
  ./ \
  awdeorio@login.engin.umich.edu:p1-stats-copy/

Then you should be able to connect to a CAEN Linux machine with SSH and run the style checks.

$ ssh awdeorio@login.engin.umich.edu
Success. Logging you in...
...
$ cd p1-stats-copy
$ make style

Check for undefined behavior

These two tutorials help locate memory problems, for example an uninitialized variable.

Valgrind is a dynamic analysis tool that helps locate undefined behavior and memory leaks.

Address Sanitizer uses compiler flags that automatically add code to check for things like out-of-bounds accesses.

Acknowledgments

Original how-to written by Andrew DeOrio awdeorio@umich.edu, fall 2017.