Lecture 1 Next Lecture

Lecture 1, Tue 04/02

Introduction, Compilation Review

Course Syllabus

Be sure to read the course syllabus for information on the logistics of this course.

https://ucsb-cs32.github.io/s19/info/syllabus/

Makefiles (a simple example)

// main.cpp
#include <iostream>

using namespace std;

int main() {
	cout << "Hello CS 32!" << endl;
	return 0;
}

Can compile this with g++ or clang++:

$ g++ main.cpp
$ ls
a.out		main.cpp
$ ./a.out
Hello CS 32!

Using make command

$ make main
c++     main.cpp   -o main

Change the output of the executable with the -o flag

$ g++ -o main main.cpp
$ ls
functions.cpp	functions.h	main		main.cpp
$ ./main
Hello CS 32!

C++ Build Process

  1. Preprocessor: Text-based program that runs before the compilation step. Looks for statements such as #include and modifies the source which is the input for compilation.

  2. Compiler: A program that translates source code into “object code,” which is a lower-level representation optimized for executing instructions on the specific platform. Lower level representations are usually stored in a .o (object) file.

  3. Linker: Resolves dependencies and maps appropriate functions located in various object files. The output of the linker is an executable file for the specific platform.

Compiling multiple files example

--------
// functions.h

int doubleInt(int x);
--------
// functions.cpp

int doubleInt(int x) {
	return 2 * x;
}
--------
// main.cpp
#include <iostream>
#include “functions.h”

using namespace std;

int main() {
    cout << doubleInt(12) << endl;
    return 0;
}
--------
$ g++ main.cpp
Undefined symbols for architecture x86_64:
  "doubleInt(int)", referenced from:
      _main in main-7c4a04.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
$ g++ -o main main.cpp functions.cpp
$ ls
functions.cpp	functions.h	main		main.cpp
$ ./main
24

General format of a Makefile

[target]: [dependencies]
	[commands]
# Makefile

main: functions.cpp main.cpp
	g++ -o main main.cpp functions.cpp
$ make main
g++ -o main main.cpp functions.cpp
$ make main
make: `main' is up to date.

Note:

# Makefile

main: functions.o main.o
	g++ -o main main.o functions.o
$ make main
c++    -c -o functions.o functions.cpp
c++    -c -o main.o main.cpp
g++ -o main main.o functions.o
$ ls
Makefile	functions.h	main		main.o
functions.cpp	functions.o	main.cpp

Variables in Makefiles

# Makefile
#CXX=clang++
CXX=g++
DEPENDENCIES=functions.o main.o

main: ${DEPENDENCIES}
	${CXX} -o main ${DEPENDENCIES}

make clean

# Makefile
main: functions.o main.o
	g++ -o main main.o functions.o

clean:
	rm -f *.o main

Compiling a specific version of C++

main: ${DEPENDENCIES}
	${CXX} -std=c++11 -o main ${DEPENDENCIES}
clean:
	rm -f *.o main

Using $@ and $^

main: ${DEPENDENCIES}
	${CXX} -std=c++11 -o $@ $^

# Expands out to
# main: functions.o main.o
#	g++ -std=c++11 -o main functions.o main.o