Skip to content
Open
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
235 changes: 169 additions & 66 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,103 +1,206 @@
# cxon -- C++ builder configured with JSON
# cxon — C and C++ builds configured with JSON

> [!IMPORTANT]
>
> - ~~cxon is still in development, and the configrantion field is not stable yet.~~
> - `cxon` has been published now!
> - `cxon` is for C++ beginners and build system learners. It not having enough rich features is intentional.

## What is the goal for cxon?

We want to provide a build system that is easy to use and config for C++ beginners or who are not the programming prefessors, which can help them focus on their project and code instrendad of dealing with the build system configration.
We only require a small number of essential fields for cxon.json and make the build system configration as simple as possible.
cxon is a small build tool for C and C++ projects. Describe your sources, compiler options, and dependencies in `cxon.json`, then run `cxon` to compile and link them.

The project is intended for C++ beginners and people learning how build systems work. It keeps configuration focused on a small set of essential fields.

## Features

- [x] Build project with compiler and linker by cxon.json immediately.(unsupport custom)
- [x] Build cache
- [x] Mult-thread build.
- [x] Mutiple build target type.
- [x] cxon.json schema support
- [x] Export compile_commands.json
- [x] Submodule support.
- [ ] Multiple compile targets.
- [ ] Platform-specific configuration.
- GNU, LLVM/Clang, and MSVC toolchains, with explicit compiler paths and custom toolchain selection.
- Parallel source compilation and timestamp-based object caching.
- Executable, static-library, shared-library, and object-library target types.
- Recursive modules built in dependency order, with library outputs passed to their parents.
- `compile_commands.json` export.
- JSON Schema integration for editor completion and validation.

## Installation

- ### Build and insall from cargo
Install from crates.io with Cargo:

```sh
cargo install cxon
```

