Skip to content

esp32s3_4827s043c_build_scripts

Build automation scripts for the ESP32-S3 4827S043C board — a 480×272 capacitive-touch LCD panel. This module handles the full firmware build pipeline: CMake flag composition, ESP-IDF invocation, UI resource generation, factory artifact staging, and installer packaging for every supported firmware variant.


  1. Module Overview
  2. File Structure
  3. Architecture Diagram
  4. Component Reference
  5. Variant Catalogue
  6. Build Pipeline
  7. CMake Flag System
  8. Installer Output Layout
  9. Dependency Map
  10. Usage
  11. Related Modules

PropertyValue
BoardESP32-S3 4827S043C
Display480 × 272 px, RGB parallel, capacitive touch (GT911)
Resolution constantres_480_272
IDF targetesp32s3
Flash variants16 MB only
Supported CNC firmwaresFluidNC, grblHAL, GRBL
TransportsSerial, WiFi (socket client)
Factory appboards/esp32s3_4827s043c/Factory/

The scripts reside in boards/esp32s3_4827s043c/build_scripts/ and follow the same three-file pattern used across all board targets in this repository. They are the primary build entry point for developers targeting this board, and are also called programmatically by the repository-wide build manager (tools/build_scripts/build_mgr.py).

See also: esp32s3_4827s043c_bsp.md for the Board Support Package (BSP) that these scripts compile, and esp32s3_4827s043c_factory.md for the factory application whose artifacts are staged here.


boards/esp32s3_4827s043c/build_scripts/
├── variants.py # Variant definitions and CMake flag composition
├── common.py # Build orchestration, IDF invocation, artifact management
└── build_one.py # CLI entry point — build or check a single named variant

Factory (auto-built if absent)

boards/esp32s3_4827s043c/build_scripts/

imports

imports

reads cmake args from

subprocess: idf.py build

subprocess: generate_resources.py

subprocess: package_user_resources_kit.py

subprocess: flash_mgr.py --generate

produces

produces

postbuild copies

staged by build_variant

produces

produces

copy_factory_artifacts

merged into

python build_one.py name

variants.py

─────────────

ROOT_CMAKE_OPTIONS

make_variant_args()

VARIANTS{}

FACTORY_VARIANTS{}

common.py

─────────────

build_variant()

check_variant()

generate_resources()

copy_factory_artifacts()

generate_flash_map()

run_cmake_build()

prepare_build_dir()

build_one.py

─────────────

main()

ESP-IDF 5.x

(idf.py)

tools/build_scripts/

generate_resources.py

tools/build_scripts/

package_user_resources_kit.py

tools/flash_scripts/

flash_mgr.py

build/variant/

*.elf, *.bin, *.map

build/variant/

ui_resources_*.bin

ui_resources_manifest_*.json

installer/config_name/

*.bin, *.elf, size_report.txt

installer/config_name/

ui_resources_kit/

installer/config_name/

config_name.json

boards/esp32s3_4827s043c/Factory/

installer/ESP3D-FACTORY_16MB/

bootloader_16MB.bin

partitions_16MB.bin

...

tools/build_scripts/

build_mgr.py

(multi-variant orchestrator)


Defines what to build. No build logic lives here — it is pure data.

A master list of every CMake OPTION() that the root CMakeLists.txt exposes, covering:

CategoryOptions
Board selectionESP32S3_4827S043C, ESP32S3_8048S043C, ESP32_PIBOT_CNC_PENDANT_V1, … (16 boards total)
MemoryMEMORY_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, …
TransportsSERIAL_SERVICE, WIFI_SERVICE, BT_SERVICE, BT_SERIAL_SERVICE, BT_BLE_SERVICE, SOCKET_CLIENT_SERVICE, …
FeaturesTFT_UI_SERVICE, MDNS_SERVICE, UPDATE_SERVICE, LUA_INTERPRETER_SERVICE, SD_CARD_SERVICE, …

Auto-generated from ROOT_CMAKE_OPTIONS: a flat list of -D OPTION=OFF pairs covering every option. This ensures no stale CMake cache value from a previous build in the same directory can accidentally activate a feature not intended for the current variant.

def make_variant_args(*on_flags):
args = DEFAULT_OFF_CMAKE_ARGS.copy() # all options → OFF
for flag in on_flags:
args.extend(["-D", flag]) # selectively enable
return args

Returns the full -D KEY=VALUE list for one variant. Each on_flag is a string like "ESP32S3_4827S043C=ON" that appends after the blanket-off defaults, overriding them. CMake processes -D flags left-to-right, so later values win.

