DEV Community

Cover image for Makefile Tip for Efficient Productivity
Ajisafe Oluwapelumi
Ajisafe Oluwapelumi

Posted on • Updated on

Makefile Tip for Efficient Productivity

Makefile is a script that defines a set of rules to build a target, such as an executable program, or a library, from a set of source files.

Basic Structure of a Makefile

  • Rules: The rules define the targets and the commands to build them. A rule consists of a target, dependencies, and a set of commands to build the target.

  • Targets: The targets are the files or actions that we want to build or execute. They can be executables, libraries, object files, documentation files, or any other type of output.

  • Dependencies: The dependencies specify the files that the target depends on. If any of the dependencies are modified, the target needs to be rebuilt.

  • Commands: The commands are the set of instructions that are executed to build the target. They can be shell commands, compiler commands, or any other type of command that is required to build the target.

Basic Structure of a MAkefile

When building C programs with multiple source files, it is best to compile each source file (.c) into an object file (.o) first before linking them into an executable.

Why?

Compiling before linking them into an executable can help improve build efficiency and save time. This allows for incremental compilation meaning that when only one source file has changed, we only need to recompile that one source file into a new object file instead of recompiling all source files each time the program is built. This significantly reduces build time especially for large projects.

Programming Humor Meme

It also provides flexibility in the build process. Object files can be compiled with different compiler flags or optimization levels, and then linked together into an executable. This can help optimize the build process and allow for better control over the final executable.

Here is a Makefile snippet I worked on with a team for a Monty project.

OFILES = .monty.o .push.o .pall.o
flags = -Wall -Werror -Wextra -pedantic -std=c89

# OFILES variable hold the object files which are prerequisites
# to the executable "monty"
monty: $(OFILES) monty.h
    gcc $(OFILES) -o monty

# The source files (.c) are compiled to object files (.o)
.monty.o: monty.c monty.h
    gcc -c $(flags) monty.c -o .monty.o

.push.o: push.c monty.h
    gcc -c $(flags) push.c -o .push.o

.pall.o: pall.c monty.h
    gcc -c $(flags) pall.c -o .pall.o

# Clean up
clean:
    rm -rf *.o
Enter fullscreen mode Exit fullscreen mode

Overall, compiling C source code to object files first before linking them into an executable can improve build efficiency, save time, and provide flexibility in the build process.

Top comments (0)