Skill v1.0.1
currentAutomated scan100/1001 files
version: "1.0.1" name: modern-c-makefile description: Create, analyze, or improve Makefiles for modern C/C++ projects using best practices from the gnaro project template. Use when working with C/C++ projects that need clean, maintainable build systems for creating new Makefiles, improving existing ones, understanding modern patterns, or setting up comprehensive build workflows with testing and code quality tools.
Modern C Makefile
Overview
This skill provides guidance and templates for creating clean, maintainable Makefiles for modern C/C++ projects, based on the best practices demonstrated in the gnaro project. It helps structure build systems that integrate compilation, testing, linting, formatting, and dependency management in a clear and organized way.
Core Concepts
Understand these key Makefile concepts before implementing:
- Variables: Centralize project settings like compiler flags, directories, and tool paths
- Wildcards: Use patterns like
*.cand**/*.cto automatically find source files - Automatic Variables: Leverage
$@(target),$<(first dependency),$*(stem),$(@D)(target directory) - Phony Targets: Declare
.PHONYtargets for actions likeclean,format,lintthat don't produce files - Conditionals: Use
ifeq/else/endiffor debug/release builds or platform-specific configurations - Pattern Rules: Create generic rules for compiling
.cto.ofiles
Makefile Template
The complete gnaro Makefile template is available in references/gnaro_makefile.md. Key sections include:
Project Structure Variables
debug ?= 0NAME := your-projectSRC_DIR := srcBUILD_DIR := buildINCLUDE_DIR := includeLIB_DIR := libTESTS_DIR := testsBIN_DIR := bin
Automatic Object File Generation
OBJS := $(patsubst %.c,%.o, $(wildcard $(SRC_DIR)/*.c) $(wildcard $(LIB_DIR)/**/*.c))
Compiler and Tool Configuration
CC := clangLINTER := clang-tidyFORMATTER := clang-formatCFLAGS := -std=gnu17 -D _GNU_SOURCE -D __STDC_WANT_LIB_EXT1__ -Wall -Wextra -pedanticLDFLAGS := -lm
Core Targets
$(NAME): Build executable with dependencies on format, lint, and object files$(OBJS): Pattern rule for compiling object files with directory creationtest: Compile and run CUnit testslint: Run static analysis with clang-tidyformat: Apply code formatting with clang-formatcheck: Run valgrind memory checkssetup: Install development dependencies (Debian/Ubuntu)clean: Remove build artifactsbear: Generate compile_commands.json for tooling
Customization Guide
Adapting to Your Project
- Basic Configuration:
- Update
NAMEto your project name - Adjust directory variables to match your project structure
- Modify
CFLAGSfor your C standard and feature requirements
- Compiler and Tools:
- Change
CC,LINTER,FORMATTERto match your installed versions - For GCC projects:
CC := gcc - Adjust tool paths for non-Debian systems
- Cross-Platform Considerations:
- Replace apt-based
setuptarget with appropriate package manager commands - Use conditionals for platform-specific configurations:
``makefile ifeq ($(OS),Windows_NT) # Windows-specific settings else ifeq ($(shell uname -s),Darwin) # macOS-specific settings else # Linux-specific settings endif ``
- Adding Features:
- Documentation: Add
docstarget for Doxygen or other documentation generators - Packaging: Add
packagetarget for creating distributable archives - Installation: Add
installanduninstalltargets for system installation
Common Modifications
Multiple Executables:
EXECUTABLES := app1 app2all: $(EXECUTABLES)app1: $(APP1_OBJS)$(CC) $(CFLAGS) -o $(BIN_DIR)/$@ $^ $(LDFLAGS)app2: $(APP2_OBJS)$(CC) $(CFLAGS) -o $(BIN_DIR)/$@ $^ $(LDFLAGS)
Header Dependency Generation:
DEPFILES := $(OBJS:.o=.d)-include $(DEPFILES)%.d: %.c@$(CC) $(CFLAGS) -MM -MP -MT $*.o -MF $@ $<
Verbose Mode:
V ?= 0ifeq ($(V),1)Q :=elseQ := @endif$(OBJS): dir$(Q)mkdir -p $(BUILD_DIR)/$(@D)$(Q)$(CC) $(CFLAGS) -o $(BUILD_DIR)/$@ -c $*.c
Usage Examples
Example 1: Creating a New Makefile
User: Create a Makefile for my C project "calculator" with source files in src/, headers in include/, tests in tests/Assistant: Creates Makefile based on template with customized variables
Example 2: Adding Testing to Existing Makefile
User: Add CUnit testing support to my existing MakefileAssistant: Adds test target and updates dependencies
Example 3: Improving Build Performance
User: My Makefile rebuilds everything when headers changeAssistant: Adds automatic dependency generation with -MM flags
Example 4: Cross-Platform Support
User: Make my Makefile work on both Linux and macOSAssistant: Adds OS detection and conditional tool paths
Quick Reference
Essential Commands
make # Build project (default target)make debug=1 # Build with debug symbols, no optimizationmake test # Run testsmake lint # Run static analysismake format # Format codemake check # Run memory checksmake clean # Clean build artifacts
Project Structure Convention
project/├── Makefile├── src/ # Source files (*.c)├── include/ # Header files (*.h)├── lib/ # Third-party libraries├── tests/ # Test files├── build/ # Object files (generated)└── bin/ # Executables (generated)
Resources
This skill includes the following bundled resources:
references/
Reference documentation for Makefile best practices and templates:
- [gnaro_makefile.md](references/gnaro_makefile.md): Complete Makefile from the gnaro project with detailed analysis and adaptation notes. Use this as the primary reference template.
- [best_practices.md](references/best_practices.md): Comprehensive guide to modern C Makefile design patterns, advanced techniques, and common solutions.
When to load references: Read these files when you need detailed analysis of Makefile patterns, adaptation guidance, or advanced techniques beyond what's covered in the main skill.
assets/
Template files and guides for project setup:
- [basic_makefile.template](assets/basic_makefile.template): Simplified Makefile template ready for customization. Replace
PROJECT_NAMEand adjust directories as needed. - [project_structure_example.md](assets/project_structure_example.md): Recommended project structure with variations for different project types (single-header libraries, applications with resources, multi-target projects).
- [cross_platform_guide.md](assets/cross_platform_guide.md): Guide for adapting Makefiles to different operating systems (Linux, macOS, Windows) with platform detection, package manager integration, and cross-compilation support.
When to use assets: These files provide starting points and templates that can be copied and adapted for specific projects. They're particularly useful when creating new projects or porting existing ones to different platforms.
scripts/
This skill doesn't include scripts since Makefile creation is primarily about configuration and structure rather than automated processing. However, consider creating custom scripts for:
- Project scaffolding (generating directory structure)
- Dependency management
- Build automation beyond Makefile capabilities