Skip to content

Instantly share code, notes, and snippets.

@ejohnso49
Last active July 30, 2023 23:26
Show Gist options
  • Save ejohnso49/cfa7c000f9b93c55b71be9116162b2a3 to your computer and use it in GitHub Desktop.
Save ejohnso49/cfa7c000f9b93c55b71be9116162b2a3 to your computer and use it in GitHub Desktop.
Zephyr Nix Flake
{
description = "Flake used to setup development environment for Zephyr";
# Nixpkgs / NixOS version to use.
inputs.nixpkgs.url = "nixpkgs/nixos-21.11";
# mach-nix used to create derivation for Python dependencies in the requirements.txt files
inputs.mach-nix.url = "mach-nix/3.5.0";
outputs = { self, nixpkgs, mach-nix }:
let
# to work with older version of flakes
lastModifiedDate = self.lastModifiedDate or self.lastModified or "19700101";
# Generate a user-friendly version number
version = builtins.substring 0 8 lastModifiedDate;
# System types to support
supportedSystems = [ "x86_64-linux" "x86_64-darwin" "aarch64-linux" "aarch64-darwin" ];
# Helper function to generate an attrset '{ x86_64-linux = f "x86_64-linux"; ... }'
forAllSystems = nixpkgs.lib.genAttrs supportedSystems;
# Nixpkgs instantiated for supported system types
nixpkgsFor = forAllSystems (system: import nixpkgs { inherit system; });
# Read requirements files to get Python dependencies
# mach-nix is not capable of using a requirements.txt with -r directives
# Using list of requirements files: read each file, concatenate contents in single string
requirementsFileList = [ ./scripts/requirements-base.txt ./scripts/requirements-build-test.txt ./scripts/requirements-compliance.txt ./scripts/requirements-doc.txt ./scripts/requirements-extras.txt ./scripts/requirements-run-test.txt ];
allRequirements = nixpkgs.lib.concatStrings (map (x: builtins.readFile x) requirementsFileList);
in {
devShells = forAllSystems (system:
let
pkgs = nixpkgsFor.${system};
# Import SDK derivation
zephyrSdk = import ./sdk.nix { inherit pkgs system; };
# Create Python dependency derivation
pyEnv = mach-nix.lib.${system}.mkPython { requirements = allRequirements; };
in {
default = pkgs.mkShell {
# Combine all required dependencies into the buildInputs (system + Python + Zephyr SDK)
buildInputs = with pkgs; [ cmake python39Full python39Packages.pip python39Packages.setuptools dtc git ninja gperf ccache dfu-util wget xz file gnumake gcc gcc_multi SDL2 pyEnv zephyrSdk ];
# When shell is created, start with a few Zephyr related environment variables defined.
shellHook = ''
export ZEPHYR_TOOLCHAIN_VARIANT=zephyr
export ZEPHYR_SDK_INSTALL_DIR=${zephyrSdk}/${zephyrSdk.pname}-${zephyrSdk.version}
'';
};
}
);
};
}
{ pkgs ? import <nixpkgs> {}, system ? builtins.currentSystem }:
with pkgs;
let
pname = "zephyr-sdk";
version = "0.14.2";
# SDK uses slightly different system names, use this variable to fix them up for use in the URL
system_fixup = { x86_64-linux = "linux-x86_64"; aarch64-linux = "linux-aarch64"; x86_64-darwin = "macos-x86_64"; aarch64-darwin = "macos-aarch64";};
# Use the minimal installer as starting point
url = "https://github.com/zephyrproject-rtos/sdk-ng/releases/download/v${version}/${pname}-${version}_${system_fixup.${system}}_minimal.tar.gz";
in stdenvNoCC.mkDerivation {
# Allows derivation to access network
#
# This is needed due to the way setup.sh works with the minimal toolchain. The script uses wget to retrieve the
# specific toolchain variants over the network.
#
# Users of this package must set options to indicate that the sandbox conditions can be relaxed for this package.
# These are:
# - In the appropriate nix.conf file (depends on multi vs single user nix installation), add the line: sandbox = relaxed
# - When used in a flake, set the flake's config with this line: nixConfig.sandbox = "relaxed";
# - Same as above, but disabling the sandbox completely: nixConfig.sandbox = false;
# - From the command line with nix <command>, add one of these options:
# - --option sandbox relaxed
# - --option sandbox false
# - --no-sandbox
# - --relaxed-sandbox
__noChroot = true;
inherit pname version;
src = builtins.fetchurl { inherit url; sha256 = "1v0xil72cq9wcpk1ns8ica82i13zdv2jkn6i3cq4fwy0y61cvj4c";};
# Our source is right where the unzip happens, not in a "src/" directory (default)
sourceRoot = ".";
# Build scripts require each packages
nativeBuildInputs = [ pkgs.cacert pkgs.which pkgs.wget pkgs.cmake ];
# Required to prevent CMake running in configuration phases
dontUseCmakeConfigure = true;
# Run setup script
# TODO: Allow user to specify which targets to install
# TODO: Figure out if host tools could be ported to Nix
buildPhase = ''
bash ${pname}-${version}/setup.sh -t arm-zephyr-eabi
'';
# Move SDK directory into installation directory
installPhase = ''
mkdir -p $out
mv $name $out/
'';
}
@ejohnso49
Copy link
Author

