diff --git a/README.md b/README.md index b96a45c..55fc67c 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,134 @@ # makemake -a 100ish line gnu makefile which simplifies the make process for C projects. \ No newline at end of file +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 `_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.
+ +
**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.
+ +
**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`.
+ +
**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).
+ +
**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.
+ +
**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`.
+ +
**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.
+ +
**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). \ No newline at end of file