diff --git a/distros/build-env/default.nix b/distros/build-env/default.nix index 569a9893e9..bcf5bcaf5c 100644 --- a/distros/build-env/default.nix +++ b/distros/build-env/default.nix @@ -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}' \ diff --git a/distros/jazzy/overrides.nix b/distros/jazzy/overrides.nix index 5b7309527b..bf0003bc03 100644 --- a/distros/jazzy/overrides.nix +++ b/distros/jazzy/overrides.nix @@ -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" ''; }); diff --git a/distros/rolling/overrides.nix b/distros/rolling/overrides.nix index ca4d34d60d..2f78eae070 100644 --- a/distros/rolling/overrides.nix +++ b/distros/rolling/overrides.nix @@ -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" ''; }); diff --git a/distros/ros2-overlay.nix b/distros/ros2-overlay.nix index 0af9d8e6d0..c80eb88885 100644 --- a/distros/ros2-overlay.nix +++ b/distros/ros2-overlay.nix @@ -13,10 +13,22 @@ rosSelf: rosSuper: with rosSelf.lib; { }); ament-cmake-vendor-package = rosSuper.ament-cmake-vendor-package.overrideAttrs ({ - # the regular cmake fixing replaces /opt 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' diff --git a/examples/ros2-gz-example.nix b/examples/ros2-gz-example.nix index 22288addb3..a3046070f3 100644 --- a/examples/ros2-gz-example.nix +++ b/examples/ros2-gz-example.nix @@ -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 ''; diff --git a/lib/default.nix b/lib/default.nix index 183ddec6d4..59baf7e7a4 100644 --- a/lib/default.nix +++ b/lib/default.nix @@ -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 ? "", ...