Build Tools: Writing and Using Makefile in C Language

Build Tools: Writing and Using Makefile in C Language

In software development, build tools are an indispensable part. For C language developers, Makefile is a widely used build tool that simplifies the process of compilation and linking. This article will provide a detailed introduction for basic users on how to write and use Makefile.

What is Makefile?

Makefile is a text file that contains instructions to guide the <span>make</span> command on how to generate executable programs from source code. When you modify the source code, you only need to run the <span>make</span> command, and it will automatically identify the changed files and recompile them.

Basic Structure of Makefile

A simple Makefile typically consists of three parts: targets, dependencies, and rules:

target: dependencies    command
  • target (Target): The file to be generated, such as an executable or object file.
  • dependencies (Dependencies): The source files or other targets required to generate the target.
  • command (Command): One or more shell commands that need to be executed to generate the target.

Note that all commands must start with a tab, not spaces.

Creating a Simple Example

Let’s create a simple C project that includes two source files and a main program. Assume our project directory structure is as follows:

my_project│├── main.c├── hello.c├── hello.h└── Makefile

Source Code Example

<span>main.c</span>

#include <stdio.h>#include "hello.h"
int main() {    printf("Hello from Main!\n");    hello();    return 0;}

<span>hello.c</span>

#include <stdio.h>#include "hello.h"
void hello() {    printf("Hello from Hello!\n");}

<span>hello.h</span>

#ifndef HELLO_H  // Prevent multiple definitions
#define HELLO_H 
void hello();
#endif // HELLO_H

Writing Makefile

Create a text file named <span>Makefile</span> in your project directory (/my_project) and fill it with the following content:

# Specify variables, adjust CC and CFLAGS as needed.
CC=gcc              CFLAGS=-Wall -g     
# Define target name.
TARGET=main         OBJ_FILES=main.o hello.o  
# Default rule, called when no parameters are provided.
all: $(TARGET)
# Rule to generate executable file, linking object files into output file.
$(TARGET): $(OBJ_FILES)    $(CC) -o $@ $^
# Compile each .c file into corresponding .o file.
%.o: %.c    $(CC) $(CFLAGS) -c $< 
# Clean workspace, removing unnecessary files.
clean:    rm -f $(OBJ_FILES) $(TARGET)

Interpreting Makefile Content

  1. Variable Definitions:

  • CC: Specifies the compiler, here it is gcc.
  • CFLAGS: Reports warnings and outputs debugging information.
  • Default Rule (<span>all</span>):

    • When you simply enter <span>make</span>, this rule is called first, generating the specified TARGET (the executable program main).
  • Linking Stage (<span>$(TARGET): $(OBJ_FILES)</span>):

    • Uses gcc to link all .o object files into the final output.
  • Compilation Stage (<span>%.o: %.c</span>):

    • Uses pattern matching to call the corresponding command for each .c source file when converting to .o object files.
  • Clean Task (<span>clean</span>):

    • Provides a way to remove most temporary/unnecessary files generated during the build process.

    Using Make Command

    Navigate to your project directory and enter the following command in the terminal to build your application:

    make       # This will build using default parameters, then run to get results
    ../main      # Execute your program, if successful as described above, you will see console output.

    To clean up unnecessary products, you can use:

    make clean  # Deletes all created temporary documents to ensure a clean environment for the next operation.

    Conclusion

    Through this article, you should have a preliminary understanding of how to write a basic MAKEFILE for your C language project. MAKEFILE makes full use of system status and greatly facilitates the management process of large software engineering, making maintenance easier and reducing the pain of overtime. Additionally, you can gradually add complex features as needed, such as custom options and modules. This article is just a starting point, and it is recommended to continuously explore more aspects and techniques in actual development!

    I hope this content helps you get started smoothly.

    Leave a Comment