writing-oslib-defs
Skill4 starsChanged 7 months agoMITView on GitHub
Use when writing, reading, or reviewing OSLib Def interface description files, or when generating C headers, ObjAsm veneers, assembler/C SWI headers, SrcEdit help, or StrongHelp content from them with riscos-defmod.
We split this skill into the rules it gives an agent
8 rules. About 0 are common, 2 are distinctive, and 6 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈2
Distinctive · estimate
This author's own choices. Worth a look.
6
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- could be automatic: a setting could enforce it
- Distinctive: line 17
Read only the reference files needed for the task:
- Very specific: line 103
Write or edit the .Def source describing the interface (types, constants, SWI signatures).
- Distinctive: line 108
Keep the Def file under source control as the reviewed artefact.
- Very specific: line 113
Keep one Def file per logical interface (module or shared header), named to match its TITLE.
- Very specific: line 115
Use NEEDS to declare cross-interface dependencies explicitly rather than relying on include order in generated headers.
- Very specific: line 117
Prefer named TYPE declarations over inline .struct/.union expressions when a structure is used by more than one SWI, so the generated …
- Very specific: line 120
Use the starred-description form (NUMBER &12345 "description" or a bare *) on SWI numbers and constant reason codes you want exposed as …
- Very specific: line 124
Do not hand-edit generated headers, veneers, or help output — re-run riscos-defmod after editing the Def file instead.
≈ “Common” is an estimate: at least 1 in 5 of the 308,232 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Writing OSLib Def files
A Def file is a compact, declarative description of an OSLib-style RISC OS
interface: module metadata, types, constants, and SWI signatures. One
reviewed Def file is processed by riscos-defmod to derive C headers, ObjAsm
veneers, assembler headers, SrcEdit help, and StrongHelp content, so the Def
file is the source of truth and the generated files are build artefacts.
Read only the reference files needed for the task:
- Full grammar (types, structs, SWI entry/exit conditions, literals):
references/grammar.md riscos-defmodcommand-line flags and output-format selectors:references/command-line.md
The one rule that will trip you up
The semicolon between declarations is a separator, not a terminator. A
trailing semicolon after the last top-level declaration in the file is a
syntax error reported at end of file, even though every other pair of
declarations must be separated by one. Verified directly against the real
defmod binary and against oslibsrc/Core/def/portable, a genuine
production Def file, which itself ends on a bare closing parenthesis with no
trailing semicolon.
TITLE Example "Example OSLib interface";
AUTHOR "Example Author";
NEEDS os;
CONST ExampleReason = .int: 1 "Primary reason code";
TYPE ExampleBlock = .struct (.int: value, .bool: enabled);
SWI Example_DoThing = (NUMBER &54321 "DoThing",
ENTRY (R0 -> ExampleBlock: block,
R1 # ExampleReason),
EXIT (R0! = .int: result, R1 ?))Note there is no semicolon after the closing )) of the SWI declaration,
because it is the last declaration in the file. If another declaration
followed it, that SWI declaration would need a trailing semicolon to
separate it from the next one.
Minimal worked example
This is the smallest realistic file: metadata, one constant, and one SWI.
TITLE Example;
AUTHOR "Test Author";
NEEDS OS;
CONST
ReasonCode = .Int: 5 "Reason code for the SWI";
SWI
Example_Call =
( NUMBER &12345 "Example call",
ENTRY
( R0 = .Int: value,
R1 # ReasonCode
),
EXIT
( R0! = .Int: result
) )Type and keyword names are matched case-insensitively by the lexer, so
.Int/.int, TITLE/title, and similar pairs are equivalent; pick one
style and stay consistent within a file.
Running riscos-defmod
riscos-defmod reads the Def file from standard input; most output forms
write to standard output, so redirect them yourself:
mkdir -p h s
riscos-defmod -h < InterfaceDef > h/interface # C header
riscos-defmod -hdr < InterfaceDef > h/interface_asm # ObjAsm header
riscos-defmod -s -byte_wide bytewide.txt < InterfaceDef > s/interface # ObjAsm veneersDirectory-producing modes (-l, -cstrong) take -o <dir> and create that
directory themselves; everything else relies on the shell redirection, so the
destination directory for those must already exist:
riscos-defmod -l -o LibraryOut -26bit -32bit < InterfaceDefSee references/command-line.md for the full flag list, including which
historical flags (-p for Pascal, -asmstrong) are accepted by the parser
but do not actually produce output.
Workflow
- Write or edit the
.Defsource describing the interface (types, constants, SWI signatures). - Generate the header(s) and veneer(s) you need with
riscos-defmod. - Build the generated
.s/.oveneer alongside your C source in the normal way; seeusing-makefilesfor wiring this into a project's build. - Keep the Def file under source control as the reviewed artefact; treat generated output as disposable and regenerate it on each build.
Style guidelines
- Keep one
Deffile per logical interface (module or shared header), named to match itsTITLE. - Use
NEEDSto declare cross-interface dependencies explicitly rather than relying on include order in generated headers. - Prefer named
TYPEdeclarations over inline.struct/.unionexpressions when a structure is used by more than one SWI, so the generated header gives it a stable name. - Use the starred-description form (
NUMBER &12345 "description"or a bare*) on SWI numbers and constant reason codes you want exposed as named manifest constants in generated headers; omit it for values that are implementation detail only. - Do not hand-edit generated headers, veneers, or help output — re-run
riscos-defmodafter editing the Def file instead.
In this repository47 other files it gives its agents.
- allocating-resourcesSkill
- ci-testingSkill
- creating-pull-requestsSkill
- designing-modulesSkill
- porting-to-riscos-cSkill
- reading-assemblySkill
- riscos-commandsSkill
- riscos-desktop-fileractionSkill
- riscos-filer-likeSkill
- riscos-filesystemSkill
- riscos-graphics-convertersSkill
- riscos-network-dcistatisticsSkill
- riscos-network-resolverSkill
- riscos-outputSkill
- riscos-reSkill
- riscos-styleSkill
- riscos-throwbackSkill
- riscos-urls-fetchingSkill
- riscos-urls-launchingSkill
- riscos-wimp-appSkill
- riscos-wimpSkill
- riscos-wimp-templatesSkill
- updating-robe-skillsSkill
- using-bbcbasicSkill
- using-cmhgSkill
- using-ghSkill
- using-gitSkill
- using-libasmSkill
- using-libgcontextSkill
- using-liboslibSkill
- using-libriscoslibSkill
- using-libtoolboxSkill
- using-makefilesSkill
- using-perlSkill
- using-stronghelpSkill
- using-toolbox-imagefilegadgetSkill
- using-tooltesterSkill
- writing-assemblySkill
- writing-assembly-testsSkill
- writing-cmodulesSkill
- writing-cplusplusSkill
- writing-cSkill
- writing-fortranSkill
- writing-pascalSkill
- writing-prminxmlSkill
- writing-pymodulesSkill
- writing-pyromaniac-integration-testsSkill
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
Reviews can't be read right now.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

