When compiling C code, you need to convert every .c to a .o. Unfortunately, gcc doesn't have that ability. So you need to employ a make file that does it.
The code below is a simple example of using Makefile's wildcard
and patsubst
functions to do it.
The wildcard is easy, it's just globbing (src/*.c)
. The patsubst is the harder part for me. It replaces every string that it got from the wildcard to look like this ('obj/*.o')
.
After that, it runs gcc
per each individual string that it got out. I've been looking through the docs of just
https://just.systems/man/en/chapter_1.html, but I couldn't get it working.
# Define source directory
SRC_DIR := src
# Define object directory
OBJ_DIR := obj
# Define source files using wildcard function
SRC_FILES := $(wildcard $(SRC_DIR)/*.c)
# Define object files using patsubst function
OBJ_FILES := $(patsubst $(SRC_DIR)/%.c,$(OBJ_DIR)/%.o,$(SRC_FILES))
# Compiler
CC := gcc
# Compiler flags
CFLAGS := -Wall -Wextra -Iinclude
# Target executable
TARGET := my_program
# Default rule to build the executable
$(TARGET): $(OBJ_FILES)
$(CC) $^ -o $@
# Rule to compile source files into object files
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.c
$(CC) $(CFLAGS) -c $< -o $@
# Clean rule
clean:
rm -f $(OBJ_DIR)/*.o $(TARGET)
I haven't gotten the full makefile made, but here is the code for the wildcard and patsubst:
# Define source directory
SRC_DIR := 'src'
# Define object directory
OBJ_DIR := 'obj'
# Define source files using wildcard
SRC_FILES := `echo src/*.c`
# Define object files
OBJ_FILES := replace_regex(SRC_FILES, SRC_DIR / '([^/]+)\.c(\s|$)', OBJ_DIR / '${1}.o$2')
run:
@echo {{SRC_FILES}}
@echo {{OBJ_FILES}}