Files
makemake/README.md
2026-08-29 04:17:12 +02:00

134 lines
6.1 KiB
Markdown

# makemake
This repository contains a makefile for C projects. It is configured out-of-the-box for **C17** using **GCC**, enforces extremely strict compilation standards (treating all warnings as errors), manages out-of-source builds, and includes automatic dependency tracking and versioning.
## Setup Tutorial
Follow these steps to bootstrap your project from scratch using this Makefile:
### 1. Initialize the Project
Place the `Makefile` in the root of your new (and empty) project directory. Note that the output executable will be named after your root directory.
Run the following command to scaffold the required directory structure:
```bash
make init
```
**What this does:** Creates the `config/`, `includes/`, `output/`, and `source_code/` directories. It also generates a starter `main.c` and initializes the versioning and file list configuration files.
### 2. Write Your Code
* Place all your `.c` files inside the `source_code/` directory (or subdirectories within it).
* Place all your `.h` files inside the `includes/` directory.
### 3. Synchronize the Build System
Whenever you **add, rename, or delete** a `.c` or `.h` file, you must tell the Makefile to update its tracking lists:
```bash
make synch
```
**What this does:** Scans your directories and updates `config/source_code_list` and `config/header_list`.
### 4. Build the Project
Compile your code for the first time in debug mode:
```bash
make debug
```
Your compiled executable will be located in the `output/` directory, named `<your_folder_name>_00.000.00.0000` (or whatever the current version string is).
---
## Make Targets Overview
Here is a detailed breakdown of every command available in this Makefile, what it does, and when to use it.
| Target | Description & Use Case |
| --- | --- |
| `make` / `make help` | **Behavior:** Prints a help message with available commands.<br>
<br>**When to use:** When you need a quick reminder of the available targets. |
| `make init` | **Behavior:** Scaffolds the project directories (`source_code`, `includes`, `config`, `output`) and creates base tracker files.<br>
<br>**When to use:** Only once, at the very beginning of a new project. |
| `make synch` | **Behavior:** Searches the project for `.c` and `.h` files and writes their paths to `config/source_code_list` and `config/header_list`.<br>
<br>**When to use:** Every time you create a new file, delete a file, or rename a file. (You do *not* need to run this if you only edited the contents of an existing file). |
| `make debug` | **Behavior:** Compiles the project incrementally using `DEBUG_FLAGS` (`-g3`, `-O0`, Undefined Behavior Sanitizer).<br>
<br>**When to use:** During active development. This build includes debug symbols for `gdb`, disables optimization for accurate stepping, and catches undefined behavior at runtime. |
| `make fast` | **Behavior:** Compiles the project incrementally using `RELEASE_FLAGS` (`-O2`, `NDEBUG`) **without** bumping the project version.<br>
<br>**When to use:** When you want to test the performance of the optimized build locally, but you aren't ready to officially "release" a new version yet. |
| `make release` | **Behavior:** Bumps the project version using a date/time stamp (Format: `_YY.DAY.HH.MMSS`), saves it to `config/version`, and compiles the project using `RELEASE_FLAGS`.<br>
<br>**When to use:** When your code is tested, stable, and ready to be packaged or deployed. |
| `make clean` | **Behavior:** Deletes the `output/` directory, removing all compiled object files (`.o`), dependency files (`.d`), and executables.<br>
<br>**When to use:** When you want a completely fresh build, or if you change compiler flags in the Makefile and need to force a full recompilation. |
---
## Project Structure
After running `make init` and building, your project will look like this:
```text
my_project/ # Root folder (dictates the executable name)
├── Makefile # The build script
├── config/ # Build tracking files (auto-generated)
│ ├── header_list
│ ├── source_code_list
│ └── version
├── includes/ # Place all your .h files here
├── source_code/ # Place all your .c files here
│ └── main.c
└── output/ # Build artifacts (ignored by git ideally)
├── obj_debug/ # .o and .d files for debug builds
├── obj_release/ # .o and .d files for release builds
└── my_project_version # The final compiled executables
```
---
## Configuration & Defaults
This Makefile is heavily configured for safety and strictness. Here is how to modify the defaults to suit your needs:
### 1. Changing the C Standard
The project defaults to **C17**. To change this to C11, C99, or C2x:
* Open the `Makefile`.
* Locate the `CFLAGS = -std=c17 \` line.
* Change `-std=c17` to `-std=c11` (or your preferred standard).
### 2. Changing the Compiler
The default compiler is **GCC**. To use Clang (which is highly recommended for macOS users or for its excellent static analyzer):
* Locate `CC = gcc` at the top of the file.
* Change it to `CC = clang`.
### 3. Modifying Warning Strictness (Fixing Compilation Blocks)
By default, this Makefile includes `-Werror`, which **treats all warnings as errors** and halts compilation. It also includes an extensive list of strict warnings (like `-Wconversion`, `-Wshadow`, `-Wpadded`, etc.).
* **To allow warnings to pass without failing the build:** Remove the `-Werror \` line from the `CFLAGS` block.
* **To remove specific strict checks:** Simply delete or comment out the specific flag (e.g., `-Wmissing-prototypes \`) from the `CFLAGS` list.
### 4. Modifying Debug and Release Flags
You can tweak optimization levels and sanitizers at the top of the file:
* **Debug (`DEBUG_FLAGS`):** Defaults to `-g3 -O0 -fsanitize=undefined -fno-omit-frame-pointer`. You can add Address Sanitizer by appending `-fsanitize=address`.
* **Release (`RELEASE_FLAGS`):** Defaults to `-O2 -D NDEBUG`. (`NDEBUG` strips out `assert()` calls). If you want maximum optimization, you can change `-O2` to `-O3` or `-Ofast` (use `-Ofast` with caution as it breaks strict IEEE compliance for math).