Skip to content

ESP32S3_8048S043C Build Scripts

The esp32s3_8048s043c_build_scripts module is the board-specific build automation layer for the ESP32S3-8048S043C hardware target — an ESP32-S3 board with an 800×480 RGB parallel display and 16 MB flash. Its three Python scripts wrap ESP-IDF’s idf.py to produce fully self-consistent firmware installer packages: UI resources partition, firmware binary, factory bootloader and partition table, flash map JSON, and a standalone user-customization kit, all in one reproducible pipeline.


  1. Module Overview
  2. Architecture
  3. File Structure
  4. Key Concepts
  5. Component Reference
  6. Variant Catalogue
  7. Build Process Flow
  8. Data Flow: Artefact Assembly
  9. Inter-Module Dependencies
  10. Usage
  11. Board Constants and Environment

PropertyValue
Locationboards/esp32s3_8048s043c/build_scripts/
LanguagePython 3
ESP-IDF version5.4.3
IDF targetesp32s3
Board resolution800 × 480 (res_800_480)
Supported flash sizes16 MB only
Sibling modulesSee esp32s3_8048s043c_bsp.md, esp32s3_8048s043c_factory.md

This module follows the identical three-file pattern used by every other board under boards/:

FileRole
variants.pyDeclares every buildable variant as a plain Python dict
build_one.pyCLI entry point — names one variant and dispatches to common.py
common.pyBuild engine — orchestrates ESP-IDF, resource generation and artefact packaging

For the shared, board-agnostic build tooling (resource generator, kit packager, size reporter, build manager) see Build,Resource&_Development_Toolchain.md.


Output (installer/)

Sibling board modules

ESP-IDF

Shared tools (tools/build_scripts/)

esp32s3_8048s043c_build_scripts

lookup variant dict

build_variant / check_variant

idf.py build / reconfigure

generate_resources.py --variant

package_user_resources_kit.py

flash_mgr.py --generate

auto-build if artifacts missing

firmware binary

ui_resources_*.bin

bootloader + partition table

*.json flash map

ui_resources_kit/

build_one.py

(CLI entry point)

common.py

(build engine)

variants.py

(variant registry)

generate_resources.py

package_user_resources_kit.py

flash_mgr.py

idf.py

esp32s3_8048s043c_factory

(factory variant build)

installer/ESP32S3_8048S043C_16MB_*/

firmware.bin

bootloader_16MB.bin

partitions_16MB.bin

ui_resources_*.bin

flash_map.json

ui_resources_kit/

installer_history.log

from common import build_variant, check_variant

from variants import VARIANTS, FACTORY_VARIANTS

from variants import FACTORY_VARIANTS

(auto-rebuild factory path)

build_one.py

common.py

variants.py


boards/esp32s3_8048s043c/
└── build_scripts/
├── build_one.py # CLI: build or validate one named variant
├── common.py # Build engine: ESP-IDF wrapper + artefact pipeline
└── variants.py # Variant registry: cmake flag sets + build directories

All paths in common.py and variants.py are anchored at:

AnchorValueDerived from
SCRIPT_DIRboards/esp32s3_8048s043c/build_scripts__file__
BOARD_ROOTboards/esp32s3_8048s043cSCRIPT_DIR/..
REPO_ROOTrepository rootSCRIPT_DIR/../../..
IDF_PATHESP-IDF installation$IDF_PATH env var (default: C:\Users\luc\esp\v5.4.3\esp-idf)

Every buildable configuration is represented as a plain Python dict with four keys:

{
"name": str, # Human-readable identifier used in logging and directory names
"cmake": list[str], # Flat list of -D KEY=VALUE arguments forwarded to idf.py
"cwd": str, # Working directory for idf.py (REPO_ROOT or FACTORY_DIR)
"build_dir": str, # Absolute path to the per-variant build output directory
}

Two registries exist:

  • VARIANTS — regular firmware variants; cwd is REPO_ROOT.
  • FACTORY_VARIANTS — factory app variants; cwd is boards/esp32s3_8048s043c/Factory/.

