Don't install ament-cmake-vendor packages to /opt

Use the standard install directories instead. This makes the packages
integrate with Nix better and doesn't appear to break anything.
This commit is contained in:
Ben Wolsieffer 2024-10-15 21:40:40 -04:00
parent 833c9a8291
commit a5a2a217b3
6 changed files with 79 additions and 62 deletions

View file

@ -10,7 +10,7 @@
#
# 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, symlinkJoin, makeWrapper, python, ros-environment }:
{ lib, stdenv, buildPackages, writeText, buildEnv, makeWrapper, python, ros-environment }:
{ paths ? [], wrapPrograms ? true, postBuild ? "", passthru ? { }, ... }@args:
with lib;
@ -33,11 +33,6 @@ let
propagatedPaths = propagatePackages paths;
gzEnv = symlinkJoin {
name = "gz-env";
paths = map (pkg: "${pkg}/${pkg.gzConfigPath}") (builtins.filter (pkg: pkg ? gzConfigPath) propagatedPaths.rosPackages);
};
env = (buildEnv ((removeAttrs args [ "wrapPrograms" ]) // {
name = "ros-env";
# Only add ROS packages to environment. The rest are propagated like normal.
@ -52,15 +47,6 @@ let
postBuild = postBuild + ''
"${buildPackages.perl}/bin/perl" "${./setup-hook-builder.pl}"
# Some ROS programs keep libraries and binaries in /opt.
if [ -d "$out/opt" ]; then
declare -A optMv=([lib]=lib [lib64]=lib [bin]=bin)
for dir in ''${!optMv[@]}; do
mkdir -p "$out/''${optMv["$dir"]}"
find -L "$out/opt" -mindepth 3 -maxdepth 3 -type f -executable -path "*/$dir/*" -not -name '.*' -exec ln -sf '{}' "$out/''${optMv["$dir"]}" \;
done
fi
'' + optionalString wrapPrograms ''
if [ -d "$out/bin" ]; then
find -L "$out/bin" -executable -type f -xtype l -print0 | \
@ -77,7 +63,7 @@ let
--prefix CMAKE_PREFIX_PATH : "$out" \
--prefix AMENT_PREFIX_PATH : "$out" \
--prefix ROS_PACKAGE_PATH : "$out/share" \
--prefix GZ_CONFIG_PATH : '${gzEnv}' \
--prefix GZ_CONFIG_PATH : "$out/share/gz" \
--set ROS_DISTRO '${ros-environment.rosDistro}' \
--set ROS_VERSION '${toString ros-environment.rosVersion}' \
--set ROS_PYTHON_VERSION '${lib.versions.major python.version}' \

View file

@ -66,7 +66,7 @@ in {
# "RPATH of binary libGrid3D.so contains a forbidden reference to
# /build/" (see https://github.com/gazebosim/gz-gui/issues/627).
postInstall = postInstall + ''
${self.patchelf}/bin/patchelf --remove-rpath $out/opt/gz_gui_vendor/lib64/gz-gui-8/plugins/libGrid3D.so
${self.patchelf}/bin/patchelf --remove-rpath $out/lib64/gz-gui-8/plugins/libGrid3D.so
'';
});
@ -122,16 +122,24 @@ in {
version = "2.0.1";
hash = "sha256-sV/T53oVk1fgjwqn/SRTaPTukt+vAlGGxGvTN8+G6Mo=";
}).overrideAttrs({
nativeBuildInputs ? [], propagatedNativeBuildInputs ? [], qtWrapperArgs ? [], postFixup ? "", ...
nativeBuildInputs ? [],
propagatedNativeBuildInputs ? [],
qtWrapperArgs ? [],
postFixup ? "", ...
}: {
nativeBuildInputs = nativeBuildInputs ++ [ self.qt5.wrapQtAppsHook ];
propagatedNativeBuildInputs = propagatedNativeBuildInputs ++ [self.qt5.qtquickcontrols2 self.qt5.qtgraphicaleffects self.pkg-config];
propagatedNativeBuildInputs = propagatedNativeBuildInputs ++ [
self.qt5.qtquickcontrols2
self.qt5.qtgraphicaleffects
self.pkg-config
];
qtWrapperArgs = qtWrapperArgs ++ [
# Use X11 by default
# Gazebo is currently broken on Wayland
# https://gazebosim.org/docs/ionic/troubleshooting/#wayland-issues
"--set-default QT_QPA_PLATFORM xcb"
];
postFixup = postFixup + ''
wrapQtApp "$out/opt/gz_tools_vendor/bin/gz"
wrapQtApp "$out/bin/gz"
'';
});

