Install
$ agentstack add skill-flydev-fr-mormot2-superpowers-fpc-build ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
About
fpc-build
Build-time configuration for Free Pascal Compiler and Lazarus projects that consume mORMot 2: command-line fpc invocations, mode selection (-Mobjfpc, -Mdelphi), unit and include search paths into $MORMOT2_PATH/src/{core,orm,rest,soa,db,crypt,net,app,lib}, .lpi project files driven by lazbuild, and cross-target builds (-T, -P) for ARM, AArch64, and Linux from a Windows host. This skill teaches WHY/WHICH flags to set; the wrapper script scripts/fpc-build.sh covers WHEN/HOW to drive them from CI. It assumes the runtime/topology decisions of mormot2-deploy (services, reverse proxy, static libs) and stops where Delphi begins: dcc32, dcc64, .dproj, and MSBuild all belong in delphi-build.
When to use
- Adding
-Fu(unit) and-Fi(include) search paths to anfpccommand line so a project picks upmormot.core.base.pas,mormot.orm.core.pas, and the rest of the namespace tree under$MORMOT2_PATH/src. - Choosing between
-Mobjfpc(mORMot's required default) and-Mdelphi(compatibility mode) for a given source tree, and pairing it with-Sciso C-style operators like+=and^=parse. - Configuring a Lazarus
.lpiproject file: search paths, custom build modes (Debug,Release), package dependencies, and triggering builds from CI vialazbuild file.lpi --build-mode=Release. - Cross-compiling from a Windows host to ARM Linux (
-Tlinux -Parm), AArch64 Linux (-Tlinux -Paarch64), or 32-bit Linux (-Tlinux -Pi386) using a pre-built FPC cross toolchain. - Wiring
scripts/fpc-build.shinto CI: pinningMORMOT2_PATH, parsing theBUILD_RESULT exit=... errors=... warnings=...trailer, and switching betweenfpc(for.dpr/.lpr) andlazbuild(for.lpi) automatically based on file extension. - Toggling FPC-specific defines:
FPC_X64MM(use mORMot's x86_64 memory manager),FPCMM_BOOST(boost mode),FPC_HAS_FEATURE_STACKCHECKfamily. - Diagnosing
Fatal: Can't find unit mormot.core.base used by ..., which on FPC always traces back to a missing-Fu, the wrong mode (-Mtp), or a stalelib/output dir from a prior architecture.
When NOT to use
- Delphi command-line builds:
dcc32,dcc64,.dproj, MSBuild, `properties,rsvars.bat. Use **delphi-build**. (Conditional defines such asSTATICSQLITEapply to both compilers;delphi-build` covers them on the Delphi side, this skill on the FPC side.) - Runtime deployment: bundling static C archives with the binary, registering a Windows Service, writing a systemd unit, choosing a reverse proxy. Use mormot2-deploy.
- In-process TLS, ACME, HTTP engine selection. Use mormot2-net.
- REST routes, SOA contracts,
TRestServerlifecycle. Use mormot2-rest-soa. RawUtf8,TSynLog,TDocVariant, RTTI conventions used in the examples. Use mormot2-core.
Core idioms
1. Compile a .dpr or .lpr directly with fpc
When you do not have an .lpi (a small tool, a CLI, a test harness), fpc takes search paths on the command line. -Fu adds a unit search path, -Fi an include search path, -FE sets the executable output dir, -FU sets the unit (.ppu) output dir, and -B forces a rebuild of every unit.
SRC="$MORMOT2_PATH/src"
fpc \
-Mobjfpc -Sci \
-Fu"$SRC" -Fu"$SRC/core" -Fu"$SRC/orm" -Fu"$SRC/rest" \
-Fi"$SRC" -Fi"$SRC/core" \
-FE./bin -FU./lib \
-dDEBUG -B \
myserver.lpr
-Mobjfpc enables the Object Pascal mode mORMot 2 is written against; -Sci adds C-style operators (+=, -=, *=, /=) that mORMot uses heavily. Drop -Sci and the compiler will reject perfectly valid mORMot source with cryptic syntax errors. scripts/fpc-build.sh wraps exactly this pattern: it expands the path list under $MORMOT2_PATH/src, drops any subfolder that does not exist, and quotes each -Fu/-Fi argument so spaces in the install path do not split the token. See references/fpc-modes-and-flags.md for the full flag table.
2. Build an .lpi through lazbuild
Lazarus stores project state in an .lpi file: search paths, build modes (Default, Debug, Release, plus any custom modes), package dependencies, target OS/CPU. lazbuild is the headless builder that consumes the same .lpi the IDE writes, with no GUI.
# Build the default mode.
lazbuild myserver.lpi
# Build a specific mode.
lazbuild myserver.lpi --build-mode=Release
# Build all modes in a row (CI matrix).
lazbuild myserver.lpi --build-all
# Override the OS/CPU at the command line (cross-compile target).
lazbuild myserver.lpi --build-mode=Release --os=linux --cpu=aarch64
# Skip dependency checks (useful when a sibling package has its own build).
lazbuild myserver.lpi --skip-dependencies
Custom search paths configured in the IDE under Project Options | Compiler Options | Paths are written into the .lpi and travel with source control. Avoid paths added under Tools | Options | Files: those live in IDE config and CI runners do not have them. See references/lazbuild-and-lpi.md for the .lpi schema and per-mode override rules.
3. Cross-compile from Windows to Linux/ARM
FPC ships separate compiler binaries per host/target pair, plus a cross-binutils toolchain. The host invokes fpc (the Windows binary), passes -T -P to switch the target, and fpc calls into the cross-assembler (-as) and cross-linker (-ld) found on PATH or in $FPCDIR/bin.
# Windows host -> AArch64 Linux target.
fpc -Mobjfpc -Sci \
-Tlinux -Paarch64 \
-Fu"$MORMOT2_PATH/src" -Fu"$MORMOT2_PATH/src/core" \
-FE./bin/aarch64-linux \
-FU./lib/aarch64-linux \
myserver.lpr
The output unit dir (-FU) MUST be partitioned per target: a .ppu built for linux/aarch64 is binary-incompatible with win64/x86_64 and the linker will silently pick the wrong one if both share lib/. lazbuild partitions automatically when Project Options | Paths | Unit output directory contains $(TargetOS)-$(TargetCPU). Hand-rolled fpc calls must do the same. See references/cross-compilation.md for host triplets, runtime DLL/SO requirements, and the -XR flag for offline cross-builds.
4. Toggle FPC-specific defines consistently
mORMot 2 has FPC-only conditional symbols that toggle the bundled memory manager and other runtime features. Set them in exactly one place per build:
FPC_X64MM— replace FPC's default heap with mORMot'smormot.core.fpcx64mm(faster on multi-threaded server workloads). Set via-dFPC_X64MMon the command line or underCustom Optionsin the.lpi.FPCMM_BOOST— enables aggressive small-block allocation infpcx64mm(further speedup, slightly more memory).FPCMM_DEBUG— adds leak/double-free detection at the cost of throughput. Pair with a development build, never production.FPCMM_NOASSEMBLER— falls back to pure-Pascal allocator (slower but portable to any CPU).
Do not mix: a project that sets FPC_X64MM in the .lpi Release mode AND inherits -dFPC_X64MM from lazbuild --build-mode=Release ends up with the define set twice, which is harmless until a dependency .inc does {$IFDEF FPC_X64MM}{$DEFINE FPCMM_BOOST}{$ENDIF} and now you get boost mode without asking. Search the tree (rg -F '{$DEFINE FPC_X64MM}', rg -F '{$UNDEF FPC_X64MM}') before adding a new global.
5. Run via scripts/fpc-build.sh
The wrapper resolves MORMOT2_PATH, picks fpc versus lazbuild from the project file extension, injects search paths under $MORMOT2_PATH/src, captures stdout, parses errors and warnings, and emits a single trailer line CI can grep:
export MORMOT2_PATH=/src/mormot2
scripts/fpc-build.sh --project myserver.lpr
# ...build output...
# BUILD_RESULT exit=0 errors=0 warnings=2 first=
scripts/fpc-build.sh --lpi myserver.lpi
# ...build output...
# BUILD_RESULT exit=0 errors=0 warnings=0 first=
Exit codes map cleanly: 0 success, 2 MORMOT2_PATH unset/invalid, 5 project missing, 6 fpc/lazbuild not on PATH, 7 build failed (errors > 0). CI scripts should grep for the BUILD_RESULT trailer rather than rely on $? alone, because some FPC error patterns can leave $? at 0 even when the build produced unresolved-unit fatals.
Common pitfalls
- Missing
-Sci. mORMot 2 source uses+=,-=,*=, and/=everywhere. Without-Sci, the compiler emitsError: Illegal expressionorError: ":=" expectedat the first such line, with no hint that a single missing flag is the cause. Always pass-Sci(or setCompiler Options | Parsing | C-style operatorsin the.lpi).scripts/fpc-build.shpasses it unconditionally on thefpcpath;.lpiprojects must enable it explicitly per build mode. - Wrong mode for mORMot 2 (
-Mtpor-Mdelphi). mORMot 2 requires-Mobjfpc.-Mdelphicompiles a subset but breaks on operator overloading and inline classes;-Mtp(Turbo Pascal) does not get out of unit 1. Symptom:Error: Operator is not overloadedorError: Identifier not found 'inline'. Set-Mobjfpcon the command line or underCompiler Options | Parsing | Syntax modein the.lpi. - Lazarus IDE-only paths in
.lpinot propagating to lazbuild. Paths added viaTools | Options | Files | Other unit fileslive in the IDE config (environmentoptions.xml), not in the.lpi. The IDE finds them;lazbuilddoes not. Symptom: builds work in the IDE, fail in CI withFatal: Can't find unit .... Move every dependency path into the.lpiunderProject Options | Compiler Options | Paths | Other unit files, or pass--add-package/--ws=...flags tolazbuild. - Shared lib/ directory across targets.
fpc -FU./libwrites.ppufiles into one directory regardless of target OS/CPU. Switch fromwin64tolinux/aarch64withoutrm -rf lib/(or without partitioning intolib/$(TargetOS)-$(TargetCPU)) and the linker pulls a Win64.ppuinto a Linux build, with no error until link time when symbol mangling differs. Always partition:-FU./lib/$fpctarget.scripts/fpc-build.shdoes not auto-partition; CI scripts must cleanlib/between targets. MORMOT2_PATHset per shell, missing from CI. Local devs putexport MORMOT2_PATH=/src/mormot2in.bashrc; CI runners have nothing.scripts/fpc-build.shexits2("MORMOT2_PATH unset") with a clear message, but a hand-rolledfpccall just producesFatal: Can't find unit mormot.core.basewith no hint. SetMORMOT2_PATHin the CI job's environment block, and assert it is non-empty as the first step of the build.fpc.cfgshadowing command-line flags. FPC readsfpc.cfgfrom$FPCDIR/etc/,~/.fpc.cfg, and the working directory in that order. A user-level~/.fpc.cfgwith-Fu/usr/local/lib/fpc/3.2.2/units/$FPCTARGETis fine for non-mORMot work but can pull in mismatched.ppuversions of shared units (fpwidestring,cwstring). Pass-nto ignore the default config and rely entirely on the explicit flagsscripts/fpc-build.shpasses, when the build host is shared or untrusted.- Mixed FPC versions across CI runners. mORMot 2 requires FPC 3.2.0 or newer; some skip-list features need 3.2.2. A runner with FPC 3.0.4 produces
Fatal: Can't find unit Generics.Collectionsbecause that unit only landed in 3.2.0. Pin the FPC version per runner (fpc -iVshould print3.2.2or newer), and document the minimum in the project README. Lazarus pinning is separate: a Lazarus 2.0 IDE can drive an FPC 3.2.2 backend, but the.lpischema migrated at Lazarus 2.2 and old IDEs strip new properties on save. - Spaces in
MORMOT2_PATHnot quoted.fpc -Fu/c/Program Files/mormot2/srcparses as-Fu/c/Programplus a positional argumentFiles/mormot2/src, which fails withFatal: Compilation aborted. Always quote:-Fu"$MORMOT2_PATH/src".scripts/fpc-build.shquotes correctly; ad-hocevalcalls usually do not. (Even better: install mORMot under a path with no spaces; Windows + MSYS2 path mangling makes spaces fragile no matter how careful the quoting.)
See also
$MORMOT2_DOC_PATH/mORMot2-SAD-Chapter-26.md- Installation and Compilationreferences/fpc-modes-and-flags.mdreferences/lazbuild-and-lpi.mdreferences/cross-compilation.mdscripts/fpc-build.sh- the build wrapper this skill teachesdelphi-buildfor Delphidcc32/dcc64/.dproj/MSBuild buildsmormot2-deployfor runtime topology, services, static-library bundlingmormot2-coreforRawUtf8,TSynLog, and the unit conventions every snippet above leans on
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: flydev-fr
- Source: flydev-fr/mormot2-superpowers
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.