Alex Rivera | Logout

Multiple source files in C- How exactly do makefiles work?

Asked 2010-12-03T20:24:22.493
34

I'm a relative beginner to C and I need to learn how makefiles work and I'm a bit confused on how the combination of C files work. Say we have a main.c, a foo.c, and a bar.c. How should the code be written so that main.c recognizes functions in the other files? Also, in foo.c and bar.c, is all of the code written in the main function there or do we need to write other functions for what we need them to do? I've read tutorials on how makefiles are written, and it makes sense for the most part, but I'm still a bit confused on the basic logistics of it.

Edit
Report

1 Answer

25

About C/C++ compilation

When you have a set of files, you usually do 2 things:

  • compile each source file (.c) to an object file (.o)
  • link all object files into an executable.

The source files are independent - you need header files to be able to provide the "information" (declarations) about functions in a given module in order to let any other module use them. Header files are not compiled by themselves - they are #included as parts of source files.

Have a look below on how the commands for that look like and how they are handled by make.


About makefiles

Makefile is a set of targets and rules to build them. A target is "something which can be built and results in a given file". (There exist also "phony" targets which don't result in a file and just are there to execute commands - a common one is called clean to remove the compilation results).

Each target has 2 parts:

  • list of dependencies, "sensitivity list" (other files and targets which are needed for this target) (after :, comma-separated),
  • list of shell commands which are executed to build this target (below the above, indented)

Consider this example:

main: main.o module1.o module2.o
    g++ main.o module1.o module2.o -o main

This means that: "To build the file main, I need to first make sure that targets main.o, module1.o and module2.o are up to date; then I need to call the following command...".

This can be also rewritten as:

main: main.o module1.o module2.o
    gcc $^ -o $@

The variables (everything starting with $ is a variable) will be expanded to the dep

answered 2010-12-03T20:46:56.853

Your Answer