KeyTransportCNC FirmwareKey extra features
16mb_wifi_fluidncWiFi + SerialFluidNCMDNS, SOCKET_CLIENT, LUA
16mb_serial_fluidncSerial onlyFluidNCUPDATE
16mb_serial_grblSerial onlyGRBLUPDATE
16mb_wifi_grblhalWiFi + SerialgrblHALMDNS, SOCKET_CLIENT, LUA

Each entry is a dict with four keys:

{
"name": "16mb_wifi_fluidnc", # human label and log identifier
"cmake": make_variant_args(...), # full CMake arg list
"cwd": REPO_ROOT, # idf.py working directory
"build_dir": os.path.join(BUILD_BASE, "esp32s3_4827s043c_16mb_wifi_fluidnc"),
}
KeyMemoryCWDPurpose
factory_16mb16 MBboards/esp32s3_4827s043c/Factory/Factory application — provides bootloader and partition table for all regular variants

Factory variants use a minimal CMake flag set (memory only) because the factory app has its own CMakeLists.txt and does not share the root feature flag system.


Implements how to build. All subprocess calls and file management are centralised here.

ConstantValue
SCRIPT_DIRAbsolute path to build_scripts/
BOARD_ROOTboards/esp32s3_4827s043c/
REPO_ROOTRepository root
IDF_PATHFrom env IDF_PATH, defaults to a local Windows path
IDF_PY$IDF_PATH/tools/idf.py
GENERATE_RESOURCEStools/build_scripts/generate_resources.py
PACKAGE_USER_KITtools/build_scripts/package_user_resources_kit.py
RESOLUTION"res_480_272" — must match board_config.cmake
EXPECTED_IDF_TARGET"esp32s3"
FunctionPurpose
ensure_idf_py()Validate idf.py is reachable; exit with an informative message if not
prepare_build_dir(build_dir)Create dir; write .idf_target marker; wipe dir if marker mismatches EXPECTED_IDF_TARGET
clean_build_dir(build_dir)shutil.rmtree a build or installer directory
parse_cmake_flags(cmake_args)Parse a -D KEY=VALUE list into a dict
build_config_name(cmake_args)Derive installer subdirectory name, e.g. ESP32S3_4827S043C_16MB_wifi_fluidnc
resource_variant_string(cmake_args)Derive the generate_resources.py --variant string, e.g. 16mb_wifi_fluidnc; returns None for factory
generate_resources(cmake_args, build_dir)Invoke generate_resources.py to produce ui_resources_*.bin + manifest
run_cmake_build(cmake_args, cwd, build_dir)idf.py -B <build_dir> <cmake_args> build
run_cmake_check(cmake_args, cwd, build_dir)idf.py -B <build_dir> <cmake_args> reconfigure
check_variant(config)Run run_cmake_check and report pass/fail
build_variant(config)Full build pipeline (see §6)
copy_factory_artifacts(cmake_args)Merge factory installer dir into variant installer dir; auto-builds factory if absent
installer_dir_for(config)Resolve output installer path for a given variant config
generate_flash_map(config)Run flash_mgr.py --generate to produce <config>.json
_get_jobs_env_value()Extract --jobs=N from sys.argv for CMAKE_BUILD_PARALLEL_LEVEL
_show_size_report(build_dir, cwd)idf.py size — printed to stdout only, not blocking
_copy_ui_resources_bin(build_dir, installer_dir)Stage ui_resources_*.bin to installer dir
_package_user_resources_kit(...)Run package_user_resources_kit.py to create ui_resources_kit/
_log_firmware_artifacts(...)Append build provenance to installer_history.log
_factory_artifacts_complete(source_dir)Check that bootloader_*.bin exists in factory installer dir
_build_missing_factory(source_dir)Recursively invoke build_variant for the matching factory variant
_ensure_clean_build_dir(build_dir)Internal: wipe build dir on IDF_TARGET mismatch

prepare_build_dir writes a .idf_target marker file into every build directory containing the string esp32s3. If the marker exists but contains a different target string (e.g. esp32 left over from a different board), the directory is wiped automatically before any new files are written. This prevents silent cross-target contamination when a build directory is reused across different boards.

Unless --dev is present in sys.argv, the flag -D PROD_BUILD=ON is appended automatically to every CMake invocation. This keeps debug/logging symbols out of release images without requiring the caller to remember the flag.

