Skip to content

Instantly share code, notes, and snippets.

@planetis-m
Last active February 2, 2026 16:00
Show Gist options
  • Select an option

  • Save planetis-m/cb61aafb71893ded1385e441f1b14574 to your computer and use it in GitHub Desktop.

Select an option

Save planetis-m/cb61aafb71893ded1385e441f1b14574 to your computer and use it in GitHub Desktop.

Read the SPEC.md document to understand the intended behavior and scope of the application. Based on this, identify only the libcurl functions, structs, constants, and enums required to implement minimal Nim bindings sufficient for the application to work.

You are provided with a curl_temp/ directory containing libcurl header files for reference only. Use these headers to:

  • Verify enum values and constants
  • Avoid deprecated APIs
  • Ensure correctness and completeness

Do not invent enum values or constants — always confirm them directly from the headers. Despite using curl_temp/ for reference, the bindings must link against the system-installed libcurl, not the temporary headers.

Follow the style and patterns used by existing bindings in src/pdfocr/wrappers/. All passC and passL directives must be added to src/config.nims, using the same conventions already present.

Additionally:

  • Create an appropriate test file under tests/
  • Ensure .github/workflows/ci.yml runs successfully on macOS, Windows, and Linux
  • Consult SKILLS.md for required design decisions, constraints, and common pitfalls to avoid when writing bindings

You may freely experiment and make commits to the repository. For every commit, clearly explain:

  • What problem was addressed
  • Why the change was necessary
  • How it resolves the issue (especially in response to CI failures)

The CI output will be shared with you after each run and should directly inform your next changes.

Good luck.

You are an AI coding agent responsible for producing a SKILLS.md file for a Nim repository that provides bindings to C libraries.

Your task is to analyze the repository’s evolution and extract authoritative, platform-specific rules for successfully creating and maintaining C bindings in Nim.


Inputs to Analyze

  • The complete git commit history (including failed attempts and subsequent fixes)
  • config.nims
  • CI.yml

Core Objective

Generate a short, concise, and prescriptive SKILLS.md intended for AI coding agents. The document must encode hard constraints, required workflows, and known failure modes discovered through the repository’s history.

This is not a tutorial. It is an operational rulebook.


Critical Interpretation Rules

  • Do not assume CI always passes. CI failures in earlier commits represent incorrect approaches and must be treated as negative examples.
  • The final state of the repository is the reference point. Only workflows consistent with the final, passing CI configuration should be endorsed.
  • Any reverted, removed, or explicitly “fixed” approach must be documented as something to avoid.

Platform Coverage (Mandatory)

You must provide explicit, separate instructions for:

  • Linux
  • macOS
  • Windows

Each platform section must clearly define:

  • Supported compilers and toolchains
  • Required linker and compiler flags
  • Known incompatible environments

Example (Windows):

  • ❌ Do not use MSYS2 — it does not work with Nim
  • ✅ Use the preinstalled MinGW64 toolchain

These rules must be justified by commit history or configuration changes.


Required Content Sections

  1. Do’s and Don’ts from Commit History

    • Extract rules from commits that:

      • Remove tools or approaches
      • Fix build or runtime failures
      • Modify CI configuration
    • Convert these into explicit constraints for agents

  2. Correct Nim ↔ C Binding Workflow

    • Header inclusion strategy
    • ABI and calling convention requirements
    • Use of --passC and --passL
    • Static vs shared library expectations
    • Naming and symbol visibility conventions
  3. Runtime and Portability Assumptions

    • Assume shared libraries are copied into the same directory as the executable

    • Document required runtime linker configuration, for example:

      • Linux:

        --passL:"-Wl,-rpath,\$ORIGIN"
        
  4. CI-Driven Constraints

    • Treat CI.yml as the authoritative specification of:

      • Supported platforms
      • Supported compilers
      • Required flags and environment assumptions
    • Any approach not compatible with CI must be explicitly disallowed


Output Constraints

  • Output only the contents of SKILLS.md
  • Use concise, imperative language
  • Prefer bullet points over prose
  • No speculation or general advice
  • Every rule must be traceable to commits or configuration
  • Optimize for repeatable success by autonomous AI agents

End Goal

