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.

This guide walks you through the shortest path to a working build: one C source file, one makefile, and the framework. By the end you will have compiled a program into bin/ and run it through Make — with automatic dependency tracking enabled from the start.

Prerequisites

Before you begin, make sure the following tools are available on your system:
  • GNU Make 3.81 or later — run make --version to check
  • GCC — run gcc --version to check (or set CC to an alternative C compiler)
  • A POSIX shell at /bin/sh — required by the framework’s startup checks
Optional tools (needed only for specific features):
  • Bison — for .y grammar files (bison --version)
  • Flex — for .l scanner files (flex --version)
  • GDB — for make gdb-<program> targets
  • Valgrind — for make valgrind-* targets
On Windows, use MSYS2, Cygwin, or Git Bash to get a POSIX shell and GNU Make. The framework detects OS=Windows_NT and automatically appends .exe to program names.

Steps

1

Obtain the framework

Clone the repository or download the mkframework/ directory and place it in your project root.
git clone https://github.com/fernandodanielmaqueda/gcc-bison-flex-GNUmakefile.git
cp -r gcc-bison-flex-GNUmakefile/mkframework/ your-project/
After copying, your project layout should look like this:
your-project/
├── mkframework/
│   ├── main.mk
│   ├── header/
│   ├── footer/
│   └── lang/
└── (your files will go here)
You only need the mkframework/ directory. The example GNUmakefile in the repository root is a template you can adapt — you do not need to copy it as-is.
2

Create your GNUmakefile

Create a GNUmakefile in your project root. The structure below is the canonical template derived from the reference implementation:
# Include the framework's main.mk — falls back to mkframework/main.mk if
# MKFWK_MAIN_MAKEFILE is not set from the command line
$(if $(MKFWK_MAIN_MAKEFILE),$(eval include $(MKFWK_MAIN_MAKEFILE)),$(eval include mkframework/main.mk))

# Prevent GNU Make from trying to remake this file
.PHONY: $(MKFWK_LAST_INCLUDING_DIR)GNUmakefile

# --- Declare your program ---

# Short name used as a handle for all per-program variables
program1 := myprogram

# Register the program with the framework
BIN_PROGRAMS += $(program1)

# Arguments passed when running: make run-myprogram
$(program1)_ARGS :=
# Working directory used when running the program (empty = current directory)
$(program1)_CWD  := $(BINDIR)

# Directory to search for source files
$(program1)_SRCDIR := src/
$(call mkfwk_make_check_set_directory_existence,$(program1)_SRCDIR)

# Auto-discover .c, .y, and .l files under SRCDIR
$(program1)_FIND_SOURCES := $(shell $(FIND) \
    $(if $($(program1)_SRCDIR),'$($(program1)_SRCDIR)',.) \
    -type f \( \( -name '*.c' ! -name '*.tab.c' ! -name '*.lex.yy.c' \) \
              -o \( -name '*.y' -o -name '*.l' \) \) -print \
    | $(SED) -e 's?^\./??' ;)
$(program1)_SOURCES := $($(program1)_FIND_SOURCES)
$(program1)_LDADD   := $($(program1)_SOURCES)

# Per-program compiler flags (append to global flags defined in main.mk)
$(program1)_CPPFLAGS =
$(program1)_CFLAGS   =
$(program1)_ASFLAGS  =
$(program1)_LDFLAGS  =

# Header search directory (defaults to SRCDIR)
$(program1)_INCLUDEDIR := $($(program1)_SRCDIR)
$(call mkfwk_make_check_set_directory_existence,$(program1)_INCLUDEDIR)
$(program1)_FIND_-I_FLAGS := \
    $(sort $(shell $(FIND) $(if $($(program1)_SRCDIR),'$($(program1)_INCLUDEDIR)',.) \
        -type f -name '*.h' -print \
        | $(SED) -e 's?^\./??' -e 's?[^/]*$$??' -e 's?/$$??' \
                 -e "s?^?-I'?" -e "s?\$$?'?" -e "s?^-I''\$$?-I'.'?" ;))
$(program1)_CPPFLAGS += $($(program1)_FIND_-I_FLAGS)

# Library search directory
$(program1)_LIBDIR := $($(program1)_SRCDIR)
$(call mkfwk_make_check_set_directory_existence,$(program1)_LIBDIR)
$(program1)_FIND_-L_FLAGS := \
    $(sort $(shell $(FIND) $(if $($(program1)_SRCDIR),'$($(program1)_LIBDIR)',.) \
        -type f \( -name 'lib*.a' -o -name 'lib*.so' \) -print \
        | $(SED) -e 's?^\./??' -e 's?[^/]*$$??' -e 's?/$$??' \
                 -e "s?^?-L'?" -e "s?\$$?'?" -e "s?^-L''\$$?-L'.'?" ;))
$(program1)_LDFLAGS += $($(program1)_FIND_-L_FLAGS)

# --- Required: activate all framework build rules ---
$(eval $(value MKFWK_FOOTER))
The $(eval $(value MKFWK_FOOTER)) line at the end is required. Without it the framework never registers any build targets and make all will report that there is nothing to do.
3

Create your source file

Create the src/ directory and a simple C file:
mkdir src
/* src/hello.c */
#include <stdio.h>

int main(void) {
    printf("Hello, world!\n");
    return 0;
}
The framework discovers hello.c automatically via the $(FIND) call in your makefile — you do not need to list it by name.
4

Build with make all

Run the build from your project root:
make all
The framework will:
  1. Create bin/, obj/, and .deps/ directories
  2. Compile src/hello.cobj/src/hello.o (with debug info and warnings enabled by default)
  3. Generate obj/src/hello.d for incremental dependency tracking
  4. Link obj/src/hello.obin/myprogram (or bin/myprogram.exe on Windows)
Expected output (with VERBOSE=X, which is the default):
#####( [all] ... )#####

mkdir -p 'bin/' 'obj/src/' '.deps/src/'
gcc ... -c -o 'obj/src/hello.o' 'src/hello.c'
gcc ... -o 'bin/myprogram' 'obj/src/hello.o' -lm

#####( Finished )#####
If Make reports make: Nothing to be done for 'all', verify that $(eval $(value MKFWK_FOOTER)) is the last line in your GNUmakefile and that src/hello.c exists.
5

Run the program

Use the built-in run-<program> target to execute the compiled program:
make run-myprogram
The framework changes to the directory specified in $(program1)_CWD (set to $(BINDIR), i.e. bin/) and runs the program from there. Expected output:
Hello, world!
To pass arguments, set myprogram_ARGS in your makefile or override from the command line:
make run-myprogram myprogram_ARGS="--verbose"

What to do next

Installation

Full system requirements, startup checks, and how to obtain the framework.

Configuration variables

All variables you can set globally or per-program to control the build.

Bison and Flex project

Add grammar and scanner files to your project.

Building targets

All make targets for building, cleaning, and more.

Build docs developers (and LLMs) love