_get_jobs_env_value() scans sys.argv for --jobs=N (injected by build_mgr.py) and sets CMAKE_BUILD_PARALLEL_LEVEL in the subprocess environment. The idf.py CLI does not accept -j/--jobs directly, so the environment variable is the correct mechanism.


Thin CLI wrapper around common.build_variant and common.check_variant.

Usage: python build_one.py <variant_name> [--clean] [--check]
Flags:
--clean Wipe build dir + installer dir before building.
--check Run cmake reconfigure only (no compilation — fast).

main() control flow:

No

Yes

No

Yes

Yes

No

start

positional args present?

print usage + available variant names

exit 1

merge FACTORY_VARIANTS + VARIANTS

into all_variants dict

name in all_variants?

print error + available names

exit 1

--check in args?

check_variant(all_variants[name])

exit with return code

build_variant(all_variants[name])

exit with return code

The merged lookup ({**FACTORY_VARIANTS, **VARIANTS}) ensures factory and regular variants share the same CLI namespace — python build_one.py factory_16mb works the same as python build_one.py 16mb_wifi_fluidnc.


ESP32S3-4827S043C - 16 MB Flash

16mb_wifi_fluidnc

FluidNC · WiFi + Serial

MDNS · SocketClient · Lua

16mb_serial_fluidnc

FluidNC · Serial

Update

16mb_serial_grbl

GRBL · Serial

Update

16mb_wifi_grblhal

grblHAL · WiFi + Serial

MDNS · SocketClient · Lua

Variant keyMemoryTransportCNC targetNotable extra features
16mb_wifi_fluidnc16 MBWiFi + SerialFluidNCMDNS, SocketClient, Lua
16mb_serial_fluidnc16 MBSerialFluidNCUpdate
16mb_serial_grbl16 MBSerialGRBLUpdate
16mb_wifi_grblhal16 MBWiFi + SerialgrblHALMDNS, SocketClient, Lua

All four variants share: ESP32S3_4827S043C=ON, MEMORY_16_MB=ON, TFT_UI_SERVICE=ON, TFT_TOUCH_SERVICE=ON, SERIAL_SERVICE=ON.

Variant keyMemoryCWDArtifacts produced
factory_16mb16 MBboards/esp32s3_4827s043c/Factory/bootloader_16MB.bin, partitions_16MB.bin, factory app binary

Regular variant builds automatically invoke the factory build if its artifacts are absent or incomplete (no bootloader_*.bin).


The full sequence executed by build_variant(config):

Yes

No

No

Yes

No

Yes

No

Yes

No

Yes

build_variant called

--clean flag?

clean_build_dir(build_dir)

clean_build_dir(installer_dir)

if factory cwd: wipe parent build dir too

return 0

prepare_build_dir(build_dir)

• check .idf_target marker

• wipe if IDF_TARGET mismatch

• create dir

• write marker

generate_resources(cmake_args, build_dir)

• resolve resource_variant_string()

• run generate_resources.py

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

[--board-resources if boards/.../resources/ exists]

returncode == 0?

FAILED: ui_resources generation

return non-zero

run_cmake_build(cmake_args, cwd, build_dir)

• idf.py -B build_dir cmake_args [-D PROD_BUILD=ON] build

• env IDF_TARGET=esp32s3

• env CMAKE_BUILD_PARALLEL_LEVEL=N (if --jobs=N)

returncode == 0?

FAILED: firmware build

return non-zero

_show_size_report()

idf.py size (informational only)

cwd == REPO_ROOT?

i.e. not a factory variant

OK: factory variant done

return 0

copy_factory_artifacts(cmake_args)

• locate Factory/installer/ESP3D-FACTORY_16MB/

• if missing or incomplete: _build_missing_factory()

• copy bootloader, partitions, factory bin

into installer/config_name/

returncode == 0?

FAILED: factory artifacts unavailable

return 1

verify bootloader_16MB.bin in installer dir

(print file size for confirmation)

_copy_ui_resources_bin(build_dir, installer_dir)

copy ui_resources_*.bin into installer/config_name/

_package_user_resources_kit()

• find ui_resources_manifest_*.json in build_dir

• run package_user_resources_kit.py

into installer/config_name/ui_resources_kit/

non-fatal on failure

_log_firmware_artifacts()

append FIRMWARE and FACTORY entries

to installer_history.log

generate_flash_map(config)

flash_mgr.py --variant-dir ... --generate

into installer/config_name/config_name.json

OK: return 0

