Open Source

Code in Motion

Build anything easily. Skip READMEs, manual toolchain setup and scattered configs. Share repos and stop re-downloading files. One tool does it all in a developer friendly way.

CiM demo
$cim list-targets
no-OS
optee-qemu-v8
u-boot
...
$cim init --install -t no-OS
Initializing...
Workspace ready
$cd ~/dsdk-no-OS
$make sdk-envsetup && make sdk-build

Setup and Build Software Shouldn't Be This Hard

Layers of tools, scripts, dedicated environments and tribal knowledge make setups fragile, onboarding slow and CI/CD inefficient. CiM makes project setup explicit, reproducible and automatable — without sacrificing developer experience.

😵‍💫

The Old Way

  • Copy-paste from outdated READMEs
  • Takes installed toolchains for granted
  • Scattered files everywhere
  • "Works on my machine"
  • Re-download files
  • Not AI/LLM ready (when GUI only)
  • Supports specific user cases
  • Release work is manual and takes time
  • Python workspace tooling requires virtual environments

The Code in Motion Way

  • Declared around standardized commands
  • Finds and installs the correct toolchain
  • Everything in one place
  • Reproducible builds
  • Clever caching
  • CLI based prepared for AI agents
  • Works with any type of project
  • Creates and pins new releases in minutes
  • Single executable binary

Four Commands to Build Anything

No complex configurations. No dependencies to manage. Just these four simple steps.

1

Discover

Find available build targets

cim list-targets
2

Initialize

Create a confined workspace

cim init <target>
3

Configure

Generate the build system

cim makefile
4

Build

Compile and test

make sdk-build

Under the Hood

How CiM orchestrates the build process from initialization to completion.

cim init cim install ... cim makefile sdk.yml toolchain config sdk.yml manifest build rules os-dependencies .yml Host packages Toolchains Cross-compilers python-dependencies .yaml Python packages Generated Makefile make sdk-build build/Makefile optional extra.mk optional project cmake workspace configure reads reads installs generates runs includes includes

Ready to Build?

Get CiM running in under 60 seconds. No complex setup required.

1

Download CiM

Grab the latest precompiled binary from GitHub releases for your platform.

View Releases →
2

Find a Manifest

Explore available build targets from the public manifest repository.

Browse Manifests →
3

Initialize & Build

Pick a target, initialize your workspace, and start building immediately.

Example Targets

🔧
no-OS Drivers without an OS
🔒
optee-qemu-v8 OP-TEE on QEMU ARMv8
u-boot Universal Boot Loader
bash
# List available targets
cim list-targets --source https://github.com/joabech/cim-manifests

# Initialize a workspace (use the same --source if needed)
cim init --install -t no-OS

# Generate makefile and build
cim makefile && make sdk-envsetup && make sdk-build

Common Questions

Everything you need to know about Code in Motion.

Are you tired of outdated build instructions and scattered configs that assume Ubuntu while you’re running Fedora or macOS? Do you find yourself hunting down equivalent packages just to get started? Or wondering where files will end up? Your workspace, /opt/, or /usr/...? And do build instructions sometimes assume you already have the required toolchains installed?

If any of this sounds familiar, CiM is worth a try.

In short, CiM offers:
- Frictionless, target-specific workspace creation.
- A standardized way to build default targets.
- Full control over files, remove a target workspace without leaving stray files behind.
CiM was created to address the growing complexity of building software today. Many existing tools are designed with a single community or a specific runtime in mind. CiM takes a different approach, it doesn’t mandate a target. A single CiM manifest can define standalone tools, as well as environments like Zephyr, Yocto, and Buildroot within the same project if you so wish.

