Base Makefile (basemk) Engine
Relevant source files
The following files were used as context for generating this wiki page:
The Base Makefile (basemk) Engine is a core component of the FLEXT infrastructure responsible for generating, validating, and synchronizing the standardized base.mk files used across projects. This engine ensures that all governed packages adhere to a unified "Make Contract," providing a consistent set of CLI verbs for development operations such as building, testing, linting, and documentation generation.
In the FLEXT ecosystem, the canonical base.mk file resides only within the flext-infra project. Other projects in the workspace include this functionality via a generated Makefile bootstrap mechanism, effectively centralizing build logic while maintaining local project autonomy.
Sources: src/flext_infra/basemk/generator.py:1-25, src/flext_infra/workspace/_sync_artifacts.py:117-133
Core Architecture
The engine is structured around three primary responsibilities: configuration normalization, template rendering, and output validation.
Component Overview
| Component | Responsibility | Key Class |
|---|---|---|
| Generator | Orchestrates the generation process, including writing to disk and dry-run validation. | FlextInfraBaseMkGenerator |
| Renderer | Handles Jinja2 template logic to produce the final Makefile text. | FlextInfraBaseMkTemplateRenderer |
| Validator | Ensures generated output is syntactically valid by running make --dry-run in a temp directory. | FlextInfraBaseMkGenerator._validate_generated_output |
Sources: src/flext_infra/basemk/generator.py:24-40, src/flext_infra/basemk/renderer.py:10-20
Generation Flow
The following diagram illustrates the lifecycle of a base.mk generation request:
The generator uses a "validation-first" approach, writing the generated content and a temporary Makefile to a unique directory (prefixed with flext-basemk-) to verify the output before committing it to the project root.
Sources: src/flext_infra/basemk/generator.py:53-115
The Make Contract
The engine enforces a standardized "Make Contract" which defines the public API for FLEXT projects. This contract specifies required verbs, available runtime options, and environment isolation rules.
Standard Verbs
The engine exposes a set of canonical public targets defined in PROJECT_CORE_VERBS:
boot: Install dependencies and hooks.check: Run lint gates (e.g., ruff, mypy, pyright).test: Run pytest with diagnostic support.val: Run validation gates for complexity and docstrings.docs: Generate documentation via the docs subpackage.clean: Remove build and test artifacts.
Sources: src/flext_infra/_constants/make.py:146-159, tests/unit/basemk/test_renderer.py:61-75
Runtime Configuration Options
Generated base.mk files support several dynamic variables that modify execution behavior:
| Variable | Description | Supported Values |
|---|---|---|
CHECK_GATES | Selects specific linting tools. | lint,format,pyrefly,mypy,pyright,security,markdown,smells,type |
FILE / FILES | Scopes check/fmt/test to specific paths. | e.g., src/module.py |
FIX | Enables auto-fixing for supported gates. | 1 or 0 |
CHANGED_ONLY | Filters operations to git-changed Python files. | 1 or 0 |
DIAG | Emits extended pytest diagnostics. | 1 or 0 |
Sources: src/flext_infra/_constants/make.py:35-42, tests/unit/basemk/test_make_contract.py:118-132
Template Rendering Logic
The FlextInfraBaseMkTemplateRenderer manages the composition of multiple .mk.j2 templates into a single cohesive file.
Rendering Strategy
- Configuration: Accepts a
BaseMkConfigmodel containing project-specific overrides (name, python version, etc.). - Bootstrap: Provides a specific
render_bootstrap_includemethod for subprojects to include the infra-providedbase.mkwithout local duplication. - Components: Renders specific sections like CLI group roots (e.g.,
PROJECT_INFRA_CHECK,PROJECT_INFRA_DOCS) and environment sanitization blocks.
Sources: src/flext_infra/basemk/renderer.py:45-75, src/flext_infra/workspace/_migrator_artifacts.py:148-164
Environment Isolation
A critical feature of the generated engine is the sanitization of the Python environment. It explicitly unsets PYTHONPATH and MYPYPATH before executing infra tools to prevent local environment "poisoning" during workspace-wide operations.
# Implementation detail in generated base.mk
'PROJECT_INFRA_ROOT := env -u PYTHONPATH -u MYPYPATH PYTHONPATH="$(PROJECT_INFRA_SRC)" $(VENV_PYTHON) -m flext_infra'
Sources: tests/unit/basemk/test_make_contract.py:141-155, src/flext_infra/_constants/make.py:61-76
Workspace Integration and Sync
The basemk engine is integrated into the workspace synchronization and migration services.
Synchronization Rules
- Canonical Source: If the target directory is the
flext-infraroot, the engine regenerates and overwritesbase.mkif the SHA256 hash of the content has changed. - Consumer Projects: For other projects, the synchronizer ensures
base.mkis removed if it exists locally, forcing the use of the centralized version via the Makefile bootstrap. - Makefile Update: The
FlextInfraProjectMakefileUpdatermodifies the project'sMakefileto replace old include patterns with the new bootstrap include.
Sources: src/flext_infra/workspace/_sync_artifacts.py:117-142, src/flext_infra/workspace/_migrator_artifacts.py:45-75
Migration Lifecycle
The migration process for artifacts is handled by FlextInfraProjectMigratorArtifactsMixin:
Conclusion
The Base Makefile Engine provides the foundation for FLEXT's build automation. By combining Jinja2 templating with strict validation and centralized synchronization, it ensures that every project in a workspace possesses a robust, standardized interface for development while minimizing maintenance overhead through the "include-not-duplicate" strategy.
Sources: src/flext_infra/basemk/generator.py, src/flext_infra/workspace/_sync_artifacts.py