Skip to content

Instantly share code, notes, and snippets.

@drawnwren
Last active April 28, 2025 00:24
Show Gist options
  • Save drawnwren/a53506ea7864b7eeaaca211fdfa9555c to your computer and use it in GitHub Desktop.
Save drawnwren/a53506ea7864b7eeaaca211fdfa9555c to your computer and use it in GitHub Desktop.
px4 wip
final: prev: let
# Define version info
px4VersionInfo = {
version = "v1.14.0";
commitHash = "1234567890abcdef1234567890abcdef12345678";
shortHash = "1234567890abcdef";
branch = "master";
nuttxVersion = "v8.2.0";
gitVersion = "2.42.0";
};
# Create a Python environment with all the required packages
python3 = let
customPython = prev.python3.override {
packageOverrides = python-final: python-prev: {
pyulog = python-prev.buildPythonPackage rec {
pname = "pyulog";
version = "0.9.0";
src = prev.fetchFromGitHub {
owner = "PX4";
repo = "pyulog";
rev = "v${version}";
sha256 = "sha256-k9A/Ya17f032p/RW760Rqb4E61EMm88gznhlVC7wUII=";
};
propagatedBuildInputs = with python-prev; [ numpy ];
doCheck = false;
};
empy = python-prev.buildPythonPackage rec {
pname = "empy";
version = "3.3.4";
src = prev.fetchPypi {
inherit pname version;
sha256 = "sha256-c6xJeFtgFHnfTqGKfHm8EwSop8NMArlHLPEgauiPAbM=";
};
doCheck = false;
};
catkin-pkg = python-prev.buildPythonPackage rec {
pname = "catkin_pkg";
version = "0.5.2";
src = prev.fetchPypi {
inherit pname version;
sha256 = "sha256-XWQ+6vvOSJD8zq+dsZfq3yyloYfSVZP2W25cV5NfXaI=";
};
propagatedBuildInputs = with python-prev; [
docutils
python-dateutil
pyparsing
];
doCheck = false;
};
pyros-genmsg = python-prev.buildPythonPackage rec {
pname = "pyros-genmsg";
version = "0.5.8";
src = prev.fetchFromGitHub {
owner = "ros";
repo = "genmsg";
rev = version;
sha256 = "sha256-yvT1XVzUhwoFH32EMrrGzrDwe1zCi9ceSIbTakzrbd8=";
};
nativeBuildInputs = with python-prev; [ catkin-pkg ];
propagatedBuildInputs = with python-prev; [ pyyaml ];
doCheck = false;
};
kconfiglib = python-prev.buildPythonPackage rec {
pname = "kconfiglib";
version = "14.1.0";
src = prev.fetchPypi {
inherit pname version;
sha256 = "sha256-vtLMIhb1OOykJVqDpFiNiCNWPN1QEU+GzxomdOYCyTw=";
};
doCheck = false;
};
nunavut = python-prev.buildPythonPackage rec {
pname = "nunavut";
version = "1.1.0";
src = prev.fetchPypi {
inherit pname version;
sha256 = "sha256-/nIEj//2rsRlmS0sO3y0Uh3v6s1pTfkqTEPIsn8iSBA=";
};
propagatedBuildInputs = with python-prev; [
pydsdl
jinja2
typing-extensions
];
doCheck = false;
};
pydsdl = python-prev.buildPythonPackage rec {
pname = "pydsdl";
version = "1.12.0";
src = prev.fetchPypi {
inherit pname version;
sha256 = "sha256-MFUbET7LdCpv9vXqiFWl8yJQkXlUYWA5oGh91k/Inno=";
};
propagatedBuildInputs = with python-prev; [
lark
typing-extensions
];
doCheck = false;
};
lark = python-prev.buildPythonPackage rec {
pname = "lark";
version = "1.1.5";
src = prev.fetchPypi {
inherit pname version;
sha256 = "sha256-z0OJrNgvyoqChi7dPK3c2XfhAUBkcMy51vypt5Zvu08=";
};
doCheck = false;
};
};
};
in customPython.withPackages (ps: with ps; [
argcomplete
cerberus
coverage
empy
future
jinja2
jsonschema
kconfiglib
loguru
lxml
matplotlib
numpy
nunavut
packaging
pandas
pkgconfig
psutil
pygments
wheel
pymavlink
pyros-genmsg
pyserial
pyulog
pyyaml
requests
setuptools
six
toml
sympy
]);
in {
# PX4 build tools
fakeKconfig = prev.writeShellScriptBin "olddefconfig" ''
vendor="''${PX4_BOARD_VENDOR}"
board="''${PX4_BOARD_MODEL}"
config="''${PX4_BOARD_LABEL}"
if [ -f "boards/$vendor/$board/$config.px4board" ]; then
mkdir -p build
cp "boards/$vendor/$board/$config.px4board" build/.config
${python3}/bin/python3 -m kconfiglib --olddefconfig Kconfig
exit 0
else
echo "No board config found for $vendor/$board/$config"
exit 1
fi
'';
fakeGit = prev.writeShellScriptBin "git" ''
case "''${@}" in
"-c versionsort.suffix=- tag --sort=v:refname")
echo "nuttx-${px4VersionInfo.nuttxVersion}"
;;
"rev-parse "*|"--version"|"symbolic-ref"*|"describe"*|"tag"*|"submodule summary"*)
echo "passing through to real git: $@"
# pass read commands through to the real git
${prev.git}/bin/git "$@"
;;
*)
# ignore all other git commands
echo "git command ignored: $@"
exit 0
;;
esac
'';
# PX4 firmware builder
px4-firmware = { vendor, board, config, jobs ? 8 }: let
submodules = {
"src/modules/mavlink/mavlink" = prev.fetchFromGitHub {
owner = "mavlink";
repo = "mavlink";
rev = "d65952bacc02c4a5a1ed8249be73e6a66fa800ab";
sha256 = "sha256-MyDjPXUGckdVhqUHuuFGsw/4v/PAFB+x9tRWD/8lU0M=";
leaveDotGit = true;
};
"src/drivers/uavcan/libuavcan" = prev.fetchFromGitHub {
owner = "dronecan";
repo = "libuavcan";
rev = "9a0fd624c448cad5633720676233f74846387a9f";
sha256 = "sha256-UbcDLco7mvVX0b21t3OKtLWN8a1ZWCPgllpql0LXSuk=";
leaveDotGit = true;
};
"Tools/simulation/jmavsim/jMAVSim" = prev.fetchFromGitHub {
owner = "PX4";
repo = "jMAVSim";
rev = "66b764ada522893c05224950aa6268c809f8e48a";
sha256 = "sha256-Bd8zX+D+E0w76LtEnm1oPtn6CuPOwCqWP+uSsB2ToNI=";
leaveDotGit = true;
};
"Tools/simulation/gazebo-classic/sitl_gazebo-classic" = prev.fetchFromGitHub {
owner = "PX4";
repo = "PX4-SITL_gazebo-classic";
rev = "67431d233f0f08de647f0eb11239816f9c8bd6c6";
sha256 = "sha256-zh0Lh0iX8vJce6ZwYKRjyJ8nzZGZ7mKVnYSy3jO6Vjk=";
leaveDotGit = true;
};
"src/drivers/gps/devices" = prev.fetchFromGitHub {
owner = "PX4";
repo = "PX4-GPSDrivers";
rev = "a41210ede8c2d22dd8e9fdcf388fca927c1fc5e1";
sha256 = "sha256-C9fmpK56bCX40HkTwAgf0BK7yqxuAhX1a9ca2oQ0Zic=";
leaveDotGit = true;
};
"platforms/nuttx/NuttX/nuttx" = prev.fetchFromGitHub {
owner = "PX4";
repo = "NuttX";
rev = "d3b85f3e545de3692c100143f4a9ae67762ce679";
sha256 = "sha256-8QWvt+Mp8YoS9X2wLbLo4HaUpi1oSJk+qoG05JIPRU0=";
leaveDotGit = true;
};
"platforms/nuttx/NuttX/apps" = prev.fetchFromGitHub {
owner = "PX4";
repo = "NuttX-apps";
# px4_firmware_nuttx-10.3.0+
rev = "e37940d8535f603a16b8f6f21c21edaf584218aa";
sha256 = "sha256-o5j/UjoLHMhjnG/4YYmJH1mknA6+UFYA0oLiadwaXZo=";
leaveDotGit = true;
};
"Tools/simulation/flightgear/flightgear_bridge" = prev.fetchFromGitHub {
owner = "PX4";
repo = "PX4-FlightGear-Bridge";
rev = "f47ce7b5fbbb3aa43d33d2be1f6cd3746b13d5bf";
sha256 = "sha256-hSGImBeggFQ7N6XXS7b/tgGAXcEAEoO4MlYQyA7BujE=";
leaveDotGit = true;
};
# Tools/simulation/gz
# Tools/simulation/jsbsim/jsbsim_bridge
# boards/modalai/voxl2/libfc-sensor-api
#
#
"src/drivers/cyphal/libcanard" = prev.fetchFromGitHub {
owner = "opencyphal";
repo = "libcanard";
rev = "5c69d451ab0787a81dcb615692d707f2a286f5e5";
sha256 = "sha256-/P8bx4jJFHPTNXI7DYT03mZpT4rvP2jGj8PIrtDAI7w=";
leaveDotGit = true;
};
"src/drivers/cyphal/public_regulated_data_types" = prev.fetchFromGitHub {
owner = "opencyphal";
repo = "public_regulated_data_types";
rev = "d0bd6516dac8ff61287fe49a9f2c75e7d4dc1b8e";
sha256 = "sha256-n3fn2GdK0IdZKHdbeTw5F24f0wQOEjCKWOxS6IejwNM=";
leaveDotGit = true;
};
"src/drivers/cyphal/legacy_data_types" = prev.fetchFromGitHub {
owner = "PX4";
repo = "public_regulated_data_types";
rev = "36a01e428b110ff84c8babe5b65667b5e3037d5e";
sha256 = "sha256-Gm9X0GOkfHu3282psisYXVQWyznwuBaVd6h0b37R00s=";
leaveDotGit = true;
};
"src/lib/crypto/monocypher" = prev.fetchFromGitHub {
owner = "PX4";
repo = "Monocypher";
rev = "baca5d31259c598540e4d1284bc8d8f793abf83a";
sha256 = "sha256-3lo9NgWKpXSMmgs2hhG1X89hZ9wA4mgoqJTfSRK150o=";
leaveDotGit = true;
};
"src/lib/events/libevents" = prev.fetchFromGitHub {
owner = "mavlink";
repo = "libevents";
rev = "9474657606d13301d426e044450c4f84de2221be";
sha256 = "sha256-lBO6IrW13kazWsKOgQAfQBJAC1OSy2rLWILQs8iuTZ0=";
leaveDotGit = true;
};
"src/lib/crypto/libtomcrypt" = prev.fetchFromGitHub {
owner = "PX4";
repo = "libtomcrypt";
rev = "673f5ce29015a9bba3c96792920a10601b5b0718";
sha256 = "sha256-fnKLrqYcPdREhBnLv4xBf9Z8wUGiyGR927+GMVW7laU=";
leaveDotGit = true;
};
"src/lib/crypto/libtommath" = prev.fetchFromGitHub {
owner = "PX4";
repo = "libtommath";
rev = "fd73d7630b9d3ed5a79d613ff680a549e9780de7";
sha256 = "sha256-LpdPAW8BFzLnDhBN948SFUxA2XwbccdMQSz19jAftFs=";
leaveDotGit = true;
};
"src/modules/uxrce_dds_client/Micro-XRCE-DDS-Client" = prev.fetchFromGitHub {
owner = "PX4";
repo = "Micro-XRCE-DDS-Client";
rev = "711aef423edd1820347b866d1e4164832df35d04";
sha256 = "sha256-nsaicaPu1NZnqQGGdItmoSHrhuwxLrcFwSopvHekUgc=";
leaveDotGit = true;
fetchSubmodules = true;
};
"src/lib/cdrstream/cyclonedds" = prev.fetchFromGitHub {
owner = "PX4";
repo = "cyclonedds";
rev = "314887ca403c2fb0a0316add22672102936ed36c";
sha256 = "sha256-1khfA75tnREV/33tr5lLeRLP6rEo/ebfu0R/VyaRZKg=";
leaveDotGit = true;
};
"src/lib/cdrstream/rosidl" = prev.fetchFromGitHub {
owner = "PX4";
repo = "rosidl";
rev = "7790c70717e09c003711f6f65015666c223fc283";
sha256 = "sha256-mxku8CXOZ7qXQB4zn6raj7U7oiRtFsvdiCus4qosdVA=";
leaveDotGit = true;
};
"src/modules/zenoh/zenoh-pico" = prev.fetchFromGitHub {
owner = "px4";
repo = "zenoh-pico";
rev = "22bbfc215092a051341c234fdcf68f5baa267dec";
sha256 = "sha256-9HV3lUhsl4O0NvtaXKi4ox14otDWy8Sv6Na7gP3ItLk=";
leaveDotGit = true;
};
"src/lib/heatshrink/heatshrink" = prev.fetchFromGitHub {
owner = "PX4";
repo = "heatshrink";
rev = "052e6de72f67f1777198bce98f3de62f7f3c16a0";
sha256 = "sha256-j7uBOhuyz+b0JGCApGID0yj3NlKtJ0da1ZDbO67hDwc=";
leaveDotGit = true;
};
};
in prev.stdenv.mkDerivation {
name = "${vendor}_${board}_${config}-unstable";
src = ./.;
nativeBuildInputs = with final; [
fakeGit
fakeKconfig
cmake
gcc-arm-embedded
gnumake
pkg-config
zip
unzip
procps
makeWrapper
jdk
] ++ [python3];
buildInputs = with final; [
gtest
eigen
boost
opencv
protobuf
tinyxml
tinyxml2
graphviz
doxygen
libxml2
libxslt
libyaml
] ++ [python3];
patchPhase = ''
mkdir -p .git
touch .git/HEAD
mkdir -p .git/refs/heads
echo "fake-commit" > .git/refs/heads/main
${prev.lib.concatMapStrings (path: ''
mkdir -p "${path}"
cp -r "${submodules.${path}}"/* "${path}/"
chmod -R +w "${path}"
'') (prev.lib.attrNames submodules)}
# Create a simplified version of the px_update_git_header.py script that doesn't depend on git tags
cat > src/lib/version/px_update_git_header.py << 'EOF'
#!/usr/bin/env python3
import argparse
import sys
import re
parser = argparse.ArgumentParser(description="""Extract version info from git and
generate a version header file. This version is simplified for Nix builds.""")
parser.add_argument('filename', metavar='version.h', help='Header output file')
parser.add_argument('-v', '--verbose', dest='verbose', action='store_true',
help='Verbose output', default=False)
parser.add_argument('--validate', dest='validate', action='store_true',
help='Validate the tag format', default=False)
args = parser.parse_args()
filename = args.filename
verbose = args.verbose
validate = args.validate
# Generate the header file content with hardcoded values
header = """
/* Auto Magically Generated file */
/* Do not edit! */
#pragma once
#define PX4_GIT_VERSION_STR ""rsionInfo.gitVersion}"
#define PX4_GIT_VERSION_BINARY 0x${px4VersionInfo.shortHash}
#define PX4_GIT_TAG_STR "${px4VersionInfo.version}"
#define PX4_GIT_BRANCH_NAME "${px4VersionInfo.branch}"
#define PX4_GIT_OEM_VERSION_STR "${px4VersionInfo.gitVersion}"
#define PX4_GIT_TAG_OR_BRANCH_NAME "${px4VersionInfo.branch}"
#define MAVLINK_LIB_GIT_VERSION_STR "d65952bacc02c4a5a1ed8249be73e6a66fa800ab"
#define MAVLINK_LIB_GIT_VERSION_BINARY 0xd65952bacc02c4a5
#define NUTTX_GIT_VERSION_STR "d3b85f3e545de3692c100143f4a9ae67762ce679"
#define NUTTX_GIT_VERSION_BINARY 0xd3b85f3e545de369
#define NUTTX_GIT_TAG_STR "v${px4VersionInfo.nuttxVersion}"
"""
with open(filename, 'w') as fp_header:
fp_header.write(header)
EOF
chmod +x src/lib/version/px_update_git_header.py
'';
preConfigure = ''
mkdir -p build
chmod -R 755 build
chmod -R 755 platforms/nuttx/NuttX/nuttx
mkdir -p platforms/nuttx/NuttX/nuttx/tools
cp ${submodules."platforms/nuttx/NuttX/nuttx"}/tools/incdir.sh platforms/nuttx/NuttX/nuttx/tools/incdir
chmod +x platforms/nuttx/NuttX/nuttx/tools/incdir
'';
installPhase = ''
mkdir -p $out/bin
cp build/px4_* $out/bin/
'';
env = {
GIT_SUBMODULES_ARE_EVIL = "1";
PX4_BOARD_VENDOR = vendor;
PX4_BOARD_MODEL = board;
PX4_BOARD_LABEL = config;
};
meta = with prev.lib; {
description = "PX4 Firmware for ${vendor} ${board} ${config}";
homepage = "https://px4.io/";
license = licenses.bsd3;
platforms = platforms.all;
};
};
# Development shell
px4-dev-shell = prev.mkShell {
nativeBuildInputs = [
final.cmake
final.ccache
final.gcc-arm-embedded
final.ncurses
python3
final.libusb1
];
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment