Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 8 additions & 18 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name: Generate Release
on:
push:
tags:
- 'v*.*.*'
- "v*.*.*"

jobs:
build-release:
Expand All @@ -15,41 +15,32 @@ jobs:
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.x'
python-version: "3.x"

- name: Install CMake and Ninja
run: |
sudo apt-get update
sudo apt-get install -y cmake ninja-build zip

- name: Generate release artifact
run: |
python scripts/build_single_file.py --check || python scripts/build_single_file.py
echo "Generated dist/single_file/ab.cmake"

- name: Build CMake package
run: |
pwsh scripts/build_package.ps1

- name: Capture version
id: version
run: |
TAG_REF="${GITHUB_REF##*/}"
VERSION="${TAG_REF#v}"
echo "tag=$TAG_REF" >> $GITHUB_OUTPUT
echo "version=$VERSION" >> $GITHUB_OUTPUT

- name: Archive CMake package
- name: Generate release artifact
run: |
TAG="${{ steps.version.outputs.tag }}"
mkdir -p dist/release
zip -r "dist/release/abcmake-package-${TAG}.zip" dist/package
python scripts/build_single_file.py --check || python scripts/build_single_file.py
echo "Generated dist/single_file/ab.cmake"

- name: Upload release artifact
uses: actions/upload-artifact@v4
with:
name: abcmake-${{ steps.version.outputs.tag }}
path: |
dist/single_file/ab.cmake
dist/release/abcmake-package-${{ steps.version.outputs.tag }}.zip

- name: Create GitHub Release
uses: softprops/action-gh-release@v2
Expand All @@ -60,6 +51,5 @@ jobs:
The single-file module and CMake package are attached as assets.
files: |
dist/single_file/ab.cmake
dist/release/abcmake-package-${{ steps.version.outputs.tag }}.zip
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
5 changes: 2 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,10 @@ All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [6.2.1] - 2025-11-15
## [Unreleased]

### Added
- ...

- Introduce abcmake CMake package

## [6.2.0] - 2025-09-17

Expand Down
17 changes: 17 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ install(FILES
src/abcmake/add_component.cmake
src/abcmake/register_components.cmake
src/abcmake/target_link_components.cmake
LICENSE
DESTINATION ${ABCMAKE_INSTALL_CMAKEDIR}/abcmake
)

Expand All @@ -53,6 +54,22 @@ install(FILES
DESTINATION ${ABCMAKE_INSTALL_CMAKEDIR}
)

# Install LICENSE to abcmake subdirectory
install(FILES
LICENSE
DESTINATION ${ABCMAKE_INSTALL_CMAKEDIR}/abcmake
)

