diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..2bc152073b6e68806f7632836d296aee5dabeb17 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +build +*.swo +*.swp +.DS_Store diff --git a/01_hello_world/.gitignore b/01_hello_world/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..15f47d081a203b85d98f53f0869208b20f1a3da4 --- /dev/null +++ b/01_hello_world/.gitignore @@ -0,0 +1,2 @@ +hello_world_c +hello_world_cpp diff --git a/01_hello_world/Makefile b/01_hello_world/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..7f8f9f513f97b7c6a56056bd0a9eae526e93ad4f --- /dev/null +++ b/01_hello_world/Makefile @@ -0,0 +1,34 @@ +# Change your compiler here if you're not using gcc. CC is for C, and CXX is for C++. +CC = gcc +CXX = g++ + +# These are options that we pass to the compiler. They say to emit all warnings ("warn all"), and +# optimize the program aggresively to make it fast ("optimization level 3"). +CFLAGS = -Wall -O3 + +# This line is here so that by default, Make will build both programs. It's not strictly necessary. +# With or without this line, you can run "make hello_world_c" or "make hello_world_cpp". With this +# line, if you just run "make" you'll get both. (Make executes the first rule in the Makefile when +# you don't give it a target specifically, so we put this rule first.) We tell Make that this rule +# is "phony" so that it understands it's just a combination of other rules and doesn't produce any +# of its own files. +.PHONY: all +all: hello_world_c hello_world_cpp + +# These are essentially recipes for programs. The first line tells Make that we are going to build +# a program "hello_world_c" from the source file "hello_world.c". The second lines Make how to +# do it; Make basically copies and pastes this line into the terminal. Note that to use the compiler +# and options we defined earlier (CC, CXX, and CFLAGS), we have to enclose them in parentheses and +# add a dollar sign. +hello_world_c: hello_world.c + $(CC) $(CFLAGS) -o hello_world_c hello_world.c + +# Here's the same thing except for the C++ version. +hello_world_cpp: hello_world.cpp + $(CXX) $(CFLAGS) -o hello_world_cpp hello_world.cpp + +# This rule deletes all the binaries. It's declared "phony" which means it doesn't actually make +# anything. Otherwise Make would get confused about when it should run this rule. +.PHONY: clean +clean: + rm hello_world_c hello_world_cpp diff --git a/01_hello_world/README.md b/01_hello_world/README.md new file mode 100644 index 0000000000000000000000000000000000000000..f8f9231e5bd1e60b6f54afc9b459fcc90ecabd30 --- /dev/null +++ b/01_hello_world/README.md @@ -0,0 +1,21 @@ +# Hello World + +From this directory (i.e. first run `cd /wherever/you/put/this/repo/01_hello_world`), run `make`. If +your toolchain is installed correctly, this will build two programs: `hello_world_c` and +`hello_world_cpp`. You can run them like this: `./hello_world_c` and `./hello_world_cpp`. + +``` +demo@linux:01_hello_world$ make +gcc -Wall -O3 -o hello_world_c hello_world.c +g++ -Wall -O3 -o hello_world_cpp hello_world.cpp +demo@linux:01_hello_world$ ./hello_world_c +hello, world, I'm C +demo@linux:01_hello_world$ ./hello_world_cpp +hello, world, I'm C++ +``` + +Note: Putting `./` in front of the executable files tells the shell unambiguously that you want to +run the programs located in this directory. The shell will say something like `command not found` if +you leave it out. This might seem annoying, but it's really important from a security perspective. +Otherwise if you made a program called `cd` or `make` or something, you could accidentally run it +and it might do something bad. diff --git a/01_hello_world/hello_world.c b/01_hello_world/hello_world.c new file mode 100644 index 0000000000000000000000000000000000000000..b57adc801dd96b424f2a60ac9596a9be2af4b0ab --- /dev/null +++ b/01_hello_world/hello_world.c @@ -0,0 +1,6 @@ +#include <stdio.h> + +// Every C program has a function called main. This is where your program starts. +int main(void) { + printf("hello, world, I'm C\n"); +} diff --git a/01_hello_world/hello_world.cpp b/01_hello_world/hello_world.cpp new file mode 100644 index 0000000000000000000000000000000000000000..614631986ed0f64780f2bfb060e7d0a6c9ed56b3 --- /dev/null +++ b/01_hello_world/hello_world.cpp @@ -0,0 +1,7 @@ +#include <iostream> + +// C++ uses a main routine just like C. We could use printf here, too, but it's more idiomatic to +// use std::cout. +int main() { + std::cout << "hello, world, I'm C++\n"; +} diff --git a/README.md b/README.md index 25979186df0a0ef8bb7af1992933268a29355b65..1c9d10ce37efb1ed0ee2d75cf4ce76afb0bc163e 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,51 @@ -# c_cpp_and_make +# C, C++, and Makefiles -Hello world programs for C and C++, built with Makefiles. \ No newline at end of file +Microcontrollers are great and all, but if you're new to programming it can help to learn a bit +about the software tools on their own before diving into the hardware as well. This repo has some +example programs in C and C++, along with Makefiles that help you build them. + +## The Basics + +C is a programming language. It was created in the early 70s at Bell Labs by Dennis Ritchie and Ken +Thompson. This makes it quite old, as far as programming languages go, but it certainly wasn't the +first (Fortran, Lisp, COBOL, and BASIC are all older, to name a few). And it's still widely used +today -- number one, in fact, in some popularity [rankings](https://www.tiobe.com/tiobe-index/). + +C++ is an extended version of C, created by Bjarne Stroustrup in the 80s. The syntax is basically +the same, so usually any C program you write will also be a valid C++ program. The original +difference is that C++ is [object +oriented](https://en.wikipedia.org/wiki/Object-oriented_programming) (basically, allows you to +associate data and methods with "classes"), but since then it's had all sorts of other stuff bolted +on too (like [templates](https://en.wikipedia.org/wiki/Template_(C%2B%2B)), +[lambdas](https://stackoverflow.com/questions/7627098/what-is-a-lambda-expression-in-c11), etc.). C +and C++ are commonly used together. + +Unlike Python or JavaScript, C and C++ are compiled languages. This means that before you run your +program, you always convert it into a binary format that your computer can execute directly. This is +called building your program, and it is done by a compiler. To run code on your own computer, you'll +almost certainly end up using [gcc](https://gcc.gnu.org/), [clang](https://clang.llvm.org/), or +[MSVC](https://visualstudio.microsoft.com/vs/features/cplusplus/). The first two are usually run +from the command line, while the third is integrated into Visual Studio. We'll be using the UNIX +style command line exclusively, so even if you run Windows, it's recommended that you install a +command line toolchain. + +## Required Software + +Overall, we'll need a compiler, and [Make](https://www.gnu.org/software/make/). + +On Linux, if these tools aren't installed already, you can use your package manager. Most distros +have one package that has all the basic tools bundled together. On Ubuntu, for example, you can run +`sudo apt install build-essential`. + +On Mac, if you've installed XCode, you already have clang. (You may need to tell XCode to install +the command line tools specifically for it to show up on your path.) You can also use homebrew to +install gcc. One gotcha is that Apple decided to alias clang as gcc in the stock install. So if you +run gcc, you'll actually get clang. This is bad because not all the options are the same, so +sometimes it just won't work to switch between the two. So if you do install gcc with homebrew, +you'll want to run gcc-8 or gcc-9 (or whatever specific version you got). + +On Windows... honestly I'm not sure. I haven't set up a development environment there in years. + +## Examples + +- [hello world](./01_hello_world)