Skip to content

Commit 1589461

Browse files
doc: docs setup
1 parent 6427374 commit 1589461

8 files changed

Lines changed: 568 additions & 175 deletions

File tree

CONTRIBUTING.md

Lines changed: 101 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,32 +10,124 @@ Thank you for your interest in CFBox. This document covers building, testing, an
1010

1111
## Building
1212

13+
### Debug Build (Default)
14+
1315
```bash
1416
cmake -B build
1517
cmake --build build
1618
```
1719

18-
Debug builds (default) include AddressSanitizer and UBSan. For a release build:
20+
Debug builds automatically enable AddressSanitizer (ASan) and UndefinedBehaviorSanitizer (UBSan) with `-g3 -O0`. Compiler warnings are treated as errors (`-Werror`) with extensive warning flags (see [CompilerFlag.cmake](cmake/compile/CompilerFlag.cmake)).
21+
22+
### Release Build
1923

2024
```bash
2125
cmake -B build -DCMAKE_BUILD_TYPE=Release
2226
cmake --build build
2327
```
2428

29+
Release builds use `-O2` by default and enable LTO. For size-optimized builds, add `-DCFBOX_OPTIMIZE_FOR_SIZE=ON` to use `-Os` instead.
30+
2531
## Running Tests
2632

2733
```bash
2834
# Unit tests (108 GTest cases)
2935
ctest --test-dir build --output-on-failure
3036

31-
# Integration tests (16 shell scripts)
37+
# Integration tests (16 shell scripts comparing against GNU coreutils)
3238
bash tests/integration/run_all.sh
3339
```
3440

41+
## Cross-Compilation
42+
43+
### AArch64
44+
45+
```bash
46+
# Dynamic linking
47+
cmake -B build-aarch64 \
48+
-DCMAKE_TOOLCHAIN_FILE=cmake/toolchain/Toolchain-aarch64.cmake \
49+
-DCMAKE_BUILD_TYPE=Release \
50+
-DCFBOX_OPTIMIZE_FOR_SIZE=ON
51+
cmake --build build-aarch64
52+
53+
# Static linking
54+
cmake -B build-aarch64-static \
55+
-DCMAKE_TOOLCHAIN_FILE=cmake/toolchain/Toolchain-aarch64.cmake \
56+
-DCMAKE_BUILD_TYPE=Release \
57+
-DCFBOX_OPTIMIZE_FOR_SIZE=ON \
58+
-DCFBOX_STATIC_LINK=ON
59+
cmake --build build-aarch64-static
60+
```
61+
62+
Requires: `aarch64-linux-gnu-g++` (install via `gcc-aarch64-linux-gnu g++-aarch64-linux-gnu`).
63+
64+
### ARMv7-A
65+
66+
```bash
67+
# Static linking (requires Arm GNU Toolchain)
68+
cmake -B build-armhf-static \
69+
-DCMAKE_TOOLCHAIN_FILE=cmake/toolchain/Toolchain-armhf.cmake \
70+
-DCMAKE_BUILD_TYPE=Release \
71+
-DCFBOX_OPTIMIZE_FOR_SIZE=ON \
72+
-DCFBOX_STATIC_LINK=ON
73+
cmake --build build-armhf-static
74+
```
75+
76+
Requires: [Arm GNU Toolchain](https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain) (`arm-none-linux-gnueabihf-g++`).
77+
78+
### Verifying Cross-Compiled Binaries
79+
80+
```bash
81+
file build-aarch64/cfbox # Confirm target architecture
82+
size build-aarch64/cfbox # Check section sizes
83+
scripts/measure_size.sh build-aarch64/cfbox # Detailed size analysis
84+
```
85+
86+
## QEMU Testing
87+
88+
### User-Mode Testing
89+
90+
Run cross-compiled binaries under QEMU user-mode emulation with full integration tests:
91+
92+
```bash
93+
# Requires: qemu-user-static
94+
./scripts/qemu_user_test.sh --target aarch64 --link static
95+
./scripts/qemu_user_test.sh --target armhf --link static
96+
```
97+
98+
### System-Mode Testing
99+
100+
Boot a minimal Linux kernel with CFBox as PID 1. Requires the Linux kernel source (as a git submodule):
101+
102+
```bash
103+
# Build initramfs
104+
./scripts/build_initramfs.sh --arch aarch64 --cfbox build-aarch64-static/cfbox
105+
106+
# Boot and test
107+
./scripts/qemu_system_test.sh \
108+
--arch aarch64 \
109+
--kernel path/to/Image \
110+
--initramfs build/aarch64-initramfs.cpio
111+
```
112+
113+
The `init` applet auto-mounts proc/sysfs/devtmpfs, runs smoke tests, then powers off. Minimal kernel config: [configs/qemu-virt-aarch64.config](configs/qemu-virt-aarch64.config).
114+
115+
## CI Pipeline
116+
117+
The CI pipeline ([ci.yml](.github/workflows/ci.yml)) runs on every push/PR to `main` with 5 stages:
118+
119+
| Stage | Description |
120+
|-------|-------------|
121+
| **native** | x86-64 Debug build with ASan/UBSan + all tests |
122+
| **release-size** | Release build (`-Os` + LTO) + binary size report |
123+
| **cross-compile** | aarch64/armhf cross-compilation (dynamic + static) |
124+
| **qemu-user-test** | Integration tests under QEMU user-mode emulation |
125+
| **qemu-system-test** | Full boot test with CFBox as PID 1 (main/release branches only) |
126+
35127
## Code Style
36128

