CodeFreak
CodeFreak

Reputation: 110

How to run a C program when it has multiple files?

In a program, I have a list.c file, list.h file and run.c file. In the run.c file, the code contains my main program and also "#include list.h". In my list.h file, my functions are just void and being defined. Finally, in my list.c file, I include list.h again and I have the meaning and code of what each function is going to do. I made a makefile that looks like so:

SOURCES = run.c list.c
OBJECTS= run.o list.o
HEADERS = list.h
CC = gcc
CFLAGS = -g -Wall

lab1: $(OBJECTS)
(tab)    $(CC) $(CFLAGS) $(OBJECTS) -o lab1

clean:
(tab)    rm -fR *o lab1

There is nothing wrong in any of my code because it is already finished and I am just copying code. However, I am unsure how to use the makefile to run these multiple files. I am only familiar with runner files after compiling with gcc and using "./". Is there something wrong with my makefile or is there a step for compiling these files in a different way?

Thank you for any help

Upvotes: 0

Views: 1798

Answers (3)

AlexPogue
AlexPogue

Reputation: 777

The given makefile is working and generates an executable lab1 file. However, the .o files depend on the list.h file, and this dependency is not captured.

You should specify targets to build the .o files, as follows:

SOURCES = run.c list.c
OBJECTS= run.o list.o
HEADERS = list.h
CC = gcc
CFLAGS = -g -Wall

lab1: $(OBJECTS)
(tab)    $(CC) $(CFLAGS) $(OBJECTS) -o lab1

%.o: %.c $(HEADERS)
    $(CC) -c $(CFLAGS) $< -o $@

clean:
    rm -fR *o lab1

Word of caution: With this makefile, if the list of HEADERS grows, a change in any of the headers will warrant a rebuild of all .o files.

For example, imagine we also have buf.c which uses buf.h. Now HEADERS = list.h buf.h. If we change buf.h, our makefile would rebuild both list.o and buf.o, even though a buf.o rebuild would suffice.

To remedy this, we could use a more verbose makefile which identifies the specific header prerequisites for each .o file with rules such as the following:

list.o: list.c list.h
    $(CC) -c $(CFLAGS) $< -o $@

buf.o: buf.c buf.h
    $(CC) -c $(CFLAGS) $< -o $@

Upvotes: 5

CodeFreak
CodeFreak

Reputation: 110

After compiling, it did end up making a lab1 file that I could run and everything worked. My makefile ended up working fine, I was just completely oblivious to the fact that it was making a file called lab1. I did change my makefile to the above options and that also worked. Thank you

Upvotes: 0

David
David

Reputation: 1694

Solution 1: Simply list each .c file separately as input and compile once

gcc list.c run.c -o lab1

Solution 2: Compile each .c file separately

gcc -c list.c
gcc -c run.c
gcc -o lab1 list.o run.o

Your project is small and simple enough that a fully generalized makefile is overkill:

SOURCES = run.c list.c
CC = gcc
CFLAGS = -g -Wall

all:
    $(CC) $(CFLAGS) $(SOURCES) -o lab1

clean:
    rm -fR *o lab1

The all: is a default target that executes when you simply type make with no arguments.

Upvotes: 1

Related Questions