doc: improve documentation

This commit is contained in:
Supercip971 2023-06-06 10:16:22 -04:00 committed by Sleepy Monax
parent aea0678f65
commit d33b129e54
8 changed files with 553 additions and 236 deletions

257
README.md
View file

@ -15,252 +15,37 @@
## Table of contents
- [Table of contents](#table-of-contents)
- [Macros](#macros)
- [`@latest`](#latest)
- [`@uname`](#uname)
- [`@include`](#include)
- [`@join`](#join)
- [`@concat`](#concat)
- [`@exec`](#exec)
- [Manifest file format](#manifest-file-format)
- [`id`](#id)
- [`type`](#type)
- [`description`](#description)
- [`enabledIf`](#enabledif)
- [`requires`](#requires)
- [`provides`](#provides)
- [Target file format](#target-file-format)
- [`id`](#id-1)
- [`type`](#type-1)
- [`props`](#props)
- [`tools`](#tools)
- [Introduction](#introduction)
- [Quick-start](#quick-start)
- [Example](#example)
## Macros
## Introduction
**CuteKit** is a simple - yet - powerful build system and package manager for C and C++. It:
### `@latest`
- ✨ It uses **JSON**: Cutekit uses JSON instead of introducing a whole new programming language for describing the project. And also has macros to help the user experience (see [Jexpr](doc/spec/jexpr.md)).
- ✨ It's a **package manager**: Cutekit package manager is based on **Git**, nothing is centralized.
- ✨ It's **extendible**: Cutekit can be [extended](./doc/extends.md) by writing custom Python plugins.
- ✨ It's **easy**: the [**templates**](./doc/templates.md) help the user quick-start a project.
- ✨ It's **portable**: Cutekit can run on MacOS Gnu/Linux and Windows.
Find the latest version of a command in the path.
## Quick-start
```json
"cc": {
"cmd": ["@latest", "clang"], // clang-14
/* ... */
```
-> If you directly want to start using Cutekit for a new project, you can just run `$ ck I host` and it will create a new project in the host directory (you can rename it later).
### `@uname`
-> If you want to use Cutekit for writing operating systems, you can create a new [limine](https://github.com/limine-bootloader/limine/)-based project by running `$ ck I limine-barebone`.
Query the system for information about the current operating system.
## Example
If you want to see how it works you can read the [doc/cutekit.md](doc/cutekit.md) file.
```json
"cc": {
"cmd": ["@uname", "machine"], // "x86_64"
/* ... */
```
# License
### `@include`
<a href="https://opensource.org/licenses/MIT">
<img align="right" height="96" alt="MIT License" src="doc/mit.svg" />
</a>
Include a file
Cutekit is licensed under the **MIT License**.
### `@join`
Join two objects
Example:
```json
["@join", {"a": 1}, {"b": 2}] // {"a": 1, "b": 2}
```
### `@concat`
Concatenate strings
Example:
```json
["@concat", "a", "b", "c"] // "abc"
```
### `@exec`
Execute a command and return the output
Example:
```json
["@exec", "uname", "-m"] // "x86_64"
```
## Manifest file format
### `id`
The id of the package. This is used to identify the package in the manifest file.
Exemple:
```json
{
"id": "hello"
}
```
### `type`
The type of the package. This is used to identify the package in the manifest file.
Exemple:
```json
{
"type": "exe"
}
```
### `description`
The description of the package for the user.
Exemple:
```json
{
"description": "Hello world"
}
```
### `enabledIf`
A list of requirements for the package check agaisnt the build props. If the requirement is not met, the package will be disabled.
```json
{
"enabledIf": {
"freestanding": [
false
]
}
}
```
### `requires`
Dependencies of the package. The name listed here must be the same as the id of the package or member of a provide list.
Exemple:
```json
{
"requires": [
"libc",
"libm"
]
}
```
### `provides`
Alias for the package.
Exemple:
```json
{
"provides": [
"hello"
]
}
```
## Target file format
### `id`
The id of the target. This is used to identify the target in the target file.
### `type`
Should be `target`.
### `props`
A list of properties for the target.
Exemple:
```json
{
"props": {
"arch": "x86_64",
"vendor": "pc",
"os": "linux",
"env": "gnu",
"abi": "elf",
"cpu": "x86_64",
"features": "fxsr,sse,sse2"
}
}
```
Theses values are exposed the translation unit as `__ck_{prop}__`.
### `tools`
A list of tools for the target.
```json
{
"tools": {
"cc": {
"cmd": ["@latest", "clang"],
"args": [
"-target",
"x86_64-unknown-windows",
"-ffreestanding",
"-fno-stack-protector",
"-fshort-wchar",
"-mno-red-zone"
]
},
"cxx": {
"cmd": ["@latest", "clang++"],
"args": [
"-target",
"x86_64-unknown-windows",
"-ffreestanding",
"-fno-stack-protector",
"-fshort-wchar",
"-mno-red-zone"
]
},
"ld": {
"cmd": ["@latest", "clang++"],
"args": [
"-target",
"x86_64-unknown-windows",
"-nostdlib",
"-Wl,-entry:efi_main",
"-Wl,-subsystem:efi_application",
"-fuse-ld=lld-link"
]
},
"ar": {
"cmd": ["@latest", "llvm-ar"],
"args": [
"rcs"
]
},
"as": {
"cmd": "nasm",
"args": [
"-f",
"win64"
]
}
}
}
```
The full text of the license can be accessed via [this link](https://opensource.org/licenses/MIT) and is also included in the [license.md](license.md) file of this software package.

114
doc/cutekit.md Normal file
View file

@ -0,0 +1,114 @@
# Cutekit
Cutekit is a build system that aims to be simple, fast and easy to use.
A project is described using json files.
## Project file
The project file is used to describe the project and its dependencies.
See: [doc/spec/project.md](doc/spec/project.md) for the full specification.
Example:
> project.json
```json
{
"$schema": "https://schemas.cute.engineering/stable/cutekit.manifest.project.v1",
"id": "skift-org/skift",
"type": "project",
"description": "The Skift Operating System",
"extern": {
"cute-engineering/libheap": {
"git": "https://github.com/cute-engineering/libheap.git",
"tag": "v1.1.0"
}
}
}
```
Here we describe a project with the id `skift-org/skift` and a dependency to `cute-engineering/libheap` at version `v1.1.0`.
## An executable package manifest
When you want to create an executable package, you need to create a `manifest.json` file in any directory under `src/`.
This is the file that describe an executable with its dependencies.
> src/nyan-cat-app/manifest.json
```json
{
"$schema": "https://schemas.cute.engineering/stable/cutekit.manifest.component.v1",
"id": "nyan-cat-app",
"type": "exe",
"description": "rainbows everywhere",
"requires": [
"easy-lib"
]
}
```
Here we describe an executable with the id `nyan-cat-app` and a dependency to `easy-lib` (which is a library built by the project).
You can run the executable by running `$ ck run nyan-cat-app`.
## A library package manifest
When you want to create a library package, you need to create a `manifest.json` file in any directory under `src/`, like an executable package.
> src/easy-lib/manifest.json
```json
{
"$schema": "https://schemas.cute.engineering/stable/cutekit.manifest.component.v1",
"id": "easy-lib",
"type": "lib",
"description": "easy to use library",
"requires": [
"cute-engineering/libheap"
]
}
```
Here we describe a library with the id `easy-lib` and a dependency to `cute-engineering/libheap` (which is an external dependency described above in the `project.json`).
## Using installed libraries
You can create a specific installed library through the use of `pkg-config` files.
For example here is how you add `SDL2` to your project:
> src/extern/sdl2/manifest.json
```json
{
"$schema": "https://schemas.cute.engineering/stable/cutekit.manifest.component.v1",
"id": "sdl2",
"type": "lib",
"description": "A cross-platform development library designed to provide low level access to hardware",
"tools": {
"cc": {
"args": [
"@exec",
"pkg-config",
"--cflags",
"sdl2"
]
},
"cxx": {
"args": [
"@exec",
"pkg-config",
"--cflags",
"sdl2"
]
},
"ld": {
"args": [
"@exec",
"pkg-config",
"--libs",
"sdl2"
]
}
}
}
```

32
doc/extends.md Normal file
View file

@ -0,0 +1,32 @@
# Extending cutekit
By writing custom Python plugins, you can extend Cutekit to do whatever you want.
First the file need to be located in `meta/plugins` and have the `.py` extension.
Then you can import cutekit and change/add whatever you want.
For example you can add a new command to the CLI:
```python
import os
import json
import magic
import logging
from pathlib import Path
from cutekit import shell, builder, const, project
from cutekit.cmds import Cmd, append
from cutekit.args import Args
from typing import Callable
def bootCmd(args: Args) -> None:
project.chdir()
print("Hello world!")
append(Cmd("h", "hello", "Print hello world", bootCmd))
```
This feature is used - for example - by [SkiftOS](https://github.com/skift-org/skift/blob/main/meta/plugins/start-cmd.py) to add the `start` command, that build packages and run a virtual machine.

92
doc/spec/jexpr.md Normal file
View file

@ -0,0 +1,92 @@
## Macros
To avoid headache, Cutekit extends JSON through simple macros, this is what we call **Jexpr**.
### `@latest`
Find the latest version of a command in the path.
```json
"cc": {
"cmd": ["@latest", "clang"], // clang-14
/* ... */
```
### `@uname`
Query the system for information about the current operating system.
```json
"cc": {
"cmd": ["@uname", "machine"], // "x86_64"
/* ... */
```
The `@uname` commands has 1 argument that may be:
- `node`: to get the current machine hostname.
- `machine`: to get the current machine running architecture
- `aarch64` is renamed to `arm64`
- `AMD64` is renamed to `x86_64`
- `system`: to get the current machine running operating system:
- `Linux`
- `Windows`
- `release`: to get the current machine operating system's version
- `version`: to get more information about the host operating system.
### `@include`
Include a manifest file.
### `@read`
Read a Json file and output its value.
### `@join`
Join two objects
Example:
```json
["@join", {"a": 1}, {"b": 2}] // {"a": 1, "b": 2}
```
### `@concat`
Concatenate strings
Example:
```json
["@concat", "a", "b", "c"] // "abc"
```
### `@exec`
Execute a command and return the output
Example:
```json
["@exec", "uname", "-m"] // "x86_64"
```
### `@eval`
Execute python code and return the output
Example:
```json
"32limit": ["@eval", "2**32"]
```
### `@abspath`
Returns the absolute path of a path.

102
doc/spec/manifest.md Normal file
View file

@ -0,0 +1,102 @@
## Manifest file format
### `id`
The `id` of the package. This is used to identify the package in the manifest file.
Example:
```json
{
"id": "hello"
}
```
### `type`
The type of the package. This is used to identify the package in the manifest file.
Example:
```json
{
"type": "exe"
}
```
**Values:**
- `"exe"`
- `"lib"`
### `description`
The description of the package for the user.
Example:
```json
{
"description": "Hello world"
}
```
### `enabledIf`
A list of requirements for the package check against the build props. If the requirement is not met, the package will be disabled.
```json
{
"enabledIf": {
"freestanding": [
false
]
}
}
```
**Values:**
`enableIf` is a map of variable and values:
```
"variable-name": [array of expected value]
```
If `variable-name` is equal to one of the value in the table, then the package will be enabled.
### `requires`
Dependencies of the package. The name listed here must be the same as the `id` of the package or member of a provide list.
Example:
```json
{
"requires": [
"libc",
"libm"
]
}
```
### `provides`
An alias for the package.
Example:
```json
{
"provides": [
"hello"
]
}
```
This alias may be used by other package when using `requires`.
This is used when you have multiple package implementing the same features, but only one is enabled through `enableIf`.
**Value**:
- An array of `id`.

33
doc/spec/project.md Normal file
View file

@ -0,0 +1,33 @@
## project.json
The project file is the main file of the project.
It describes the project and its dependencies.
### `id`
The `id` of the project. This is used to identify the project.
### `type`
Should be `project`.
### `description`
The description of the project for the user.
### `extern`
A list of external dependencies for the project, for example:
```json
"externs": {
"cute-engineering/libheap": {
"git": "https://github.com/cute-engineering/libheap.git",
"tag": "v1.1.0"
}
}
```
You describe the project `id`, the `git` repository and the `tag` to use.

119
doc/spec/target.md Normal file
View file

@ -0,0 +1,119 @@
## Target file format
A target file is used for describing a new cross-compiler to use.
Generally, a target file is named like this: `{target}-{arch}.json`. For example, you could have:
- `host-x86-64`
- `windows-arm`
- ...
### `id`
The `id` of the target. This is used to identify the target in the target file.
### `type`
Should be `target`.
### `props`
A list of properties for the target.
Example:
```json
{
"props": {
"arch": "x86_64",
"vendor": "pc",
"os": "linux",
"env": "gnu",
"abi": "elf",
"cpu": "x86_64",
"features": "fxsr,sse,sse2"
}
}
```
Theses may be accessed during compilation as C-Macros: `__ck_{prop}__`.
### `tools`
A list of tools for the target.
Each tool is described like this:
```json
"name": {
"cmd": "",
"args": [
...
]
}
```
Where:
- `cmd` describe the command to run
- `arg` describes each argument to use (note: each entry of the table correspond to ONE argument).
You have different tools names that you can use:
- "cc"
- "cxx"
- "ld"
- "ar"
- "as"
**Example**:
```json
{
"tools": {
"cc": {
"cmd": ["@latest", "clang"],
"args": [
"-target",
"x86_64-unknown-windows",
"-ffreestanding",
"-fno-stack-protector",
"-fshort-wchar",
"-mno-red-zone"
]
},
"cxx": {
"cmd": ["@latest", "clang++"],
"args": [
"-target",
"x86_64-unknown-windows",
"-ffreestanding",
"-fno-stack-protector",
"-fshort-wchar",
"-mno-red-zone"
]
},
"ld": {
"cmd": ["@latest", "clang++"],
"args": [
"-target",
"x86_64-unknown-windows",
"-nostdlib",
"-Wl,-entry:efi_main",
"-Wl,-subsystem:efi_application",
"-fuse-ld=lld-link"
]
},
"ar": {
"cmd": ["@latest", "llvm-ar"],
"args": [
"rcs"
]
},
"as": {
"cmd": "nasm",
"args": [
"-f",
"win64"
]
}
}
}
```

40
doc/templates.md Normal file
View file

@ -0,0 +1,40 @@
# Templates
Templates are based on this [repository (cute-engineering/cutekit-templates)](https://github.com/cute-engineering/cutekit-templates).
Each directory correspond to a template.
You can create a new Cutekit project with the `ck I {template-name}` command.
If you want to use another repository as a template, you can use the `ck I --repo="github-link" name` command. For example:
```bash
ck I --repo="cute-engineering/cutekit-templates.git" host
```
## Writing a template
When writing a template, you do it through a github repository (only github for now).
Then add a `registry.json` file at the root of the repository contaning a table of entry directories.
For example, if you have a UI library called `cute-ui`, you can add a `registry.json` file like this:
```json
[
{
"id": "cute-ui-simple",
"description": "A simple template"
},
{
"id": "cute-ui-advanced",
"description": "A more advanced template"
}
]
```
And each "id" will correspond to a directory in the repository:
- `cute-ui-simple` will be in `cute-ui-simple/`
- `cute-ui-advanced` will be in `cute-ui-advanced/`