Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/fernandodanielmaqueda/gcc-bison-flex-GNUmakefile/llms.txt

Use this file to discover all available pages before exploring further.

gcc-bison-flex-GNUmakefile is a reusable GNU Make framework that solves a recurring problem in C development: assembling a build system that handles automatic source discovery, dependency tracking, code generation from grammar files, and integration with debugging tools — all without writing hundreds of lines of boilerplate. You copy one directory into your project, declare your programs, and the framework handles the rest.

What problems it solves

Writing a robust GNUmakefile for a C project that uses Bison and Flex typically requires managing generated source files, header dependencies, object file locations, and clean targets by hand. As projects grow, these makefiles become fragile and hard to maintain. This framework provides a structured, tested foundation so you can focus on writing code instead of maintaining build logic. Key problems it addresses:
  • Source discovery — finds .c, .y, and .l source files automatically under a configured directory
  • Code generation — runs Bison to produce .tab.c/.tab.h and Flex to produce .lex.yy.c, integrating the results transparently into the build
  • Incremental compilation — generates .d dependency files so only files affected by a header change get recompiled
  • Tool integration — provides ready-made targets for running programs, debugging with GDB, and memory analysis with Valgrind
  • Multiple output types — builds executables, static libraries (.a), and shared libraries (.so) from the same makefile pattern

Integrated tools

The framework integrates with the following tools:
ToolPurposeVariable
GCC (cc)C compiler for all compilation and linking stagesCC
BisonLALR parser generator — produces C source from .y grammar filesYACC
FlexLexical scanner generator — produces C source from .l scanner filesLEX
GDBSource-level debugger — invoked via make gdb-<program>GDB
ValgrindRuntime analysis — invoked via make valgrind-<tool>-<program>VALGRIND
ar / ranlibArchive and index tools for static library creationAR, RANLIB
All tool pathnames are configurable variables, so you can substitute alternatives (for example, clang for CC or yacc for YACC) without modifying the framework files.

Architectural decisions

The framework splits its logic across header makefiles and footer makefiles. Including mkframework/main.mk at the top of your GNUmakefile pulls in the header layer, which defines all variables, functions, and option flags. Your declarations — programs, source directories, flags — go in the middle. At the very end of your makefile, you expand the MKFWK_FOOTER canned directive, which includes the footer makefiles and registers all build rules. This two-phase design means the footer makefiles can see the fully assembled variable state when they generate targets, enabling per-program rules that depend on values you defined between the two includes. The last line of every project makefile must be:
$(eval $(value MKFWK_FOOTER))
MKFWK_FOOTER is a canned directive — a variable holding unexpanded makefile text. Calling $(eval $(value MKFWK_FOOTER)) expands and parses it in-place, causing the framework’s footer makefiles (base.mk, central.mk, cleaning.mk, executing.mk, making.mk, void.mk) to be included. Without this line, no build targets are registered and make all will fail. The framework uses an internal depth stack (MKFWK_DEPTH_STACK) to ensure footer makefiles are included exactly once — at the top-level makefile — even when the framework is included from sub-makefiles.

Directory structure

When you run make all, the framework creates three output directories in your project root:
your-project/
├── GNUmakefile
├── mkframework/        ← framework files (you copy this in)
├── src/                ← your source files
├── bin/                ← compiled programs and libraries (BINDIR)
├── obj/                ← intermediate object files (OBJDIR)
└── .deps/              ← auto-generated dependency files (DEPDIR)
DirectoryVariableContents
bin/BINDIRFinal executables and library files
obj/OBJDIR.o object files, .i preprocessed files, .s assembly files, Bison/Flex-generated C files
.deps/DEPDIR.d dependency makefiles and timestamp files for incremental builds
These directories are created automatically on first build and removed by the appropriate clean targets.

Supported output types

Declare the kind of output you want using the corresponding variable:
  • BIN_PROGRAMS — executables placed in bin/, with .exe extension on Windows
  • BIN_LIBRARIES — static libraries (lib<name>.a) placed in bin/
  • BIN_SOLIBRARIES — shared libraries (lib<name>.so) placed in bin/
You can mix all three in a single GNUmakefile.

Cross-platform support

The framework runs on Unix-like systems (Linux, macOS, BSDs) and on Windows via environments that provide GNU Make and a POSIX shell, such as MSYS2, Cygwin, or Git Bash. On Windows, the OS environment variable is typically set to Windows_NT. The framework detects this automatically and appends .exe to all program names:
ifeq ($(OS),Windows_NT)
EXEEXT=.exe
endif
No manual configuration is needed — the EXEEXT variable propagates to all program targets and run-<program> invocations automatically.

License

gcc-bison-flex-GNUmakefile is free software released under the GNU General Public License v3.0 or later (GPL-3.0+). You can redistribute it and modify it under the terms of the GPL as published by the Free Software Foundation.

Next steps

Quickstart

Build your first C program with the framework in five steps.

Framework structure

Understand the header/footer architecture and directory layout in depth.

Building targets

Full reference for all build targets the framework provides.

Build docs developers (and LLMs) love