The lib folder contains many *.h and *.c files, and all files are in development phrase and they contain many errors including syntax errors. So I want to write the Makefile to debug all libraries one by one.
Here is the project folder structure (All *.c files contain the "main" function for testing purpose):
./Makefile
./src/lib/hello.h
./src/lib/hello.c
./src/lib/world.h
./src/lib/world.c
./src/lib/foo.h
./src/lib/foo.c
./src/lib/bar.h
./src/lib/bar.c
Here is the Makefile_hello for debugging "hello.h" and "hello.c":
CC = gcc
CFLAGS = -Wall -g
# How to include only "hello.h"?
INCLUDES = -Isrc/lilb
# How to write the rest for debugging only "hello.c"?
Here is the Makefile_world for debugging "world.h" and "world.c":
CC = gcc
CFLAGS = -Wall -g
# How to include only "world.h"?
INCLUDES = -Isrc/lilb
# How to write the rest for debugging only "world.c"?
How to write the correct Makefile?
# ==========================================================
# Makefile for Modular C Project with Debug Selector
# Usage:
# make → build all modules (debug)
# make lib=foo → build only foo.c / foo.h
# make mode=release → build all in release mode
# make clean → remove build artifacts
# ==========================================================
# Compiler and flags
CC := gcc
MODE ?= debug
CFLAGS := -Wall -std=c17
INCLUDES := -Isrc/lib
BUILD := build
ifeq ($(MODE),debug)
CFLAGS += -g -O0
else
CFLAGS += -O2 -DNDEBUG
endif
# Source discovery
SRC_DIR := src/lib
SRC_ALL := $(wildcard $(SRC_DIR)/*.c)
OBJ_ALL := $(patsubst $(SRC_DIR)/%.c,$(BUILD)/%.o,$(SRC_ALL))
EXE := app
# Optional single library
LIB ?=
ifeq ($(LIB),)
SRC := $(SRC_ALL)
OBJ := $(OBJ_ALL)
TARGET := $(EXE)
else
SRC := $(SRC_DIR)/$(LIB).c
OBJ := $(BUILD)/$(LIB).o
TARGET := $(BUILD)/$(LIB)_test
endif
# Build rules
.PHONY: all clean dirs
all: dirs $(TARGET)
dirs:
@mkdir -p $(BUILD)
$(EXE): $(OBJ)
$(CC) $(CFLAGS) $(INCLUDES) -o $@ $^
$(BUILD)/%.o: $(SRC_DIR)/%.c $(SRC_DIR)/%.h
$(CC) $(CFLAGS) $(INCLUDES) -c $< -o $@
$(BUILD)/%_test: $(BUILD)/%.o
$(CC) $(CFLAGS) $(INCLUDES) -o $@ $^
clean:
rm -rf $(BUILD) $(EXE)