37-
- Format code with the project `.clang-format` (LLVM-based, 4-space indent, 100-column limit).
38-
- All code must compile cleanly with the flags in `cmake/compile/CompilerFlag.cmake` (`-Wall -Wextra -Wpedantic` plus additional warnings).
129+
- Format code with the project [.clang-format](.clang-format) (LLVM-based, 4-space indent, 100-column limit).
130+
- All code must compile cleanly with the flags in [CompilerFlag.cmake](cmake/compile/CompilerFlag.cmake) (`-Wall -Wextra -Wpedantic` plus additional warnings, all treated as errors).
39131
- Follow existing patterns:
40132
- `std::expected<T, Error>` with `CFBOX_TRY` for error handling
41133
- `cfbox::args::parse()` for CLI argument parsing
@@ -46,11 +138,13 @@ bash tests/integration/run_all.sh
46138

47139
1. Create `src/applets/<name>.cpp` with signature `auto <name>_main(int argc, char* argv[]) -> int`.
48140
- Add a comment header listing supported flags and known differences from GNU.
49-
2. Declare the function in `include/cfbox/applets.hpp`.
50-
3. Add one entry to `APPLET_REGISTRY` in `include/cfbox/applets.hpp`.
51-
4. Add GTest unit tests in `tests/unit/test_<name>.cpp` (see `test_capture.hpp` for stdout capture and `TempDir` utilities).
141+
2. Declare the function in [applets.hpp](include/cfbox/applets.hpp).
142+
3. Add one entry to `APPLET_REGISTRY` in [applets.hpp](include/cfbox/applets.hpp).
143+
4. Add GTest unit tests in `tests/unit/test_<name>.cpp` (see [test_capture.hpp](tests/unit/test_capture.hpp) for stdout capture and `TempDir` utilities).
52144
5. Add shell integration tests in `tests/integration/test_<name>.sh` following the pattern in existing scripts.
53145

146+
> **Note:** The `init` applet is special — it runs as PID 1 in QEMU system-mode tests. Regular applets should not need special PID 1 handling.
147+
54148
## Submitting Changes
55149

56150
1. Fork the repository.

README.en.md

Lines changed: 48 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,18 @@
44

55
A minimalist BusyBox alternative written in modern C++23.
66