CiM is inspired by several widely used tools, including Google’s repo, Zephyr’s west, Docker, Git, and Yocto. Each of these solves important problems, but also comes with limitations:
- repo – Excellent for managing large sets of independent repositories and supports mirroring well.
- west – Works great for MCU development, but is tightly coupled to the Zephyr ecosystem.
- Docker – Strong for sandboxing, packaging, and CI/CD workflows, but less convenient for developers who need to debug directly on their local machines.
- Yocto – Extremely powerful and capable of building almost anything, but highly complex, often involving hundreds of configuration files. Modifying source code typically requires separate tools (e.g., devtool) or patching recipes, which differs from the Git-based workflows most developers prefer.
- Git – The backbone of modern software development for nearly two decades. While features like submodules and worktrees are powerful, they don’t fully address issues like duplication and fragmentation across projects.

CiM builds on the strengths of these tools while aiming to reduce their complexity and limitations.
Not really. CiM’s primary role is to set up and manage your workspace. Once that’s done, you can work exactly as you normally would, using Git, your usual build commands and your preferred debugging tools.

Think of CiM as a setup and orchestration layer, not something that replaces your workflow.

For example, imagine your product consists of 50+ repositories. As a Linux kernel developer, you might normally clone only the kernel repository. However, that alone won’t include the other components, manifests, build tools, or test assets required to build and validate the full product.

If you use CiM to set up the workspace, everything is prepared for you. From there, you can jump into the kernel repository and work as usual. When you’re ready, you can run commands like make sdk-build or make sdk-test from the workspace to build and test the full product, including your changes.
Yes. CiM is command-line based, which makes it easy for agentic tools to interact with.

For developers working on CiM itself, there are prepared files designed for tools like Claude, Copilot, and similar assistants. These help with developing new features and debugging issues as they arise.

For CiM users, agentic workflows can be integrated directly into projects. Files such as CLAUDE.md (and similar) can be added to a manifest repository under a target and automatically copied into the workspace using the copy_files feature during workspace creation.

In short, CiM manifests can include tailored prompt files, making it easy to customize agent behavior for each specific project.
Core Concepts
A manifest primarily consists of three YAML files: sdk.yml, os-dependencies.yml, and python-dependencies.yml. These can be supplemented with additional files as needed for a given project.

The manifest defines the scope of a project or product, what source code is required, which toolchains are needed, how components are structured, and how the default build is initialized.

A manifest repository itself is simply a Git repository that contains one or more manifests for different targets. Because it’s just Git, you can create and organize as many as needed. For example, a company might maintain:
- An internal manifest repository for private projects
- A public repository for open-source use
- Separate repositories for specific customers or partners

Individual developers can also create and host their own manifest repositories.
CiM uses a default manifest source, but this can be changed. You can either update it via:
- cim config -e

Or specify a source directly when running commands, for example:
- cim list-targets --source https://...
- cim init --source https://...
When you run cim init, CiM creates a self-contained workspace directory that includes everything the project needs, source code, toolchains, dependencies and build artifacts. All operations are performed within this directory.

When you’re done, you can simply delete the workspace folder and your system returns to its original state, no lingering environment variables, no global installs, and no leftover files.

There are a couple of exceptions:
- Host dependencies are installed as OS-level packages
- Repository mirrors are stored outside the workspace (opt out possible)

For host dependencies, CiM will always present the list of required packages and ask for your approval before installing anything. Nothing is installed on your system without your consent.
Getting Started
Yes. You can either create a new target in an existing manifest repository or extend an existing target if your project fits within it. In that case, add support to get your source code and include the necessary build scripts and Makefiles.
Manifests are YAML files (sdk.yml) that define how to set up and build a target. They specify dependencies, environment variables, build commands, and more. Refer to the cim documentation for the full manifest schema and examples.

In short, if you contribute to an existing manifest repository, you need to create a new subfolder under the targets directory. Inside that folder, add the sdk.yml, os-dependencies.yml and python-dependencies.yml files. Once your build is working as expected, commit your changes and submit a pull request. After it is merged, your new target will be available for others to use.
Available targets depend on the manifest source you’re using. The public repository at cim-manifests includes targets such as No-OS, Jupiter-SDR, OP-TEE secure OS on QEMU, U-Boot, and more. This is a list that will continuously grow. You can also create and host your own manifests as needed (see the cim init --source flag).
Technical Details
The toolchain directive in sdk.yml has been tested with:
- GCC
- LLVM/Clang
- Rust

Support for additional toolchains can be added as needed.

If a toolchain isn’t directly supported, you can still use it by combining the copy_files and install directives in sdk.yml. This allows you to download or copy the toolchain into the workspace and then extract and set it up as required.
CiM runs on Linux (x86_64 and arm64), Windows and macOS. Whether a specific target runs on all of these operating systems depends on the source code used for that target and its ability to build and compile binaries in each environment.
The use of make and Makefile in CiM helps standardize high-level build targets and define the order in which components are built when necessary. For example, if you need to build Zephyr and Linux before flashing a device, this dependency can be defined in the sdk.yml using the depends_on node, which then generates the corresponding make dependencies.

The generated Makefile primarily acts as a wrapper that redirects calls to the appropriate build system used by the project, such as CMake, Ninja, Bazel, or West. Keeping the Makefile minimal and just redirect if possible is recommended.

If additional flags or complexity are needed to improve the user experience, you can either extend the Makefile or, preferably, place that complexity in a separate build.git repository. This keeps the manifest clean and maintainable. The OP-TEE manifest is a good example of this approach (see build.git)
Yes. While the mirror feature can save significant time and bandwidth by caching downloads, you can disable it if you prefer fresh downloads for every workspace.

See the documentation for the specific flag or configuration option to turn off mirroring.
Features & Scope
No. While workspace creation and building are core features, CiM also provides additional commands. Running CiM without arguments lists all available commands.

There is a release command that helps tag repositories and create pinned sdk.yml files, and a config command that allows users to customize their CiM setup. For projects using reStructuredText, CiM can collect all documentation into a temporary folder and start a local web server, making it easier to browse documentation and serve as a starting point for AI agents.

If a manifest tracks branches instead of pinned versions, you can use the update command to pull the latest changes. There is also an experimental docker command, though it is still under development and may be unstable. Additionally, the utils command provides tools such as updating the CiM binary and computing hashes for integrity checks.

In addition to individual commands, CiM offers many flags to refine behavior. For example, the --match flag can be used with init to create a workspace that includes only matching repositories.
Yes. CiM supports versioned targets using a simple branch naming convention. CiM uses the target name to discover available versions by matching Git branch names in the form <target>-<version>

For example, if you have a target named no-OS, you can create branches such as:
no-OS-v1.0, no-OS-v1.1, etc.

When you run:
cim list-targets -t no-OS

CiM looks for branches matching no-OS-* and lists the available versions.

As an example, try:
cim list-targets -t optee-qemu-v8 --source https://github.com/joabech/cim-manifests

Once you know the available versions, you can create a workspace for a specific version:
cim init -t optee-qemu-v8 -v optee-qemu-v8-v4.9.0

Using branches instead of tags provides greater flexibility: branches can be updated with hotfixes or security fixes without changing the version reference.
Licensing & Support
Yes, cim is open source and free to use. It’s released under a permissive license, allowing both personal and commercial use. Contributions are welcome!
Send issues, patches etc to the CiM git if it’s about the tool and send to the the manifest git in question is it is about a target.
Roadmap
CiM is still a young project, and there are many ideas and improvements in progress. A key focus is improving the dynamic nature of workspace creation. While this is relatively straightforward from a source code perspective, the main challenge lies in the build system.

CiM is designed to delegate builds to existing project build systems, which works well in simple cases. However, handling dependencies between multiple components within the same project introduces additional complexity. This may require features such as overlays, but the goal is to avoid recreating large, complex systems like Yocto or Buildroot.

There is also a tui branch in the CiM repository that may be of interest. Once it has matured, it will be merged into the main branch. Contributions are welcome, especially for users and developers interested in the TUI.
Copied to clipboard!