Main issue that remains to be solved is how to allow sdk.nix access to the network during building because the script, setup.sh, will use wget to download the various toolchains requested. There also seems to be a limitation due to size for using the full toolchain package so I have left it at the minimal one for now.

This is fixed as noted in the comments of sdk.nix

@RicArch97
Copy link

Thanks for this flake. I used the sdk.nix to create a derivation for the SDK but with the xtensa toolkit instead, but I'm running into permission issues when cmake is trying to get the compiler version;
west build -p always -b esp32 mysource
runs into the following error:

-- Found host-tools: zephyr 0.15.1 (/nix/store/dk9y8vkrxys9w49rhvshw6l2c429m3cx-zephyr-sdk-0.15.1/zephyr-sdk-0.15.1)
-- Found toolchain: zephyr 0.15.1 (/nix/store/dk9y8vkrxys9w49rhvshw6l2c429m3cx-zephyr-sdk-0.15.1/zephyr-sdk-0.15.1)
CMake Error at /run/media/ricardo/RicardoHDD/Afstuderen/code/zephyr-workspace/zephyr/cmake/compiler/gcc/generic.cmake:25 (message):
  Executing the below command failed.  Are permissions set correctly?

  
  '/nix/store/dk9y8vkrxys9w49rhvshw6l2c429m3cx-zephyr-sdk-0.15.1/zephyr-sdk-0.15.1/xtensa-espressif_esp32_zephyr-elf/bin/xtensa-espressif_esp32_zephyr-elf-gcc
  --version'

Any ideas on how to get around this?

@ejohnso49
Copy link
Author

Best guess I would have is to try to run that command manually outside of west or looking at any logs in build that might have more info than the CMake output. I don't remember hitting anything like this in the past but my memory is quite fuzzy from when I did this experiment. Sorry :-/

@nuxeh
Copy link

nuxeh commented Feb 27, 2023

I may be a flakes noob, but I can't get this to evaluate, nix says it doesn't contain any flakes

@nuxeh
Copy link

nuxeh commented Feb 27, 2023

My bad, the flake has to be added to git, duh. Thanks!

@ejohnso49
Copy link
Author

My bad, the flake has to be added to git, duh. Thanks!

Yeah, I definitely ran into that issue as well. It is not obvious that's required. Thanks for noting!

@nuxeh
Copy link

nuxeh commented Feb 27, 2023

Still having the issue that I can't run any of the toolchains, dynamic linking problems, even when I add autoPatchElfHook, pff

@SeungheonOh
Copy link

Thanks for this!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment