The RetroDECK Alchemist - Guide
The alchemist.sh it is a Plugin‑Based Component Assembler.
Alchemy - noun - "A power or process that changes or transforms something in a mysterious or impressive way."
HEREBY BE WARNED!
The RetroDECK Alchemist is a magician / chef / bartender
Who, when given the proper instruction, can transmute one or more base source ingredients into the perfect creation of a component artifact.
Alchemy and cooking are, by definition, delicate.
- The ingredients must be known and pure.
- The recipe must be exact.
- Any deviation from this process can be disastrous.
To achieve a perfect artifact, the ingredients must be well known.
Only by pulling ingredients when they are just right can we guarantee consistency.
To always chase the freshest ingredients all the time is a fool’s errand and would produce unreliable artifacts.
(Be careful with versioning of components for stable builds and lock them down.)
Repository Context
- The
alchemist.shscript is invoked from the…/componentsdirectory of the cloned repository:
https://github.com/RetroDECK/components.git - The script’s location is flexible, but the calling directory matters:
- If run inside a Git repo,
$REPO_ROOTpoints to the repo’s root. - Otherwise,
$REPO_ROOTdefaults to the directory containingalchemist.sh.
Running Locally
Follow the steps below to build a component artifact locally using Alchemist.
1. Download Alchemist
Clone or download the Alchemist automation tools directory from the RetroDECK repository: Cooker: Alchemist
2. Prepare Your Component Directory
Place the component directory (containing the recipe and ingredient files) inside the alchemist directory using the following structure:
alchemist/<new-component-directory>/<files>
Your component directory must include a component_recipe.json and the other ingredient files.
3. Build the Artifact
From within the alchemist directory, run:
./alchemist.sh -f <component-directory>/component_recipe.json
4. Output
After a successful build, the generated artifact will be available at:
<component-directory>/artifact/<component-artifact>.tar.gz
5. Extract the Artifact
Extract the generated artifact: <component-artifact>.tar.gz
This will create a new component directory.
6. Install the Component
Move the extracted component directory into RetroDECK’s internal components directory.
Note:
The installation path depends on whether RetroDECK is installed locally (user) or system-wide.
A system-wide installation requires sudo privileges to modify files.
| Directory Name | Path (Local Install) | Path (System Install) | Comment |
|---|---|---|---|
components |
~/.local/share/flatpak/app/net.retrodeck.retrodeck/current/active/files/retrodeck/components/ |
/var/lib/flatpak/app/net.retrodeck.retrodeck/current/active/files/retrodeck/components/ |
RetroDECK components directory |
7. Launch RetroDECK
Start RetroDECK after installation. If everything is configured correctly, RetroDECK will automatically detect and load the newly installed component.
If the component does not appear in the frontend, you may need to update the ES-DE custom configuration files to register the new component.
Configuration files:
retrodeck/ES-DE/custom_systems/es_find_rules.xml
retrodeck/ES-DE/custom_systems/es_systems.xml
Add the appropriate entries to ensure the new component is properly defined and discoverable within ES-DE.
Creating a new componment_recipe.json tips
Tip 1: Component Source Format: What to Prioritize?
When multiple source formats are available for a component, prioritize them in the following order for ease of integration with RetroDECK:
| Priority | Format | Description |
|---|---|---|
| 1 | Flatpak | A sandboxed package format commonly used on Linux for app distribution , published on flathub |
| 2 | AppImage | A portable, self-contained executable that runs without installation |
| 3 | Precompiled Binary | A ready-to-run executable built for a specific platform |
| 4 | Build from Source | Raw source code that must be compiled manually before use |
Tip 2: Templates and Examples of component_recipe.json
On the wiki (linked next to this guide), you’ll find templates and example component_recipe.json files.
Use these as a baseline when creating a new recipe. More examples will be added over time.
You should also check the cooker components repository for the most up-to-date recipes to use as inspiration:
RetroDECK Components Repository (cooker branch)
Structure of component_recipe.json
All component_recipe.json contain at least four parts:
Name
- The root key of the
component_recipe.jsonfile, indicating the component’s name. - The artifact name and some source paths (e.g., the directory name in the components repo) are derived from this name, so it should be consistent across the component.
Source
- Each component has a single source from which files are pulled to be stored in the final artifact.
Asset
- Every component source includes at least one asset-the file(s) pulled from the source ingredient.
Extras
- Minimum extras: component launcher, component manifest, and shipped default config.
- May also include prepared symlinks or other locally‑available files that do not come from downloaded sources.
Optional Inclusions
Additional Sources
- Used when a component requires more than one download to gather all needed files, or when the original source is a nested archive requiring multiple extraction passes.
Additional Assets
- Each source can have its own set of assets, directing the recipe to pull specific files from specific sources.
Libraries
- Most sources need extra libraries to function within the base Flatpak environment.
- The
hunt_libraries.shscript can bootstrap a list of requirements for every binary.
Key Principles
- Pin to a Release - All ingredients must be taken from a fixed release to preserve quality and avoid unpredictable changes.
- Stable Versions List - The
desired_versions.shfile enumerates all "stable" source versions. These can be referenced in component recipes as placeholders, reducing the need for frequent edits when a new stable version appears.
Example - Recipe Breakdown: Azahar
{
"azahar": [
{
"source_url": "org.azahar_emu.Azahar",
"source_type": "flatpak_id",
"version": "$AZAHAR_DESIRED_VERSION",
"dest": "user",
"extraction_type": "flatpak",
"assets": [
{
"type": "dir",
"source": "bin",
"dest": "bin"
},
{
"type": "dir",
"source": "$REPO_ROOT/$COMPONENT_NAME",
"dest": "$COMPONENT_ARTIFACT_ROOT"
},
{
"type": "create",
"dest": "component_version",
"contents": "$SOURCE_VERSION"
},
{
"type": "dir",
"source": "$REPO_ROOT/$COMPONENT_NAME/assets/rd_config",
"dest": "rd_config"
},
{
"type": "file",
"source": "$REPO_ROOT/$COMPONENT_NAME/component_functions.sh",
"dest": "$COMPONENT_ARTIFACT_ROOT"
},
{
"type": "file",
"source": "$REPO_ROOT/$COMPONENT_NAME/component_launcher.sh",
"dest": "$COMPONENT_ARTIFACT_ROOT"
},
{
"type": "file",
"source": "$REPO_ROOT/$COMPONENT_NAME/component_manifest.json",
"dest": "$COMPONENT_ARTIFACT_ROOT"
},
{
"type": "file",
"source": "$REPO_ROOT/$COMPONENT_NAME/component_recipe.json",
"dest": "$COMPONENT_ARTIFACT_ROOT"
},
{
"type": "file",
"source": "$REPO_ROOT/$COMPONENT_NAME/component_prepare.sh",
"dest": "$COMPONENT_ARTIFACT_ROOT"
}
],
"libs": []
}
]
}
Component Recipes: Component Information & Key‑Value Reference
| Field | Description |
|---|---|
| JSON root key | Defines the component name and creates the placeholder variable $COMPONENT_NAME. |
| source_url | {SOURCE_URL} - URL/path to download the source. Acceptable forms: direct HTTP(S) link, redirect, GitHub repo URL, flathub ID or local filesystem path. Can contain a {VERSION} placeholder that will be replaced by the value of the version key. Relative local paths expand to $WORKDIR/. |
| source_type | {SOURCE_TYPE} - Determines which downloader plugin to use • - flatpak-id - Flathub ID - github-release - Github Releases - http - Web download |
| version | {VERSION} - Specific version to fetch. For non‑local sources, this replaces {VERSION} in source_url. For local sources, latest can be used if no version is required. Required for all types except local. Substituted for {VERSION} in source_url.• http / github-release - Specific version string (or latest for GitHub) |
| extraction_type | {EXTRACTION_TYPE} - Extraction plugin to apply to the downloaded file. Supported methods:• appimage - Extract AppImage ($EXTRACTED_PATH = <dest>/<AppImage‑name>-extracted)• archive - Extract any archive ($EXTRACTED_PATH = <dest>/<archive‑name>-extracted)• local / git / flatpak - Dummy plugins returning $DOWNLOADED_FILE as $EXTRACTED_PATH |
| dest | (Optional) Absolute destination for download/extraction. Defaults to $WORKDIR. For flatpak-id it also selects install scope (user / system). |
| additional_sources | (Optional) Array of extra source objects with the same structure, allowing multiple downloads to be processed similarly. |
assets
Items to copy from the extracted source into the final artifact.
| Field | Description |
|---|---|
| type | Defines the kind of asset operation.dir - Pull an entire directoryfile - Pull a single filesymlink - Create a symbolic linkcreate - Create a filearchive - Create an archivemerge - Merge filesfile-rename - Rename filesscript - Run a bash script |
| source | Path to the desired or created file, script, or directory, relative to $EXTRACTED_PATH (from the extraction stage).Example: usr/bin |
| dest | Destination relative to $COMPONENT_ARTIFACT_ROOT for dir, file, and create.For symlink, this is an absolute target path.If a relative path is provided, it expands to: $COMPONENT_ARTIFACT_ROOT/<dest>For archive, specify the output archive type:7z, zip, tar.gz, tgz, tar.bz2, tbz2, tar.xz, txz, tar |
| contents | (Optional) Allows inserting provided content directly into the destination file. For script, this can also define arguments such as --verbose. |
libs
This section lists additional library objects, each processed identically to the library entries described earlier.
For guidance on generating a starting array automatically, refer to the library hunter documentation. It explains how to use hunt_libraries.sh to bootstrap your libs[] array.
| Field | Description |
|---|---|
| library | Name of the library to collect. Libraries are resolved by stripping the filename to its base extension to capture dynamic symlinks. Example: specifying libQt6Widgets.so.6 gathers all matching files like libQt6Widgets.so* from the source. |
| runtime_name | (Optional) Name of the Flatpak runtime from which to obtain the library. Requires runtime_version. |
| runtime_version | (Optional) Specific Flatpak runtime version to target. Requires runtime_name. |
| dest | Directory where the library should be placed, relative to $COMPONENT_ARTIFACT_ROOT.If a runtime is specified, expands to: $COMPONENT_ARTIFACT_ROOT/<runtime_name>/<runtime_version>/Otherwise expands to: $COMPONENT_ARTIFACT_ROOT/Most libraries should use shared-libs to support the decoupling features in the RetroDECK build process.However, this depends on the application - some require libraries in lib or directly next to the binary. |
| source | (Optional) Specifies a concrete source location for the library, relative to $EXTRACTED_PATH when not using a runtime.Used when the library must be taken from a specific asset rather than a Flatpak runtime. |
\(REPO_ROOT/\)COMPONENT_NAME/assets/
This directory contains all custom, component-specific RetroDECK configuration files and assets that need to be included in the Flatpak environment.
Examples:
- Component-specific RetroDECK pre-configured files located under
$REPO_ROOT/$COMPONENT_NAME/assets/rd_config, ranging from individual files to organized subfolders. - Other assets required by the component.
For additional examples, see the components repo.
\(REPO_ROOT/\)COMPONENT_NAME/tmp_assets/
This directory stores component-specific temporary files and assets. Not all files in this directory are included in the final Flatpak. Only the files required by the recipe are used.
Examples:
- Built from Source component artifacts compressed into a
.tar.gzfile, stored in$REPO_ROOT/$COMPONENT_NAME/tmp_assets/<component>.tar.gzfor recipes that cannot fetch them from external sources.
For additional examples, see the components repo.
Guide: Adding Libraries - The Library Hunter
Use hunt_libraries.sh to automatically generate the libs[] array:
Simply run the script against the binary you are integrating, and it will help identify the required libraries.
Note:
This is not a perfect solution, but it provides a solid starting point and can significantly speed up the process.
Best Practices While Hunting Libraries
It is recommended to have multiple GNOME and KDE Platform runtimes installed, as the hunter can resolve libraries directly from the corresponding runtime.
For older components, dependencies may require libraries from previous runtime versions. Rather than defining these manually, the hunter can automatically pull the correct versions from the appropriate runtime.
If the hunter cannot locate certain libraries, check whether they are included in the component’s native libraries and grab it from there.
In rare cases where a required library is not available via the component package or the found by the hunter:
- Locate the library manually (from the web or your host system).
- Include it as a
tmp_assetin a compressed format. - Integrate it during the recipe process.
Nested Archives & additional_sources
- A nested archive creates a new archive that also needs extraction.
- Objects are processed in the order they appear in the recipe, allowing later sources to depend on earlier ones.
Simplified Example: Extracting a Nested Archive
{
"retroarch": [
{
"source_url": "https://buildbot.libretro.com/stable/{VERSION}/linux/x86_64/RetroArch.7z",
"source_type": "http",
"version": "1.22.2",
"extraction_type": "archive",
"assets": [
{
"type": "dir",
"source": "RetroArch-Linux-x86_64/RetroArch-Linux-x86_64.AppImage.home/.config/retroarch/cores",
"dest": "$WORKDIR/cores"
},
{
"type": "dir",
"source": "RetroArch-Linux-x86_64/RetroArch-Linux-x86_64.AppImage.home/.config/retroarch/overlays",
"dest": "$WORKDIR/overlays"
},
{
"type": "merge",
"source": "$REPO_ROOT/$COMPONENT_NAME/assets/rd_extras/borders",
"dest": "$WORKDIR/overlays/borders"
},
{
"type": "dir",
"source": "RetroArch-Linux-x86_64/RetroArch-Linux-x86_64.AppImage.home/.config/retroarch/assets",
"dest": "assets"
},
{
"type": "dir",
"source": "RetroArch-Linux-x86_64/RetroArch-Linux-x86_64.AppImage.home/.config/retroarch/autoconfig",
"dest": "autoconfig"
},
{
"type": "dir",
"source": "RetroArch-Linux-x86_64/RetroArch-Linux-x86_64.AppImage.home/.config/retroarch/database/cursors",
"dest": "database/cursors"
},
{
"type": "dir",
"source": "RetroArch-Linux-x86_64/RetroArch-Linux-x86_64.AppImage.home/.config/retroarch/database/rdb",
"dest": "database/rdb"
},
{
"type": "dir",
"source": "RetroArch-Linux-x86_64/RetroArch-Linux-x86_64.AppImage.home/.config/retroarch/filters",
"dest": "filters"
},
{
"type": "tar.gz",
"source": "RetroArch-Linux-x86_64/RetroArch-Linux-x86_64.AppImage.home/.config/retroarch/shaders/.",
"dest": "rd_extras/shaders"
},
{
"type": "dir",
"source": "$REPO_ROOT/$COMPONENT_NAME/assets/rd_config",
"dest": "rd_config"
},
{
"type": "file",
"source": "$REPO_ROOT/$COMPONENT_NAME/assets/rd_extras/ScummVM.zip",
"dest": "rd_extras"
},
{
"type": "create",
"dest": "component_version",
"contents": "$SOURCE_VERSION"
},
{
"type": "file",
"source": "$REPO_ROOT/$COMPONENT_NAME/component_functions.sh",
"dest": "$COMPONENT_ARTIFACT_ROOT"
},
{
"type": "file",
"source": "$REPO_ROOT/$COMPONENT_NAME/component_launcher.sh",
"dest": "$COMPONENT_ARTIFACT_ROOT"
},
{
"type": "file",
"source": "$REPO_ROOT/$COMPONENT_NAME/component_manifest.json",
"dest": "$COMPONENT_ARTIFACT_ROOT"
},
{
"type": "file",
"source": "$REPO_ROOT/$COMPONENT_NAME/component_recipe.json",
"dest": "$COMPONENT_ARTIFACT_ROOT"
},
{
"type": "file",
"source": "$REPO_ROOT/$COMPONENT_NAME/component_prepare.sh",
"dest": "$COMPONENT_ARTIFACT_ROOT"
},
{
"type": "file",
"source": "$REPO_ROOT/$COMPONENT_NAME/component_update.sh",
"dest": "$COMPONENT_ARTIFACT_ROOT"
}
],
"libs": []
},
{
"source_url": "$EXTRACTED_PATH/RetroArch-Linux-x86_64/RetroArch-Linux-x86_64.AppImage",
"source_type": "local",
"extraction_type": "appimage",
"assets": [
{
"type": "dir",
"source": "usr/bin",
"dest": "bin"
}
]
},
{
"source_url": "https://buildbot.libretro.com/stable/{VERSION}/linux/x86_64/RetroArch_cores.7z",
"source_type": "http",
"version": "1.22.2",
"extraction_type": "archive",
"assets": [
{
"type": "merge",
"source": "RetroArch-Linux-x86_64/RetroArch-Linux-x86_64.AppImage.home/.config/retroarch/cores",
"dest": "$WORKDIR/cores"
}
]
},
{
"source_url": "https://buildbot.libretro.com/{VERSION}/linux/x86_64/latest/citra_libretro.so.zip",
"source_type": "http",
"version": "nightly",
"extraction_type": "archive",
"assets": [
{
"type": "file",
"source": "citra_libretro.so",
"dest": "$WORKDIR/cores"
}
]
},
{
"source_url": "https://buildbot.libretro.com/{VERSION}/linux/x86_64/latest/sameduck_libretro.so.zip",
"source_type": "http",
"version": "nightly",
"extraction_type": "archive",
"assets": [
{
"type": "file",
"source": "sameduck_libretro.so",
"dest": "$WORKDIR/cores"
}
]
},
{
"source_url": "https://github.com/RapidEdwin08/Genesis-Plus-GX-Expanded-Rom-Size",
"source_type": "git",
"version": "latest",
"dest": "Genesis-Plus-GX-Expanded-Rom-Size",
"extraction_type": "local",
"assets": [
{
"type": "file",
"source": "builds/Linux_so64/genesis_plus_gx_libretro.so",
"dest": "$WORKDIR/cores"
}
]
},
{
"source_url": "https://buildbot.libretro.com/{VERSION}/linux/x86_64/RetroArch_cores.7z",
"source_type": "http",
"version": "nightly",
"dest": "nightly-cores",
"extraction_type": "archive",
"assets": [
{
"type": "merge",
"source": "RetroArch-Linux-x86_64/RetroArch-Linux-x86_64.AppImage.home/.config/retroarch/cores",
"dest": "$WORKDIR/cores"
}
]
},
{
"source_url": "https://github.com/libretro/libretro-database",
"source_type": "git",
"version": "latest",
"extraction_type": "local",
"assets": [
{
"type": "tar.gz",
"source": "cht/.",
"dest": "rd_extras/cheats"
}
]
},
{
"source_url": "http://bluemsx.msxblue.com/rel_download/blueMSXv{VERSION}full.zip",
"source_type": "http",
"version": "282",
"extraction_type": "archive",
"assets": [
{
"type": "dir",
"source": "Machines",
"dest": "rd_extras/MSX/Machines"
},
{
"type": "dir",
"source": "Databases",
"dest": "rd_extras/MSX/Databases"
}
]
},
{
"source_url": "https://github.com/rsn8887/capsimg/releases/download/{VERSION}/Capsimg_for_Retroarch.zip",
"source_type": "github-release",
"version": "1.1",
"extraction_type": "archive",
"assets": [
{
"type": "file",
"source": "Linux/x86-64/capsimg.so",
"dest": "rd_extras/Amiga"
}
]
},
{
"source_url": "$WORKDIR",
"source_type": "local",
"extraction_type": "local",
"assets": [
{
"type": "tar.gz",
"source": "cores",
"dest": "rd_extras/cores"
}
]
},
{
"source_url": "$WORKDIR",
"source_type": "local",
"extraction_type": "local",
"assets": [
{
"type": "tar.gz",
"source": "overlays/.",
"dest": "rd_extras/overlays"
}
]
}
]
}
Explanation
- Core source - Downloads
RetroArch.7zand extracts it as an archive. - First additional source - Treats the already‑extracted AppImage (
RetroArch-Linux-x86_64.AppImage) as a local source, extracts it, and copies itsusr/bindirectory to the artifact’sbinfolder. - Second additional source - Downloads a second archive (
RetroArch_cores.7z), extracts it, and copies the cores directory into the artifact’scoresfolder.
By ordering the additional sources array this way, the Alchemist ensures that each step has the necessary data from the previous step before proceeding.
Object 1 - Core Archive (downloaded)
{
"source_url": "https://buildbot.libretro.com/stable/{VERSION}/linux/x86_64/RetroArch.7z",
"source_type": "http",
"version": "1.21.0",
"extraction_type": "archive"
}
Alchemist:
- Download:
RetroArch.7zis fetched from the internet and placed into$WORKDIR. - Extraction: Treated as an
archive; it is extracted to the default destination$WORKDIR/RetroArch.7z-extracted. - Post‑extract actions: None (no assets, libs, or extras).
- Next step: The Alchemist proceeds to Object 2.
Object 2 - Local AppImage (extracted from the first archive)
{
"source_url": "https://buildbot.libretro.com/stable/{VERSION}/linux/x86_64/RetroArch_cores.7z",
"source_type": "http",
"version": "1.21.0",
"extraction_type": "archive",
"assets": [
{
"type": "dir",
"source": "RetroArch-Linux-x86_64/RetroArch-Linux-x86_64.AppImage.home/.config/retroarch/cores",
"dest": "cores"
}
]
}
]
}
Alchemist:
- Source: The AppImage located at
$WORKDIR/RetroArch.7z-extracted/RetroArch-Linux-x86_64/RetroArch-Linux-x86_64.AppImage(produced by Object 1). - Extraction: Handled as an
appimage. - Asset gathering: The directory
$WORKDIR/$EXTRACTED_PATH/usr/bin/is collected and copied to$COMPONENT_ARTIFACT_ROOT/bin/.
Object 3 - Additional Cores Archive (downloaded)
- Download: A new archive
RetroArch_cores.7zis retrieved from the internet. - Extraction: Treated as an
archive. - Asset gathering: The path
$WORKDIR/$EXTRACTED_PATH/RetroArch-Linux-x86_64/RetroArch-Linux-x86_64.AppImage.home/.config/retroarch/cores/is collected and placed into$COMPONENT_ARTIFACT_ROOT/cores/.
{
"source_url": "https://buildbot.libretro.com/stable/{VERSION}/linux/x86_64/RetroArch_cores.7z",
"source_type": "http",
"version": "1.21.0",
"extraction_type": "archive",
"assets": [
{
"type": "dir",
"source": "RetroArch-Linux-x86_64/RetroArch-Linux-x86_64.AppImage.home/.config/retroarch/cores",
"dest": "cores"
}
]
}
Why This Verbose Multi‑Object Approach?
- Fine‑grained control: Each object can specify its own assets, libraries, and extras, ensuring precise handling of files.
- Avoids conflicts: Prevents issues where a parent archive contains multiple files with the same extensions (blob‑matching problems).
- Flexibility: Different classes of files (assets, libs, etc.) can originate from distinct sources, allowing consistent and reproducible builds.
By processing each source object sequentially, the Alchemist maintains strict control over every step, guaranteeing deterministic results across builds.
Reusable Environmental Variable Reference
Core Paths
| Variable | Description |
|---|---|
| $REPO_ROOT | Set to the root of the git-cloned repository if alchemist.sh is invoked inside one.Otherwise defaults to the directory from which the script is called. |
| $WORKDIR | Working directory for the current component build. Holds downloaded sources, extracted files, and the temporary artifact directory. Can be overridden via an argument to alchemist.sh.Otherwise falls back to $DEFAULT_WORKDIR defined in defaults.sh. |
| $COMPONENT_NAME | Name of the component currently being processed. Should match the component directory name in the components repository for consistency. |
| $COMPONENT_ARTIFACT_ROOT | Path to the final artifact directory where all files destined for the archive are placed. Computed as: $WORKDIR/$COMPONENT_NAME-artifact |
Download & Extraction Helpers
| Variable | Description |
|---|---|
| $DOWNLOADED_FILE | Full path of the most recently downloaded file. Populated by the download.sh plugin via:echo "DOWNLOADED_FILE=..." |
| $EXTRACTED_PATH | Full path of the most recently extracted archive. Populated by the extract.sh plugin via:echo "EXTRACTED_PATH=..."For local extractions (no real archive), a dummy plugin returns the same path as $DOWNLOADED_FILE. |
Flatpak-Related Variables
| Variable | Description |
|---|---|
| $FLATPAK_USER_ROOT | Default user install location:$HOME/.local/share/flatpak/appDefined in defaults.sh. |
| $FLATPAK_SYSTEM_ROOT | Default system install location:/var/lib/flatpak/appDefined in defaults.sh. |
| $FLATPAK_DEFAULT_INSTALL_MODE | Default install mode for Flatpak packages:userSystem mode may require sudo. |
| $FLATHUB_REPO | URL of the Flathub repository:https://flathub.org/repo/flathub.flatpakrepoAdjust if the repository location changes. |
Version Management
| Variable | Description |
|---|---|
| $DESIRED_VERSIONS | Path to the desired_versions.sh script containing the catalog of desired component versions.Used to resolve version placeholders in component recipes. Can be overridden per alchemist.sh run via an input argument,allowing separate stable and beta version sets. |
Alchemist Execution Logic
Take the Azahar example for above:
- Component Name - Set to
azahar. - Download URL -
org.azahar_emu.Azahar. - Downloader Plugin -
flatpak_id(selected viasource_type). - Version Resolution -
$AZAHAR_DESIRED_VERSIONis read fromdesired_versions.sh(e.g.,export AZAHAR_DESIRED_VERSION="2123.3"). This value replaces{VERSION}in the URL. - Downloaded File Path - Stored in
$DOWNLOADED_FILE. - Extraction Plugin -
flatpak, applied to$DOWNLOADED_FILE. - Extracted Destination - Path returned in
$EXTRACTED_PATH. - Copy the full directory from
$EXTRACTED_PATH/usr/binto$COMPONENT_ARTIFACT_ROOT/bin. - Flatpak Runtime - Install the required runtime (name and version) if it isn’t already present.
- Gather Library - Retrieve
libQt6Widgets.so.6from the specified Flatpak runtime and place it in the appropriate location within the artifact.
Alchemist Process Abstraction
At a high level, the Alchemist processes information in this loop:
- Read
component_recipe.jsonfile. - Read component name from the root key.
- Generate a set of parent objects to be processed.
- Each parent object contains download sources, extraction commands, asset‑gathering instructions, library‑gathering instructions, and extras‑gathering instructions.
- Process each object sequentially.
- Compress the contents of the
*-artifactdirectory for storage.
Example: Final Artifact Layout ($COMPONENT_NAME-artifact) for Azahar
azahar-artifact
├── bin
│ ├── azahar
│ └── qt.conf
├── component_extras.sh
├── component_functions.sh
├── component_launcher.sh
├── component_libs.json
├── component_manifest.json
├── component_prepare.sh
├── component_recipe.json
└── assets
└── rd_config
└── qt-config.ini