Skip to content
Agentmart
Submit a tool

nim-c-bindings

Bind C libraries to Nim and make them build reliably across Linux, macOS, and Windows, including headers, types, linking, shared-library loading, and…

Skill by Vyrnexis

IndexedMIT★ 4
Write a review

Chalk Labs

Need help deploying nim-c-bindings?

Chalk Labs sets up agents like this inside real teams: connected to your tools, tested on your data, with a human in the loop where it matters.

Book a call

Install

Works with Claude Code, Claude apps, Codex, Cursor, Gemini CLI, GitHub Copilot, VS Code, OpenCode, Goose, Windsurf. Read the repository before you give any tool access to your data.

npx agentmarket install skill/vyrnexis-nim-c-bindings

Asks which of your tools to add it to (Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI, Claude Desktop) and shows the change first. See https://agentmart.dev/cli.

Get the weekly diff

The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.

We use your email only for this newsletter. Privacy

About

Bind C libraries to Nim and make them build reliably across Linux, macOS, and Windows, including headers, types, linking, shared-library loading, and CI/release workflows. Use when wrapping a C dependency, fixing Nim FFI build issues, or setting up cross-platform GitHub Actions for a Nim native library project.

Use cases: devops

No reviews yet. Installed it? Reviews come from verified installers only. How reviews work

Permissions

What this skill can do and what it asks for, from its SKILL.md. Checked Oct 25, 2026.

Tools
No tools found
Secrets
None asked for
Install scripts
None found

Network hosts it talks to 1

  • codeload.github.com · found in install command

Files it touches

  • ~/.claude/skills/nim-c-bindings

What's inside

Skill name
nim-c-bindings
Description
Bind C libraries to Nim and make them build reliably across Linux, macOS, and Windows, including headers, types, linking, shared-library loading, and CI/release workflows. Use when wrapping a C dependency, fixing Nim FFI build issues, or setting up cross-platform GitHub Actions for a Nim native library project.
License
MIT
Instructions
97 lines in SKILL.md · view on GitHub

Files (4)

  • SKILL.md
  • ci.yml · references/
  • raw_binding.md · references/
  • release.yml · references/

SKILL.md (first lines)

# Nim C Bindings & CI

## Rules

### Binding Fundamentals

- Use `importc` with `cdecl` for C APIs unless the library explicitly requires a different calling convention (e.g., `stdcall`).
- Represent opaque C handles as `type Name = ptr object` types. Use `incompleteStruct` for partial/opaque structs to avoid size/layout mismatches.
- Use `{.bycopy.}` on structs that Nim must pass by value to C.
- Declare the C header in the binding when the compiler needs the C definitions for compilation, for example `header: "foo.h"`.
- Use `{.push callconv: cdecl, importc.}` blocks when many declarations share the same convention.
- Match C storage with Nim's C-compatible types such as `cint`, `cuint`,
  `clong`, `culong`, `clonglong`, `csize_t`, `cfloat`, `cdouble`, `cstring`,
  and pointer types.
- Preserve the complete field order for concrete structs passed or returned by
  value.
- When the requested deliverable is a raw binding, import C symbols directly.
  Put ergonomic aliases and conversions in a separate wrapper layer.

### Linking

- **System libraries**: link with `-l<name>` only. Do not hardcode `-L` paths — the OS toolchain already knows where system libs live.
- **Local/third-party libraries**: add both `-L<dir>` and `-l<name>` (or `.lib`/`.dll.lib` paths on Windows MSVC).
- Use repository-relative paths for vendored dependencies, for example `third_party/libfoo`, to keep builds hermetic.
- Distinguish linker-resolved imports from Nim runtime `dynlib` imports.
  `header` supplies declarations for generated C; a runtime-only `dynlib` proc
  should not also use `header`.

### Runtime Library Resolution

- **Vendored/local shared libs**: colocate the `.so`/`.dylib`/`.dll` next to the executable. Do not rely on environment variables for discovery.
- **System-installed libs**: do not copy DLLs/shared libs next to the executable. Rely on the platform's normal system loader configuration. Use environment variables only as temporary overrides.
- On Linux, add rpath `$ORIGIN` only when loading colocated shared libs. From the shell, pass `--passL:"-Wl,-rpath,\$ORIGIN"`. In Nim source, use `{.passL: "-Wl,-rpath,\\$ORIGIN".}`.
- Do not use build-tree-only rpaths or absolute paths to non-system shared libraries.

### Platform Rules

| Platform | Toolchain | Deps | Link flags | Runtime |
|----------|-----------|------|------------|---------|
| Linux | System GCC/Clang | apt | `-l<name>` or `-L<dir> -l<name>` | Colocate local `.so`; rpath `$ORIGIN` if needed |
| macOS | Apple Clang | Homebrew | `staticExec("brew --prefix")` for `-I`/`-L` | Colocate local `.dylib` |
| Windows | MSVC (`--cc:vcc`) | vcpkg only | `.lib`/`.dll.lib` full paths | Colocate `.dll` next to `.exe` |