7+
[![CI](https://github.com/Awesome-Embedded-Learning-Studio/CFBox/actions/workflows/ci.yml/badge.svg)](https://github.com/Awesome-Embedded-Learning-Studio/CFBox/actions/workflows/ci.yml)
78
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
89
[![C++23](https://img.shields.io/badge/C++23-00599C?logo=cplusplus)](https://en.cppreference.com/w/cpp/23)
910
[![CMake](https://img.shields.io/badge/CMake-3.26+-064F8C?logo=cmake)](https://cmake.org/)
1011
[![Tests](https://img.shields.io/badge/Tests-124_passing-brightgreen)](tests/)
11-
[![Applets](https://img.shields.io/badge/Applets-16%2F16-brightgreen)](src/applets/)
12+
[![Applets](https://img.shields.io/badge/Applets-17-brightgreen)](src/applets/)
1213

1314
## Overview
1415

15-
CFBox is a single-executable Unix utility collection distributed via symbolic links. Each subcommand can be invoked either through `argv[0]` detection or explicit subcommand syntax.
16+
CFBox is a single-executable Unix utility collection distributed via symbolic links. All development is complete — 17 applets implemented and tested, with a CI pipeline covering native builds, cross-compilation, and QEMU user/system-mode testing across 5 stages.
1617

17-
**Design philosophy:**
18-
- **Simplicity first** — Get core functionality working before pursuing full POSIX compliance
19-
- **Modern C++** — Leverage C++23 features with `std::expected` for error handling
20-
- **Embedded-friendly** — Cross-compilation ready, minimal runtime dependencies
21-
22-
All 16 applets are implemented and tested.
18+
**Design philosophy:** Simplicity first — Modern C++ (`std::expected`) — Embedded-friendly (cross-compilation, static linking)
2319

2420
## Quick Start
2521

@@ -42,91 +38,86 @@ echo "Hello, World!" # now calls cfbox via symlink
4238

4339
## Supported Commands
4440

41+
### Text Processing
42+
4543
| Applet | Supported Flags / Features |
4644
|--------|----------------------------|
4745
| `echo` | `-n` (no trailing newline), `-e` (interpret escape sequences) |
4846
| `printf` | Format strings (`%s` `%d` `%f` `%c` `%%`), format reuse |
4947
| `cat` | `-n` (number lines), `-b` (number non-blank), `-A` (show non-printing), stdin passthrough |
5048
| `head` | `-n N` (first N lines), `-c N` (first N bytes), multi-file headers |
51-
| `tail` | `-n N` (last N lines), `-c N` (last N bytes), multi-file headers |
49+
| `tail` | `-n N` (last N lines), `-c N` (last N bytes), multi-file footers |
5250
| `wc` | `-l` (lines), `-w` (words), `-c` (bytes), `-m` (chars), multi-file totals |
5351
| `sort` | `-r` (reverse), `-n` (numeric), `-u` (unique), `-k N` (key field), multi-file merge |
5452
| `uniq` | `-c` (count), `-d` (duplicates only), `-u` (unique only), stdin support |
53+
| `grep` | `-E` (extended regex), `-i` (ignore case), `-v` (invert), `-n` (line numbers), `-r` (recursive), `-c` (count), `-l` (files with matches), `-q` (quiet) |
54+
| `sed` | `-n` (suppress auto-print), `-e SCRIPT`; substitution `s/pat/repl/[g\|p\|d]`, line addresses, ranges, `$` |
55+
56+
### File Operations
57+
58+
| Applet | Supported Flags / Features |
59+
|--------|----------------------------|
5560
| `mkdir` | `-p` (create parents), `-m MODE` (permissions) |
5661
| `rm` | `-r` (recursive), `-f` (force), `-i` (interactive), `/` safety check |
5762
| `cp` | `-r` (recursive), `-p` (preserve permissions), multi-file to directory |
5863
| `mv` | `-f` (force overwrite), cross-filesystem fallback (copy + remove) |
64+
65+
### Directory & Search
66+
67+
| Applet | Supported Flags / Features |
68+
|--------|----------------------------|
5969
| `ls` | `-a` (show hidden), `-l` (long format), `-h` (human-readable sizes) |
60-
| `grep` | `-E` (extended regex), `-i` (ignore case), `-v` (invert), `-n` (line numbers), `-r` (recursive), `-c` (count), `-l` (files with matches), `-q` (quiet) |
6170
| `find` | `-name PATTERN` (glob), `-type [f\|d\|l]`, `-maxdepth N`, `-exec CMD {} ;` |
62-
| `sed` | `-n` (suppress auto-print), `-e SCRIPT`; substitution `s/pat/repl/[g\|p\|d]`, line addresses, ranges, `$` |
71+
72+
### System
73+
74+
| Applet | Description |
75+
|--------|-------------|
76+
| `init` | System initialization — auto-mounts proc/sysfs/devtmpfs when PID 1, runs smoke tests, then powers off |
6377

6478
## Requirements
6579

6680
- **Compiler:** GCC 13+ / Clang 17+ (C++23 support required)
6781
- **CMake:** 3.26+
6882
- **Platform:** Linux (x86_64 / aarch64)
6983

70-
## Architecture
84+
## Documentation
7185

72-
**Dispatch mechanism:** `main.cpp` detects the invoked name via `argv[0]` (symlink detection) and falls back to subcommand syntax (`cfbox echo ...`). The `APPLET_REGISTRY` in [applets.hpp](include/cfbox/applets.hpp) is a `constexpr std::array` mapping names to entry functions.
73-
74-
**Core infrastructure:**
75-
76-
| Header | Purpose |
77-
|--------|---------|
78-
| [error.hpp](include/cfbox/error.hpp) | `std::expected<T, Error>` with `CFBOX_TRY` macro for error propagation |
79-
| [applet.hpp](include/cfbox/applet.hpp) | `AppEntry` struct and `find_applet()` lookup |
80-
| [args.hpp](include/cfbox/args.hpp) | CLI argument parser — short flags, flag values, `--` separator, positional args |
81-
| [io.hpp](include/cfbox/io.hpp) | File I/O helpers — `read_all`, `read_lines`, `read_all_stdin`, `write_all`, `split_lines` |
82-
| [fs_util.hpp](include/cfbox/fs_util.hpp) | Filesystem wrappers returning `Result<T>``exists`, `mkdir_recursive`, `copy_recursive`, `rename`, etc. |
83-
| [escape.hpp](include/cfbox/escape.hpp) | Escape sequence processing for `echo` / `printf` |
84-
85-
**Testing:** GTest unit tests via CPM fetch (108 cases); shell-based integration tests (16 scripts) comparing against GNU coreutils behavior.
86+
| Document | Description |
87+
|----------|-------------|
88+
| [Architecture & Design](document/architecture.md) | Dispatch mechanism, core infrastructure, error handling, testing |
89+
| [Cross-Compilation & Embedded](document/cross-compilation.md) | Toolchains, CMake options, build examples, binary sizes |
90+
| [QEMU Testing](document/qemu-testing.md) | User-mode / system-mode testing, init applet, kernel config |
91+
| [Continuous Integration](document/ci.md) | CI pipeline 5-stage overview |
92+
| [Contributing Guide](CONTRIBUTING.md) | Build, test, code style, submission |
8693

8794
## Project Structure
8895

8996
```
9097
cfbox/
9198
├── CMakeLists.txt
9299
├── cmake/
93-
│ ├── compile/CompilerFlag.cmake
94-
│ ├── third_party/CPM.cmake
95-
│ └── toolchain/ # cross-compilation toolchains (Phase 4)
96-
├── include/cfbox/
97-
│ ├── applet.hpp # AppEntry registry & lookup
98-
│ ├── applets.hpp # 16 applet declarations & APPLET_REGISTRY
99-
│ ├── args.hpp # CLI argument parser
100-
│ ├── error.hpp # std::expected<T, Error> & CFBOX_TRY
101-
│ ├── escape.hpp # escape sequence processor
102-
│ ├── fs_util.hpp # filesystem utility wrappers
103-
│ └── io.hpp # file I/O helpers
100+
│ ├── compile/CompilerFlag.cmake # Compiler warnings & optimization flags
101+
│ ├── third_party/CPM.cmake # CPM dependency manager
102+
│ └── toolchain/ # Cross-compilation toolchains
103+
├── configs/
104+
│ └── qemu-virt-aarch64.config # Minimal QEMU aarch64 kernel config
105+
├── document/ # Detailed documentation
106+
├── include/cfbox/ # Public headers
104107
├── src/
105-
│ ├── main.cpp # Dispatch entry (argv[0] + subcommand)
106-
│ └── applets/ # 16 command implementations
107-
│ ├── echo.cpp printf.cpp cat.cpp head.cpp
108-
│ ├── tail.cpp wc.cpp sort.cpp uniq.cpp
109-
│ ├── mkdir.cpp rm.cpp cp.cpp mv.cpp
110-
│ ├── ls.cpp grep.cpp find.cpp sed.cpp
108+
│ ├── main.cpp # Dispatch entry
109+
│ └── applets/ # 17 command implementations
111110
├── tests/
112-
│ ├── unit/ # GTest unit tests (108 cases)
113-
│ └── integration/ # Shell integration tests (16 scripts)
114-
├── scripts/
115-
│ └── gen_links.sh # Symlink installer
116-
├── .clang-format
117-
├── CONTRIBUTING.md
118-
├── LICENSE
119-
├── README.md
120-
└── ROADMAP.md
111+
│ ├── unit/ # GTest unit tests (108 cases)
112+
│ └── integration/ # Shell integration tests (16 scripts)
113+
├── scripts/ # Build, test, install scripts
114+
├── .github/workflows/ci.yml # CI pipeline
115+
└── CONTRIBUTING.md # Contributing guide
121116
```
122117

123-
## Development Status
124-
125-
All core applets implemented (Phase 0-3 complete). See [ROADMAP.md](ROADMAP.md) for remaining Phase 4 (cross-compilation) work.
126-
127118
## Contributing
128119

129-
See [CONTRIBUTING.md](CONTRIBUTING.md) for build instructions, coding conventions, and how to submit changes.
120+
See [CONTRIBUTING.md](CONTRIBUTING.md).
130121

131122
## License
132123

0 commit comments

Comments
 (0)