StepTool invokedPrimary output
UI resource generationtools/build_scripts/generate_resources.pyui_resources_<variant>.bin, ui_resources_manifest_<variant>.json, esp3d_ui_offsets.h
Firmware compilationidf.py build<variant>.elf, <variant>.bin, bootloader.bin, partitions.bin
Size reportidf.py sizeStdout only
Factory staginginternal shutil.copy2bootloader_16MB.bin, partitions_16MB.bin, factory bin → installer/<config>/
UI resource staginginternal shutil.copy2ui_resources_<variant>.bin → installer/<config>/
User kit packagingtools/build_scripts/package_user_resources_kit.pyinstaller/<config>/ui_resources_kit/
Provenance logginginternalinstaller/<config>/installer_history.log (append)
Flash map generationtools/flash_scripts/flash_mgr.py --generateinstaller/<config>/<config>.json

  • 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).

ROOT_CMAKE_OPTIONS

40+ option names

DEFAULT_OFF_CMAKE_ARGS

-D BOARD_A=OFF

-D BOARD_B=OFF

-D MEMORY_4_MB=OFF

... all options OFF

make_variant_args

'ESP32S3_4827S043C=ON'

'MEMORY_16_MB=ON'

'TARGET_FW_FLUIDNC=ON'

...

Final cmake arg list passed to idf.py

...-D ESP32S3_4827S043C=ON

...-D MEMORY_16_MB=ON

...-D TARGET_FW_FLUIDNC=ON

+ -D PROD_BUILD=ON (added by common.py)

The “all-off, then selectively enable” strategy ensures reproducible configuration regardless of what is cached in the build directory.

build_config_name() maps CMake flags to a canonical installer directory name:

Pattern: ESP32S3_4827S043C_{MEMORY}{_radio}_{firmware}
Examples:
ESP32S3_4827S043C_16MB_wifi_fluidnc
ESP32S3_4827S043C_16MB_serial_grbl
ESP32S3_4827S043C_16MB_wifi_grblhal

resource_variant_string() maps the same flags to the shorter resource variant identifier used by generate_resources.py:

Pattern: {mem}mb_{transport}_{firmware}
Examples:
16mb_wifi_fluidnc
16mb_serial_grbl
16mb_wifi_grblhal

Returns None for factory variants — they have no UI resource partition.

CategoryRule
Board selectionExactly one board flag =ON
MemoryExactly one memory flag =ON
Firmware targetExactly one TARGET_FW_*=ON
WiFi vs BluetoothMutually exclusive — no PSRAM on this board. cmake/sanity_check.cmake enforces this at configure time.
SOCKET_CLIENT_SERVICEOnly valid when WIFI_SERVICE=ON. When ON, WEBUI_SERVER, SSDP_SERVICE, and WS_SERVER_SERVICE are prohibited.

After a successful build_variant for a regular variant:

installer/ESP32S3_4827S043C_16MB_wifi_fluidnc/
├── bootloader_16MB.bin ← factory artifact
├── partitions_16MB.bin ← factory artifact
├── ESP3D-FACTORY_16MB.bin ← factory artifact
├── ESP32S3_4827S043C_16MB_wifi_fluidnc.bin ← main firmware
├── ESP32S3_4827S043C_16MB_wifi_fluidnc.elf ← debug symbols
├── ui_resources_16mb_wifi_fluidnc.bin ← UI partition
├── ESP32S3_4827S043C_16MB_wifi_fluidnc.json ← flash map
├── size_report.txt ← memory usage summary
├── installer_history.log ← provenance audit trail
└── ui_resources_kit/ ← standalone customization kit
├── README.md
├── ui_resources_manifest_16mb_wifi_fluidnc.json
├── build_ui_resources_from_manifest.py
└── resources/
└── (default PNG + font sources)

Factory variant output:

boards/esp32s3_4827s043c/Factory/installer/ESP3D-FACTORY_16MB/
├── bootloader_16MB.bin
├── partitions_16MB.bin
└── ESP3D-FACTORY_16MB.bin

The installer_history.log separates entries by type to track which files came from the factory build and which from the firmware build:

[2026-08-18 10:30:00] factory artifacts from .../Factory/installer/ESP3D-FACTORY_16MB
FACTORY bootloader_16MB.bin
FACTORY partitions_16MB.bin
FACTORY ESP3D-FACTORY_16MB.bin
[2026-08-18 10:35:42] firmware build: 16mb_wifi_fluidnc
FIRMWARE ESP32S3_4827S043C_16MB_wifi_fluidnc.bin
FIRMWARE ESP32S3_4827S043C_16MB_wifi_fluidnc.elf
FIRMWARE ui_resources_16mb_wifi_fluidnc.bin

ESP-IDF 5.4.3

Factory source

Firmware source

tools/ (external scripts)

esp32s3_4827s043c_build_scripts

subprocess

subprocess

subprocess

subprocess

subprocess

reads

reads

reads

reads board config from

uses RESOLUTION constant from

build_one.py

common.py

variants.py

build_scripts/generate_resources.py

build_scripts/package_user_resources_kit.py

flash_scripts/flash_mgr.py

build_scripts/build_mgr.py

calls build_one.py per variant

CMakeLists.txt

cmake/features.cmake

cmake/sanity_check.cmake

boards/esp32s3_4827s043c/

components/bsp/

board_config.cmake

boards/esp32s3_4827s043c/Factory/

CMakeLists.txt and main/*.c

idf.py


Terminal window
# Navigate to the build scripts directory
cd boards/esp32s3_4827s043c/build_scripts
# Standard firmware build
python build_one.py 16mb_wifi_fluidnc
# Factory application build
python build_one.py factory_16mb
# Clean build — wipes build dir + installer dir first
python build_one.py 16mb_serial_grbl --clean
# CMake reconfigure only — fast config check, no compilation
python build_one.py 16mb_wifi_grblhal --check
# List all available variant names
python build_one.py
Terminal window
# From repository root
python tools/build_scripts/build_mgr.py --board esp32s3_4827s043c
# Parallel build with 8 jobs
python tools/build_scripts/build_mgr.py --board esp32s3_4827s043c --jobs=8
RequirementNotes
IDF_PATH env variableMust point to ESP-IDF 5.4.3 installation
ESP-IDF activated shellRun . $IDF_PATH/export.sh (Linux/Mac) or export.bat (Windows) before building
Python 3.8+Used via sys.executable for all subprocess calls, ensuring version consistency
--dev flagOmit PROD_BUILD=ON to retain debug/verbose logging macros in the firmware
  1. Open boards/esp32s3_4827s043c/build_scripts/variants.py.
  2. Add an entry to VARIANTS using make_variant_args():
"16mb_serial_grblhal": {
"name": "16mb_serial_grblhal",
"cmake": make_variant_args(
"ESP32S3_4827S043C=ON",
"MEMORY_16_MB=ON",
"TARGET_FW_GRBLHAL=ON",
"SERIAL_SERVICE=ON",
"TFT_UI_SERVICE=ON",
"TFT_TOUCH_SERVICE=ON",
"UPDATE_SERVICE=ON",
),
"cwd": REPO_ROOT,
"build_dir": os.path.join(BUILD_BASE, "esp32s3_4827s043c_16mb_serial_grblhal"),
},
  1. Verify the CMake configuration: python build_one.py 16mb_serial_grblhal --check.
  2. Run a full build: python build_one.py 16mb_serial_grblhal.

Constraint reminder: WiFi (WIFI_SERVICE) and Bluetooth (BT_SERVICE) are mutually exclusive on this board (no PSRAM). cmake/sanity_check.cmake enforces this at configure time. Refer to docs/features/feature_resource_matrix.md before adding new service combinations, and docs/guides/esp32_memory_constraints.md for RAM budget implications.


ModuleRelationship
esp32s3_4827s043c_bsp.mdBSP compiled by these scripts — board_init, LVGL setup, RGB display driver, GT911 touch
esp32s3_4827s043c_factory.mdFactory application whose installer artifacts are staged during regular variant builds
tools_build_scripts.mdRepository-wide build tools: build_mgr.py, generate_resources.py, package_user_resources_kit.py
esp32_3248s035c_build_scripts.mdSibling board build scripts — identical three-file pattern, SPI display
esp32_3248s035r_build_scripts.mdSibling board build scripts — SPI display, resistive touch
esp32s3_8048s043c.mdSibling ESP32-S3 board — 800×480 RGB display, same build script pattern
esp32s3_8048s070c_build_scripts.mdSibling ESP32-S3 board — 800×480 7-inch display
docs/guides/board_build_guidelines.mdCross-board build conventions and guidelines
docs/features/feature_resource_matrix.mdFeature compatibility matrix — consult before changing transport or service flags
docs/ui_resources/development.mdUI resource partition format; explains generate_resources.py inputs and outputs
docs/guides/esp32_memory_constraints.mdESP32-S3 heap constraints relevant to variant selection