build_one.py merges both with {**FACTORY_VARIANTS, **VARIANTS} so every name is reachable from a single CLI call.

4.2 Deterministic Defaults (All-OFF Baseline)

Section titled “4.2 Deterministic Defaults (All-OFF Baseline)”

variants.py defines ROOT_CMAKE_OPTIONS — an exhaustive list of every toggleable CMake option across the project (board selection, memory size, PSRAM, firmware target, transports, features). make_variant_args() pre-generates DEFAULT_OFF_CMAKE_ARGS which sets every option to OFF, then selectively overrides only the flags that belong to the requested variant:

def make_variant_args(*on_flags):
args = DEFAULT_OFF_CMAKE_ARGS.copy() # Every option = OFF
for flag in on_flags:
args.extend(["-D", flag]) # Override specific options to ON
return args

This guarantees that stale CMake cache values from a previous build of a different variant cannot leak into the current one.

prepare_build_dir() in common.py writes a .idf_target marker file inside the build directory. Before any build, _ensure_clean_build_dir() reads the marker and wipes the entire build directory if it was produced for a different target chip. This prevents silent MCU cross-contamination when the same host machine has recently built for a different ESP32 variant.

Regular firmware variants depend on factory artefacts (custom bootloader binary, partition table) produced by the factory_16mb variant. copy_factory_artifacts() checks whether boards/esp32s3_8048s043c/Factory/installer/ESP3D-FACTORY_16MB/ contains a bootloader_*.bin file. If not — or if the directory is empty because cmake/targets.cmake recreated it without completing the build — it automatically runs build_variant(factory_16mb_config) before continuing with the regular build.

resource_variant_string(cmake_args) decodes the CMake flags back into the string format consumed by generate_resources.py (e.g. 16mb_wifi_grblhal). It returns None for the Factory variant (which has no UI resources partition), causing generate_resources() to silently skip resource generation for that variant.


make_variant_args(*on_flags) → list[str]

Section titled “make_variant_args(*on_flags) → list[str]”

Creates the complete cmake argument list for a variant.

AspectDetail
InputOne or more "KEY=VALUE" strings (the flags to enable)
OutputFlat list[str] of -D KEY=VALUE pairs: all options OFF first, then the requested overrides appended
Side effectsNone — purely functional
make_variant_args("ESP32S3_8048S043C=ON", "MEMORY_16_MB=ON", "WIFI_SERVICE=ON")
# → ["-D", "ESP32_PIBOT_CNC_PENDANT_V1=OFF", ..., "-D", "ESP32S3_8048S043C=ON",
# "-D", "MEMORY_16_MB=ON", "-D", "WIFI_SERVICE=ON"]

Master list of every project-wide CMake option. Grouped into categories:

CategoryOptions
Board selectionESP32S3_8048S043C, ESP32S3_4827S043C, ESP32S3_8048S050C, … (15 boards total)
Memory sizeMEMORY_4_MB, MEMORY_8_MB, MEMORY_16_MB
PSRAMPSRAM_NONE, PSRAM_2_MB, PSRAM_4_MB, PSRAM_8_MB
Firmware targetTARGET_FW_FLUIDNC, TARGET_FW_GRBLHAL, TARGET_FW_GRBL, TARGET_FW_MARLIN, TARGET_FW_SMOOTHIEWARE, TARGET_FW_REPETIER, TARGET_FW_NONE
TransportsSERIAL_SERVICE, UART_EXT_SERVICE, USB_SERIAL_SERVICE, WIFI_SERVICE, BT_SERVICE, BT_SERIAL_SERVICE, BT_BLE_SERVICE
FeaturesTFT_UI_SERVICE, SD_CARD_SERVICE, BUZZER_SERVICE, LUA_INTERPRETER_SERVICE, MDNS_SERVICE, SSDP_SERVICE, WEBUI_SERVER, SOCKET_CLIENT_SERVICE, UPDATE_SERVICE, …

See Section 6 for the complete table.


CLI entry point. Accepts a positional variant name plus optional mode flags.

python build_one.py <variant_name> [--clean] [--check] [--dev] [--jobs=N]
FlagBehaviour
(none)Full build of the named variant via build_variant()
--cleanCleans build and installer directories, then exits
--checkValidates cmake configuration via check_variant() without compiling
--devSuppresses PROD_BUILD=ON (development build)
--jobs=NSets CMAKE_BUILD_PARALLEL_LEVEL=N for parallel ninja compilation

Error handling:

  • No variant name → prints usage and available names, exits with code 1.
  • Unknown name → prints error and the list of valid names, exits with code 1.
  • Build/check failure → forwards the non-zero exit code from common.py.

Main build orchestrator. Returns 0 on success, non-zero on any failure.

Pipeline (in order):

1. If --clean: wipe build dir + installer dir → return 0
2. prepare_build_dir() — IDF_TARGET guard, create dir, write marker
3. generate_resources() — produce ui_resources_*.bin + esp3d_ui_offsets.h
4. run_cmake_build() — idf.py build
5. _show_size_report() — idf.py size (informational, non-gating)
6. copy_factory_artifacts() — auto-build factory_16mb if missing, copy to installer/
7. _copy_ui_resources_bin() — copy ui_resources_*.bin to installer/
8. _package_user_resources_kit() — assemble standalone end-user kit
9. _log_firmware_artifacts() — append timestamped record to installer_history.log
10. generate_flash_map() — run flash_mgr.py --generate → *.json flash map

If cwd != REPO_ROOT (i.e. the factory variant itself), steps 6–10 are skipped because the factory build produces its own installer directory independently.


Dry-run validation. Runs idf.py reconfigure (CMake configure phase only) to catch cmake errors without compiling anything. Useful for CI pre-flight checks or quickly validating new variant definitions.


Ensures build_dir exists and belongs to the expected IDF target (esp32s3). Delegates to _ensure_clean_build_dir() which reads .idf_target and wipes the directory if the stored target does not match EXPECTED_IDF_TARGET. Must be called before generate_resources() writes any files into build_dir, so the marker file exists when cmake starts.


generate_resources(cmake_args, build_dir) → int

Section titled “generate_resources(cmake_args, build_dir) → int”

Decodes cmake_args into a resource variant string via resource_variant_string(), then invokes:

Terminal window
python tools/build_scripts/generate_resources.py \
--variant <variant> \
--resolution res_800_480 \
--partition-csv boards/esp32s3_8048s043c/partitions_16mb.csv \
--out <build_dir> \
[--board-resources boards/esp32s3_8048s043c/resources/]

The --board-resources argument is only appended when boards/esp32s3_8048s043c/resources/ exists, allowing optional per-board icon/font/theme overrides on top of the shared resource defaults. Returns 0 (skips silently) for variants with no recognized resource variant (e.g. Factory).


copy_factory_artifacts(cmake_args) → int

Section titled “copy_factory_artifacts(cmake_args) → int”
  1. Checks boards/esp32s3_8048s043c/Factory/installer/ESP3D-FACTORY_16MB/ for a bootloader_*.bin (_factory_artifacts_complete()).
  2. If absent or directory is empty: calls _build_missing_factory() which looks up the matching factory config from FACTORY_VARIANTS and runs a full build_variant() on it.
  3. Copies all artefacts (excluding size_report.txt) to installer/<config_name>/.
  4. Appends a FACTORY log section to installer_history.log.

Derives the installer subdirectory name from cmake flags. Format:

ESP32S3_8048S043C_<memory>_<radio>_<firmware>

Examples:

  • ESP32S3_8048S043C_16MB_wifi_fluidnc
  • ESP32S3_8048S043C_16MB_serial_grbl
  • ESP32S3_8048S043C_16MB_bt_serial_grblhal

resource_variant_string(cmake_args) → str | None

Section titled “resource_variant_string(cmake_args) → str | None”

Maps cmake flags → generate_resources.py variant string. Format: <mem>mb_<transport>_<firmware>.

cmake flags set to ONResource variant string
MEMORY_16_MB, WIFI_SERVICE, TARGET_FW_FLUIDNC16mb_wifi_fluidnc
MEMORY_16_MB, TARGET_FW_GRBL (no explicit radio)16mb_serial_grbl
MEMORY_16_MB, BT_SERIAL_SERVICE, TARGET_FW_GRBLHAL16mb_bt_serial_grblhal
MEMORY_16_MB, BT_BLE_SERVICE, TARGET_FW_FLUIDNC16mb_bt_ble_fluidnc
Factory variant (no recognized mem/fw combination)None — resource generation skipped

run_cmake_build(cmake_args, cwd, build_dir) → int

Section titled “run_cmake_build(cmake_args, cwd, build_dir) → int”

Assembles and runs:

Terminal window
python $IDF_PATH/tools/idf.py -B <build_dir> <cmake_args> [-D PROD_BUILD=ON] build

Environment overrides applied to the subprocess:

  • IDF_TARGET=esp32s3 — forces correct target regardless of any VS Code / shell setting.
  • CMAKE_BUILD_PARALLEL_LEVEL=N — set when --jobs=N is present in sys.argv (propagated by build_mgr.py).

PROD_BUILD=ON is appended unless --dev is in sys.argv.


Invokes tools/flash_scripts/flash_mgr.py --variant-dir <installer_dir> --generate (with optional --flash-params boards/esp32s3_8048s043c/flash_params.json). Produces the variant’s JSON flash map consumed by the web installer and flash_mgr.


_package_user_resources_kit(cmake_args, build_dir, installer_dir) → int

Section titled “_package_user_resources_kit(cmake_args, build_dir, installer_dir) → int”

Finds the ui_resources_manifest_*.json written by generate_resources.py and invokes:

Terminal window
python tools/build_scripts/package_user_resources_kit.py \
--variant <variant> \
--manifest <manifest_path> \
--out installer/<config>/ui_resources_kit/

Produces a standalone directory (no repo clone required) that end-users can use to customise icons, fonts and theme colours via SD card. See Build,Resource&_Development_Toolchain.md.


FunctionPurpose
ensure_idf_py()Validates that idf.py exists at IDF_PATH; exits with error if missing
clean_build_dir(build_dir)shutil.rmtree on build_dir
parse_cmake_flags(cmake_args)Parses a flat -D KEY=VALUE list into a {KEY: VALUE} dict
run_cmake_check(cmake_args, cwd, build_dir)Runs idf.py reconfigure for check_variant()
_show_size_report(build_dir, cwd)Runs idf.py size — informational, not gating
installer_dir_for(config)Returns the installer output directory path for a config dict
_factory_artifacts_complete(source_dir)Returns True only when directory exists and contains a bootloader_*.bin
_build_missing_factory(source_dir)Resolves and builds the factory variant whose installer dir matches source_dir
_copy_ui_resources_bin(build_dir, installer_dir)Copies ui_resources_*.bin from build dir to installer dir
_log_firmware_artifacts(...)Appends a timestamped FIRMWARE section to installer_history.log
_get_jobs_env_value()Parses --jobs=N from sys.argv for CMAKE_BUILD_PARALLEL_LEVEL

NameMemoryRadioCNC FirmwareExtra ServicesBuild dir
16mb_wifi_fluidnc16 MBWiFiFluidNCSerial, mDNS, Socket Client, Lua, Updatebuild/esp32s3_8048s043c_16mb_wifi_fluidnc/
16mb_serial_fluidnc16 MBSerialFluidNCUpdatebuild/esp32s3_8048s043c_16mb_serial_fluidnc/
16mb_serial_grbl16 MBSerialGRBLUpdatebuild/esp32s3_8048s043c_16mb_serial_grbl/
16mb_wifi_grblhal16 MBWiFigrblHALSerial, mDNS, Socket Client, Lua, Updatebuild/esp32s3_8048s043c_16mb_wifi_grblhal/

All regular variants enable TFT_UI_SERVICE=ON and TFT_TOUCH_SERVICE=ON.

NameMemoryCWDBuild dir
factory_16mb16 MBboards/esp32s3_8048s043c/Factory/boards/esp32s3_8048s043c/Factory/build/factory_16mb/

The factory variant produces the custom bootloader and partition table artefacts that all regular variants depend on. It runs from the Factory/ subdirectory and produces its own installer output under Factory/installer/ESP3D-FACTORY_16MB/. See esp32s3_8048s043c_factory.md for the factory application details.


  • The installer directory name comes from CMake (cmake/build_config_name.cmake, which appends the log level _LOG_<LEVEL>): installer_config_name(cmake_args, build_dir) reads <build_dir>/build_config_name.txt and falls back to build_config_name() before any configure; copy_factory_artifacts(cmake_args, build_dir) uses it too.
  • build_config_name() (no log suffix) is passed to generate_resources.py as --build-name, so a resources binary fits the variant with or without logs (build trailer, see tools_build_scripts_ui_resources.md).
  • New 16mb_serial_marlin variant (Marlin groundwork, TARGET_FW_MARLIN=ON).
  • components/bsp/lv_conf.h is regenerated for LVGL 9.6 (see Board_Support_Packages.md).

--check

0

non-0

--clean

build

no

yes

no

yes

factory variant

cwd = Factory/

regular variant

no

yes

python build_one.py variant_name [flags]

Look up variant dict

from VARIANTS + FACTORY_VARIANTS

Flag?

check_variant()

idf.py reconfigure

validate cmake only

result

OK

FAILED

Clean build_dir

Clean installer_dir

If factory cwd: also clean parent build dir

Done - no artifacts built

prepare_build_dir()

IDF_TARGET guard

Create dir + write .idf_target marker

generate_resources()

Decode resource_variant_string()

Run generate_resources.py

--variant --resolution --partition-csv --out

rc == 0?

FAILED

UI resources generation

run_cmake_build()

idf.py -B build_dir ... build

env: IDF_TARGET=esp32s3, PROD_BUILD=ON

rc == 0?

FAILED

cmake/ninja build

_show_size_report()

idf.py size (informational)

cwd == REPO_ROOT?

OK

copy_factory_artifacts()

Check Factory/installer/ESP3D-FACTORY_16MB/

_factory_artifacts_complete()

bootloader_*.bin

present?

_build_missing_factory()

Lookup factory config

Run build_variant(factory_16mb)

Copy bootloader, partitions, ota_data

to installer/config_name/ dir

Verify bootloader in installer/

Print file size to console

_copy_ui_resources_bin()

Copy ui_resources_*.bin

from build_dir to installer/

_package_user_resources_kit()

Find ui_resources_manifest_*.json

Run package_user_resources_kit.py

--out installer/config/ui_resources_kit/

_log_firmware_artifacts()

Append FIRMWARE section

to installer_history.log

generate_flash_map()

flash_mgr.py --generate

Produce *.json flash map


installer/ESP32S3_8048S043C_16MB_radio_fw/

flash_mgr.py --generate

package_user_resources_kit.py

Factory build (factory_16mb)

idf.py build

generate_resources.py

cmake flag source

cmake args

cmake args

make_variant_args

manifest JSON

variant dir path

VARIANTS / FACTORY_VARIANTS

dicts in variants.py

ui_resources_*.bin

esp3d_ui_offsets.h

ui_resources_manifest_*.json

firmware.bin

firmware.elf

*.map

bootloader_16MB.bin

partitions_16MB.bin

ota_data_initial.bin

ui_resources_kit/

build_ui_resources_from_manifest.py

resources_config.py

*.png *.ttf *.fnt

ESP32S3_8048S043C_16MB_*.json

flash address map

bootloader_16MB.bin

partitions_16MB.bin

ota_data_initial.bin

firmware.bin

ui_resources_*.bin

*.json flash map

ui_resources_kit/

installer_history.log


Runtime tooling

Shared build tools

Board siblings

esp32s3_8048s043c_build_scripts (this module)

auto-trigger if artifacts missing

subprocess: python build_one.py

bootloader + partition table binaries

compiled into firmware by idf.py

build_one.py

common.py

variants.py

esp32s3_8048s043c_factory

Factory app + custom bootloader

