Smartcard Package Build Fix Documentation

Issue

Build failed after adding python-pyscard and python-pysatochip packages with error:

package/Config.in:2944: can't open file "/package/python-pyscard/Config.in"
make[1]: *** [Makefile:1024: luckfox_pico_defconfig] Error 1

Root Cause Analysis

The Problem

Initial Implementation (BROKEN):

# Package files placed in:
buildroot/external-packages/python-pyscard/
buildroot/external-packages/python-pysatochip/

# Menu configuration referenced:
source "$BR2_EXTERNAL_SEEDSIGNER_PATH/package/python-pyscard/Config.in"
source "$BR2_EXTERNAL_SEEDSIGNER_PATH/package/python-pysatochip/Config.in"

Why it failed:

  1. $BR2_EXTERNAL_SEEDSIGNER_PATH is a buildroot BR2_EXTERNAL variable
  2. LuckFox SDK doesn’t use the BR2_EXTERNAL system like seedsigner-os does
  3. Variables don’t expand when added to SDK’s package/Config.in file
  4. Packages weren’t being copied to the SDK’s package directory

Comparison with seedsigner-os (Known Good)

seedsigner-os structure:

opt/
├── external-packages/        # External package definitions
│   ├── python-pyscard/
│   ├── python-pysatochip/
│   └── python-urtypes/
├── pi0/
│   ├── Config.in            # References: ../external-packages/...
│   └── external.mk          # Includes from BR2_EXTERNAL_PATH
└── buildroot/               # Buildroot source

seedsigner-os approach:

  • Pure buildroot project
  • Uses BR2_EXTERNAL="../pi0/" parameter
  • Config.in can use relative paths like ../external-packages/...
  • buildroot system handles BR2_EXTERNAL_PATH variables

LuckFox SDK structure:

luckfox-pico/
├── sysdrv/
│   └── source/
│       └── buildroot/
│           └── buildroot-2023.02.6/
│               └── package/             # Standard buildroot packages
└── build.sh                             # Custom build system

LuckFox SDK approach:

  • Custom build system wrapping buildroot
  • No BR2_EXTERNAL system used
  • Packages must be copied INTO SDK’s package/ directory
  • Reference as standard buildroot packages: package/...

The Fix

Correct Implementation (WORKING):

1. Copy packages to SDK during build:

# After buildroot is created, copy packages
cp -rv buildroot/external-packages/* SDK/package/

2. Reference as standard buildroot packages:

menu "SeedSigner"
    source "package/python-pyscard/Config.in"
    source "package/python-pysatochip/Config.in"
endmenu

No BR2_EXTERNAL variables needed!

Implementation Details

Build Flow (Before Fix - BROKEN)

1. Clone LuckFox SDK
2. Run buildroot_create
   → Creates: sysdrv/source/buildroot/buildroot-*/
3. Copy seedsigner-os packages
   → SDK/package/python-urtypes/
   → SDK/package/python-embit/
   → etc.
