Raspberry Pi Weather Station. Software 2: Make

Now it’s a matter of plumbing it all together. I have created a Makefile – by copying an existing one and changing it (I used the one from the gpio program because it’s similar) then I took the weather.c program and split it out into 2 files – one is still called weather.c and is the “main” program for the system, the other is now windDirection.c – and from this I created windDirection.h. The .h file has the function prototype and some data in it.

I also needed to create a new header file; pins.h. This will contain all the pin definitions for the sensors in the system.

Once that was running, I did the same for the air quality program – I deleted it’s main() section and created airq.h from it and integrated it into the Makefile.

A word on Makefiles before you dive in and start editing them yourself. This is what mine currently looks like:

#
# Makefile:
#	Raspberry Pi weather station project
#################################################################################

ifneq ($V,1)
Q ?= @
endif

#DEBUG	= -g -O0
DEBUG	= -O2
CC	= gcc
CFLAGS	= $(DEBUG) -Wall -Wextra -Winline -pipe

LIBS    = -lwiringPi -lm


SRC	=	weather.c		\
		windDirection.c airq.c

OBJ	=	$(SRC:.c=.o)

all:		weather

weather:	$(OBJ)
	$Q echo [Link]
	$Q $(CC) -o $@ $(OBJ) $(LDFLAGS) $(LIBS)

.c.o:
	$Q echo [Compile] $<
	$Q $(CC) -c $(CFLAGS) $< -o $@

.PHONY:	clean
clean:
	$Q echo "[Clean]"
	$Q rm -f $(OBJ) weather *~ core tags *.bak

.PHONY:	tags
tags:	$(SRC)
	$Q echo [ctags]
	$Q ctags $(SRC)


.PHONY:	depend
depend:
	makedepend -Y $(SRC)

# DO NOT DELETE

weather.o: pins.h windDirection.h
windDirection.o: pins.h windDirection.h
airq.o: pins.h airq.h

There is one very important thing to note when editing Makefiles: The lines that do not start on the left-hand edge start with a TAB character. That’s a proper, hard TAB and not 8 spaces. If you use spaces then it will all go horribly wrong. Trust me on this.

Makefiles were developed in the days when processors were slow (compared to today), disks were small (compared to today) and people wanted to make it easy for themselves. So in a Makefile, a line that starts with a TAB in deemed to be a rule continuation line. The time when this will trip you up is when you copy & paste a Makefile. If you ever do that, then double-check that its got the right stuff in it before trying to run it.

A quick explanation of what this makefile does – any how…

The lines near the top define variables which can be used later. e.g. DEBUG  = -O2. This lets me quickly change a few parameters. Note the CFLAGS containing -Wall and -Wextra. These are going to give me lots of whinges from the compiler which will pick out some silly mistakes.

Note the SRC line. It’s continued over 2 lines using a backslash.

Next is the OBJ line. It’s starting to become weird here, however what that line is saying is OBJ will contain what’s in SRC but change the .c into .o. We are going to compile the files, one at a time into object files which have a .o suffix, then we’ll link them together into an executable program. That way when we change one file, only that file needs compiling and not every file. (Although there are exceptions – later!)

Now we have lines which have a target followed by a dependency rule. The first target is all. This really refers to a file – which doesn’t exist, so it checks the dependency. This is weather, so all depends on weather. (which is also a file).

Carrying on, weather depends on OBJ – or all the .o files in OBJ – so if one of these has changed, then we re-do the weather rule – which is the final linking stage.

Under that, there is a target .c.o: This says that every .o file depends on a .c file, so if the .c file changes, then make the .o file. The commands under there run the compiler on that file.

The make system works recursively – it descends the file looking for things that depend on other things then performs the actions to satisfy the dependency.

Further down there are some fake (or phony) targets. These allow us to perform actions – e.g. make clean makes the clean target which in this case removes unwanted files.

The bottom part is computer generated – that’s why it says DO NOT DELETE. It’s generated by the makedepend script – called when I type make depend This goes through all the C source files, looking for the headers that they depend on. So if I change a header file, then it re-compiles the file that includes that header. Note the pins.h file – that is included in all files, so if I change that, then all files will be re-compiled…

Here are some examples:

$ make clean
[Clean]

This runs the clean rule and removes all the compiled stuff.

$ make
[Compile] weather.c
[Compile] windDirection.c
[Compile] airq.c
[Link]

This compiles everything – needed after the clean.

$ touch airq.c
$ make
[Compile] airq.c
[Link]

Here I touched (which updates the time-stamp) the airq.c file, then ran make. It compiled that file only, then did the link stage.

$ touch pins.h
$ make
[Compile] weather.c
[Compile] windDirection.c
[Compile] airq.c
[Link]

and here I touched the pins.h file – which everything depends on, so it compiled the lot. I’ll crack on and start coding up little routines to sanitise the sensors now and see where I get…

Comments are closed.