esp32s3_8048s043c_bsp

Board Support Package

generate_resources.py

(tools/build_scripts)

package_user_resources_kit.py

(tools/build_scripts)

build_mgr.py

(tools/build_scripts)

idf.py (ESP-IDF v5.4.3)

flash_mgr.py

(tools/flash_scripts)

Relationship with build_mgr.py: The higher-level Build,Resource&_Development_Toolchain.md build_mgr.py script coordinates multi-board, multi-variant batch builds by calling each board’s build_one.py as a subprocess, passing --jobs=N for parallel compilation. This module is designed to be invoked either directly by a developer or as a subprocess of build_mgr.py.


Terminal window
cd boards/esp32s3_8048s043c/build_scripts
python build_one.py 16mb_wifi_fluidnc
python build_one.py 16mb_serial_grbl
python build_one.py factory_16mb
Terminal window
python build_one.py

Output:

Usage: build_one.py <variant_name> [--clean] [--check]
Available variants:
factory_16mb
16mb_wifi_fluidnc
16mb_serial_fluidnc
16mb_serial_grbl
16mb_wifi_grblhal
Terminal window
python build_one.py 16mb_wifi_fluidnc --clean # wipe artifacts only
python build_one.py 16mb_wifi_fluidnc # then build fresh

Validate cmake configuration without compiling

Section titled “Validate cmake configuration without compiling”
Terminal window
python build_one.py 16mb_wifi_grblhal --check
Terminal window
python build_one.py 16mb_serial_fluidnc --dev
Terminal window
python build_one.py 16mb_wifi_fluidnc --jobs=8
Terminal window
# ESP-IDF must be activated before running any build
. $IDF_PATH/export.sh # Linux / macOS
%IDF_PATH%\export.bat # Windows
# IDF_PATH must point to ESP-IDF v5.4.3
export IDF_PATH=/path/to/esp-idf

If IDF_PATH is not set, common.py falls back to C:\Users\luc\esp\v5.4.3\esp-idf and exits with a clear error if idf.py is not found there.


ConstantValuePurpose
RESOLUTIONres_800_480Passed to generate_resources.py — selects image/font scale for the 800×480 panel
EXPECTED_IDF_TARGETesp32s3Written to .idf_target marker; mismatches trigger a full clean of the build directory
_TARGET_MARKER.idf_targetFilename of the per-build-dir IDF target guard file
PROD_BUILD=ONCMake defineApplied unless --dev flag is present; enables production optimisations in cmake/
Factory installer subdirESP3D-FACTORY_16MBHardcoded name matching cmake/targets.cmake’s output path for the factory build
<REPO_ROOT>/
├── build/
│ ├── esp32s3_8048s043c_16mb_wifi_fluidnc/ ← idf.py -B target
│ │ ├── .idf_target ← "esp32s3"
│ │ ├── esp3d_ui_offsets.h ← generate_resources output
│ │ ├── ui_resources_16mb_wifi_fluidnc.bin
│ │ ├── ui_resources_manifest_16mb_wifi_fluidnc.json
│ │ └── ... (cmake / ninja artifacts)
│ └── esp32s3_8048s043c_16mb_serial_grbl/
│ └── ...
│
├── installer/
│ └── ESP32S3_8048S043C_16MB_wifi_fluidnc/
│ ├── firmware.bin ← from idf.py build
│ ├── bootloader_16MB.bin ← from factory_16mb build
│ ├── partitions_16MB.bin ← from factory_16mb build
│ ├── ota_data_initial.bin ← from factory_16mb build
│ ├── ui_resources_16mb_wifi_fluidnc.bin ← from generate_resources
│ ├── ESP32S3_8048S043C_16MB_wifi_fluidnc.json ← from flash_mgr
│ ├── ui_resources_kit/ ← from package_user_resources_kit
│ └── installer_history.log
│
└── boards/esp32s3_8048s043c/
└── Factory/
└── installer/
└── ESP3D-FACTORY_16MB/ ← factory build output (source)
├── bootloader_16MB.bin
├── partitions_16MB.bin
└── ota_data_initial.bin