Here we talk about KDE Craft buildtool, rather than something like Minecraft, Warcraft or Starcraft.
Craft is an open source meta build system and package manager written in Python. It manages dependencies and builds libraries and applications from source, on Windows, Mac, Linux and FreeBSD. Please go to https://community.kde.org/Craft for more information.
To setup Craft, follow the steps on Setup Craft on KDE Community Wiki. Here I use Craftin Unix/Linux environment. So, if all is well, we should use source CraftRoot/craft/craftenv.sh to enter the build environment. But try to stop doing this, the subject of the post is to study the bootstrap script.
The most important stuffs for bootstrapping of Craft is the craftenv.sh script, which script is used for preparing Craft environment.
We try to comprehend the environment configuration script craftenv.sh. What does it happen when we execute source craftenv.sh?
Find craftenv.sh directory
There is no assumption of interpreter at the beginning of this script. For the compatibility, the script firstly try to get BASH_SOURCE[0]. If nothing is contained in the variable, at least we can infer the interpreter is not a bash Bourne-Again shell. And then for others, if none of ${BASH_SOURCE[0]}, $0 and $_ works, we may use an interpreter which is not supported by this script. We just stop trying to continue the work.
Meanwhile, the script store the relative path into $craftRoot.
1 | craftRoot="${BASH_SOURCE[0]}" |
In fact, after the detection, the shell is not important anymore. Which we concerned is just the $craftRoot.
Find compatible Python 3 with appropriate minor version
It’s confirmed that Craft would like to use Python 3. It recommends user Python 3.6.
Craft bootstrap script uses command -v python-<version> to check if an appropriate version of Python exists.
1 | if command -v python3.7 >/dev/null; then |
This section is to used to detect whether Python 3.7 or Python 3.6 exists in your system path.
By the way, I’d like to introduce something about versions in software distribution. If this is useful, it will be my pleasure. We usually use Semantic Versioning to describe changes. It means: given a version number MAJOR.MINOR.PATCH, increment the:
- MAJOR version when you make incompatible API changes,
- MINOR version when you add functionality in a backwards-compatible manner, and
- PATCH version when you make backwards-compatible bug fixes.
So the difference is in the minor version. We can see the Python 3.7 is also supported by Craft. And the preference is Python 3.7 according to the priority of instruction.
Then, the script tries to find other potentially compitable Python version. But at least, it should be Python 3.6. Otherwise it will not continue.
1 | ... |
So if Python is ok, its path will be stored in $CRAFT_PYTHON_BIN and exported.
As we already have Python, the script uses it immediately, to correct the $craftRoot. If the variable is not a directory, we get its parent directory and replace the $craftRoot.
1 | if [[ ! -d "$craftRoot" ]]; then |
For now, $craftRoot should be craft/ in your Craft install directory.
Generating and exporting $CRAFT_ENV
The following single line is used for acquiring some environment variables for Craft.
1 | CRAFT_ENV=$(${CRAFT_PYTHON_BIN} "$craftRoot/bin/CraftSetupHelper.py" --setup) |
In fact, it called bin/CraftSetupHelper.py with --setup option, it does have done many things.
1 | def run(self): |
We can see that printEnv and printBanner are invoked, all their ouputs will be filled into $CRAFT_ENV in shell. The generated env variables are too many, here we only talk about the bootstrapping. Maybe there will be an article about those.
1 | # Split the CraftSetupHelper.py output by newlines instead of any whitespace |
Then with export_lines, all the lines can be exported seperatly without confusion.
Exporting other necessary variables and functions
If the prompt exists in $PS1, which means the interpreter is using the strings in $PS1 as its prompt, then the script add CRAFT: before it. This would be realy useful because it could remind user that we’re in the Craft environment.
1 | if [ -n "$PS1" ]; then |
Then just some useful functions:
1 | craft() { |
The main entry of Craft. It will invoke bin/craft.py. All other things will be done in it.
1 | cs() { |
Change current work directory to source directory in Craft.
1 | cb() { |
Change current work directory to build directory in Craft.
1 | cr() { |
Change current work directory to root in Craft.
And export them
1 | declare -x -F cs cb cr |
Conclusion
With all environment variables prepared, and some useful function exported, we can begin our trip in building everything with Craft.
References
- KDE Craft wiki, https://community.kde.org/Craft
- Utilisation de la variable BASH_SOURCE[0], https://logd.fr/utilisation-variable-bash_source/