- On macOS, resolve include/link paths via `staticExec("brew --prefix <formula>")`.
- On Windows, use MSVC via `--cc:vcc`. Use vcpkg only — avoid Chocolatey and MSYS2. Never mix toolchains.
- On Windows, do not rely on implicit `-l<name>` for MSVC. Use explicit `.lib` or `.dll.lib` paths.
- On Windows CI, export `VCPKG_ROOT` to the installed triplet root and prepend its `bin` to `PATH`.

### CI & Release

- CI is the authoritative spec for supported platforms, toolchains, and flags. Local workflows must be compatible with CI.
- Keep test builds simple: compile, then run, with minimal environment mutation.
- Align the local toolchain with CI (e.g., MSVC + vcpkg `x64-windows-release` with `--cc:vcc`).
- Use the reference workflows as starting points — `references/ci.yml` for validation, `references/release.yml` for tagged releases.

### Verification

- Compile against the real header and call the real C implementation.
- Exercise concrete structs passed and returned by value. Compare Nim layout
  with C `sizeof` and `offsetof` probes when layout is in doubt.
- Test bundled shared libraries after copying the executable and library into
  a clean directory.
- For `dynlib`, verify runtime loading without also linking that library.

## Workflow

1. **Identify the C API.** Determine calling convention, opaque vs value types, and ownership.
2. **Write bindings.** Use `importc`, correct calling convention, `incompleteStruct` for opaque types, `bycopy` for value types. Add `header` pragma.
3. **Set up linking.** System libs: `-l` only. Local libs: `-L` + `-l` with repo-relative paths. Windows: explicit `.lib` paths.
4. **Handle runtime.** Colocate local shared libs. For system-installed libs, rely on the normal loader search path. Add rpath `$ORIGIN` on Linux only for colocated local libs.
5. **Verify the ABI.** Run a real C round trip for the types and calls used by
   the binding.
6. **Add CI.** Copy `references/ci.yml`, adapt placeholders (`<package>`, `<src/main.nim>`, dependency lists).
7. **Add release.** Copy `references/release.yml`, adapt placeholders, configure draft releases.
8. **Test locally, then push.** Verify the build works locally with the same flags CI uses.

## Common Mistakes

| Mistake | Why it's wrong |
|---------|----------------|
| Hardcoding `-L` paths for system libraries | OS toolchain already knows where they are; breaks portability |
| Mixing MSVC + MSYS2/MinGW on Windows | Incompatible ABIs, linker errors, runtime crashes |
| Using implicit `-l<name>` with MSVC | MSVC doesn't resolve libs the same way GCC does; use explicit `.lib` paths |
| Relying on env vars for vendored shared libs | Fragile across machines; colocate instead |
| Build-tree-only rpaths | Breaks when the binary moves; use `$ORIGIN` for colocated libs |
| Guessing Windows dependency paths | Non-deterministic; use vcpkg with known install roots |
| Compiling C sources into the executable when the task requires an existing shared library | Bypasses shared-library link and relocation behavior |
| Adding Nim-bodied wrappers to a requested raw binding surface | Hides whether the C API was imported directly and changes the requested layer |

## References

- `references/raw_binding.md` — Mapping an opaque handle and by-value C struct.
- `references/ci.yml` — Building a C-dependent project on Linux, macOS, and Windows with Nim,
  Atlas, and vcpkg.
- `references/release.yml` — Publishing tagged cross-platform archives in a draft release.

From Vyrnexis/nim-agent-template, MIT.

More from Vyrnexis/nim-agent-template

Signals

Stars
4
Forks
2
Open issues
0
Last commit (this folder)
Aug 20, 2026 (2 months ago)

From GitHub (fetched Oct 24, 2026).

Details

License
MIT
First seen
Oct 24, 2026
Last checked
Oct 24, 2026

More from Vyrnexis

Done for you

Rather not set it up yourself?

Chalk Labs scopes, builds and runs agents for your team: the task audit, the eval harness, the integrations and the weekly ops report. Fixed scope, priced before we start.

See how we build AI agents →Read the case studies

Chalk Labs is a two-founder AI and growth studio. We build AI agents, CRMs and MVPs for Web3 and AI companies, and have shipped 50+ product and token launches.

launches shipped
50+
launches shipped
media placements
500+
media placements
founders on every account
2
founders on every account

Press we've placed: Forbes · CoinDesk · Decrypt · Cointelegraph · The Block

Rahil Jain, Co-founder, Chalk Labs. Ex-Goldman Sachs engineer. You talk to the person who builds it.

Get nim-c-bindings running in your business

Tell us what you want to automate. A founder replies within one working day with a plan, not a pitch deck.

Goes to the Chalk Labs founders, not the newsletter. Privacy

Need help deploying nim-c-bindings?

CallGet help
Cite this page

nim-c-bindings skill. Agent Mart. https://agentmart.dev/skills/vyrnexis-nim-c-bindings (last updated 2026-10-24)