- ### [Install directly from github release](https: //github.com/CoraBlack/cxon/releases)
Prebuilt packages are available on the [GitHub releases page](https://github.com/CoraBlack/cxon/releases).

## cxon.json schema support
```json5
{
// beginning your cxon with field $schema to get cxon competition intellisence
"$schema": "https://corablack.github.io/cxon_schema/cxon.schema.json"
To install the current checkout, including the custom toolchain support documented below:

```sh
cargo install --path .
```

You also need a C/C++ toolchain. By default, cxon looks for its tools on `PATH`; explicit compiler paths can be configured as described below.

## Quick start

Create `main.cpp`:

```cpp
#include <iostream>

// other config
int main() {
std::cout << "Hello from cxon!\n";
}
```

the schema service is deployed [here](https://github.com/CoraBlack/cxon_schema/tree/main)
Create `cxon.json` in the same directory:

## cxon.json Example
```json5
```json
{
"project": "HelloWorld", // (Required) project name
"target_name": "hello", // the final compiled product name, the default value is the project field
"target_type": "execuable", // (Required) build type (execuable, static_lib, shared_lib, object_lib)
"build_dir": "build", // the directory storing intermediate compiled product
"output_dir": "bin", // the directory storing final compiled product
"modules": [ // other module(will be linked automatically in parent cxon project)
"module_a",
"module_b"
],
"project": "hello",
"toolchain": "gnu",
"sources": ["./main.cpp"]
}
```

"toolchain": "gnu", // gnu, llvm, msvc only currently
"cc_prefix": "", // c compiler mangle
"cxxc_prefix": "", // c++ compiler mangle
"cc": "", // (unsupport) custom c compiler
"cxx": "", // (unsupport) custom c++ compiler
Run cxon from that directory:

"threads": 4, // count of build threads, the default value is number of your cpu - 1
```sh
cxon
```

"flags": [ // parameters for c and c++ compiler
"-Wall",
"-Wextra"
],
You can also pass a project directory or a path to its configuration:

"cflags": [ // parameters for c compiler
```sh
cxon ./path/to/project
cxon ./path/to/project/cxon.json
```

],
Intermediate files go into `build/`, and the executable goes into `output/` by default. Use `toolchain: "llvm"` for Clang or `toolchain: "msvc"` for MSVC, with flags appropriate to that compiler.

"cxxflags": [ // parameters for c++ compiler
## Configuration

],
`cxon.json` must be valid JSON: comments and trailing commas are not supported. Relative paths are resolved from the directory containing that configuration file.

"include": [ // directories where the header files are

],
This example builds a GNU C++ executable and exports its compilation commands:

"defines": [ // defination for compiler
```json
{
"$schema": "https://corablack.github.io/cxon_schema/cxon.schema.json",
"project": "HelloWorld",
"target_name": "hello",
"target_type": "executable",
"toolchain": "gnu",
"build_dir": "build",
"output_dir": "bin",
"threads": 4,
"flags": ["-Wall", "-Wextra"],
"cxxflags": ["-std=c++17"],
"sources": ["./main.cpp"],
"export_compile_commands": true,
"export_compile_commands_path": "./build"
}
```

],
### Project and build settings

| Field | Description | Default |
| --- | --- | --- |
| `project` | Project name. Required. | — |
| `toolchain` | `gnu`, `llvm`, `msvc`, or `custom`. Required. | — |
| `target_name` | Output name before the toolchain's extension is applied. | `project` |
| `target_type` | `executable`, `static_lib`, `shared_lib`, or `object_lib`. | `executable` |
| `sources` | Array of source file paths. List files explicitly. | None |
| `modules` | Array of child module paths or objects with a `path` field. | None |
| `build_dir` | Directory for intermediate object files. | `./build` |
| `output_dir` | Directory for the final output. | `./output` |
| `threads` | Number of compilation workers. Use a positive integer. | Logical CPU count minus one, with a minimum of one |
| `export_compile_commands` | Export compilation commands after the root project builds. | `false` |
| `export_compile_commands_path` | Directory for `compile_commands.json`. | `build_dir` |

Each configuration must contain a nonempty `sources` or `modules` array. Target types and toolchain names are case-insensitive.

### Compiler and linker settings

| Field | Description |
| --- | --- |
| `flags` | Compiler arguments shared by C and C++ sources. |
| `cflags` | Additional arguments for C sources. |
| `cxxflags` | Additional arguments for C++ sources. |
| `defines` | Preprocessor definitions, such as `["DEBUG", "VERSION=1"]`. |
| `include` | Existing header search directories. |
| `link` | Existing library search directories. |
| `libs` | Library names passed with the selected toolchain's library flag. For GNU/LLVM, `["m"]` becomes `-lm`. |
| `cc_prefix` | Prefix for the C compiler name, such as `aarch64-linux-gnu-`. |
| `cxxc_prefix` | Prefix for the C++ compiler name. The field is spelled `cxxc_prefix`. |
| `cc_path` | C compiler executable or a directory containing it. |
| `cxx_path` | C++ compiler executable or a directory containing it. |

Argument fields are arrays of strings. The legacy `cc` and `cxx` fields are not used to select compilers; use `cc_path` and `cxx_path` instead.

### Explicit compiler paths and custom toolchains

For `gnu`, `llvm`, and `msvc`, `cc_path` and `cxx_path` optionally override compiler lookup on `PATH`. For `custom`, both fields are required, even if the project contains only one source language.

For example, with an MSYS2 UCRT64 installation on Windows:

```json
{
"project": "custom_hello",
"toolchain": "custom",
"cc_path": "C:/msys64/ucrt64/bin/gcc.exe",
"cxx_path": "C:/msys64/ucrt64/bin",
"cxxflags": ["-std=c++17"],
"sources": ["./main.cpp"]
}
```

Replace these paths with your installation paths. Relative compiler paths are resolved from the project directory. Windows paths can use forward slashes, as above, or escaped backslashes.

When a path names a directory, cxon searches for the selected toolchain's compiler name. With `custom`, it tries `gcc`, `clang`, `cc`, then `cl` for C, and `g++`, `clang++`, `c++`, then `cl` for C++. Configured prefixes apply to these names; Windows lookup also checks `.exe` files. An invalid explicit path produces an error instead of falling back to `PATH`.

"sources": [ // (Required) source files which will be compiled
"./main.cpp",
"./func.cpp"
],
Custom toolchains reuse an existing command-line convention based on the resolved C++ compiler filename: names containing `clang` use LLVM conventions, `cl` or `cl.exe` uses MSVC, and other names use GNU. This does not provide arbitrary compiler command templates.

"link": [ // directories storing required libraries
When linking uses the C++ compiler, cxon uses the selected `cxx_path`. For a custom toolchain that needs a separate linker or archiver, cxon looks beside the C++ compiler, for example for `ar` when building a GNU/LLVM static library. The selected tool's directory is prepended to the child process's `PATH` so companion tools and runtime libraries can be found.

],
### Modules

"libs": [ // required libaries
Each module has its own `cxon.json`. Add dependencies using either supported form:

```json
{
"project": "app",
"toolchain": "gnu",
"sources": ["./main.cpp"],
"modules": [
"./modules/core",
{ "path": "./modules/utils" }
]
}
```

Module paths are relative to the declaring configuration. Dependencies build before their parents, and direct child static-library, shared-library, and object-library outputs become parent linker inputs. Executable outputs are not linked into parents.

All modules in a tree must use the same `toolchain` value. Each module configures its own sources, flags, include paths, and compiler paths. Cyclic dependencies are rejected.

### Editor integration and caching

Add the `$schema` field shown above to enable schema-aware editor support. The schema is maintained in the separate [cxon_schema repository](https://github.com/CoraBlack/cxon_schema).

Set `export_compile_commands` on the root project to export commands collected during the build, including module compilations. The export path is a directory, not a filename.

The object cache checks source and object timestamps. Header changes, compiler changes, and flag changes do not automatically invalidate cached objects. Remove the relevant project's `build_dir` contents before rebuilding after those changes. Cached sources also do not contribute commands to the current export, so use a clean build when you need a complete `compile_commands.json`.

## Examples

Run the included examples from the repository root:

```sh
cargo run -- ./example/hello_world
cargo run -- ./example/static_lib
cargo run -- ./example/shared_lib
```

The [custom toolchain example](example/custom-toolchain) compiles C and C++ together; adjust its compiler paths before running `cargo run -- ./example/custom-toolchain`. The [snake example](example/snake) demonstrates multiple modules and requires SDL3 headers and libraries.

## Development

```sh
cargo build
cargo test
cargo fmt --all -- --check
cargo clippy --all-targets --all-features -- -D warnings
cargo build --release
```

Multiple targets within a single configuration and platform-specific configuration remain future work.