- Go 73.5%
- Zig 11.5%
- C++ 11%
- Makefile 2.1%
- CMake 1.9%
|
|
||
|---|---|---|
| TemplateCpp | rename build/stage/ to install/ | |
| TemplateHostCpp | Clean up the initial studio list ( #8 ) | |
| TemplateHostZig | Clean up the initial studio list ( #8 ) | |
| TemplateZig | zig-fmt-wrinkles pass on the zig code ( #7 ) | |
| tools | Sound and Texture | |
| .gitignore | Infinitely improve dependency workflow | |
| Makefile | Add Zig template host | |
| README.md | Fix Zig startup, use new StudiolaHost library | |
| TODO.md | Update docs | |
Studiola
Studiola is the tool chain and SDK for the Studiola ecosystem.
Studiola Introduction
At its root, a Studiola application is one created and specialized as a particular end point configuration, and can be specialized via selection of components, and creations of new ones into being a particular application.
For example, color management and image loading components may be selected to create an application that focusses on conceerns of color rendition of images.
The Studiola SDK (https://codeberg.org/meshula/Studiola.git) is a configuration program that provides management of an inventory a plugin components, and also has the ability to "stamp out" a shell application (e.g. ColorScienceApp), new Activities and Providers, and also aid with building and change management.
Applications that the SDK produces are thin, specifying configuration, performing start up intialization, and processing command line arguments; those concerns that are unique to every bespoke configuration.
This Framework
Studiola, the framework and SDK, organizes the workspace of a growing family of C++ and Zig based creative tool libraries, host applications, and plugins. The configuration tool fetches and orchestrates the builds of into a designated workspace under a single layout:
workspace/
├── Studiola/ this framework; it can be located outside the workspace as well
├── build/ each component's cmake build occurs here (see notes for zig)
├── install/ the runtime installation structure
│ ├── plugins/ runtime plugins for workspace applications
│ ├── include/ installed headers for all components and dependencies
│ ├── lib/ installed libraries for all components and dependencies
│ ├── bin/ runnable components and tools
├── {components} all the individual dependencies and "stamped" components.
...
├── Makefile build · install · launch
What's in the box
The Studiola ecosystem is layered into foundational components, always available, selected components, the host library, and applications.
Foundation libraries
- LabText — small text / s-expression parsing utilities.
- LabCamera — camera math and interactive camera controllers.
- LabGL — OpenGL / Metal rendering utilities and sample showcases.
- MeshulaLab — the Studiola host application (built as
Studiola). It provides the Studio / Activity / Provider architecture, the plugin loader, the CSP (ZeroMQ) transaction pump, ImGui-based UI, font and resource resolution, and a macOS.appbundle layout.
Optional components
- LabDb9 — graph database layer used by memex-style tools.
- LabLlama — llama.cpp wrapper exposing model hosting to the framework.
Host
- StudiolaHost - binds plugins, graphics backend, and UI system together.
Plugins
- StudiolaColor — color-science activities (spectral locus, Macbeth chart) and a ColorProvider.
- StudiolaEffekseer — Effekseer particle effects, packaged as an EffectStudio with its EffectViewer activity and provider.
- StudiolaMemex — a memex/knowledge-graph plugin backed by LabDb9 and LabLlama, aggregating several activities into a single plugin.
Applications
Applications are stamped out by the configuration utility. If your workspace is named pasta, the generated application will be named PastaApp. Once an application is generated, it servers as a seed for your bespoke application, and may be modified as needed.
Third-party libraries.
These are cloned into the workspace by the wizard or studiola-build --fetch whenever something depends on them. Such third party libraries
include:
llama.cpp— large language model runtime (required by LabLlama).oneTBB,OpenSubdiv,USD— the OpenUSD stack, for eventual StudiolaUSD plugin work. Built with a no-python, shared-libs recipe derived fromtinyusd/recipes/macos-dynamic-nopy(github: meshula/tinyusd).
Architecture
The host exposes a stable C descriptor ABI (LabGetPluginDescriptor)
that plugins implement. A plugin descriptor enumerates the studios,
activities, and providers it ships, plus factory functions to create and
destroy them. The host loads plugins by walking upward from the executable
looking for a sibling plugins/ directory — the same walk-up strategy is
used for resources/fonts/, so one convention handles the dev tree,
installed prefix, and .app bundle shapes uniformly. A Studio may
request activities it does not own (the host wires them up) and
instantiate the ones it does.
Quickstart
Requirements:
- macOS (arm64) — Linux/Windows support exists in the host but the orchestrator's current deployment story targets macOS.
- CMake ≥ 3.26, Ninja, a recent clang, git, Go 1.22+ (to build the orchestrator and the configure wizard).
This repository is a workspace manifest, not a monorepo. It contains
only the build orchestrator and docs. The actual component sources
(LabText, LabGL, MeshulaLab, StudiolaColor, ...) live in their own
upstream repos and are cloned into a workspace directory that you
choose — typically a sibling of this repo.
Cold-clone workflow:
git clone https://codeberg.org/meshula/Studiola.git
cd Studiola
# Build the Go tools (only when sources or the embedded registry change)
# and launch the configure wizard — a TUI for selecting components and
# picking a workspace directory. Plain `make` builds + prints help.
make configure
In the wizard:
| key | action |
|---|---|
[space] |
toggle a plugin |
[w] |
set the workspace directory (where repos clone to) |
[p] |
choose target platform (macos, ios, ios-simulator) |
[n] |
scaffold a new plugin (see below) |
[a] |
add a plugin from an external git URL |
[g] |
open the Sync panel (repo status · fetch/pull/push) |
[enter] |
provision the workspace and build |
When you press [enter], the wizard writes studiola-config.toml at the
workspace root, copies tools/ into the workspace, clones the selected
components, and runs the build. Plugins are installed into
<workspace>/install/plugins/ and the host is installed at
<workspace>/install/bin/Studiola.
To re-enter the wizard on an existing workspace, run the configurator with the saved config to prepopulate selections:
make build
build/bin/studiola-configure --config <workspace>/studiola-config.toml
Authoring a new plugin in the wizard
Press [n] to open the new-plugin form. Fill in:
- Plugin name — the on-disk directory and CMake target
(e.g.
StudiolaMyPlugin). - Component — the class prefix for the roles (e.g.
MyproducesMyProvider,MyActivity,MyStudio). - Roles — toggle Provider / Activity / Studio with
[space]. - Language — C++ or Zig (radio).
The right-hand panel previews exactly what will be scaffolded: the
classes that will be generated and the file list. Press [enter] to
create the plugin in the workspace. The wizard writes
CMakeLists.txt, studiola-plugin.toml, the role source files, and
a smoke test (or the Zig equivalents).
Offline workflow
The component registry lives at tools/studiola/registry.toml and is
embedded into the configure / build binaries (override with the
STUDIOLA_REGISTRY env var). Offline mode lets you build entirely
from a local mirror of every repo it lists.
- Press
[r]and point at a directory containing one clone per component, named to match the registry (LabText/,LabCamera/,MeshulaLab/, etc.). The path is recorded instudiola-config.tomlwhether or not offline mode is on, so the breadcrumb survives between sessions. - Press
[u]to open populate. The left panel shows the selected configuration; the right panel shows the git status of each repo in the offline root (✓up to date,↑nahead,↓nbehind,⇅diverged,✗missing,·no upstream / detached HEAD). [enter]clones missing repos from upstream and runsgit fetchon the rest, concurrently.[r]re-checks status without touching the network.- Press
[o]to toggle offline. While offline,[enter] installclones the workspace from your local mirror instead of upstream — no network required.
Repos cloned by populate use --depth 1 and the registered ref; if you
want full history, re-clone the offline mirror by hand and the wizard
will leave it alone.
Headless build (no wizard)
The orchestrator can also run standalone, the way the wizard does internally. It expects a workspace that already has components checked out:
cd <workspace>
./tools/studiola-build/studiola-build --fetch # clone what's missing
./tools/studiola-build/studiola-build # build everything
./install/bin/Studiola # run the host
--fetch honours the same registry as the wizard. Other useful flags:
./tools/studiola-build/studiola-build --list # show plan
./tools/studiola-build/studiola-build --plugins X,Y # subset build
./tools/studiola-build/studiola-build --dry-run # print, don't run
./tools/studiola-build/studiola-build --clean # wipe build/ + install/
./tools/studiola-build/studiola-build --bundle # inject into .app
Per-component build directories live side-by-side under build/; the
shared install prefix is install/ (a peer of build/, not nested
inside it). Foundations install their exports into
install/lib/cmake/<Package>/ so downstream find_package calls
resolve against the workspace install, not against any system prefix.
The orchestrator passes CMAKE_PREFIX_PATH=<install> on every
configure to enforce that. Cross-compiled builds get suffixed
sibling prefixes (e.g. install-ios-simulator/).
Authoring a plugin by hand
The wizard's [n] flow above is the path of least resistance. If you'd
rather hand-roll a plugin (or you're integrating a pre-existing repo),
drop a studiola-plugin.toml next to your CMakeLists.txt:
name = "StudiolaYourPlugin"
kind = "plugin"
depends = ["LabGL", "MeshulaLab"]
[build]
system = "cmake"
[build.cmake]
generator = "Ninja"
config = "Release"
[install]
artifacts = ["lib/**"]
bundle_subdir = "Contents/PlugIns/StudiolaYourPlugin"
Implement LabGetPluginDescriptor in your plugin (see StudiolaColor or
StudiolaEffekseer for worked examples). The orchestrator will discover
the plugin on its next run. No bookkeeping anywhere else in the workspace
is needed.
Acknowledgments
The fetched third-party components retain their own licenses and remain
owned by their upstream projects. Studiola's own code is licensed
per-repository — see each component's LICENSE file.