Encode the repository’s accumulated knowledge so that an AI agent can:

  • Avoid previously failed approaches
  • Produce correct and portable C bindings in Nim
  • Reach a build state consistent with the repository’s final, passing CI configuration

Nim ↔ C Bindings — Operational Rules

Scope

  • This is a prescriptive rulebook for building Nim bindings to C libraries across Linux, macOS, and Windows.
  • Use it as a checklist for reliable CI builds and portable runtime behavior.

Core Workflow (Binding + Build)

  • Use importc with callconv: cdecl for C APIs unless the library explicitly uses a different calling convention.
  • Represent opaque C handles as distinct pointer types in Nim.
  • For partial or opaque C structs, use incompleteStruct to avoid size/layout mismatches.
  • For value structs that Nim must pass by value, use bycopy.
  • Declare the C header in the binding (header: "<...>") when the compiler needs definitions.

System vs Local/Third-Party Libraries

  • System libraries:
    • Link with -l<name> only; do not hardcode -L paths when the OS toolchain can locate them.
  • Local/third-party libraries (vendored or downloaded):
    • Add -L<dir> plus -l<name> (or the platform import library on Windows).
    • Use repository-relative paths (e.g., third_party/...) to keep builds hermetic.

Runtime and Portability Assumptions

  • For local/third-party libs (e.g., PDFium), colocate the shared library next to the executable at runtime.
  • For system-installed libs (e.g., curl), do not copy DLLs; rely on environment variables (LD_LIBRARY_PATH, DYLD_LIBRARY_PATH, PATH) for runtime resolution.
  • On Linux, add rpath only for tests/apps that load colocated shared libs:
    • --passL:"-Wl,-rpath,\\$ORIGIN"

CI-Driven Constraints (Generalized)

  • Treat CI as the authoritative spec for supported platforms, toolchains, and flags.
  • Any local workflow not compatible with CI is disallowed.
  • Keep test builds simple and reproducible: compile, then run, with minimal environment mutation.

Platform-Specific Rules

Linux

  • Toolchain: system GCC/Clang on the CI image.
  • System deps: install via the OS package manager.
  • Link flags (typical):
    • --passL:"-l<systemlib>"
    • --passL:"-L<local_lib_dir> -l<locallib>"
  • Runtime: copy local shared libraries next to the executable when used.
  • Incompatible: rpath pointing to build-tree-only locations.

macOS

  • Toolchain: Apple Clang on the CI image.
  • System deps: install via the platform’s package manager (e.g., Homebrew).
  • Include/link flags (typical):
    • --passC:"-I" & staticExec("<pkg-manager> --prefix <formula>") & "/include"
    • --passL:"-L" & staticExec("<pkg-manager> --prefix <formula>") & "/lib"
    • --passL:"-l<systemlib>"
    • --passL:"-L<local_lib_dir> -l<locallib>"
  • Runtime: copy local shared libraries next to the executable.
  • Incompatible: relying on DYLD_LIBRARY_PATH or full-path linking to a .dylib.

Windows

  • Toolchain: MinGW64 as used by Nim on CI.
  • System deps: install via a package manager (e.g., Chocolatey) with fixed install roots.
  • Include/link flags (typical):
    • --passC:"-I<dep_root>/include"
    • --passL:"-L<dep_root>/lib"
    • --passL:"-l<systemlib>"
    • --passL:"<local_lib_dir>/<name>.dll.lib" (for DLL import libraries)
  • Runtime: copy required .dll files next to the executable.
  • Incompatible: MSYS2 toolchains or guessing dependency paths.

How to Locate Include/Lib Directories

  • Use explicit, deterministic paths:
    • Linux: package manager default locations (/usr/include, /usr/lib) via toolchain search.
    • macOS: resolve prefixes via staticExec("<pkg-manager> --prefix <formula>").
  • Windows: use the known install root from the package manager (avoid probing PATH).
  • For vendored libs, always prefer repository-relative paths under third_party/.

Anti-Patterns

  • Embedding -l<name> inside -L... strings.
  • Relying on environment variables for runtime library discovery.
  • Using build-tree-only rpaths or absolute paths to shared libraries.
@planetis-m
Copy link
Author

keep working on this: codex resume 019c1e62-2899-7032-a5e6-bcbc905ee2bf

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment