mirror of
https://github.com/MarlinFirmware/Marlin.git
synced 2025-12-27 09:59:52 -07:00
176 lines
7.9 KiB
Makefile
176 lines
7.9 KiB
Makefile
SCRIPTS_DIR := buildroot/share/scripts
|
||
MAKESCRIPTS_DIR := buildroot/share/make
|
||
CONTAINER_RT_BIN := docker
|
||
CONTAINER_RT_OPTS := --rm -v $(PWD):/code -v platformio-cache:/root/.platformio
|
||
CONTAINER_IMAGE := marlin-dev
|
||
UNIT_TEST_CONFIG ?= default
|
||
|
||
# Find a Python 3 interpreter
|
||
ifeq ($(OS),Windows_NT)
|
||
# Windows: use `where` – fall back through the three common names
|
||
PYTHON := $(shell which python 2>nul || which python3 2>nul || which py 2>nul)
|
||
# Windows: Use Python script to find pins files
|
||
PINS := $(shell $(PYTHON) $(MAKESCRIPTS_DIR)/find.py Marlin/src/pins -mindepth 2 -name 'pins_*.h')
|
||
else
|
||
# POSIX: use `command -v` – prefer python3 over python
|
||
PYTHON := $(shell command -v python3 2>/dev/null || command -v python 2>/dev/null)
|
||
# Unix/Linux: Use find command
|
||
PINS := $(shell find Marlin/src/pins -mindepth 2 -name 'pins_*.h')
|
||
endif
|
||
|
||
# Check that the found interpreter is Python 3
|
||
# Error if there's no Python 3 available
|
||
ifneq ($(strip $(PYTHON)),)
|
||
PYTHON_VERSION := $(shell $(PYTHON) -c "import sys; print(sys.version_info[0])" 2>/dev/null)
|
||
ifneq ($(PYTHON_VERSION),3)
|
||
$(error $(PYTHON) is not Python 3 – install a Python‑3.x interpreter or adjust your PATH)
|
||
endif
|
||
else
|
||
$(error No Python executable found – install Python 3.x and make sure it is in your PATH)
|
||
endif
|
||
|
||
help:
|
||
@echo "Tasks for local development:"
|
||
@echo "make marlin : Build Marlin for the configured board"
|
||
@echo "make format-pins -j : Reformat all pins files (-j for parallel execution)"
|
||
@echo "make validate-lines -j : Validate line endings, fails on trailing whitespace, etc."
|
||
@echo "make validate-pins -j : Validate all pins files, fails if any require reformatting"
|
||
@echo "make validate-boards -j : Validate boards.h and pins.h for standards compliance"
|
||
@echo "make validate-urls : Validate URLs in source files"
|
||
@echo "make tests-single-ci : Run a single test from inside the CI"
|
||
@echo "make tests-single-local : Run a single test locally"
|
||
@echo "make tests-single-local-docker : Run a single test locally, using docker"
|
||
@echo "make tests-all-local : Run all tests locally"
|
||
@echo "make tests-all-local-docker : Run all tests locally, using docker"
|
||
@echo "make unit-test-single-local : Run unit tests for a single config locally"
|
||
@echo "make unit-test-single-local-docker : Run unit tests for a single config locally, using docker"
|
||
@echo "make unit-test-all-local : Run all code tests locally"
|
||
@echo "make unit-test-all-local-docker : Run all code tests locally, using docker"
|
||
@echo "make setup-local-docker : Setup local docker"
|
||
@echo ""
|
||
@echo "Options for testing:"
|
||
@echo " TEST_TARGET Set when running tests-single-*, to select the"
|
||
@echo " test. If you set it to ALL it will run all "
|
||
@echo " tests, but some of them are broken: use "
|
||
@echo " tests-all-* instead to run only the ones that "
|
||
@echo " run on GitHub CI"
|
||
@echo " ONLY_TEST Limit tests to only those that contain this, or"
|
||
@echo " the index of the test (1-based)"
|
||
@echo " UNIT_TEST_CONFIG Set the name of the config from the test folder, without"
|
||
@echo " the leading number. Default is 'default'". Used with the
|
||
@echo " unit-test-single-* tasks"
|
||
@echo " VERBOSE_PLATFORMIO If you want the full PIO output, set any value"
|
||
@echo " GIT_RESET_HARD Used by CI: reset all local changes. WARNING:"
|
||
@echo " THIS WILL UNDO ANY CHANGES YOU'VE MADE!"
|
||
|
||
marlin:
|
||
./buildroot/bin/mftest -a
|
||
.PHONY: marlin
|
||
|
||
clean:
|
||
rm -rf .pio/build*
|
||
|
||
tests-single-ci:
|
||
export GIT_RESET_HARD=true
|
||
$(MAKE) tests-single-local TEST_TARGET=$(TEST_TARGET) PLATFORMIO_BUILD_FLAGS=-DGITHUB_ACTION
|
||
|
||
tests-single-local:
|
||
@if ! test -n "$(TEST_TARGET)" ; then echo "***ERROR*** Set TEST_TARGET=<your-module> or use make tests-all-local" ; return 1; fi
|
||
export PATH="./buildroot/bin/:./buildroot/tests/:${PATH}" \
|
||
&& export VERBOSE_PLATFORMIO=$(VERBOSE_PLATFORMIO) \
|
||
&& run_tests . $(TEST_TARGET) "$(ONLY_TEST)"
|
||
|
||
tests-single-local-docker:
|
||
@if ! test -n "$(TEST_TARGET)" ; then echo "***ERROR*** Set TEST_TARGET=<your-module> or use make tests-all-local-docker" ; return 1; fi
|
||
@if ! $(CONTAINER_RT_BIN) images -q $(CONTAINER_IMAGE) > /dev/null ; then $(MAKE) setup-local-docker ; fi
|
||
$(CONTAINER_RT_BIN) run $(CONTAINER_RT_OPTS) $(CONTAINER_IMAGE) make tests-single-local TEST_TARGET=$(TEST_TARGET) VERBOSE_PLATFORMIO=$(VERBOSE_PLATFORMIO) GIT_RESET_HARD=$(GIT_RESET_HARD) ONLY_TEST="$(ONLY_TEST)"
|
||
|
||
tests-all-local:
|
||
@$(PYTHON) -c "import yaml" 2>/dev/null || (echo 'pyyaml module is not installed. Install it with "$(PYTHON) -m pip install pyyaml"' && exit 1)
|
||
export PATH="./buildroot/bin/:./buildroot/tests/:${PATH}" \
|
||
&& export VERBOSE_PLATFORMIO=$(VERBOSE_PLATFORMIO) \
|
||
&& for TEST_TARGET in $$($(PYTHON) $(MAKESCRIPTS_DIR)/get_test_targets.py) ; do \
|
||
if [ "$$TEST_TARGET" = "linux_native" ] && [ "$$(uname)" = "Darwin" ]; then \
|
||
echo "Skipping tests for $$TEST_TARGET on macOS" ; \
|
||
continue ; \
|
||
fi ; \
|
||
echo "Running tests for $$TEST_TARGET" ; \
|
||
run_tests . $$TEST_TARGET || exit 1 ; \
|
||
sleep 5; \
|
||
done
|
||
|
||
tests-all-local-docker:
|
||
@if ! $(CONTAINER_RT_BIN) images -q $(CONTAINER_IMAGE) > /dev/null ; then $(MAKE) setup-local-docker ; fi
|
||
$(CONTAINER_RT_BIN) run $(CONTAINER_RT_OPTS) $(CONTAINER_IMAGE) make tests-all-local VERBOSE_PLATFORMIO=$(VERBOSE_PLATFORMIO) GIT_RESET_HARD=$(GIT_RESET_HARD)
|
||
|
||
unit-test-single-local:
|
||
platformio run -t marlin_$(UNIT_TEST_CONFIG) -e linux_native_test
|
||
|
||
unit-test-single-local-docker:
|
||
@if ! $(CONTAINER_RT_BIN) images -q $(CONTAINER_IMAGE) > /dev/null ; then $(MAKE) setup-local-docker ; fi
|
||
$(CONTAINER_RT_BIN) run $(CONTAINER_RT_OPTS) $(CONTAINER_IMAGE) make unit-test-single-local UNIT_TEST_CONFIG=$(UNIT_TEST_CONFIG)
|
||
|
||
unit-test-all-local:
|
||
platformio run -t test-marlin -e linux_native_test
|
||
|
||
unit-test-all-local-docker:
|
||
@if ! $(CONTAINER_RT_BIN) images -q $(CONTAINER_IMAGE) > /dev/null ; then $(MAKE) setup-local-docker ; fi
|
||
$(CONTAINER_RT_BIN) run $(CONTAINER_RT_OPTS) $(CONTAINER_IMAGE) make unit-test-all-local
|
||
|
||
USERNAME := $(shell whoami)
|
||
USER_ID := $(shell id -u)
|
||
GROUP_ID := $(shell id -g)
|
||
|
||
.PHONY: setup-local-docker setup-local-docker-old
|
||
|
||
setup-local-docker:
|
||
@echo "Building marlin-dev Docker image..."
|
||
$(CONTAINER_RT_BIN) build -t $(CONTAINER_IMAGE) \
|
||
--build-arg USERNAME=$(USERNAME) \
|
||
--build-arg USER_ID=$(USER_ID) \
|
||
--build-arg GROUP_ID=$(GROUP_ID) \
|
||
-f docker/Dockerfile .
|
||
@echo
|
||
@echo "To run all tests in Docker:"
|
||
@echo " make tests-all-local-docker"
|
||
@echo "To run a single test in Docker:"
|
||
@echo " make tests-single-local-docker TEST_TARGET=mega2560"
|
||
|
||
setup-local-docker-old:
|
||
$(CONTAINER_RT_BIN) buildx build -t $(CONTAINER_IMAGE) -f docker/Dockerfile .
|
||
|
||
.PHONY: $(PINS) format-pins validate-pins
|
||
|
||
$(PINS): %:
|
||
@echo "Formatting pins $@"
|
||
@$(PYTHON) $(SCRIPTS_DIR)/pinsformat.py $< $@
|
||
|
||
format-pins: $(PINS)
|
||
@echo "Processed $(words $(PINS)) pins files"
|
||
|
||
validate-pins: format-pins
|
||
@echo "Validating pins files"
|
||
@git diff --exit-code || (git status && echo "\nError: Pins files are not formatted correctly. Run \"make format-pins\" to fix.\n" && exit 1)
|
||
|
||
.PHONY: format-lines validate-lines validate-urls
|
||
|
||
format-lines:
|
||
@echo "Formatting all sources"
|
||
@$(PYTHON) $(SCRIPTS_DIR)/linesformat.py buildroot
|
||
@$(PYTHON) $(SCRIPTS_DIR)/linesformat.py Marlin
|
||
|
||
validate-lines:
|
||
@echo "Validating text formatting"
|
||
@npx prettier --check . --editorconfig --object-wrap preserve
|
||
|
||
validate-urls:
|
||
@echo "Checking URLs in source files"
|
||
@$(MAKESCRIPTS_DIR)/check-urls.sh
|
||
|
||
BOARDS_FILE := Marlin/src/core/boards.h
|
||
|
||
.PHONY: validate-boards
|
||
|
||
validate-boards:
|
||
@echo "Validating boards.h file"
|
||
@$(PYTHON) $(MAKESCRIPTS_DIR)/validate_boards.py $(BOARDS_FILE) || (echo "\nError: boards.h file is not valid. Please check and correct it.\n" && exit 1)
|