This file provides guidance for AI coding assistants working with the spksrc repository.
spksrc is a cross-compilation framework for building Synology NAS packages (SPK files). The codebase uses GNU Make extensively with custom Makefile includes.
- Don't push to GitHub without explicit user approval - Always ask before pushing commits
- Test builds before committing - Run
make arch-x64-7.2to verify changes compile - Preserve existing patterns - Follow conventions from similar packages in the repo
- Patches must apply cleanly - No fuzz or offset warnings
- Simplicity over cleverness - If a simpler solution works for all cases, prefer it over complex conditionals
- Always rebase against master before merging - Keep branch history clean
cross/- Libraries and applications cross-compiled for target architecturediyspk/- Do-it-yourself SPK templates for standalone versions of bundled packagesspk/- Final SPK package definitions that users installnative/- Tools built for the host system (used during cross-compilation)mk/- Framework Makefiles (avoid modifying unless necessary)toolchain/- Synology toolchain definitions (rarely modified)kernel/- Synology modified kernel sources for building modules
make setup # Initial setup (creates local.mk) - run once
cd spk/packagename
make arch-x64-7.2 # Build for specific architecture
make all-supported # Build all supported architectures
make clean # Clean build artifacts- Edit
PKG_VERSincross/packagename/Makefile - Run
make digeststo update checksums - Edit
SPK_VERSinspk/packagename/Makefile, incrementSPK_REV - Update
CHANGELOG - Test with
make arch-x64-7.2
For major version upgrades, check upstream release notes for breaking changes, dependency compatibility, and migration requirements.
- Use unified diff format (
diff -u) - Name sequentially:
001-description.patch,002-another.patch - Place arch-specific patches in
patches/archname/subdirectory - Patches apply with
-p0(no directory prefix stripping)
SPK_REVstarts at 1, increments for packaging changes- Never reset
SPK_REV- always increment, even whenSPK_VERSchanges - Never decrement version numbers
The digests file contains THREE checksums per file (SHA1, SHA256, MD5), not just SHA256.
For complex packages (Erlang-based, large dependency trees), PLIST may need regeneration from actual build output when library versions change.
- DSM 7.2 uses GCC 8.5
- DSM 7.1 uses GCC 7.x (except comcerto2k which uses older GCC)
- DSM 6.2.4 uses GCC 4.9.x (except ARMv5/88f6281 which uses GCC 4.6.4)
- ARMv5/88f6281 (GCC 4.6.4) does not support
-std=c11- use-std=gnu99 - Use arch-specific patches in
patches/archname/for toolchain-specific fixes - Atomic support varies by architecture (some require libatomic linking)
- When a flag works across all toolchains, use it universally rather than complex conditionals
- When using
ifeqconditionals with arch variables, includespksrc.common.mkfirst to defineARMv5_ARCHS, etc. - Python wheels have four types: pure-python, crossenv, abi3-limited, and cross-package
- Pin all wheel versions exactly (e.g.,
mercurial==6.5.1); never include setuptools/pip/wheel - See copilot-instructions.md for detailed Python package patterns
Icons should be 512x512 pixels; the framework scales down automatically.
Defined in mk/spksrc.common/archs.mk:
x64_ARCHS- Intel/AMD 64-bitARMv8_ARCHS- ARM 64-bit (aarch64)ARMv7_ARCHS- ARM 32-bitARMv7L_ARCHS- Legacy ARM 32-bit (hi3535)ARMv5_ARCHS- Legacy ARM (88f6281) - GCC 4.6.4, limited C standard supportPPC_ARCHS- PowerPC (qoriq, ppc853x, etc.)OLD_PPC_ARCHS- Legacy PowerPC (often unsupported)32bit_ARCHS- All 32-bit architectures64bit_ARCHS- All 64-bit architectures
- Always work in feature branches - never commit directly to master
- Branch naming:
packagename-versionorfix-issue-description(no/in branch names) - Never push without explicit approval - always ask first
- Never amend commits already pushed to GitHub - create new commits instead
- Always rebase against master before merging - keep branch history clean
- Configured user: check
git config user.nameandgit config user.email
- Use
DISPLAY_NAME:prefix fromspk/*/Makefile(e.g.,Borg: Use gnu99 for GCC < 5.0) - Use
Framework:prefix for mk/ changes (not filename prefix) - Keep messages concise but descriptive
- Keep commit messages in sync with PR title/description
- Keep related items separated but simple - e.g., each wheel's CFLAGS in its own block, but don't nest conditionals unnecessarily
- Remove redundant code - don't leave dead code paths
- Check existing patterns first - look at how similar packages solve the same problem before inventing new approaches
- Question necessity - before making framework changes, verify they're truly required by comparing working vs failing cases
- Analyze CI logs carefully rather than guessing at fixes
- Compare working vs failing builds to isolate differences
- Check if the issue is arch-specific (toolchain version, available libraries)
- Upload CI logs for review when debugging complex failures
- Local builds may differ from CI (e.g., pre-existing work directories affect dependency resolution)
- Updating widely-used dependencies (zlib, openssl) triggers many package rebuilds - isolate in separate PRs
See .github/copilot-instructions.md for comprehensive build system documentation.