mirror of
https://github.com/lopsided98/nix-ros-overlay.git
synced 2025-06-10 17:54:49 +03:00
95 lines
3.5 KiB
Nix
95 lines
3.5 KiB
Nix
# Provides a specialized version of buildEnv, designed specifically for ROS
|
|
# packages. It is useful when using a large number of ROS packages that would
|
|
# otherwise cause ROS_PACKAGE_PATH or other environment variables to become too
|
|
# long.
|
|
#
|
|
# All ROS packages in the 'paths' closure are added to the environment, while
|
|
# other packages are propagated. This makes it usable in nix-shell, while
|
|
# preventing ROS_PACKAGE_PATH and CMAKE_PREFIX_PATH from becoming too large due
|
|
# to a huge number of ROS packages.
|
|
#
|
|
# By default, all binaries in the environment are wrapped, setting the relevant
|
|
# ROS environment variables, allowing use outside of nix-shell.
|
|
{ lib, stdenv, buildPackages, writeText, buildEnv, makeWrapper }:
|
|
{ paths ? [], wrapPrograms ? true, ... }@args:
|
|
|
|
with lib;
|
|
|
|
let
|
|
propagatePackages = packages: let
|
|
validPackages = filter (d: d != null) packages;
|
|
partitionedPackages = partition (d: d.rosPackage or false) validPackages;
|
|
rosPackages = partitionedPackages.right;
|
|
otherPackages = partitionedPackages.wrong;
|
|
rosPropagatedPackages = unique (concatLists (catAttrs "propagatedBuildInputs" rosPackages));
|
|
recurse = propagatePackages rosPropagatedPackages;
|
|
in if length validPackages == 0 then {
|
|
rosPackages = [];
|
|
otherPackages = [];
|
|
} else {
|
|
rosPackages = unique (rosPackages ++ recurse.rosPackages);
|
|
otherPackages = unique (otherPackages ++ recurse.otherPackages);
|
|
};
|
|
|
|
propagatedPaths = propagatePackages paths;
|
|
|
|
env = (buildEnv (args // {
|
|
name = "ros-env";
|
|
# Only add ROS packages to environment. The rest are propagated like normal.
|
|
# ROS packages propagate a huge number of dependencies, which are added all
|
|
# added to the environment with nix-shell -p, but would not normally not be
|
|
# added with buildEnv. This file adds all specified ROS packages and their
|
|
# ROS dependencies to the environment, while propagating other packages like
|
|
# nix-shell -p does.
|
|
paths = propagatedPaths.rosPackages;
|
|
|
|
nativeBuildInputs = optional wrapPrograms makeWrapper;
|
|
|
|
postBuild = ''
|
|
"${buildPackages.perl}/bin/perl" "${./setup-hook-builder.pl}"
|
|
'' + optionalString wrapPrograms ''
|
|
if [ -d "$out/bin" ]; then
|
|
find -L "$out/bin" -executable -type f -xtype l -print0 | \
|
|
while IFS= read -r -d "" link; do
|
|
file="$(readlink "$link")"
|
|
rm "$link"
|
|
# Remove unwrapped versions of binaries
|
|
if [[ "$(basename "$link")" == .*-wrapped ]]; then continue; fi
|
|
|
|
makeWrapper "$file" "$link" \
|
|
--prefix PATH : "$out/bin" \
|
|
--prefix CMAKE_PREFIX_PATH : "$out" \
|
|
--prefix AMENT_PREFIX_PATH : "$out" \
|
|
--prefix ROS_PACKAGE_PATH : "$out/share"
|
|
done
|
|
fi
|
|
'';
|
|
|
|
passthru.env = stdenv.mkDerivation {
|
|
name = "interactive-ros-env";
|
|
|
|
buildInputs = [ env ];
|
|
|
|
buildCommand = ''
|
|
echo >&2 ""
|
|
echo >&2 "*** ROS 'env' attributes are intended for interactive nix-shell sessions, not for building! ***"
|
|
echo >&2 ""
|
|
exit 1
|
|
'';
|
|
};
|
|
})).overrideAttrs ({ buildCommand, passAsFile ? [], ...}: {
|
|
# Hack to allow buildEnv to use propagatedBuildInputs
|
|
buildCommand = null;
|
|
oldBuildCommand = buildCommand;
|
|
passAsFile = (if passAsFile == null then [] else passAsFile) ++ [ "oldBuildCommand" ];
|
|
|
|
propagatedBuildInputs = propagatedPaths.otherPackages;
|
|
|
|
buildPhase = ''
|
|
runHook preBuild
|
|
. "$oldBuildCommandPath"
|
|
runHook postBuild
|
|
'';
|
|
phases = [ "buildPhase" "fixupPhase" ];
|
|
});
|
|
in env
|