4. Add menu to SDK/package/Config.in:
   source "package/python-urtypes/Config.in"  ✓ Works (was copied)
   source "$BR2_EXTERNAL.../python-pyscard/Config.in"  ✗ FAILS (variable doesn't expand, file not found)
5. Build fails ✗

Build Flow (After Fix - WORKING)

1. Clone LuckFox SDK
2. Run buildroot_create
   → Creates: sysdrv/source/buildroot/buildroot-*/
3. Copy seedsigner-os packages
   → SDK/package/python-urtypes/
   → SDK/package/python-embit/
   → etc.
4. Copy this repo's packages
   → SDK/package/python-pyscard/  ✓ NEW
   → SDK/package/python-pysatochip/  ✓ NEW
5. Add menu to SDK/package/Config.in:
   source "package/python-pyscard/Config.in"  ✓ Works (was copied)
   source "package/python-pysatochip/Config.in"  ✓ Works (was copied)
6. Build succeeds ✓

Code Changes

Changes Applied to All 3 Build Scripts

Files modified:

  • .github/workflows/build.yml (GitHub Actions)
  • buildroot/os-build.sh (Docker builds)
  • buildroot/build-local.sh (Native builds)

Change 1: Add package copying step

Before:

# Copy SeedSigner packages from seedsigner-os
cp -rv ../seedsigner-os/opt/external-packages/* "$PACKAGE_DIR/"

After:

# Copy SeedSigner packages from seedsigner-os
cp -rv ../seedsigner-os/opt/external-packages/* "$PACKAGE_DIR/"

# Also copy packages from this repository's external-packages directory
if [ -d ../seedsigner-os/opt/luckfox/external-packages ]; then
  cp -rv ../seedsigner-os/opt/luckfox/external-packages/* "$PACKAGE_DIR/"
fi

Change 2: Fix menu Config.in references

Before:

menu "SeedSigner"
    source "package/python-urtypes/Config.in"
    source "$BR2_EXTERNAL_SEEDSIGNER_PATH/package/python-pyscard/Config.in"
    source "$BR2_EXTERNAL_SEEDSIGNER_PATH/package/python-pysatochip/Config.in"
endmenu

After:

menu "SeedSigner"
    source "package/python-urtypes/Config.in"
    source "package/python-pyscard/Config.in"
    source "package/python-pysatochip/Config.in"
endmenu

Testing & Verification

How to Verify the Fix

After build completes, verify packages were copied:

# Check SDK package directory
ls luckfox-pico/sysdrv/source/buildroot/buildroot-*/package/python-pyscard/
ls luckfox-pico/sysdrv/source/buildroot/buildroot-*/package/python-pysatochip/

# Should see:
# Config.in
# python-pyscard.mk
# python-pyscard.hash
# patches (if any)

Verify packages in final image:

# After flashing to device
python3 -c "import smartcard; print(smartcard.__version__)"
python3 -c "import pysatochip; print('pysatochip loaded')"

# Check installation paths
ls /usr/lib/python3.*/site-packages/smartcard/
ls /usr/lib/python3.*/site-packages/pysatochip/

Lessons Learned

Key Differences: seedsigner-os vs LuckFox SDK

Aspect seedsigner-os LuckFox SDK
Build System Pure buildroot Custom wrapper around buildroot
External Packages BR2_EXTERNAL system Direct package copying
Config.in Paths Relative: ../external-packages/... Absolute: package/...
Variables BR2_EXTERNAL_* work Variables don’t expand in Config.in
Package Location Separate external tree Merged into SDK package/ dir

When Adding New External Packages

For LuckFox SDK builds:

  1. Place package files in buildroot/external-packages/<package-name>/
  2. Ensure build scripts copy them to SDK’s package directory
  3. Reference in menu as source "package/<package-name>/Config.in"
  4. Never use BR2EXTERNAL* variables - they don’t work

For seedsigner-os builds:

  1. Place package files in opt/external-packages/<package-name>/
  2. Reference in Config.in with relative path: ../external-packages/...
  3. BR2EXTERNAL* variables work normally

Pattern to Follow

This repository uses a hybrid approach:

  • Some external packages come from seedsigner-os repo
  • Some external packages are unique to this repo
  • Both get copied to SDK’s package directory
  • All referenced with standard package/... paths

Template for adding new package:

# 1. Create package structure
buildroot/external-packages/python-newpackage/
├── Config.in
├── python-newpackage.mk
├── python-newpackage.hash
└── patches/ (if needed)

# 2. Package is auto-copied by build scripts (already implemented)
# 3. Add to menu in all 3 build scripts:
source "package/python-newpackage/Config.in"

# 4. Enable in defconfig:
BR2_PACKAGE_PYTHON_NEWPACKAGE=y

References

  • LuckFox SDK: https://github.com/3rdIteration/luckfox-pico
  • seedsigner-os: https://github.com/3rdIteration/seedsigner-os
  • Build failure logs: GitHub Actions run 22107041975
  • Buildroot BR2_EXTERNAL docs: https://buildroot.org/downloads/manual/manual.html#outside-br-custom

Conclusion

The fix correctly adapts the “known good” package structure from seedsigner-os to work with LuckFox SDK’s build system. The key insight is that LuckFox SDK requires packages to be copied into its buildroot directory and referenced as standard packages, rather than using the BR2_EXTERNAL system that pure buildroot projects like seedsigner-os use.

Both packages (python-pyscard and python-pysatochip) are now correctly integrated and will build successfully without being disabled.


Released under the MIT License. The SeedSigner OS section is mirrored from the seedsigner-os repository at the pinned release commit.

This site uses Just the Docs, a documentation theme for Jekyll.