New feature in Eiffel-Loop scons build system
Self-contained exported environment variables in ECF files
Hi all,
I have started on a project for a long overdue upgrade to Eiffel-Loop for current compiler tools and OS environments.
The first task was to convert the scons build system to use Python v3.12.x and scons v4.5.x
I wanted to share a new feature in the Eiffel-Loop scons build system that redesigns how environment variables are defined for Eiffel projects. The goal is to make ECF files fully self-contained — no more maintaining a pile of path definitions in .profile, a separate bash script, or the Windows environment just to build a project.
The export: block
Inside any target's description: field (which EiffelStudio treats as free-form text and ignores), you can now declare an export: section (Borrowing from Bash keyword). The scons build system parses this and injects the defined variables directly into os.environ — both when building with ecf and when launching EiffelStudio via the Eiffel-Loop Python scripts.
For readability the examples shown use a custom Pyxis representation of ECF XML
A basic example from ID3-tags.pecf:
The * wildcard means a version number in the directory name is matched via Python globbing, so you never need to hard-code version strings like id3lib-3.8.3.
Calling a Python function to discover a path
Where a path can't be expressed as a glob, you can delegate to a Python function instead. From ES-eiffel2java.pecf:
The jdk_home() function handles platform-specific discovery (registry lookup on Windows, JAVA_HOME / which java on Unix). Importantly, if JDK_HOME is already set in the environment — for example on a CI machine — the function respects that and steps aside. It only fires the discovery logic when needed, so existing setups are unaffected.
Recursive ECF scanning
The scons build system recursively walks the full ECF dependency graph from your application ECF outward, collecting export: blocks from every library ECF it encounters. This means transitive dependencies like LIB_ID3TAG are picked up automatically without any knowledge of them at the application level. Each library ECF owns its own environment requirements.
Reducing verbosity in large ECF files
The exported variables also serve as reusable aliases within the ECF itself. A good example is ES-vision2.pecf, an override of ISE's vision2.ecf. Two variables are exported:
These are then referenced across roughly 20 external_include, external_cflag, external_linker_flag, and cluster entries throughout the file — avoiding repetition of the full paths every time. Because these are real os.environ variables by build time, they even work correctly inside backtick shell expansions like:
Summary
For reference I've attached the example Pyxis format ECF files:
ID3-tags.pecf, ES-eiffel2java.pecf, ES-vision2.pecf
Regards
Finnian