# Copy installer and docs to package root (CMAKE_INSTALL_PREFIX)
install(CODE "
file(COPY ${CMAKE_CURRENT_LIST_DIR}/LICENSE
DESTINATION \"\${CMAKE_INSTALL_PREFIX}\")
file(COPY ${CMAKE_CURRENT_LIST_DIR}/README.md
DESTINATION \"\${CMAKE_INSTALL_PREFIX}\")

message(STATUS \"Package root files installed to: \${CMAKE_INSTALL_PREFIX}\")
")

# Display installation information
message(STATUS "abcmake version ${PROJECT_VERSION}")
message(STATUS "Install destination: ${CMAKE_INSTALL_PREFIX}")
Expand Down
21 changes: 21 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2025 Andrei Gramakov

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
125 changes: 79 additions & 46 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# abcmake
<div align="center">

<div align="center">
![logo](docs/README/header.drawio.svg)

Simple, component‑first CMake helper for small & medium C/C++ projects.

Expand All @@ -13,41 +13,92 @@ Simple, component‑first CMake helper for small & medium C/C++ projects.

## Why abcmake?

| Problem | What abcmake Gives You |
|---------|------------------------|
| Problem | What abcmake Gives You |
| --------------------------------------------- | -------------------------------------------------------- |
| Repeating `add_library` + globbing everywhere | Single `add_main_component()` + auto component discovery |
| Hard to reuse internal modules | Component folders become portable units |
| Tedious dependency wiring | `target_link_components()` + optional registry by name |
| Vendored CMake packages cumbersome | Auto‑detect `*Config.cmake` in `components/` and link |
| Monolithic CMakeLists.txt growth | Split naturally by component directory |
| Hard to reuse internal modules | Component folders become portable units |
| Tedious dependency wiring | `target_link_components()` + optional registry by name |
| Vendored CMake packages cumbersome | Auto‑detect `*Config.cmake` in `components/` and link |
| Monolithic CMakeLists.txt growth | Split naturally by component directory |

## Features

- Zero external Python/CMake dependency beyond stock CMake (>= 3.5).
- Zero external Python/CMake dependency beyond stock CMake (>= 3.15).
- Conventional project layout with overridable source/include directories.
- Automatic recursive discovery & linking of nested components.
- Registry for linking components by *name* rather than path.
- Auto-detection of vendored CMake packages (`*Config.cmake`).
- Generates `compile_commands.json`.
- Generates `compile_commands.json` by default.
- Install step for each built target near the build dir.
- Single-file distributable (`ab.cmake`) published per GitHub Release.

## Installation
## Table Of Contents

- [Why abcmake?](#why-abcmake)
- [Features](#features)
- [Table Of Contents](#table-of-contents)
- [Quick Start](#quick-start)
- [Install](#install)
- [Use](#use)
- [Concepts](#concepts)
- [Public API](#public-api)
- [`add_main_component(<name> [INCLUDE_DIR ...] [SOURCE_DIR ...])`](#add_main_componentname-include_dir--source_dir-)
- [`add_component(<name> [SHARED] [INCLUDE_DIR ...] [SOURCE_DIR ...])`](#add_componentname-shared-include_dir--source_dir-)
- [`register_components(<path> ...)`](#register_componentspath-)
- [`target_link_components(<target> [PATH <path> ...] [NAME <comp> ...])`](#target_link_componentstarget-path-path--name-comp-)
- [Auto Package Detection](#auto-package-detection)
- [Advanced Usage](#advanced-usage)
- [Limitations](#limitations)
- [Contributing](#contributing)
- [Changelog](#changelog)
- [License](#license)

1. Download `ab.cmake` from the latest [GitHub Release](https://github.com/an-dr/abcmake/releases).
2. Place it at your project root next to `CMakeLists.txt`.
3. `include(ab.cmake)` in your root `CMakeLists.txt`.
## Quick Start

Optional (submodules / vendored): you can also keep the whole repository and include via `set(ABCMAKE_PATH path/to/src)` & `include(${ABCMAKE_PATH}/ab.cmake)`.
### Install

## Quick Start
**Project Scope**. Download a single-file distribution and put near your CMakeLists.txt:

- <https://github.com/an-dr/abcmake/releases>

**User Scope**. Clone the repo and install it in your system:

```bash
git clone https://github.com/you/abcmake.git
cd abcmake
cmake -B build
cmake --install build --prefix ~/.local
```

For Windows:

- Use `$env:LOCALAPPDATA\CMake` instead of `~/.local` also append the path:

```cmake
list(APPEND CMAKE_PREFIX_PATH "$ENV{LOCALAPPDATA}/CMake")
find_package(abcmake REQUIRED)
```

**System-wide Scope**. Change prefix to `/usr/local` (Linux) or `C:\Program Files\CMake` (Windows), run with elevated privileges

```bash
git clone https://github.com/you/abcmake.git
cd abcmake
cmake -B build
sudo cmake --install build --prefix /usr/local
```

### Use

Minimal root `CMakeLists.txt`:

```cmake
cmake_minimum_required(VERSION 3.15)
project(HelloWorld)
include(ab.cmake)

find_package(abcmake REQUIRED)
# or include(ab.cmake) for single-file distribution

add_main_component(${PROJECT_NAME})
```

Expand All @@ -72,18 +123,20 @@ Add a component (`components/mylib/CMakeLists.txt`):
```cmake
cmake_minimum_required(VERSION 3.15)
project(mylib)
include($ENV{ABCMAKE_PATH}/ab.cmake) # or relative path if local copy

find_package(abcmake REQUIRED)

add_component(${PROJECT_NAME})
```

## Concepts

| Term | Meaning |
|------|---------|
| Component | A folder with its own `CMakeLists.txt` that calls `add_component` or `add_main_component`. |
| Main component | The top-level executable (or library) defined with `add_main_component`. |
| Registry | A global list of discovered components (added via `register_components`). |
| Auto package | A directory under `components/` containing `*Config.cmake` -> treated as a CMake package. |
| Term | Meaning |
| -------------- | ------------------------------------------------------------------------------------------ |
| Component | A folder with its own `CMakeLists.txt` that calls `add_component` or `add_main_component`. |
| Main component | The top-level executable (or library) defined with `add_main_component`. |
| Registry | A global list of discovered components (added via `register_components`). |
| Auto package | A directory under `components/` containing `*Config.cmake` -> treated as a CMake package. |

## Public API

Expand Down Expand Up @@ -136,37 +189,16 @@ Custom project layout (no `src/`):
add_main_component(App SOURCE_DIR source INCLUDE_DIR include)
```

## Configuration

Environment variables:

| Variable | Effect |
|----------|--------|
| `ABCMAKE_EMOJI=1` | Fancy emoji output in logs. |

## Limitations

- One logical component per `CMakeLists.txt` (keep them focused).
- Designed for small/medium modular trees; very large monorepos may prefer native CMake patterns.

## Release & Single-File Build

The single-file `ab.cmake` is generated automatically during tagged releases (`v*.*.*`). It is not stored in the repository.

Generate locally:

```bash
python scripts/build_single_file.py
```

Download instead: [GitHub Releases](https://github.com/an-dr/abcmake/releases)

## Contributing

1. Fork & branch.
2. Run the test suite: `python -m unittest discover -v` (from `tests/`).
3. Regenerate single file if you touch core logic: `python scripts/build_single_file.py` (optional for dev).
4. Keep PRs focused & update the **Unreleased** section in `CHANGELOG.md`.
3. Keep PRs focused & update the **Unreleased** section in `CHANGELOG.md`.

## Changelog

Expand All @@ -176,3 +208,4 @@ See [CHANGELOG.md](CHANGELOG.md) for structured history.

MIT License © Andrei Gramakov.

See [LICENSE](LICENSE) for details.
71 changes: 71 additions & 0 deletions docs/README/header.drawio.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading