What is Smidr?
Smidr is a cargo-inspired build tool for C and C++. Instead of hand-writing a Makefile or a CMakeLists.txt, you describe your project in one Smidr.toml file, and Smidr scaffolds it, compiles it, resolves its dependencies, and links it - across binaries, static libraries, and shared libraries.
It's not a replacement for CMake or Meson in large, established codebases - it's for the everyday case: you want to start a C/C++ project, add a couple of libraries, and build it, without maintaining a build script by hand.
Why
- One command to start:
smidr newscaffolds a working project, no boilerplate to copy - Dependencies without ceremony: a system library, a local project, or a git repository are all just an entry in
[dependencies] - Not tied to one compiler: works with
clang,gcc, ortcc, on Linux, macOS, or Windows (with MinGW/Clang) - Bridges other build systems: a dependency that itself uses CMake or Meson is built through Smidr transparently
- Plain TOML, not a scripting language:
Smidr.tomlis data, not a program to debug
Quick start (1 minute)
$ smidr run
Using compiler: clang
Running: target/debug/bin/hello
Hello, World!
That's it - smidr new scaffolds a project, smidr run compiles and executes it.
Installation
Requires Rust 1.85 or newer (Smidr uses the 2024 edition). Tested with Rust 1.96.0.
Or build from source:
Linux / macOS
Just needs a C/C++ compiler already on your system - clang, gcc, or tcc. Most Linux distributions and macOS (via Xcode Command Line Tools) already have one.
Windows
Smidr itself runs natively on Windows, but it needs a GCC or Clang toolchain in PATH to actually compile anything - Windows has no compiler out of the box.
The simplest way to get one:
- Install MSYS2
- Open the MSYS2 MinGW 64-bit terminal and run:
pacman -S mingw-w64-x86_64-gcc - Add
C:\msys64\mingw64\binto your systemPATH - Open a new terminal and confirm with
gcc --version
Binaries are written as .exe, static libraries as .lib, and shared libraries as .dll automatically. Native MSVC (cl.exe) support isn't implemented yet - see the Roadmap.
Usage
smidr new hello scaffolds:
hello/
├── Smidr.toml
├── .gitignore
├── include/
└── src/
└── main.c
Commands
| Command | Description |
|---|---|
smidr new <name> |
Scaffold a new project (--lib, --type dynamic, --std <standard>) |
smidr build |
Compile the project (--release, --verbose, --dry-run) |
smidr run |
Compile and run the resulting binary |
smidr rebuild |
Clean, then compile from scratch |
smidr clean |
Remove the target/ build directory |
smidr fmt |
Format source and header files with clang-format |
smidr lint |
Check source files for syntax errors without compiling |
smidr add <name> |
Add a dependency to Smidr.toml |
smidr rm <name> |
Remove a dependency from Smidr.toml |
smidr update |
Update Smidr itself to the latest version |
Configuration
[]
= "hello"
= "0.1.0"
= "bin" # bin | static | dynamic
= "c" # c | cpp
= "c17"
[]
= "auto" # auto | clang | tcc | gcc
= []
= []
= []
[]
= "1.3" # system library
= { = "https://github.com/raysan5/raylib" } # git, latest stable tag
= { = "../mymath" } # local project
Dependencies
A dependency can come from three places:
- A version string (
zlib = "1.3") - resolved from a local header search, thenpkg-config path- a local directory. If it has its ownSmidr.toml, it's built recursively with Smidr; otherwise Smidr detects and drives its CMake/Meson/Make buildgit- cloned at a pinnedtag, or the latest stable release tag if none is given, then resolved the same way aspath
build_system = "custom"runs arbitrary shell commands frombuild_commandsinSmidr.toml. Only use aSmidr.tomlfrom a source you trust, the same way you would with any shell script.
Workspaces
A Smidr.toml can also organize several projects:
[]
= ["core", "app"]
This works whether or not the root itself has a [project] section - a pure organizational root just builds its members; a root with its own [project] builds itself too.
Custom source directories
[]
= "sources" # override the default "src"
= "headers" # override the default "include"
= "core" # any extra name compiles alongside src_dir
= "platform"
Examples
- Ricochet - a DVD-logo-style terminal screensaver, built entirely with Smidr using only the C standard library. (Ricochet was built with Smidr 0.1.0.)
FAQ / Troubleshooting
Error: Compiler 'clang, tcc, cc, gcc' not found.
No C/C++ compiler is on your PATH. On Linux/macOS, install one via your package manager (apt install clang, xcode-select --install, etc.). On Windows, see Installation.
Error: Dependency '<name>' failed: not found locally or via pkg-config
The system library isn't installed, or has no pkg-config entry. Install it via your package manager, or use a path/git dependency instead.
cannot build: Smidr.toml has no [project] section (this is a workspace root)
You ran smidr run from a workspace root that only organizes other projects. Run from inside a specific member directory instead.
No .h files found in include/
A static or dynamic library project needs at least one header in include/ (or your [paths] include directory) - otherwise nothing else can use it.
A path/git dependency isn't being picked up.
Check that its Smidr.toml is valid on its own (cd into it and run smidr build directly) - a broken dependency manifest fails the same way a broken top-level one would.
How do I pass custom CMake flags?
The built-in build_system = "cmake" uses fixed flags. For custom -D... options, use build_system = "custom" with your own build_commands and $SMIDR_PREFIX.
Does smidr lint work without a full build?
Yes. It runs clang/clang++ -fsyntax-only and does not produce binaries.
Roadmap
- Project scaffolding, compiler-agnostic builds (clang, tcc, gcc)
- C++ support (compiler selection, standards, scaffolding)
- System,
path, andgitdependencies; CMake/Meson/Make bridging - Workspaces, custom source directories, build profiles
- Windows support via MinGW/Clang
- Native MSVC support
- A modular system for optional, downloadable capabilities (e.g.
smidr module add <name>) for things like kernel/bare-metal targets, kept out of the base install
Contributing
This project is in early development, maintained alongside my studies - response to issues and pull requests can be slow at times (exam periods especially). See CONTRIBUTING.md for what to do in the meantime if you run into a bug and don't hear back right away. Issues and pull requests are welcome regardless - for larger changes, open an issue first to discuss the approach.
Security
Please do not open a public issue for security vulnerabilities - see SECURITY.md for how to report them privately.
License
Licensed under either of
- Apache License, Version 2.0 (LICENSE-APACHE)
- MIT license (LICENSE-MIT)
at your option.
Contribution
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.