diff --git a/base.nix b/base.nix index 05c6222816..8c75f72cdd 100644 --- a/base.nix +++ b/base.nix @@ -15,13 +15,17 @@ self: super: with super.lib; let rosinstall-generator = pySelf.callPackage ./rosinstall-generator { }; rospkg = pySelf.callPackage ./rospkg { }; + + vcstools = pySelf.callPackage ./vcstools { }; + + wstool = pySelf.callPackage ./wstool { }; }; }); in { + openni2 = self.callPackage ./openni2 { }; + python27 = pythonOverridesFor super.python27; python36 = pythonOverridesFor super.python36; python37 = pythonOverridesFor super.python37; - - console-bridge = self.callPackage ./console-bridge { }; } diff --git a/build-env/default.nix b/build-env/default.nix index fb91c6f92a..edcb6f022a 100644 --- a/build-env/default.nix +++ b/build-env/default.nix @@ -1,21 +1,21 @@ -{ stdenv, runCommand, makeWrapper, catkin }: -{ packages ? [] -, extraOutputsToInstall ? [] -, postBuild ? "" -, ignoreCollisions ? false -# Wrap executables with the given argument. -, makeWrapperArgs ? [] }: +{ stdenv, buildEnv, requiredRosPackages, catkin, cmake }: +{ paths ? [], ... }@args: let - env = runCommand "ros-env" { - inherit packages; - - nativeBuildInputs = [ makeWrapper ]; - + propagatePackages = drvs: let + validDrvs = filter (d: d != null) drvs; + in if length validDrvs == 0 then [] + else unique (validDrvs ++ (propagatePackages (unique (concatLists (catAttrs "propagatedBuildInputs" validDrvs))))); + + env = buildEnv (args // { + name = "ros-env"; + paths = propagatePackages paths; + ignoreCollisions = true; + passthru.env = stdenv.mkDerivation { name = "interactive-ros-env"; - nativeBuildInputs = [ env ]; - buildInputs = [ catkin ]; + nativeBuildInputs = [ catkin cmake ]; + buildInputs = [ env ]; buildCommand = '' echo >&2 "" @@ -24,75 +24,5 @@ let exit 1 ''; }; - } '' - declare -A symlinks - declare -A pkgsAdded - - isCatkinPackage() { - local pkg="$1" - [ -d "$pkg/share" ] && \ - [ -n "$(find "$pkg/share" \ - -maxdepth 2 -mindepth 2 \ - -name package.xml -print -quit)" ] - } - - isPythonPackage() { - [ -d "$1/${python.sitePackages}" ] - } - - addPackageCommon() { - local pkg="$1" - shift - - if [ -n "''${pkgsAdded[$pkg]}" ]; then return; fi - pkgsAdded[$pkg]=1 - - cd "$pkg" - - local target - while IFS= read -r -d $'\0' file; do - target=$(realpath "$file") - symlinks[$file]="$pkg/$file" - done < <(find . \ - -path ./nix-support -prune -o \ - "$@" -type f -print0) - - local prop="$pkg/nix-support/propagated-build-inputs" - if [ -e "$prop" ]; then - local new_pkg - for new_pkg in $(<"$prop"); do - addPackage $new_pkg - done - fi - } - - addCatkinPackage() { - addPackageCommon "$1" - } - - addPythonPackage() { - addPackageCommon "$1" - } - - addPackage() { - local pkg="$1" - - if isCatkinPackage "$pkg"; then - addCatkinPackage "$pkg" - elif isPythonPackage "$pkg"; then - addPythonPackage "$pkg" - fi - } - - for p in ''${packages[@]}; do - addPackage "$p" - done - - for link in "''${!symlinks[@]}"; do - mkdir -p "$(dirname "$out/$link")" - ln -s "''${symlinks[$link]}" "$out/$link" - done - - ${postBuild} - ''; + }); in env diff --git a/build-ros-package/default.nix b/build-ros-package/default.nix index 324470151e..6ae65208ff 100644 --- a/build-ros-package/default.nix +++ b/build-ros-package/default.nix @@ -4,17 +4,10 @@ , buildInputs ? [] , nativeBuildInputs ? [] , propagatedNativeBuildInputs ? [] +, passthru ? {} , ... }@args: stdenv.mkDerivation (args // { nativeBuildInputs = [ python.pkgs.wrapPython ] ++ nativeBuildInputs; propagatedNativeBuildInputs = [ cmake ] ++ propagatedNativeBuildInputs; - - postInstall = '' - pushd $out - rm -f *setup.*sh - rm -f _setup_util.py - rm -f env.sh - popd - '' + postInstall; }) diff --git a/catkin-pkg/default.nix b/catkin-pkg/default.nix index bfe85e23c0..ad7b951fa1 100644 --- a/catkin-pkg/default.nix +++ b/catkin-pkg/default.nix @@ -1,4 +1,5 @@ -{ buildPythonPackage, fetchPypi, python-dateutil, docutils, pyparsing }: +{ buildPythonPackage, fetchPypi, fetchpatch, python-dateutil, docutils +, pyparsing }: buildPythonPackage rec { pname = "catkin_pkg"; @@ -9,6 +10,12 @@ buildPythonPackage rec { sha256 = "1nv4kgapn6rbdvfgz96z5h5jdga6zca3gg1a5r3n8giykzkmy992"; }; + # Fix argparse requirement + patches = [ (fetchpatch { + url = https://github.com/ros-infrastructure/catkin_pkg/commit/5cf0ea92d9ff888d48413b2948370a0bbb34abdc.patch; + sha256 = "04v3wjwmh1chziqqhxmgf47dgmcxqaissn1zjjx1jblbn2ar5fav"; + }) ]; + propagatedBuildInputs = [ python-dateutil docutils pyparsing ]; meta = { diff --git a/catkin-setup-hook/setup-hook.sh b/catkin-setup-hook/setup-hook.sh index 3faa0202a9..bbafa00751 100644 --- a/catkin-setup-hook/setup-hook.sh +++ b/catkin-setup-hook/setup-hook.sh @@ -13,9 +13,22 @@ _addRosPackagePath() { } addEnvHooks "$hostOffset" _addRosPackagePath +_catkinPostPatchHook() { + patchShebangs cfg +} +postPatchHooks+=(_catkinPostPatchHook) + _catkinPreConfigureHook() { - cmakeFlags+=" -DCATKIN_ENABLE_TESTING=${doCheck:-OFF}" + cmakeFlags+=" -DCATKIN_ENABLE_TESTING=${doCheck:-OFF}" } preConfigureHooks+=(_catkinPreConfigureHook) +_catkinPostInstallHook() { + pushd $out + rm -f *setup.*sh + rm -f _setup_util.py env.sh .rosinstall + popd +} +postInstallHooks+=(_catkinPostInstallHook) + export ROS_DISTRO="@distro@" diff --git a/console-bridge/default.nix b/console-bridge/default.nix deleted file mode 100644 index 6fc1c15fd9..0000000000 --- a/console-bridge/default.nix +++ /dev/null @@ -1,20 +0,0 @@ -{ lib, stdenv, fetchFromGitHub, cmake }: -stdenv.mkDerivation rec { - pname = "console_bridge"; - version = "0.4.3"; - - src = fetchFromGitHub { - owner = "ros"; - repo = pname; - rev = version; - sha256 = "0vk2ji4q93w3fw4s6p0i9d3x2ppsmhxm3x7qrcl4jfr0pyj96n5x"; - }; - - nativeBuildInputs = [ cmake ]; - - meta = with lib; { - description = "A ROS-independent package for logging that seamlessly pipes into rosconsole/rosout for ROS-dependent packages"; - homepage = https://github.com/ros/console_bridge; - license = licenses.bsd3; - }; -} diff --git a/default.nix b/default.nix index ad976ecb53..248ae3aeea 100644 --- a/default.nix +++ b/default.nix @@ -1,6 +1,6 @@ { overlays ? [] }@args: import { overlays = [ (import ./base.nix) - (import ./melodic) + (import ./overlay.nix) ] ++ overlays; } // args diff --git a/kinetic/astra-camera/openni2.patch b/kinetic/astra-camera/openni2.patch new file mode 100644 index 0000000000..7e6251e221 --- /dev/null +++ b/kinetic/astra-camera/openni2.patch @@ -0,0 +1,38 @@ +From e47cc42c6531cbd73831d0a58420fdd67f22fca9 Mon Sep 17 00:00:00 2001 +From: Ben Wolsieffer +Date: Wed, 3 Apr 2019 23:25:58 -0400 +Subject: [PATCH] Make OpenNI dep sane + +--- + CMakeLists.txt | 15 ++------------- + 1 file changed, 2 insertions(+), 13 deletions(-) + +diff --git a/CMakeLists.txt b/CMakeLists.txt +index c15e5db..9d674e3 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -33,19 +33,8 @@ else() + set(obfilter "Off") + endif() + +-include(ExternalProject) +- +-ExternalProject_Add(astra_openni2 +- PREFIX astra_openni2 +- # SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/astra_openni2/OpenNI2 +- GIT_REPOSITORY https://github.com/orbbec/OpenNI2.git +- GIT_TAG orbbec_ros +- CONFIGURE_COMMAND echo "no need to configure" +- BUILD_IN_SOURCE 1 +- BUILD_COMMAND make release FILTER=${obfilter} +- INSTALL_DIR openni2 +- INSTALL_COMMAND tar -xjf /Packaging/Final/OpenNI-Linux-2.3.tar.bz2 -C --strip 1 && mkdir -p /include && ln -fs /Include /include/openni2 +-) ++find_package(PkgConfig) ++pkg_check_modules(astra_openni2 REQUIRED libopenni) + + generate_dynamic_reconfigure_options(cfg/Astra.cfg) + add_service_files(FILES +-- +2.21.0 + diff --git a/kinetic/librealsense/gcc7.patch b/kinetic/librealsense/gcc7.patch new file mode 100644 index 0000000000..f7e0fb97ff --- /dev/null +++ b/kinetic/librealsense/gcc7.patch @@ -0,0 +1,24 @@ +From da0de25eb982c1476cf1276f741a11175e9b08fb Mon Sep 17 00:00:00 2001 +From: Ben Wolsieffer +Date: Wed, 3 Apr 2019 18:17:58 -0400 +Subject: [PATCH] Fix build with GCC 7. + +--- + src/types.h | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/types.h b/src/types.h +index 0455c836..a964bf3e 100644 +--- a/src/types.h ++++ b/src/types.h +@@ -22,6 +22,7 @@ + #include + #include + #include ++#include + + const uint8_t RS_STREAM_NATIVE_COUNT = 5; + const int RS_USER_QUEUE_SIZE = 20; +-- +2.21.0 + diff --git a/kinetic/overrides.nix b/kinetic/overrides.nix index 9de11ab977..94e7b4a9eb 100644 --- a/kinetic/overrides.nix +++ b/kinetic/overrides.nix @@ -6,23 +6,9 @@ rosSelf: rosSuper: { gazebo = self.gazeboSimulator.gazebo7; }; - astra-camera = rosSuper.astra-camera.overrideDerivation ({ - cmakeFlags ? [], - preConfigure ? "", ... - }: let - astraOpenNI2 = self.fetchFromGitHub { - owner = "orbbec"; - repo = "OpenNI2"; - rev = "orbbec_ros"; - sha256 = "1yxgb6vf0kic45jgxvh5bbcrcl7bnjq0fxa5cgvg45is1313d530"; - }; - in { - cmakeFlags = cmakeFlags ++ [ "-DUPDATE_DISCONNECTED=1" ]; - preConfigure = preConfigure + '' - mkdir -p build/.third-party - ln -s ${astraOpenNI2} build/.third-party/astra_openni2 - ''; - }); + # If anyone actually needs this package, its your problem to get it to + # compile. + astra-camera = null; catkin = rosSuper.catkin.overrideDerivation ({ patches ? [], ... @@ -57,6 +43,14 @@ rosSelf: rosSuper: { buildInputs = buildInputs ++ [ self.libGL self.libGL.dev self.libGLU self.libGLU.dev ]; }); + librealsense = rosSuper.librealsense.overrideDerivation ({ + patches ? [], + cmakeFlags ? [], ... + }: { + patches = patches ++ [ ./librealsense/gcc7.patch ]; + cmakeFlags = cmakeFlags ++ [ "-DROS_BUILD_TYPE=1" ]; + }); + rospack = rosSuper.rospack.overrideDerivation ({ patches ? [], ... }: { @@ -69,7 +63,7 @@ rosSelf: rosSuper: { }); realsense-camera = rosSuper.realsense-camera.overrideDerivation ({ - buildInputs ? [], + buildInputs ? [], ... }: { buildInputs = buildInputs ++ [ rosSelf.librealsense ]; }); diff --git a/mk-distro-overlay.nix b/mk-distro-overlay.nix new file mode 100644 index 0000000000..e0ad6c5639 --- /dev/null +++ b/mk-distro-overlay.nix @@ -0,0 +1,136 @@ +{ distro, python }: + +self: super: with self.lib; let + + applyOverlays = self: super: overlays: let + curSuper = applyOverlays self super (init overlays); + in if length overlays == 0 then super + else curSuper // (last overlays) self curSuper; + + mkOverlay = overlays: let + self = applyOverlays self {} overlays; + in self; + + base = rosSelf: rosSuper: { + callPackage = self.newScope rosSelf; + + buildRosPackage = rosSelf.callPackage ./build-ros-package { }; + + buildEnv = rosSelf.callPackage ./build-env { + inherit (self) buildEnv; + }; + + inherit python; + pythonPackages = rosSelf.python.pkgs; + + boost = self.boost.override { + python = rosSelf.python; + enablePython = true; + }; + }; + + overrides = rosSelf: rosSuper: let + patchBoostPython = let + pythonVersion = rosSelf.python.sourceVersion; + pythonLib = "python${pythonVersion.major}${pythonVersion.minor}"; + in '' + sed -Ei CMakeLists.txt \ + -e 's/(Boost [^)]*)python[^ )]*([ )])/\1${pythonLib}\2/' + ''; + in { + # ROS package overrides/fixups + + actionlib = rosSuper.actionlib.overrideDerivation ({ + patches ? [], ... + }: { + patches = patches ++ [ + (self.fetchpatch { + url = https://github.com/ros/actionlib/commit/677e952fcbfe49e6e4c5b835357f88740f49c6ff.patch; + sha256 = "0825w6r5kzz9y7syrrn6q1v0fjrd8qhn11rq2n4kc064702r8jf7"; + }) + ]; + }); + + camera-calibration-parsers = rosSuper.camera-calibration-parsers.overrideDerivation ({ + postPatch ? "", ... + }: { + postPatch = postPatch + patchBoostPython; + }); + + catkin = rosSuper.catkin.overrideDerivation ({ + postPatch ? "", ... + }: { + postPatch = postPatch + '' + patchShebangs cmake + substituteInPlace cmake/templates/python_distutils_install.sh.in \ + --replace /usr/bin/env "${self.coreutils}/bin/env" + ''; + setupHook = self.callPackage ./catkin-setup-hook { } distro; + }); + + cv-bridge = rosSuper.cv-bridge.overrideDerivation ({ + postPatch ? "", + propagatedBuildInputs ? [], ... + }: { + postPatch = postPatch + patchBoostPython; + propagatedBuildInputs = propagatedBuildInputs ++ [ rosSelf.pythonPackages.opencv3 ]; + }); + + dynamic-reconfigure = rosSuper.dynamic-reconfigure.overrideDerivation ({ + postPatch ? "", ... + }: { + postPatch = postPatch + '' + substituteInPlace cmake/setup_custom_pythonpath.sh.in \ + --replace '#!/usr/bin/env sh' '#!${self.stdenv.shell}' + ''; + }); + + map-server = rosSuper.map-server.overrideDerivation ({ + nativeBuildInputs ? [], ... + }: { + nativeBuildInputs = nativeBuildInputs ++ [ self.pkgconfig ]; + }); + + python-qt-binding = rosSuper.python-qt-binding.overrideDerivation ({ + postPatch ? "", ... + }: { + postPatch = '' + sed -e "s#'-I', sip_dir,#'-I', '${rosSelf.pythonPackages.pyqt5}/share/sip/PyQt5',#" \ + -e "s#qtconfig\['QT_INSTALL_HEADERS'\]#'${self.qt5.qtbase.dev}/include'#g" \ + -i cmake/sip_configure.py + '' + postPatch; + }); + + qt-gui-cpp = rosSuper.qt-gui-cpp.overrideDerivation ({ + nativeBuildInputs ? [], ... + }: { + nativeBuildInputs = nativeBuildInputs ++ [ rosSelf.pythonPackages.sip ]; + + # Prevent /build RPATH references + preFixup = "rm -r devel/lib"; + }); + + rqt-gui = rosSuper.rqt-gui.overrideDerivation ({ + nativeBuildInputs ? [], + postFixup ? "", ... + }: { + nativeBuildInputs = nativeBuildInputs ++ [ self.makeWrapper ]; + + postFixup = '' + wrapProgram $out/bin/rqt \ + --set QT_PLUGIN_PATH "${self.qt5.qtbase.bin}/${self.qt5.qtbase.qtPluginPrefix}" + '' + postFixup; + }); + + urdf = rosSuper.urdf.overrideDerivation ({ + postPatch ? "", ... + }: { + postPatch = postPatch + patchBoostPython; + }); + }; +in mkOverlay [ + base + (import (./. + "/${distro}/generated.nix")) + overrides + (import (./. + "/${distro}/overrides.nix") self) +] diff --git a/openni2/default.nix b/openni2/default.nix new file mode 100644 index 0000000000..bbfa691632 --- /dev/null +++ b/openni2/default.nix @@ -0,0 +1,65 @@ +{ clangStdenv, fetchurl, fetchFromGitHub, libusb1, jdk, python3, doxygen +, libGLU, xorg, freeglut }: + +let + libopenni2_pc = fetchurl { + url = https://salsa.debian.org/multimedia-team/openni2/raw/master/debian/libopenni2.pc; + sha256 = "1023s3j71m56fnvqmai4683ds4fbm92dhf1s8csdrdn88a726ygm"; + }; +in clangStdenv.mkDerivation rec { + pname = "openni2"; + version = "2.2.0.33"; + + src = fetchFromGitHub { + owner = "OpenNI"; + repo = "OpenNI2"; + rev = "ca2cdcf39d49332fa9462188a952ff9953e9e1d9"; + sha256 = "0mfnyzpq53wnzgjfx91xcbx0nrl0lp1vrk1rk20a3gb3kshsr675"; + }; + + nativeBuildInputs = [ jdk python3 doxygen ]; + buildInputs = [ libusb1 libGLU xorg.libX11 freeglut ]; + + outputs = [ "out" "doc" ]; + + postPatch = '' + patchShebangs Source + patchShebangs Packaging + + sed -e "s/cmd = \[javaDocExe, '-d', 'java'\]/cmd = [javaDocExe, '-d', 'java', '-Xdoclint:none']/" \ + -i Source/Documentation/Runme.py + sed -e "s%/etc/udev/rules.d/%$out/etc/udev/rules.d/%" \ + -e s%exit%% \ + -i Packaging/Linux/install.sh + ''; + + makeFlags = [ "CFG=Release" "ALLOW_WARNINGS=1" ]; + + postBuild = '' + make doc + ''; + + installPhase = '' + install -d -m755 "$out/"{etc,bin,include,lib/OpenNI2/Drivers} + + cp -r Config "$out/etc/OpenNI2" + + cp -r Include "$out/include/openni2" + + pushd Bin/*-Release + install *.so "$out/lib" + find . -type f -executable -exec install {} "$out/bin" \; + install OpenNI2/Drivers/*.so "$out/lib/OpenNI2/Drivers" + popd + + install -d -m755 "$out/etc/udev/rules.d" + Packaging/Linux/install.sh + + install -d -m755 "$out/lib/pkgconfig" + cp "${libopenni2_pc}" "$out/lib/pkgconfig/libopenni2.pc" + sed -i "s%^prefix=.*%prefix=$out%" "$out/lib/pkgconfig/libopenni2.pc" + + install -d -m755 "$doc/share/doc" + cp -r Source/Documentation/html "$doc/share/doc/OpenNI2" + ''; +} diff --git a/overlay.nix b/overlay.nix new file mode 100644 index 0000000000..c060730bf4 --- /dev/null +++ b/overlay.nix @@ -0,0 +1,18 @@ +self: super: { + rosPackages = rec { + kinetic = import ./mk-distro-overlay.nix { + distro = "kinetic"; + python = self.python2; + } self super; + + kineticPython3 = import ./mk-distro-overlay.nix { + distro = "kinetic"; + python = self.python3; + } self super; + + melodic = import ./mk-distro-overlay.nix { + distro = "melodic"; + python = self.python3; + } self super; + }; +} diff --git a/rosinstall/default.nix b/rosinstall/default.nix index 541e3ace56..46a77fa665 100644 --- a/rosinstall/default.nix +++ b/rosinstall/default.nix @@ -1,7 +1,7 @@ { lib, buildPythonPackage, fetchPypi, makeWrapper, vcstools, pyyaml, rosdistro , catkin-pkg, wstool, rospkg }: -rosinstall = buildPythonPackage rec { +buildPythonPackage rec { pname = "rosinstall"; version = "0.7.8"; @@ -18,4 +18,4 @@ rosinstall = buildPythonPackage rec { homepage = http://wiki.ros.org/rosinstall; license = licenses.bsd3; }; -}; +} diff --git a/vcstools/default.nix b/vcstools/default.nix new file mode 100644 index 0000000000..1451300f81 --- /dev/null +++ b/vcstools/default.nix @@ -0,0 +1,22 @@ +{ buildPythonPackage, fetchPypi, pyyaml, python-dateutil }: + +buildPythonPackage rec { + pname = "vcstools"; + version = "0.1.40"; + + src = fetchPypi { + inherit pname version; + sha256 = "1mfasip71ky1g968n1zlramgn3fjxk4c922d0x9cs0nwm2snln4m"; + }; + + propagatedBuildInputs = [ pyyaml python-dateutil ]; + + # Tries to download files and lots of other issues + doCheck = false; + + meta = { + description = "Python library for interacting with various VCS systems"; + homepage = http://wiki.ros.org/vcstools; + }; +} + diff --git a/wstool/default.nix b/wstool/default.nix new file mode 100644 index 0000000000..28a2f01bf1 --- /dev/null +++ b/wstool/default.nix @@ -0,0 +1,18 @@ +{ buildPythonPackage, fetchPypi, vcstools, pyyaml }: + +buildPythonPackage rec { + pname = "wstool"; + version = "0.1.17"; + + src = fetchPypi { + inherit pname version; + sha256 = "0dz2gn2qx919s1z5wa94nkvb01pnqp945mvj97108w7i1q8lz6y7"; + }; + + propagatedBuildInputs = [ vcstools pyyaml ]; + + meta = { + description = "A tool for managing a workspace of multiple heterogenous SCM repositories"; + homepage = http://wiki.ros.org/wstool; + }; +}