I recently set up a nRF Connect SDK (NCS) command-line development environment for the Nordic Thingy:91 X, which includes downloading and installing the toolchain and SDK code.
As I was getting everything set up, I discovered how to use the shell utility direnv to automatically activate Zephyr build environments when working in West workspaces via the CLI. Once direnv is configured, the build environment is automatically activated in the shell when changing directory into the workspace. Similarly, when leaving the workspace directory, the build environment is automatically deactivated.
If you’re like me, and your brain is a sieve, this will save you from having to remember and manually type the commands to activate the python virtual environment and source the required scripts to ensure the Zephyr environment variables are set correctly.
In this project, I'm going to describe how I set up this shell automation for Nordic’s nRF Connect SDK (NCS) and also for “vanilla” upstream Zephyr RTOS West workspaces.
A quick note before we dive into the project: unfortunately, direnv only works on Unix-like operating systems (macOS, Linux, etc), and requires a supported shell (bash, zsh, tcsh, fish, elvish, powershell, murex, nushell). Sorry Windows folks!
nRF Connect SDK (NCS) ExampleIn recent versions of the nRF Connect SDK, Nordic recommends using their nRF Util CLI tool to manage the installation of toolchain bundles provided by Nordic.
Described as a “unified command line utility for Nordic products”, nRF Util (nrfutil) provides a wide range of functionality through a set of installable and upgradeable sub-commands. Specifically, the toolchain-managercommand can be used to search for, install, and uninstall toolchains.
In addition to managing toolchains, the toolchain-manager command provides env and launch sub-commands to activate a specific toolchain environment in the shell.
For example, you can use the nrfutil toolchain-manager env command to display the environment variables needed to configure the toolchain environment:
❯ nrfutil toolchain-manager env
GIT_EXEC_PATH : /opt/nordic/ncs/toolchains/b8efef2ad5/Cellar/git/2.37.3/libexec/git-core
GIT_TEMPLATE_DIR : /opt/nordic/ncs/toolchains/b8efef2ad5/Cellar/git/2.37.3/share/git-core/templates
PATH : /opt/nordic/ncs/toolchains/b8efef2ad5/bin:/opt/nordic/ncs/toolchains/b8efef2ad5/usr/bin:/opt/nordic/ncs/toolchains/b8efef2ad5/usr/local/bin:/opt/nordic/ncs/toolchains/b8efef2ad5/opt/bin:/opt/nordic/ncs/toolchains/b8efef2ad5/opt/nanopb/generator-bin:/opt/nordic/ncs/toolchains/b8efef2ad5/opt/zephyr-sdk/arm-zephyr-eabi/bin:/opt/nordic/ncs/toolchains/b8efef2ad5/opt/zephyr-sdk/riscv64-zephyr-elf/bin:<redacted>
ZEPHYR_SDK_INSTALL_DIR : /opt/nordic/ncs/toolchains/b8efef2ad5/opt/zephyr-sdk
ZEPHYR_TOOLCHAIN_VARIANT : zephyrIn the Installing the nRF Connect SDK documentation, Nordic recommends using the following command to activate the toolchain in a subshell:
nrfutil toolchain-manager launch --shellUnfortunately, any shell configuration files (e.g. .bashrc) are skipped when launching this subshell:
The shell spawned is determined by theSHELLenvironment variable. An attempt is made to spawn the shell without running any config files (e.g..bashrc), as these files could (potentially) mess up the environment.
The result, as you can see in the image below, is that my custom shell prompt and other shell configuration is ignored when launching the new subshell:
As an alternative, the nrfutil toolchain-manager env --as-script command can output a script which sets up the same environment as the launch --shell sub-command:
❯ nrfutil toolchain-manager env --as-script
export PATH=/opt/nordic/ncs/toolchains/b8efef2ad5/bin:/opt/nordic/ncs/toolchains/b8efef2ad5/usr/bin:/opt/nordic/ncs/toolchains/b8efef2ad5/usr/local/bin:/opt/nordic/ncs/toolchains/b8efef2ad5/opt/bin:/opt/nordic/ncs/toolchains/b8efef2ad5/opt/nanopb/generator-bin:/opt/nordic/ncs/toolchains/b8efef2ad5/opt/zephyr-sdk/arm-zephyr-eabi/bin:/opt/nordic/ncs/toolchains/b8efef2ad5/opt/zephyr-sdk/riscv64-zephyr-elf/bin:$PATH
export GIT_EXEC_PATH=/opt/nordic/ncs/toolchains/b8efef2ad5/Cellar/git/2.37.3/libexec/git-core
export GIT_TEMPLATE_DIR=/opt/nordic/ncs/toolchains/b8efef2ad5/Cellar/git/2.37.3/share/git-core/templates
export ZEPHYR_TOOLCHAIN_VARIANT=zephyr
export ZEPHYR_SDK_INSTALL_DIR=/opt/nordic/ncs/toolchains/b8efef2ad5/opt/zephyr-sdkBy running eval on the output of that command, we can effectively activate the toolchain build environment in the current shell (without launching a new subshell):
Unfortunately, I will NEVER remember that command off the top of my head…
Automate it with direnvIt would be nice if the toolchain just automatically activated whenever we’re in a West workspace, and deactivated when we leave the workspace.
Lucky for us, direnv is a general purpose shell utility designed to enable that exact type of behavior.
Before each prompt, direnv checks for the existence of a.envrcfile (and optionally a.envfile) in the current and parent directories. If the file exists (and is authorized), it is loaded into a bash sub-shell and all exported variables are then captured by direnv and then made available to the current shell.
First, we need to install the direnv shell utility. You can follow the instructions at https://direnv.net/docs/installation.html for your preferred OS and shell.
Next, in the root of a West workspace, we need to add a .envrc file with the following lines:
eval "$(nrfutil toolchain-manager env --as-script)"
source zephyr/zephyr-env.shNow, when we enter the workspace directory, direnv will automatically run the commands above and export the resulting build environment variables into the current shell. You should see messages like the following:
❯ cd ncs-workspace/
direnv: loading ncs-workspace/.envrc
direnv: export +GIT_EXEC_PATH +GIT_TEMPLATE_DIR +ZEPHYR_BASE +ZEPHYR_SDK_INSTALL_DIR +ZEPHYR_TOOLCHAIN_VARIANT ~PATHWe can check to verify that the environment variables are set correctly. For example:
❯ echo $ZEPHYR_SDK_INSTALL_DIR
/opt/nordic/ncs/toolchains/b8efef2ad5/opt/zephyr-sdkHooray, it works! 🎉
For security purposes, direnv will not automatically load changes from an .envrc script unless it has been explicitly allowed. As a result, you may see an error like this the first time you enter the workspace:
direnv: error ncs-workspace/.envrc is blocked. Run `direnv allow` to approve its contentYou just need to run direnv allow once to allow it to run.
We can also use direnv to automatically activate build environments for “vanilla” Zephyr RTOS workspaces.
If you have worked with West workspaces via the command line, you’re probably used to typing something like this to activate the build environment:
cd zephyr-workspace/
# activate the Python virtual environment
source .venv/bin/activate
# source Zephyr environment scripts
source zephyr/zephyr-env.shIn the same vein as the NCS example above, we can add a .envrc file into the root of the West workspace with the following lines:
test -d .venv && source .venv/bin/activate
source zephyr/zephyr-env.shNow, whenever you cd into the zephyr-workspace/ directory, the python virtual environment and the Zephyr environment scripts will be activated automatically!
Have you used direnv or a similar tool to automatically activate environments in your shell? Let me know in the comments below! I'm especially interested to hear if there is an alternative solution that can also work for Windows users.








_SPmZ63wPgQ.png?auto=compress%2Cformat&w=40&h=40&fit=fillmax&bg=fff&dpr=2)
Comments