View file

@ -66,7 +66,7 @@ in {
# "RPATH of binary libGrid3D.so contains a forbidden reference to
# /build/" (see https://github.com/gazebosim/gz-gui/issues/627).
postInstall = postInstall + ''
${self.patchelf}/bin/patchelf --remove-rpath $out/opt/gz_gui_vendor/lib64/gz-gui-9/plugins/libGrid3D.so
${self.patchelf}/bin/patchelf --remove-rpath $out/lib64/gz-gui-9/plugins/libGrid3D.so
'';
});
@ -122,16 +122,24 @@ in {
version = "2.0.1";
hash = "sha256-sV/T53oVk1fgjwqn/SRTaPTukt+vAlGGxGvTN8+G6Mo=";
}).overrideAttrs({
nativeBuildInputs ? [], propagatedNativeBuildInputs ? [], qtWrapperArgs ? [], postFixup ? "", ...
nativeBuildInputs ? [],
propagatedNativeBuildInputs ? [],
qtWrapperArgs ? [],
postFixup ? "", ...
}: {
nativeBuildInputs = nativeBuildInputs ++ [ self.qt5.wrapQtAppsHook ];
propagatedNativeBuildInputs = propagatedNativeBuildInputs ++ [self.qt5.qtquickcontrols2 self.qt5.qtgraphicaleffects self.pkg-config];
propagatedNativeBuildInputs = propagatedNativeBuildInputs ++ [
self.qt5.qtquickcontrols2
self.qt5.qtgraphicaleffects
self.pkg-config
];
qtWrapperArgs = qtWrapperArgs ++ [
# Use X11 by default
# Gazebo is currently broken on Wayland
# https://gazebosim.org/docs/ionic/troubleshooting/#wayland-issues
"--set-default QT_QPA_PLATFORM xcb"
];
postFixup = postFixup + ''
wrapQtApp "$out/opt/gz_tools_vendor/bin/gz"
wrapQtApp "$out/bin/gz"
'';
});

View file

@ -13,10 +13,22 @@ rosSelf: rosSuper: with rosSelf.lib; {
});
ament-cmake-vendor-package = rosSuper.ament-cmake-vendor-package.overrideAttrs ({
# the regular cmake fixing replaces <snip>/opt<snip> with /var/empty, even within
# the local ros2 install folder, which completely breaks vendoring, since the
# cmake_prefix_path will no longer point the where the files are.
dontFixCmake = true;
postPatch ? "", ...
}: {
# Install to standard directories instead of /opt. With Nix, we don't have
# to worry about collisions with system packages and Nix tooling generally
# expects standard directories.
postPatch = postPatch + ''
ls -l cmake/templates
substituteInPlace cmake/ament_vendor.cmake \
--replace-fail 'opt/''${PROJECT_NAME}' .
substituteInPlace cmake/templates/vendor_package.dsv.in \
--replace-fail 'opt/@PROJECT_NAME@/' ""
substituteInPlace cmake/templates/{vendor_package.sh.in,vendor_package_cmake_prefix.cmake.in,vendor_package_cmake_prefix.sh.in} \
--replace-fail '/opt/@PROJECT_NAME@' ""
substituteInPlace cmake/templates/vendor_package_cmake_prefix.dsv.in \
--replace-fail 'opt/@PROJECT_NAME@' ""
'';
});
cyclonedds = rosSuper.cyclonedds.overrideAttrs ({
@ -62,6 +74,17 @@ rosSelf: rosSuper: with rosSelf.lib; {
nativeBuildInputs = nativeBuildInputs ++ [ self.buildPackages.cmake ];
});
gz-tools-vendor = rosSuper.gz-tools-vendor.overrideAttrs {
setupHook = self.writeText "gz-tools-setup-hook.sh" ''
addGzConfigPath() {
if [ -d "$1/share/gz" ]; then
addToSearchPath GZ_CONFIG_PATH "$1/share/gz"
fi
}
addEnvHooks "$targetOffset" addGzConfigPath
'';
};
iceoryx-posh = rosSuper.iceoryx-posh.overrideAttrs ({
patches ? [],
buildInputs ? [],
@ -144,10 +167,12 @@ rosSelf: rosSuper: with rosSelf.lib; {
buildInputs;
});
ros-gz-sim = rosSuper.ros-gz-sim.overrideAttrs ({ postPatch ? "", ... }: {
ros-gz-sim = rosSuper.ros-gz-sim.overrideAttrs ({
postPatch ? "", ...
}: {
# This launch file attempts to run the gz tool with a Ruby interpreter, but
# in our case it is an regular executable because it is wrapped.
postPatch = postPatch + ''
# This launch file attempts to run the gz tool with a Ruby interpreter,
# but it is actually a regular executable.
substituteInPlace launch/gz_sim.launch.py.in \
--replace-warn 'ruby $(which gz) sim' 'gz sim' \
--replace-warn 'ruby $(which ign) gazebo' 'ign gazebo'

View file

@ -35,6 +35,8 @@ with rosPackages.jazzy;
];
})
];
# Gazebo is currently broken on Wayland
# https://gazebosim.org/docs/ionic/troubleshooting/#wayland-issues
shellHook = ''
unset QT_QPA_PLATFORM
'';

View file

@ -125,35 +125,23 @@
fetchgitArgs.hash = hash;
inherit tarSourceArgs;
};
in
patchedPkg.overrideAttrs ({
pname, postPatch ? "", preBuild ? "", postInstall ? "", passthru ? {}, ...
}:
let
gzConfigPath = "opt/${lib.replaceStrings ["-"] ["_"] stem}_vendor/share/gz";
in
{
dontFixCmake = true; # don't replace $out/opt with $out/var/empty
postPatch = postPatch + ''
cat >> CMakeLists.txt <<'EOF'
if(NOT ''${LIB_VER} VERSION_EQUAL "${version}")
message(FATAL_ERROR "Mismatch in ${pname} version (Nix: ${version}, upstream: ''${LIB_VER}). Fix this in overrides.nix.")
endif()
EOF
'';
preBuild = preBuild + ''
find . -name "*build.make" -print -exec sed -i "s#var/empty#opt#g" {} \;
'';
postInstall = postInstall + ''
# Not all packages create a directory in share/gz, but it's easier to
# handle if we ensure that they do.
mkdir -p "$out/${gzConfigPath}"
'';
setupHook = self.writeText "${pname}-setup-hook.sh" ''
addToSearchPath GZ_CONFIG_PATH "@out@/${gzConfigPath}"
'';
passthru = passthru // { inherit gzConfigPath; };
});
in patchedPkg.overrideAttrs ({
pname, postPatch ? "", ...
}: {
postPatch = postPatch + ''
# Use standard installation paths rather than /opt
substituteInPlace CMakeLists.txt \
--replace-fail 'opt/''${PROJECT_NAME}/extra_cmake' 'share/extra_cmake'
substituteInPlace *-extras.cmake.in \
--replace-fail 'opt/@PROJECT_NAME@/extra_cmake' 'share/extra_cmake'
cat >> CMakeLists.txt <<'EOF'
if(NOT ''${LIB_VER} VERSION_EQUAL "${version}")
message(FATAL_ERROR "Mismatch in ${pname} version (Nix: ${version}, upstream: ''${LIB_VER}). Fix this in overrides.nix.")
endif()
EOF
'';
});
patchBoostPython = pkg: pkg.overrideAttrs ({
postPatch ? "", ...