Metadata-Version: 2.4
Name: golemcpp
Version: 1.1.2
Summary: Golem is a cross-platform build system for C/C++ projects
Keywords: cpp
Author: Barnabé BALP
Author-email: Barnabé BALP <contact@barnabebalp.fr>
License-Expression: MIT
License-File: LICENSE
Classifier: Programming Language :: Python :: 3
Classifier: Operating System :: OS Independent
Requires-Dist: golemcpp-waflib==1.1.2
Requires-Dist: node-semver==0.8.0
Requires-Python: >=3.10
Project-URL: Homepage, https://github.com/GolemCpp/golem
Project-URL: Documentation, https://github.com/GolemCpp/golem
Project-URL: Repository, https://github.com/GolemCpp/golem.git
Project-URL: Issues, https://github.com/GolemCpp/golem/issues
Description-Content-Type: text/markdown

<a href="https://github.com/GolemCpp/golem/releases">
  <picture>
    <source media="(prefers-color-scheme: dark)" srcset="docs/banner-dark.png">
    <source media="(prefers-color-scheme: light)" srcset="docs/banner-light.png">
    <img alt="Golem - Build System for Modern C++" src="docs/banner-light.png">
  </picture>
</a>

## Golem

- [Golem](#golem)
  - [What is it?](#what-is-it)
- [🌱 Getting started](#-getting-started)
  - [How to install?](#how-to-install)
  - [First project](#first-project)
- [💻 Commands](#-commands)
- [🚀 Roadmap](#-roadmap)
- [💖 Thanks](#-thanks)
- [❓ FAQ](#-faq)
  - [Why another build system?](#why-another-build-system)
  - [Known issues](#known-issues)
  - [How is it designed?](#how-is-it-designed)

### What is it?

Golem is a cross-platform build system for C/C++ projects. It can build projects like CMake does, or manage dependencies like Conan does. It only requires Python and Git to work.

Golem's main goal is to remove the noise in the project file, and favor the developers intents rather than the technical details when unneeded.

Here is how a **golemfile.py** looks like: 
``` python
def configure(project):
    
    project.dependency(name='json',
                       repository='https://github.com/nlohmann/json.git',
                       version='^3.0.0',
                       shallow=True)

    project.library(name='mylib',
                    includes=['mylib/include'],
                    source=['mylib/src'],
                    defines=['FOO_API_EXPORT'])

    project.export(name='mylib',
                   includes=['mylib/include'],
                   defines=['FOO_API_IMPORT'])

    project.program(name='hello',
                    source=['src'],
                    use=['mylib'],
                    deps=['json'])
```

But alternatively, you can also define an equivalent [golemfile.json](/examples/minimal/golemfile.json).

Have a look at the full example in [examples/minimal](/examples/minimal).

#### Other examples

TODO: List more elaborate projects here.

## 🌱 Getting started

### How to install?

**Requirements:** Python 3.10 or later, Git

Using **pipx** (recommended, creates a virtual environment):

``` bash
pipx install golemcpp

# Or install it for all users
pipx install --global golemcpp
```

Alternatively, using **pip**:

``` bash
pip install golemcpp
```

Since Golem is evolving fast, to upgrade it run:

``` bash
# When using pipx
pipx upgrade golemcpp

# When using pipx for all users
pipx upgrade --global golemcpp

# When using pip
pip install --upgrade golemcpp
```

### First project

Everything starts with `golemfile.py`. You can generate a documented starter file at the root of your project directory with:

``` bash
golem init
```

If you prefer to create it manually, here is a minimal example:

Here is an example of `golemfile.py` to compile a **Hello World** program:

``` python
def configure(project):
    project.program(name='hello',
                    source=['src'])
```

The project variable is the entry point to declare dependencies, libraries and programs that make up the project.

- `'hello'` is the name of the program being compiled (e.g. `hello.exe` or `hello-debug.exe`)
- `'src'` is the directory where all source files are expected to be found (recursively) for 'hello'

Here is `src/main.cpp`:

``` cpp
#include <iostream>
int main()
{
    std::cout << "Hello World!\n";
    return EXIT_SUCCESS;
}
```

Have a look at the full example in [examples/hello](/examples/hello).

#### Building the project

To build the program, run:

``` bash
# For a debug build
golem configure --variant=debug

# Or, for a release build
golem configure --variant=release

# In both cases, continue with
golem build
```

The built artifacts are located in `build/bin`.

Debug artifacts are suffixed with **"-debug"** by default.

## 💻 Commands

All the commands are meant to be called at the root of your project, where the project file (e.g. `golemfile.py` or `golemfile.json`) seats.

If you need to run them from somewhere else, use `--project-dir=<project_dir>`. If you need to customize the build directory, use `--build-dir=<build_dir>`.

The commands are presented in the order they are expected to be called, when needed to be called.

- [golem init](https://golemcpp.org/docs/commands/golem-init/) to generate a documented starter `golemfile.py`
- [golem configure](https://golemcpp.org/docs/commands/golem-configure/) to configure your project
- [golem resolve (if using dependencies)](https://golemcpp.org/docs/commands/golem-resolve/) to retrieve and configure dependencies
  * About the [Cache System](https://golemcpp.org/docs/advanced/cache-system/)
  * About managing [Dependencies](https://golemcpp.org/docs/advanced/dependencies/)
  * About the [Recipes](https://golemcpp.org/docs/advanced/recipes/)
- [golem dependencies (if using dependencies)](https://golemcpp.org/docs/commands/golem-dependencies/) to build dependencies
- [golem build](https://golemcpp.org/docs/commands/golem-build/) to build your project (dependencies are expected to be built if any)
- [golem package](https://golemcpp.org/docs/commands/golem-package/) to generate a package (the project is expected have built successfully)
- [golem clean](https://golemcpp.org/docs/commands/golem-clean/) to clean up built object files
- [golem distclean](https://golemcpp.org/docs/commands/golem-distclean/) to delete the build directory

## 🚀 Roadmap

Here is a list of important features to add as a priority:

- `golem` alone should welcome the user with a basic recap of the useful commands
- Add `c_standard`/`cxx_standard` on the Configuration (library, program, dependency)
- Remove v prefix from versions (see `Version.py`)
- Support parsing versions such as MAJOR.MINOR (without any PATCH defined)
- Detect automatically Qt if in `C:\Qt` or other obvious paths on other platforms
- Add an option to choose the runtime variant (debug or release, important on Windows)
- Allow the recipes to be a local folder instead of a repository
- Add a Visual Studio solution generator (investigate waf capabilities and in slnx too)
- Add the ability to remove the default flags of a variant
- Allow to define individual header files in export()
- Add the ability to have different recipes for different versions of the dependency
- Make an empty version on a dependency default to the latest available version
- Generate API header and associated defines for libraries when `auto_api_name='MYLIB_API'` is defined (can possibly switch later to a systematic generation with a switch to disable the generation)
- Add command to initialize a recipe (takes a URL and an option for the build system, include comments in project file)
- Add the ability for a project file to include another one
- Set default value for shallow on dependencies to True, or 'auto' (when version is a tag then shallow=True, otherwise for branches and commit hashes shallow=false) (this new behavior requires to check how version_template will behave, and it requires to fix how golem projects generate artifacts with the asked version to no break dependencies)
- Generate an implicit export on a library when a program tries to use it
- Support downloadable archives instead of git repositories
- Add commands to manage the dependencies in the cache system
- Supporting libraries mixing compiled targets and header only targets (e.g. boost)
- Consider packaging Golem for Windows, Linux, MacOS (see https://pyinstaller.org/en/stable/)
- Return a sensible error message to the user when running golem commands in the wrong order
- Add or improve recipes for the most popular dependencies (increase support for configuration options)
- Add first integration test
- Add pre/post build scripts
- Add user-defined options on Configuration to allow scripts in recipes to set special options (e.g. backend=opengl)
- Add support for cppfront
- Add support for C++ modules
- Implement [CPS](https://cps-org.github.io/cps/) ([sample](https://cps-org.github.io/cps/sample.html))
- Detect when `/external:I` or `-isystem` are available before using them
- Merge `use` and `deps` with a properly defined convention to differentiate the dependencies (e.g. @json, needs analysis)
- Generate by default `qmldir` and a `qrc` file for all the found QML files (allow to customize the namespace, or to disable generation)

Here is a list of important improvements to work on the long term:

- Add more documentation
- Add integration tests
- Add unit tests
- Add the ability to create user-defined variants
- Use the task mechanism of Waf for everything (e.g. resolving, building dependencies)
- Improve available helper functions to build dependencies using other build systems (recipes)
- Define default security profiles (allow creation and customization, `security_profile='all'`)
- Enhance static cache directories to be able to use read-only caches (for now they just block the generatino of missing artifacts)

Here is a list of other nice improvements to work on:

- Properly log messages instead of using print() (needs anlaysis, consider using waflibs.Logs)
- Properly abort execution when encoutering an error instead of raising an exception (needs anlaysis, consider using config.fatal(''), raise Waf.Error(), etc.)
- Show the full path of the compiler when in a NixOS shell (issue on Waf's side)
- Add a `golemfile.yml` format as project file

Contributions are very welcome!

Do not hesitate to create a PR with no change to start the conversation about something you'd be interested in developing. Do not hesitate to create issues to open the conversation about a problem or a need.

Of course, much remains to be done to make Golem the best build system!

## 💖 Thanks

A big thank you to:

- **mythicsoul** & **wtfblub** for their early testing, feedback, ideas, and support!

## ❓ FAQ

### Why another build system?

It all started back in 2016, with accumulated frustrations about the absence of proper dependency management in the tools of that time. In July 2016, Conan was not even a thing. CMake wasn't as widely adopted, but was definitely ramping up to become the success it is. At the time, I already went through a lot of thinking about how to solve the needs I had with previous scripting attempts, and being tired of it; I decided to start a proper tool on top of Waf to do it. Golem was born.

Years have passed, Golem ended up serving me better than I anticipated in the first place. I witnessed the rise of Conan and CMake, and I thought that Golem had something they didn't have. Time passed again, and I finally found the time to focus on sharing it properly, publishing it (Dec 27, 2025), documenting it and work on what's missing for it to not just be my tool, but a tool for everyone.

C++ has progressed a lot in the meantime; safety concerns, C++ modules, etc. Since the beginning, Golem's spirit is to be helpful and aware of how C++ projects are made today. It is made to be simple to use. Golem's goals are to provide premium support for both the bleeding edge features C++ can offer and the best safety and programming practices. This is how Golem's development will continue.

After the neccessary improvements, I'll advertise Golem to a broader audience.

### Known issues

- The cache system accumulates the dependencies and there are no commands yet to clean it up (requires manual deletion)
- Failure on a dependency processed by `golem resolve` may put this dependency in an unrecoverable state, requiring to delete it manually from the cache
- Errors of often not user friendly (raised exceptions)
- In some specific environments, such as NixOS, the path to the compiler is not a full path (not a blocking issue, need to fixed on Waf's side)
- When dealing with conflicting variants of a same dependency, there is no message to warn the user, and Golem attemps to link both anyway (master_dependencies.json is a good workaround for most cases)
- Only 1 template among those having the same source will get processed (bug caused by `if str(version_template_src) in self.context_tasks: continue`)
- No support for specifying header files in include parameter to export a library (needs to be a directory for now)

Additionnally to this non-exhaustive list, there are edge cases where the behavior isn't properly defined yet.

### How is it designed?

Golem is powered by [Waf](https://waf.io/), but provides a completely different API. It's a sophisticated frontend to Waf that adds many features and simplifies for the users how to define their project.

Among the added features, Golem provides dependency management with a cache system and [recipes](https://github.com/GolemCpp/recipes).

### About AI-assisted development

Golem started without any AI assistance. But as programming practices evolve, Golem's development must adapt.

Using AI tools to help develop Golem is allowed.

Vibe coding is not. Any AI-assisted change must be thoroughly reviewed by the person submitting it before it is committed.

**Owning the code is paramount:** contributors are expected to understand, validate, and stand behind every line they submit, whether it was written manually or with AI assistance.

Therefore, committing with an AI as the co-author is forbidden. Only humans are responsible for the code committed to Golem.