C Development
Building
bash
# With Make make # With CMake mkdir -p build && cd build cmake .. make # Direct compilation gcc -Wall -Wextra -Werror -o program main.c
Testing
bash
# With Makefile test target make test # With CTest (CMake) cd build && ctest -V # With Unity or other test frameworks ./run_tests
Static Analysis
bash
# Cppcheck cppcheck --enable=all --error-exitcode=1 src/ # Clang static analyzer scan-build make # GCC warnings as errors gcc -Wall -Wextra -Werror -pedantic -std=c11
Memory Checking
bash
# Valgrind memory check valgrind --leak-check=full ./program # AddressSanitizer (compile with) gcc -fsanitize=address -g -o program main.c
Formatting
bash
# Format with clang-format clang-format -i src/*.c src/*.h # Check without changing clang-format --dry-run --Werror src/*.c src/*.h
Project Structure
code
project/ ├── src/ │ ├── main.c │ └── module.c ├── include/ │ └── module.h ├── tests/ │ └── test_module.c ├── Makefile (or CMakeLists.txt) └── README.md
Makefile Template
makefile
CC = gcc CFLAGS = -Wall -Wextra -Werror -std=c11 -pedantic LDFLAGS = SRC = src/main.c src/module.c OBJ = $(SRC:.c=.o) TARGET = program all: $(TARGET) $(TARGET): $(OBJ) $(CC) $(LDFLAGS) -o $@ $^ %.o: %.c $(CC) $(CFLAGS) -c -o $@ $< test: $(TARGET) ./run_tests clean: rm -f $(OBJ) $(TARGET) .PHONY: all test clean
TDD Cycle Commands
bash
# RED: Write test, run to see it fail make test # GREEN: Implement, run to see it pass make test # REFACTOR: Clean up, ensure tests still pass make clean && make && make test && cppcheck --enable=all src/