Reputation: 135
I have 3 files in this program, lab4.c, functions.h, functions.c
The lab4.c calls a function multiply(), whose prototype is in functions.h and is defined in functions.c. Multiply then used multiple other functions from functions.c. The only includes I have for this is in lab4.c including functions.h, do I need more? The problem I am having is described below
lab4:
#include <stdio.h>
#include <stdlib.h>
#include "functions.h"
int main(void) {
...
}
functions.h:
#ifndef FUNCTIONS
#define FUNCTIONS
void divideByPowerOf2(unsigned int* a, int power);
void multiplyByPowerOf2(unsigned int* a, int power);
...
#endif /* FUNCTIONS */
functions.c:
void divideByPowerOf2(unsigned int* a, int power){
*a >>= power;
}
void multiplyByPowerOf2(unsigned int* a, int power){
*a <<= power;
}
...
Currently, my makefile looks like this:
Makefile:
#Makefile
all: lab4
lab4: lab4.o functions.o functions.h
gcc -Wall -o lab4 lab4.o functions.o
lab4.0: lab4.c
gcc -c lab4.c
functions.o: functions.c
gcc -c functions.c
now this will recompile when I change the header file, but the changes dont actually take effect. For example, if I change the header file to
#ifndef FUNCTIONS
#define FUNCTIONS
void divideByPowerOf2(unsigned int* a, int power);
//void multiplyByPowerOf2(unsigned int* a, int power);
...
#endif /* FUNCTIONS */
the program still works just fine. Im assuming I may have messed up linking the files with includes and everything, as that usually confuses me. For example, does functions.c need to refer to anything? and does functions.h need any kind of reference to the .c files? How do I get this to work properly so that if I change the header file, it recompiles and actually uses the new header
Thanks for any help!
Upvotes: 2
Views: 1860
Reputation: 140297
First, there's a typo here:
lab4.0: lab4.c
should be
lab4.o: lab4.c
then, your function.h
should be on the source => object dependency lines, not on the object => executable line, else, if you change the .h file, it just re-links without rebuilding the .o files: it changes nothing.
Moreover, it's good to use -Wall
, but you have to use it when you compile your files, not when you link the executable, or you'll miss the actual compilation warnings (-Wall
during the link phase only is pretty useless).
For instance, the -Wall
flag would show you that commenting a prototype generates an "implicit declaration" warning (which can lead to an improper call/return values of a function). It's even more effective with -Werror
, which turns warnings into errors, so you cannot ignore warnings.
Here's how your makefile should look like:
all: lab4
CFLAGS = -Wall
lab4: lab4.o functions.o
gcc -o lab4 lab4.o functions.o
lab4.o: lab4.c functions.h
gcc $(CFLAGS) -c lab4.c
functions.o: functions.c functions.h
gcc $(CFLAGS) -c functions.c
note that if you only have 2 source files and they're small enough, you could even not use the make file by just running:
gcc -Wall -o lab4 lab4.c functions.c
in a script. That's not adapted if you have too many / big source files, because it rebuilds everything everytime.
Upvotes: 4