Imported from sailfishos-mirror/swig (
AGENTS.md). Install upstream withnpx skills add sailfishos-mirror/swig. Copyright stays with the author.
AGENTS.md
This file provides guidance to AI agents such as Claude Code (claude.ai/code) when working with code in this repository.
Project skill files - read these first
A number of short SKILL.md files under .agents/skills/ are the canonical references for the most common tasks an AI agent performs in this repo. Open the matching file before improvising; each is one or two pages and contains the specific commands, flags, and conventions that AGENTS.md only summarises:
.agents/skills/swig-test/SKILL.md— the canonical way to run the test suite for a target language and individual test cases. Read before running any test..agents/skills/swig-debug/SKILL.md— debugging the SWIG compiler: full-debug-*flag list, parse tree dumps (text and XML),SWIG_FEATURESenv var, gdb with theswigprint/locswigprinthelpers fromTools/swig.gdb, valgrind viaSWIGTOOL/RUNTOOL,DOH_DEBUG_MEMORY_POOLSfor memory corruption diagnosis, and a pointer toDoc/Manual/Extending.html§40.12 as the per node attribute reference. Read before any non-trivial parse tree inspection or compiler debugging..agents/skills/swig-doc/SKILL.md— editing chapters underDoc/Manual/: heading anchor conventions, the four content<div>classes (code/targetlang/shell/diagram), cross document anchored links, and themake maketoc checkcycle. Read before any change toDoc/Manual/*.html..agents/skills/swig-conventions/SKILL.md— source and contribution conventions: clang-format / code formatting, C/C++ comment style (quote tokens with'/"not backticks, comment widths, function header blocks),parser.ynew-code rules, commit message style, hyphenation, and theAssisted-by:AI-assistance disclosure trailer. Read before writing or editingSource/orLib/code, comments, or commit messages..agents/skills/swig-ci-repro/SKILL.md— reproducing a GitHub Actions Linux CI failure locally when it does not happen on your machine: a podman/docker image (Tools/ci-repro/) that mirrors theubuntu-22.04runner by reusing the realTools/CI-linux-*.shinstall scripts, theTools/ci-repro/run.shhelper, theactfallback, and a worked Ruby 3.3 example. Read before chasing a failure that only shows up in CI.
.github/skills/ (GitHub Copilot's discovery path) and .claude/skills/ (Claude Code's discovery path) hold tracked symlinks that point at the same files, so each tool's auto discovery works without duplicating content. On Windows a contributor needs git config --global core.symlinks true for the symlinks to materialise as real links rather than text files.
What is SWIG
SWIG is a compiler that reads C/C++ header files and interface files (.i) and generates wrapper code that makes C/C++ libraries accessible from other languages: Python, Java, C#, Go, Ruby, Perl, PHP, Lua, Tcl, R, Guile, D, Octave, Scilab, OCaml, and XML output.
Project home: https://www.swig.org
Build
SWIG uses GNU Autotools. Building from a git checkout requires extra steps vs. a release tarball (see https://swig.org/svn.html):
./autogen.sh # generate configure (git checkout only)
./configure
make
Key configure options:
--prefix=/path— install location--without-pcre— disable PCRE2 dependency
The built executable is ./swig at the repo root. The test suite and examples invoke ./preinst-swig instead — a thin wrapper that sets SWIG_LIB=./Lib so tests run against the just-built binary without needing make install.
A CMakeLists.txt is also provided as an alternative build system, but Autotools is the primary path used by CI and the test suite.
CCache/ builds ccache-swig (a SWIG-specific ccache fork). It's built by default; make check runs check-ccache as part of the suite.
Testing
make -k check # full test suite, keep going on errors
make check-python-test-suite # all tests for one language
make -j8 check-java-test-suite # parallel execution
cd Examples/test-suite/python
make -s ret_by_value.cpptest # single C++ test (silent)
make -s ret_by_value.ctest # single C test
make -s ret_by_value.multicpptest # single multi module test
make -s ret_by_value.clean # clean generated files
Test suffixes match source type: .cpptest (C++), .ctest (C), .multicpptest (multiple C++ modules).
Available language test targets: c, csharp, d, go, guile, java, javascript, lua, ocaml, octave, perl5, php, python, r, ruby, scilab, tcl.
Bug fixes and new features should ideally land with a regression test in the test suite.
Test cases live in Examples/test-suite/<language>/. Each test consists of a .i interface file in Examples/test-suite/ (shared across all languages) and an optional <testname>_runme.<ext> script in the language subdirectory. The .i file drives wrapper generation/compilation; the runme exercises the wrapped code at runtime — language-specific behavior belongs in the runme, not the shared .i.
Keep comments in test cases brief. Do not add long or obvious comments; prefer a single concise line over a multi-line explanation (for example, a compiler workaround note should be one line, not a paragraph).
Test names that start with a cpp{NN}_ prefix (e.g. cpp11_, cpp17_, cpp20_) track the C++ standard that introduced the grammar / language feature being exercised, not the standard the example code happens to target. A using-declaration pack expansion is C++17 grammar, so it goes under cpp17_* even if the canonical use site is a C++20 lambda; a constrained lambda's grammar is C++20, so it goes under cpp20_* even if its body is plain C++11. When in doubt, pick the prefix matching the oldest standard that accepts the feature in isolation. Each prefix is also a CPP{NN}_TEST_CASES bucket in Examples/test-suite/common.mk - register new tests in the bucket that matches the prefix.
The shared test makefile is Examples/test-suite/common.mk (included by each per-language Makefile). New tests are typically added to common.mk in the appropriate *_TESTCASES variable.
Python runmes must never use the assert statement - python3 -O strips asserts and the test would silently pass on a regression. Use the helpers in Examples/test-suite/python/swig_test_utils.py instead: swig_check(lhs, rhs) for equality checks (prints both values on failure), swig_assert(condition, msg) for arbitrary conditions, and swig_assert_raises(exc_cls) as a context manager for expected exceptions.
For test suite procedures (per language, single test, parallel runs, valgrind/gdb hooks via SWIGTOOL / RUNTOOL), use .agents/skills/swig-test/SKILL.md as the canonical reference rather than improvising from this summary.
Architecture
SWIG processes input in this pipeline:
- Preprocessor (
Source/Preprocessor/) — C preprocessor pass over.iand header files - Scanner (
Source/Swig/scanner.c) — lexical analysis - Parser (
Source/CParse/parser.y) — Bison grammar producing a parse tree (DOH nodes) - Type system (
Source/Swig/typesys.c,typeobj.c) — type resolution and equivalences - Type passes (
Source/Modules/typepass.cxx) — tree-level analysis passes (directors, nested classes, etc.) - Language module (
Source/Modules/<lang>.cxx) — walks the parse tree and emits wrapper code
Key source directories
| Directory | Role |
|---|---|
Source/DOH/ |
Data Object Hub — SWIG's internal object system for strings, lists, hashes, files |
Source/Swig/ |
Core: type system, typemaps, symbol table, cwrap.c (C wrapper emission), scanner |
Source/CParse/ |
C/C++ parser (parser.y), template instantiation (templ.c) |
Source/Preprocessor/ |
SWIG's C preprocessor |
Source/Modules/ |
Language backends + entry point (main.cxx) |
Lib/ |
SWIG library: .i/.swg files included by interface files at runtime |
Source/Modules key files
main.cxx— entry point, command-line parsing, invokes the selected language moduleswigmain.cxx— dispatch table connecting-python,-java, etc. to module classeslang.cxx— baseLanguageclass that all backends inherit fromtypepass.cxx— post-parse tree passes run before language modulesdirectors.cxx— director (C++ virtual method callback) shared logicoverload.cxx— overloaded method dispatch code generationallocate.cxx— memory/ownership analysis
Each language backend (e.g., python.cxx, java.cxx) subclasses Language and overrides virtual methods like functionWrapper(), classDeclaration(), variableWrapper().
Parse tree
The parse tree is built from DOH nodes (hash-like objects). Key node attributes are documented in Doc/Devel/tree.html. The tree is walked by language modules using Swig_symbol_* and direct node traversal.
Typemaps
Typemaps (defined in Lib/*.swg and user .i files) control how C/C++ types are converted to/from target language types. The typemap engine is in Source/Swig/typemap.c. The %typemap directive in interface files is the primary mechanism for customizing conversions.
Template handling
C++ template instantiation is handled in Source/CParse/templ.c. Template specialization matching is a complex area — see Source/Swig/typesys.c for the type equivalence machinery.
Parser is not reentrant
Swig_cparse_parms(), Swig_cparse_type() and the other entry points that wrap yyparse() clobber parser globals (top, cparse_file, cparse_line, yylval, yychar) and cannot be called from inside a parser action. Grammar that needs to build a ParmList for a fresh subsyntax must reuse the existing parms / valparms / template_parms productions natively (see how the C++20 requires_expression rule reuses parms for the requirement-parameter-list), not recurse through Swig_cparse_parms().
DOH
Almost every SWIG internal data structure is a DOH object. Common operations:
NewString(s),NewStringf(fmt, ...),Copy(obj),Delete(obj)— strings and lifetimeGetattr(node, "name"),Setattr(node, "name", val)— parse tree node access (nodes are hashes)Printf(out, fmt, ...)whereoutmay be aStringorFile— main emission primitiveFirstitem(list)/Nextitem(list)— list iteration
See Source/DOH/doh.h for the full API and Doc/Devel/internals.html for design.
Debugging SWIG itself
For debugging the SWIG compiler — gdb setup, the swigprint/locswigprint helpers in Tools/swig.gdb, the full -debug-* flag list, the four stage processing model, SWIGTOOL/RUNTOOL/SWIG_FEATURES test suite hooks, XML parse tree dumps, and DOH_DEBUG_MEMORY_POOLS for memory corruption diagnosis — read .agents/skills/swig-debug/SKILL.md rather than working from memory.
Changelog
Any user visible change (bug fix, new feature, behavior change, deprecation) must be accompanied by a CHANGES.current entry describing it, added as part of the same change - do not leave it for later. On release, those entries are appended to CHANGES; RELEASENOTES holds higher level per release summaries.
Write entries so a user immediately understands them: clear, easy to follow, succinct and to the point. Describe only what a user observes - new syntax, generated wrapper behaviour, warning/error messages, an incompatibility - and leave internal helper names, refactors, and Source/ symbols out. Match the date and issue number format of the existing entries at the top of CHANGES.current, newest first, and flag a breaking change with a *** POTENTIAL INCOMPATIBILITY *** line. Purely internal changes with no observable effect do not get a CHANGES.current entry.
Coding conventions and contribution style
For source and contribution conventions - clang-format / code formatting (make format-check, make format-inplace), C/C++ comment style (quote tokens with ' / " not backticks, comment widths, function header blocks), parser.y new-code rules, and hyphenation - read .agents/skills/swig-conventions/SKILL.md rather than working from memory.
Commit messages - read before every commit
These rules are mandatory and override any default commit footer your AI tool or harness injects automatically (in particular a Co-Authored-By: <tool> line). If your agent framework adds such a footer by default, remove it before committing:
- Never add a
Co-Authored-By:trailer for an AI tool or model. AI agents are not authors and hold no copyright, so coauthorship attribution is inappropriate here. - Disclose significant AI assistance with a plain-text
Assisted-by:trailer naming the tool/model, with no<email>, e.g.Assisted-by: Claude Code (Opus 4.8). Required for changes underSource/orLib/, optional elsewhere. - Do not use backticks anywhere in the subject or body - they are Markdown and mean nothing in
git log/git format-patch. Quote code tokens with'or"if needed. - Keep the message plain, concise and accurate; no marketing language.
See .agents/skills/swig-conventions/SKILL.md for the full contribution conventions.
Developer Documentation
Doc/Devel/internals.html— SWIG internals (DOH, parse tree, type system)Doc/Devel/engineering.html— engineering guidelinesDoc/Devel/tree.html— parse tree node attributesDoc/Manual/Extending.html— guide to extending SWIG, adding a new target language, and the test suite
Useful background for contributors: C API design, the C++ type system, and SWIG's typemap mechanism. Adding a new target language follows the recipe in Doc/Manual/Extending.html.
Authoring the user manual
For editing chapters under Doc/Manual/ — chapter conventions, manual heading anchors (always use <filebase>_topic-style anchors, never the auto generated _nnN), the code / targetlang / shell / diagram <div> classes, link/anchor rules, and the make maketoc check cycle that renumbers headings and validates HTML — read .agents/skills/swig-doc/SKILL.md rather than working from memory.