Bug#1133453: dart: FTBFS against python 3.15rc2

Maximiliano Curia maxy at debian.org
Wed Sep 16 09:16:37 BST 2026


user debian-python at lists.debian.org
usertags 1133453 python3.15
tags 1133453 patch
thanks

Hi!

While rebuilding the python related packages against the Python 3.15rc2
version I ran into this FTBFS [1]. 

I had to apply numerous fixes to get it back to build. Two changes in
debian/rules:
- Force tests to use C++17.
- Avoid running dh_autotest workers concurrently as that hogs the
   builder's memory.

And the following backported upstream patches:
- Upstream patch
   https://github.com/dartsim/dart/commit/bed452eb990edb5998d28d6615a33b81a2bdd0f2
   Update required C++ standard to C++20 (#2068)
- Upstream patch https://github.com/dartsim/dart/commit/bb558d1a0cf
   Change how version requirement for Eigen3 package is enforced (#2107)
- Upstream patch https://github.com/dartsim/dart/commit/d4ad10917f7
   Include cassert before FCL headers (fix Eigen 5 / new-toolchain build)
   (#3021)
- Upstream patch https://github.com/dartsim/dart/commit/f33a8b3f774
   Upgrade pixi dependencies and migrate to the Eigen 5 SVD API (#2765)
- Upstream patch https://github.com/dartsim/dart/commit/e351c67b7f1 Fix
   spdlog/fmt runtime logging (DART 6.16) (#2540)
- Upstream patch e65d2cea29a "Handle ODE libccd box-cylinder contacts"
   (#2389) to avoid failing in test_ForceDependentSlip
- Upstream patch https://github.com/dartsim/dart/commit/0a4b6c20756
   Backport ARM64 joint copy and Icosphere fixes
- Add patch to silence \<ciso646> obsolete include warning

I've applied these fixes in the sandbox [2] to verify that it builds
successfully, these should be applied in Debian to get the package back
to a healthy state.

Happy hacking,

[1]: https://debusine.debian.net/debian/r-python-python3.15/artifact/4313282/
[2]: https://debusine.debian.net/debian/r-python-python3.15/

-- 
"Can you imagine what I would do if I could do all I can?" -- Sun Tzu
Saludos /\/\ /\ >< `/
-------------- next part --------------
diff -Nru dart-6.13.2+ds/debian/changelog dart-6.13.2+ds/debian/changelog
--- dart-6.13.2+ds/debian/changelog	2025-03-10 21:15:09.000000000 +0100
+++ dart-6.13.2+ds/debian/changelog	2026-09-10 20:43:14.000000000 +0200
@@ -1,3 +1,28 @@
+dart (6.13.2+ds-4) UNRELEASED; urgency=medium
+
+  * Team upload.
+  * Force tests to use C++17.
+  * Avoid running dh_autotest workers concurrently as that hogs the builder's memory.
+  * Add build dependency on python3-setuptools.
+  * Upstream patch
+    https://github.com/dartsim/dart/commit/bed452eb990edb5998d28d6615a33b81a2bdd0f2
+    Update required C++ standard to C++20 (#2068)
+  * Upstream patch https://github.com/dartsim/dart/commit/bb558d1a0cf
+    Change how version requirement for Eigen3 package is enforced (#2107)
+  * Upstream patch https://github.com/dartsim/dart/commit/d4ad10917f7
+    Include cassert before FCL headers (fix Eigen 5 / new-toolchain build) (#3021)
+  * Upstream patch https://github.com/dartsim/dart/commit/f33a8b3f774
+    Upgrade pixi dependencies and migrate to the Eigen 5 SVD API (#2765)
+  * Upstream patch https://github.com/dartsim/dart/commit/e351c67b7f1
+    Fix spdlog/fmt runtime logging (DART 6.16) (#2540)
+  * Upstream patch e65d2cea29a
+    "Handle ODE libccd box-cylinder contacts" (#2389) to avoid failing in test_ForceDependentSlip
+  * Upstream patch https://github.com/dartsim/dart/commit/0a4b6c20756
+    Backport ARM64 joint copy and Icosphere fixes
+  * Add patch to silence <ciso646> obsolete include warning
+
+ -- Maximiliano Curia <maxy at debian.org>  Thu, 10 Sep 2026 20:43:14 +0200
+
 dart (6.13.2+ds-3) unstable; urgency=medium
 
   * Team upload
diff -Nru dart-6.13.2+ds/debian/patches/0014-fix-cxx20-deprecated-this-capture.patch dart-6.13.2+ds/debian/patches/0014-fix-cxx20-deprecated-this-capture.patch
--- dart-6.13.2+ds/debian/patches/0014-fix-cxx20-deprecated-this-capture.patch	1970-01-01 01:00:00.000000000 +0100
+++ dart-6.13.2+ds/debian/patches/0014-fix-cxx20-deprecated-this-capture.patch	2026-09-10 20:43:14.000000000 +0200
@@ -0,0 +1,96 @@
+From: Jeongseok (JS) Lee <142548112+jeongseok-meta at users.noreply.github.com>
+Date: Sat, 25 Oct 2025 18:24:26 -0700
+Subject: Update required C++ standard to C++20 (#2068)
+
+Only the lambda-capture fixes from the upstream commit are backported here;
+unrelated hunks are dropped. Not yet in a released version (v6.19.4 does not
+contain it).
+
+Origin: backport, https://github.com/dartsim/dart/commit/bed452eb990edb5998d28d6615a33b81a2bdd0f2
+---
+ dart/dynamics/InverseKinematics.cpp | 12 ++++++------
+ dart/optimizer/Function.cpp         |  2 +-
+ dart/simulation/World.cpp           |  6 ++++--
+ 3 files changed, 11 insertions(+), 9 deletions(-)
+
+diff --git a/dart/dynamics/InverseKinematics.cpp b/dart/dynamics/InverseKinematics.cpp
+index 4ac29e804c2..5223a3cd967 100644
+--- a/dart/dynamics/InverseKinematics.cpp
++++ b/dart/dynamics/InverseKinematics.cpp
+@@ -943,9 +943,9 @@ void InverseKinematics::Analytical::UniqueProperties::
+ {
+   // This function prefers the configuration whose highest joint velocity is
+   // smaller than the highest joint velocity of the other configuration.
+-  mQualityComparator = [=](const Eigen::VectorXd& better,
+-                           const Eigen::VectorXd& worse,
+-                           const InverseKinematics* ik) {
++  mQualityComparator = [](const Eigen::VectorXd& better,
++                          const Eigen::VectorXd& worse,
++                          const InverseKinematics* ik) {
+     const std::vector<std::size_t>& dofs = ik->getAnalytical()->getDofs();
+     double biggestJump = 0.0;
+     bool isBetter = true;
+@@ -1049,7 +1049,7 @@ const std::vector<IK::Analytical::Solution>& IK::Analytical::getSolutions(
+       mOutOfReachCache.push_back(s);
+   }
+
+-  auto comparator = [=](const Solution& s1, const Solution& s2) {
++  auto comparator = [this](const Solution& s1, const Solution& s2) {
+     return mAnalyticalP.mQualityComparator(s1.mConfig, s2.mConfig, mIK);
+   };
+
+@@ -1844,7 +1844,7 @@ void InverseKinematics::resetTargetConnection()
+ {
+   mTargetConnection.disconnect();
+   mTargetConnection = mTarget->onTransformUpdated.connect(
+-      [=](const Entity*) { this->clearCaches(); });
++      [this](const Entity*) { this->clearCaches(); });
+   clearCaches();
+ }
+
+@@ -1853,7 +1853,7 @@ void InverseKinematics::resetNodeConnection()
+ {
+   mNodeConnection.disconnect();
+   mNodeConnection = mNode->onTransformUpdated.connect(
+-      [=](const Entity*) { this->clearCaches(); });
++      [this](const Entity*) { this->clearCaches(); });
+   clearCaches();
+ }
+
+diff --git a/dart/optimizer/Function.cpp b/dart/optimizer/Function.cpp
+index a6935a4c65f..9c6d4c6ad33 100644
+--- a/dart/optimizer/Function.cpp
++++ b/dart/optimizer/Function.cpp
+@@ -129,7 +129,7 @@ void ModularFunction::setCostFunction(CostFunction _cost)
+ //==============================================================================
+ void ModularFunction::clearCostFunction(bool _printWarning)
+ {
+-  mCostFunction = [=](const Eigen::VectorXd&) {
++  mCostFunction = [this, _printWarning](const Eigen::VectorXd&) {
+     if (_printWarning)
+     {
+       dterr
+diff --git a/dart/simulation/World.cpp b/dart/simulation/World.cpp
+index dc66e7a3e0e..c9e7d292eae 100644
+--- a/dart/simulation/World.cpp
++++ b/dart/simulation/World.cpp
+@@ -313,7 +313,8 @@ std::string World::addSkeleton(const dynamics::SkeletonPtr& _skeleton)
+   mMapForSkeletons[_skeleton] = _skeleton;
+
+   mNameConnectionsForSkeletons.push_back(_skeleton->onNameChanged.connect(
+-      [=](dynamics::ConstMetaSkeletonPtr skel,
++      [this](
++          dynamics::ConstMetaSkeletonPtr skel,
+           const std::string&,
+           const std::string&) { this->handleSkeletonNameChange(skel); }));
+
+@@ -471,7 +472,8 @@ std::string World::addSimpleFrame(const dynamics::SimpleFramePtr& _frame)
+   mSimpleFrameToShared[_frame.get()] = _frame;
+
+   mNameConnectionsForSimpleFrames.push_back(_frame->onNameChanged.connect(
+-      [=](const dynamics::Entity* _entity,
++      [this](
++          const dynamics::Entity* _entity,
+           const std::string&,
+           const std::string&) { this->handleSimpleFrameNameChange(_entity); }));
+
diff -Nru dart-6.13.2+ds/debian/patches/0015-relax-eigen3-version-check.patch dart-6.13.2+ds/debian/patches/0015-relax-eigen3-version-check.patch
--- dart-6.13.2+ds/debian/patches/0015-relax-eigen3-version-check.patch	1970-01-01 01:00:00.000000000 +0100
+++ dart-6.13.2+ds/debian/patches/0015-relax-eigen3-version-check.patch	2026-09-10 20:43:14.000000000 +0200
@@ -0,0 +1,29 @@
+From: Silvio Traversaro <silvio at traversaro.it>
+Date: Tue, 4 Nov 2025 16:47:30 +0000
+Subject: Change how version requirement for Eigen3 package is enforced (#2107)
+
+Backported with the minimum version kept at 3.3.4, as already required by
+this package, instead of upstream's later 3.4.0. Not yet in a released
+version (v6.19.4 does not contain it).
+
+Signed-off-by: Silvio Traversaro <silvio at traversaro.it>
+
+Origin: backport, adapted, https://github.com/dartsim/dart/commit/bb558d1a0cf
+---
+ cmake/DARTFindEigen3.cmake | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/cmake/DARTFindEigen3.cmake b/cmake/DARTFindEigen3.cmake
+index 004d55122cd..f1271ae8c82 100644
+--- a/cmake/DARTFindEigen3.cmake
++++ b/cmake/DARTFindEigen3.cmake
+@@ -6,5 +6,9 @@
+ #
+ # This file is provided under the "BSD-style" License
+
+-find_package(Eigen3 3.3.4 REQUIRED CONFIG)
++find_package(Eigen3 REQUIRED CONFIG)
++
++if (Eigen3_VERSION VERSION_LESS 3.3.4)
++  message(FATAL_ERROR "Eigen version>=3.3.4 is required, but found ${Eigen3_VERSION}")
++endif()
diff -Nru dart-6.13.2+ds/debian/patches/0016-fcl-missing-cassert-include.patch dart-6.13.2+ds/debian/patches/0016-fcl-missing-cassert-include.patch
--- dart-6.13.2+ds/debian/patches/0016-fcl-missing-cassert-include.patch	1970-01-01 01:00:00.000000000 +0100
+++ dart-6.13.2+ds/debian/patches/0016-fcl-missing-cassert-include.patch	2026-09-10 20:43:14.000000000 +0200
@@ -0,0 +1,30 @@
+From: Jeongseok (JS) Lee <jslee02 at users.noreply.github.com>
+Date: Sun, 14 Jun 2026 20:41:27 -0700
+Subject: Include <cassert> before FCL headers (fix Eigen 5 / new-toolchain build) (#3021)
+
+Not yet in a released version (v6.19.4 does not contain it).
+
+Origin: backport, https://github.com/dartsim/dart/commit/d4ad10917f7
+---
+ dart/collision/fcl/BackwardCompatibility.hpp | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/dart/collision/fcl/BackwardCompatibility.hpp b/dart/collision/fcl/BackwardCompatibility.hpp
+index b36c64586f1..6e370bab549 100644
+--- a/dart/collision/fcl/BackwardCompatibility.hpp
++++ b/dart/collision/fcl/BackwardCompatibility.hpp
+@@ -49,6 +49,14 @@
+   (FCL_MINOR_VERSION < y || (FCL_MINOR_VERSION <= y))))
+ // clang-format on
+
++// FCL's shape headers (e.g. geometry/shape/convex-inl.h) call assert() without
++// including <cassert> themselves, relying on it being pulled in transitively.
++// Newer toolchains and Eigen versions (e.g. Eigen 5) no longer provide that
++// transitive include, so it must be included before the FCL headers below.
++// clang-format off
++#include <cassert>
++// clang-format on
++
+ #include <fcl/config.h>
+
+ #if FCL_VERSION_AT_LEAST(0, 6, 0)
diff -Nru dart-6.13.2+ds/debian/patches/0017-migrate-jacobisvd-to-eigen5-api.patch dart-6.13.2+ds/debian/patches/0017-migrate-jacobisvd-to-eigen5-api.patch
--- dart-6.13.2+ds/debian/patches/0017-migrate-jacobisvd-to-eigen5-api.patch	1970-01-01 01:00:00.000000000 +0100
+++ dart-6.13.2+ds/debian/patches/0017-migrate-jacobisvd-to-eigen5-api.patch	2026-09-10 20:43:14.000000000 +0200
@@ -0,0 +1,140 @@
+From: Jeongseok (JS) Lee <jslee02 at users.noreply.github.com>
+Date: Fri, 29 May 2026 14:40:07 -0700
+Subject: Upgrade pixi dependencies and migrate to the Eigen 5 SVD API (#2765)
+
+Only the JacobiSVD API migration hunks from the upstream commit are
+backported here (against this package's pre-rename CamelCase file layout);
+the pixi/CI/formatting/other-API hunks are dropped. Not yet in a released
+version (v6.19.4 does not contain it).
+
+Origin: backport, adapted, https://github.com/dartsim/dart/commit/f33a8b3f774
+---
+ dart/constraint/BalanceConstraint.cpp |  6 +++---
+ dart/constraint/BalanceConstraint.hpp |  2 +-
+ dart/dynamics/HierarchicalIK.cpp      |  2 +-
+ dart/dynamics/HierarchicalIK.hpp      |  2 +-
+ dart/dynamics/InverseKinematics.cpp   |  2 +-
+ dart/dynamics/InverseKinematics.hpp   |  2 +-
+ dart/math/Geometry.hpp                |  7 ++++---
+ 7 files changed, 12 insertions(+), 11 deletions(-)
+
+diff --git a/dart/constraint/BalanceConstraint.cpp b/dart/constraint/BalanceConstraint.cpp
+index 7a225adb899..75b73050a60 100644
+--- a/dart/constraint/BalanceConstraint.cpp
++++ b/dart/constraint/BalanceConstraint.cpp
+@@ -215,7 +215,7 @@ void BalanceConstraint::evalGradient(
+
+       mEEJacCache = skel->getLinearJacobian(ee);
+
+-      mSVDCache.compute(mEEJacCache, Eigen::ComputeFullV);
++      mSVDCache.compute(mEEJacCache);
+       math::extractNullSpace(mSVDCache, mPartialNullSpaceCache);
+
+       if (mPartialNullSpaceCache.rows() > 0
+@@ -247,7 +247,7 @@ void BalanceConstraint::evalGradient(
+
+       mComJacCache = skel->getCOMLinearJacobian();
+
+-      mSVDCache.compute(mComJacCache, Eigen::ComputeFullV);
++      mSVDCache.compute(mComJacCache);
+       math::extractNullSpace(mSVDCache, mPartialNullSpaceCache);
+
+       if (mPartialNullSpaceCache.rows() > 0
+@@ -284,7 +284,7 @@ void BalanceConstraint::evalGradient(
+
+       mComJacCache = skel->getCOMLinearJacobian();
+
+-      mSVDCache.compute(mComJacCache, Eigen::ComputeFullV);
++      mSVDCache.compute(mComJacCache);
+       math::extractNullSpace(mSVDCache, mPartialNullSpaceCache);
+
+       if (mPartialNullSpaceCache.rows() > 0
+diff --git a/dart/constraint/BalanceConstraint.hpp b/dart/constraint/BalanceConstraint.hpp
+index 40ca8a3460d..83fbf7df8c0 100644
+--- a/dart/constraint/BalanceConstraint.hpp
++++ b/dart/constraint/BalanceConstraint.hpp
+@@ -183,7 +183,7 @@ protected:
+   math::LinearJacobian mEEJacCache;
+
+   /// Cache for the SVD
+-  Eigen::JacobiSVD<math::LinearJacobian> mSVDCache;
++  Eigen::JacobiSVD<math::LinearJacobian, Eigen::ComputeFullV> mSVDCache;
+
+   /// Cache for the full null space
+   Eigen::MatrixXd mNullSpaceCache;
+diff --git a/dart/dynamics/HierarchicalIK.cpp b/dart/dynamics/HierarchicalIK.cpp
+index d556927e91d..a7d344f8cdb 100644
+--- a/dart/dynamics/HierarchicalIK.cpp
++++ b/dart/dynamics/HierarchicalIK.cpp
+@@ -323,7 +323,7 @@ const std::vector<Eigen::MatrixXd>& HierarchicalIK::computeNullSpaces() const
+         mJacCache.block<6, 1>(0, k) = J.block<6, 1>(0, d);
+       }
+
+-      mSVDCache.compute(mJacCache, Eigen::ComputeFullV);
++      mSVDCache.compute(mJacCache);
+       math::extractNullSpace(mSVDCache, mPartialNullspaceCache);
+
+       if (mPartialNullspaceCache.rows() > 0
+diff --git a/dart/dynamics/HierarchicalIK.hpp b/dart/dynamics/HierarchicalIK.hpp
+index b50836e8ba8..b64f7f9a73b 100644
+--- a/dart/dynamics/HierarchicalIK.hpp
++++ b/dart/dynamics/HierarchicalIK.hpp
+@@ -335,7 +335,7 @@ protected:
+   mutable Eigen::MatrixXd mPartialNullspaceCache;
+
+   /// Cache for the null space SVD
+-  mutable Eigen::JacobiSVD<math::Jacobian> mSVDCache;
++  mutable Eigen::JacobiSVD<math::Jacobian, Eigen::ComputeFullV> mSVDCache;
+
+   /// Cache for Jacobians
+   mutable math::Jacobian mJacCache;
+diff --git a/dart/dynamics/InverseKinematics.cpp b/dart/dynamics/InverseKinematics.cpp
+index 4ac29e804c2..46037f00086 100644
+--- a/dart/dynamics/InverseKinematics.cpp
++++ b/dart/dynamics/InverseKinematics.cpp
+@@ -1744,7 +1744,7 @@ void InverseKinematics::Objective::evalGradient(
+     mIK->setPositions(_x);
+
+     const math::Jacobian& J = mIK->computeJacobian();
+-    mSVDCache.compute(J, Eigen::ComputeFullV);
++    mSVDCache.compute(J);
+     math::extractNullSpace(mSVDCache, mNullSpaceCache);
+     _grad += mNullSpaceCache * mNullSpaceCache.transpose() * mGradCache;
+   }
+diff --git a/dart/dynamics/InverseKinematics.hpp b/dart/dynamics/InverseKinematics.hpp
+index c0d2f22c2a8..e146770cd2c 100644
+--- a/dart/dynamics/InverseKinematics.hpp
++++ b/dart/dynamics/InverseKinematics.hpp
+@@ -1347,7 +1347,7 @@ protected:
+   Eigen::VectorXd mGradCache;
+
+   /// Cache for the null space SVD
+-  Eigen::JacobiSVD<math::Jacobian> mSVDCache;
++  Eigen::JacobiSVD<math::Jacobian, Eigen::ComputeFullV> mSVDCache;
+   // TODO(JS): Need to define aligned operator new for this?
+
+   /// Cache for the null space
+diff --git a/dart/math/Geometry.hpp b/dart/math/Geometry.hpp
+index 5857aae128b..409fdf70f77 100644
+--- a/dart/math/Geometry.hpp
++++ b/dart/math/Geometry.hpp
+@@ -474,8 +474,9 @@ inline double wrapToPi(double angle)
+   return std::fmod(angle + pi, 2 * pi) - pi;
+ }
+
+-template <typename MatrixType, typename ReturnType>
+-void extractNullSpace(const Eigen::JacobiSVD<MatrixType>& _SVD, ReturnType& _NS)
++template <typename MatrixType, int Options, typename ReturnType>
++void extractNullSpace(
++    const Eigen::JacobiSVD<MatrixType, Options>& _SVD, ReturnType& _NS)
+ {
+   int rank = 0;
+   // TODO(MXG): Replace this with _SVD.rank() once the latest Eigen is released
+@@ -497,7 +498,7 @@ void extractNullSpace(const Eigen::JacobiSVD<MatrixType>& _SVD, ReturnType& _NS)
+ template <typename MatrixType, typename ReturnType>
+ void computeNullSpace(const MatrixType& _M, ReturnType& _NS)
+ {
+-  Eigen::JacobiSVD<MatrixType> svd(_M, Eigen::ComputeFullV);
++  Eigen::JacobiSVD<MatrixType, Eigen::ComputeFullV> svd(_M);
+   extractNullSpace(svd, _NS);
+ }
diff -Nru dart-6.13.2+ds/debian/patches/0018-silence-octomap-ciso646-warning.patch dart-6.13.2+ds/debian/patches/0018-silence-octomap-ciso646-warning.patch
--- dart-6.13.2+ds/debian/patches/0018-silence-octomap-ciso646-warning.patch	1970-01-01 01:00:00.000000000 +0100
+++ dart-6.13.2+ds/debian/patches/0018-silence-octomap-ciso646-warning.patch	2026-09-10 20:43:14.000000000 +0200
@@ -0,0 +1,28 @@
+From: Maximiliano Curia <maxy at debian.org>
+Date: Thu, 10 Sep 2026 22:00:00 +0200
+Subject: Do not error out on octomap's obsolete <ciso646> include
+
+Workaround until octomap drops the include.
+
+Forwarded: no
+---
+ CMakeLists.txt | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/CMakeLists.txt b/CMakeLists.txt
+index acdfebf04dc..9c4f6146330 100644
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -259,6 +259,12 @@ elseif(CMAKE_COMPILER_IS_GNUCXX)
+     # TODO: These warnings should be properly addressed and these compiler options removed
+     add_compile_options(-Wno-overloaded-virtual -Wno-alloc-size-larger-than -Wno-dangling-pointer)
+   endif()
++  if(GCC_VERSION VERSION_GREATER_EQUAL 16.0.0)
++    # octomap's OcTreeKey.h still includes <ciso646>, which libstdc++ now
++    # rejects with #warning under C++20; only an error because of -Werror.
++    # Remove once octomap drops the include.
++    add_compile_options(-Wno-error=cpp)
++  endif()
+   set(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG")
+   set(CMAKE_CXX_FLAGS_DEBUG "-g -fno-omit-frame-pointer -fno-inline-functions -fno-inline-functions-called-once -fno-optimize-sibling-calls")
+   if(DART_FAST_DEBUG)
diff -Nru dart-6.13.2+ds/debian/patches/0019-fix-spdlog-fmt-runtime-logging.patch dart-6.13.2+ds/debian/patches/0019-fix-spdlog-fmt-runtime-logging.patch
--- dart-6.13.2+ds/debian/patches/0019-fix-spdlog-fmt-runtime-logging.patch	1970-01-01 01:00:00.000000000 +0100
+++ dart-6.13.2+ds/debian/patches/0019-fix-spdlog-fmt-runtime-logging.patch	2026-09-10 20:43:14.000000000 +0200
@@ -0,0 +1,78 @@
+From: Jeongseok (JS) Lee <jslee02 at users.noreply.github.com>
+Date: Sun, 3 May 2026 20:05:15 -0700
+Subject: Fix spdlog/fmt runtime logging (DART 6.16) (#2540)
+
+In a released version (>=6.16.8).
+
+Origin: backport, https://github.com/dartsim/dart/commit/e351c67b7f1
+---
+ dart/common/detail/Logging-impl.hpp | 14 ++++++++------
+ 1 file changed, 8 insertions(+), 6 deletions(-)
+
+diff --git a/dart/common/detail/Logging-impl.hpp b/dart/common/detail/Logging-impl.hpp
+index 6aca17ff69e..e3c52d605e0 100644
+--- a/dart/common/detail/Logging-impl.hpp
++++ b/dart/common/detail/Logging-impl.hpp
+@@ -37,6 +37,7 @@
+
+ #if DART_HAVE_spdlog
+   #include <spdlog/spdlog.h>
++  #define DART_SPDLOG_RUNTIME(str) SPDLOG_FMT_RUNTIME(str)
+ #else
+   #include <iostream>
+   #include <string>
+@@ -80,7 +81,7 @@ template <typename S, typename... Args>
+ void trace(const S& format_str, [[maybe_unused]] Args&&... args)
+ {
+ #if DART_HAVE_spdlog
+-  spdlog::trace(format_str, std::forward<Args>(args)...);
++  spdlog::trace(DART_SPDLOG_RUNTIME(format_str), std::forward<Args>(args)...);
+ #else
+   detail::print(
+       std::cout, "[trace]", format_str, 38, std::forward<Args>(args)...);
+@@ -92,7 +93,7 @@ template <typename S, typename... Args>
+ void debug(const S& format_str, [[maybe_unused]] Args&&... args)
+ {
+ #if DART_HAVE_spdlog
+-  spdlog::debug(format_str, std::forward<Args>(args)...);
++  spdlog::debug(DART_SPDLOG_RUNTIME(format_str), std::forward<Args>(args)...);
+ #else
+   detail::print(
+       std::cout, "[debug]", format_str, 36, std::forward<Args>(args)...);
+@@ -104,7 +105,7 @@ template <typename S, typename... Args>
+ void info(const S& format_str, [[maybe_unused]] Args&&... args)
+ {
+ #if DART_HAVE_spdlog
+-  spdlog::info(format_str, std::forward<Args>(args)...);
++  spdlog::info(DART_SPDLOG_RUNTIME(format_str), std::forward<Args>(args)...);
+ #else
+   detail::print(
+       std::cout, "[info]", format_str, 32, std::forward<Args>(args)...);
+@@ -116,7 +117,7 @@ template <typename S, typename... Args>
+ void warn(const S& format_str, [[maybe_unused]] Args&&... args)
+ {
+ #if DART_HAVE_spdlog
+-  spdlog::warn(format_str, std::forward<Args>(args)...);
++  spdlog::warn(DART_SPDLOG_RUNTIME(format_str), std::forward<Args>(args)...);
+ #else
+   detail::print(
+       std::cerr, "[warn]", format_str, 33, std::forward<Args>(args)...);
+@@ -128,7 +129,7 @@ template <typename S, typename... Args>
+ void error(const S& format_str, [[maybe_unused]] Args&&... args)
+ {
+ #if DART_HAVE_spdlog
+-  spdlog::error(format_str, std::forward<Args>(args)...);
++  spdlog::error(DART_SPDLOG_RUNTIME(format_str), std::forward<Args>(args)...);
+ #else
+   detail::print(
+       std::cerr, "[error]", format_str, 31, std::forward<Args>(args)...);
+@@ -140,7 +141,8 @@ template <typename S, typename... Args>
+ void fatal(const S& format_str, [[maybe_unused]] Args&&... args)
+ {
+ #if DART_HAVE_spdlog
+-  spdlog::critical(format_str, std::forward<Args>(args)...);
++  spdlog::critical(
++      DART_SPDLOG_RUNTIME(format_str), std::forward<Args>(args)...);
+ #else
+   detail::print(
+       std::cerr, "[fatal]", format_str, 35, std::forward<Args>(args)...);
diff -Nru dart-6.13.2+ds/debian/patches/0020-handle-ode-libccd-box-cyl-contacts.patch dart-6.13.2+ds/debian/patches/0020-handle-ode-libccd-box-cyl-contacts.patch
--- dart-6.13.2+ds/debian/patches/0020-handle-ode-libccd-box-cyl-contacts.patch	1970-01-01 01:00:00.000000000 +0100
+++ dart-6.13.2+ds/debian/patches/0020-handle-ode-libccd-box-cyl-contacts.patch	2026-09-10 20:43:14.000000000 +0200
@@ -0,0 +1,111 @@
+From: Jeongseok (JS) Lee <jslee02 at users.noreply.github.com>
+Date: Tue, 6 Jan 2026 17:12:49 -0800
+Subject: Handle ODE libccd box-cylinder contacts (#2389)
+
+Only the DART_ODE_HAS_LIBCCD_BOX_CYL detection (adapted to this package's
+simpler pre-existing cmake/DARTFindODE.cmake) and the test skip are
+backported; upstream's own libccd box-cylinder contact handling in
+OdeCollisionDetector.cpp is not. Without it, ForceDependentSlip.
+CylinderSlipVelocity fails against ODE built without libccd box-cylinder
+support (as shipped in unstable). In a released version (>=6.16.8).
+
+Origin: backport, adapted, https://github.com/dartsim/dart/commit/e65d2cea29a
+---
+ cmake/DARTFindODE.cmake                           | 37 ++++++++++++++++++++++
+ dart/config.hpp.in                                |  1 +
+ unittests/integration/test_ForceDependentSlip.cpp | 10 ++++++
+ 3 files changed, 48 insertions(+)
+
+diff --git a/cmake/DARTFindODE.cmake b/cmake/DARTFindODE.cmake
+index 7c169787cb5..ebe4e55b353 100644
+--- a/cmake/DARTFindODE.cmake
++++ b/cmake/DARTFindODE.cmake
+@@ -6,6 +6,9 @@
+ #
+ # This file is provided under the "BSD-style" License
+
++set(DART_ODE_HAS_LIBCCD_BOX_CYL 0 CACHE INTERNAL
++  "Whether ODE supports libccd box-cylinder contacts")
++
+ find_package(ODE QUIET CONFIG NAMES ODE ode)
+
+ if(NOT ODE_FOUND AND NOT ode_FOUND)
+@@ -21,3 +24,37 @@ if(NOT ODE_FOUND AND NOT ode_FOUND)
+   endif()
+
+ endif()
++
++if(ODE_FOUND OR ode_FOUND OR TARGET ODE::ODE)
++  include(CheckCSourceCompiles)
++
++  set(_dart_ode_includes "")
++  if(TARGET ODE::ODE)
++    get_target_property(_dart_ode_includes ODE::ODE
++      INTERFACE_INCLUDE_DIRECTORIES)
++  endif()
++  if(NOT _dart_ode_includes AND ODE_INCLUDE_DIRS)
++    set(_dart_ode_includes "${ODE_INCLUDE_DIRS}")
++  endif()
++
++  if(_dart_ode_includes)
++    set(CMAKE_REQUIRED_INCLUDES "${_dart_ode_includes}")
++  endif()
++
++  check_c_source_compiles("
++#include <ode/odeconfig.h>
++#ifndef dLIBCCD_BOX_CYL
++#error dLIBCCD_BOX_CYL not defined
++#endif
++int main(void) { return 0; }
++" _dart_ode_has_libccd_box_cyl)
++
++  unset(CMAKE_REQUIRED_INCLUDES)
++  unset(_dart_ode_includes)
++
++  if(_dart_ode_has_libccd_box_cyl)
++    set(DART_ODE_HAS_LIBCCD_BOX_CYL 1 CACHE INTERNAL
++      "Whether ODE supports libccd box-cylinder contacts" FORCE)
++  endif()
++  unset(_dart_ode_has_libccd_box_cyl)
++endif()
+diff --git a/dart/config.hpp.in b/dart/config.hpp.in
+index 20e4e1eb424..e076e8a6be3 100644
+--- a/dart/config.hpp.in
++++ b/dart/config.hpp.in
+@@ -55,6 +55,7 @@
+ #cmakedefine01 HAVE_SNOPT
+ #cmakedefine01 HAVE_BULLET
+ #cmakedefine01 HAVE_ODE
++#cmakedefine01 DART_ODE_HAS_LIBCCD_BOX_CYL
+ #cmakedefine01 HAVE_FLANN
+ #cmakedefine01 HAVE_OCTOMAP
+ // TODO(JS): Change names to DART_HAVE_*
+diff --git a/unittests/integration/test_ForceDependentSlip.cpp b/unittests/integration/test_ForceDependentSlip.cpp
+index 3f95e0b6e27..15a00842e6b 100644
+--- a/unittests/integration/test_ForceDependentSlip.cpp
++++ b/unittests/integration/test_ForceDependentSlip.cpp
+@@ -32,7 +32,10 @@
+
+ #include <gtest/gtest.h>
+
++#include <ode/ode.h>
++
+ #include "dart/collision/ode/OdeCollisionDetector.hpp"
++#include "dart/config.hpp"
+ #include "dart/constraint/ConstraintSolver.hpp"
+ #include "dart/dynamics/SimpleFrame.hpp"
+ #include "dart/math/Geometry.hpp"
+@@ -202,6 +205,13 @@ TEST(ForceDependentSlip, BoxSlipVelocity)
+ TEST(ForceDependentSlip, CylinderSlipVelocity)
+ {
+   using Eigen::Vector3d;
++
++#if !DART_ODE_HAS_LIBCCD_BOX_CYL
++  GTEST_SKIP() << "Skipping test because ODE was built without libccd "
++                  "box-cylinder support ("
++               << dODE_VERSION << ", see issue #2332).";
++  return;
++#endif
+   const double mass = 2.0;
+   const double radius = 0.5;
+   const double slip = 0.02;
diff -Nru dart-6.13.2+ds/debian/patches/0021-fix-arm64-alignment-and-joint-copy-bugs.patch dart-6.13.2+ds/debian/patches/0021-fix-arm64-alignment-and-joint-copy-bugs.patch
--- dart-6.13.2+ds/debian/patches/0021-fix-arm64-alignment-and-joint-copy-bugs.patch	1970-01-01 01:00:00.000000000 +0100
+++ dart-6.13.2+ds/debian/patches/0021-fix-arm64-alignment-and-joint-copy-bugs.patch	2026-09-10 20:43:14.000000000 +0200
@@ -0,0 +1,70 @@
+From: Jeongseok (JS) Lee <jslee02 at users.noreply.github.com>
+Date: Tue, 23 Jun 2026 00:43:16 -0700
+Subject: Backport ARM64 joint copy and Icosphere fixes
+
+Only the four source hunks are backported (docs/dev_tasks and the DART 7
+test addition, which targets a test file/harness this package doesn't have,
+are dropped). Not yet in a released version (v6.19.4 does not contain it).
+
+Origin: backport, https://github.com/dartsim/dart/commit/0a4b6c20756
+---
+ dart/dynamics/TranslationalJoint2D.cpp              | 2 +-
+ dart/dynamics/UniversalJoint.cpp                    | 2 +-
+ dart/dynamics/detail/TranslationalJoint2DAspect.hpp | 3 +++
+ dart/math/detail/Icosphere-impl.hpp                 | 3 ++-
+ 4 files changed, 7 insertions(+), 3 deletions(-)
+
+diff --git a/dart/dynamics/TranslationalJoint2D.cpp b/dart/dynamics/TranslationalJoint2D.cpp
+index 9bad3e7690a..7f771a9df6a 100644
+--- a/dart/dynamics/TranslationalJoint2D.cpp
++++ b/dart/dynamics/TranslationalJoint2D.cpp
+@@ -93,7 +93,7 @@ void TranslationalJoint2D::copy(const TranslationalJoint2D* otherJoint)
+   if (nullptr == otherJoint)
+     return;
+
+-  copy(*this);
++  copy(*otherJoint);
+ }
+
+ //==============================================================================
+diff --git a/dart/dynamics/UniversalJoint.cpp b/dart/dynamics/UniversalJoint.cpp
+index 27bef9d3af0..3e9e53848bc 100644
+--- a/dart/dynamics/UniversalJoint.cpp
++++ b/dart/dynamics/UniversalJoint.cpp
+@@ -88,7 +88,7 @@ void UniversalJoint::copy(const UniversalJoint* _otherJoint)
+   if (nullptr == _otherJoint)
+     return;
+
+-  copy(*this);
++  copy(*_otherJoint);
+ }
+
+ //==============================================================================
+diff --git a/dart/dynamics/detail/TranslationalJoint2DAspect.hpp b/dart/dynamics/detail/TranslationalJoint2DAspect.hpp
+index eec33029afb..010b6776f9c 100644
+--- a/dart/dynamics/detail/TranslationalJoint2DAspect.hpp
++++ b/dart/dynamics/detail/TranslationalJoint2DAspect.hpp
+@@ -51,6 +51,9 @@ namespace detail {
+ class TranslationalJoint2DUniqueProperties
+ {
+ public:
++  // To get byte-aligned Eigen vectors
++  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
++
+   /// Constructor for pre-defined plane types. Defaults to the XY plane if
+   /// PlaneType::ARBITRARY is specified.
+   explicit TranslationalJoint2DUniqueProperties(
+diff --git a/dart/math/detail/Icosphere-impl.hpp b/dart/math/detail/Icosphere-impl.hpp
+index 520fc057f8a..f5b2475d155 100644
+--- a/dart/math/detail/Icosphere-impl.hpp
++++ b/dart/math/detail/Icosphere-impl.hpp
+@@ -88,7 +88,8 @@ Icosphere<S>::computeIcosahedron(S radius)
+          {z, -x, 0},
+          {-z, -x, 0}};
+
+-  static std::vector<Triangle> triangles
++  // Do NOT make static: causes SEGFAULT on ARM64/NEON (alignment issue).
++  const std::vector<Triangle> triangles
+       = {{0, 4, 1},  {0, 9, 4},  {9, 5, 4},  {4, 5, 8},  {4, 8, 1},
+          {8, 10, 1}, {8, 3, 10}, {5, 3, 8},  {5, 2, 3},  {2, 7, 3},
+          {7, 10, 3}, {7, 6, 10}, {7, 11, 6}, {11, 0, 6}, {0, 1, 6},
diff -Nru dart-6.13.2+ds/debian/patches/series dart-6.13.2+ds/debian/patches/series
--- dart-6.13.2+ds/debian/patches/series	2025-03-10 21:12:07.000000000 +0100
+++ dart-6.13.2+ds/debian/patches/series	2026-09-10 20:43:14.000000000 +0200
@@ -7,3 +7,11 @@
 0004-fix-pkgconfig.patch
 0006-Reduce-test-result-accuracy-to-fix-i386.patch
 0013-Deaktivate-assert-failing-with-Bullet-3.24.patch
+0014-fix-cxx20-deprecated-this-capture.patch
+0015-relax-eigen3-version-check.patch
+0016-fcl-missing-cassert-include.patch
+0017-migrate-jacobisvd-to-eigen5-api.patch
+0018-silence-octomap-ciso646-warning.patch
+0019-fix-spdlog-fmt-runtime-logging.patch
+0020-handle-ode-libccd-box-cyl-contacts.patch
+0021-fix-arm64-alignment-and-joint-copy-bugs.patch
diff -Nru dart-6.13.2+ds/debian/rules dart-6.13.2+ds/debian/rules
--- dart-6.13.2+ds/debian/rules	2025-03-10 21:12:07.000000000 +0100
+++ dart-6.13.2+ds/debian/rules	2026-09-10 20:43:14.000000000 +0200
@@ -31,6 +31,11 @@
 		dh_auto_test
 endif
 
+ifeq ($(DEB_HOST_ARCH),arm64)
+override_dh_auto_test:
+	PYBUILD_TEST_ARGS="ARGS\+=-j1" dh_auto_test
+endif
+
 override_dh_compress:
 	dh_compress \
             -X.hpp -X.h -X.c -X.cpp \
diff -Nru dart-6.13.2+ds/debian/tests/build dart-6.13.2+ds/debian/tests/build
--- dart-6.13.2+ds/debian/tests/build	2025-03-10 21:12:07.000000000 +0100
+++ dart-6.13.2+ds/debian/tests/build	2026-09-10 20:43:14.000000000 +0200
@@ -18,7 +18,7 @@
 }
 EOF
 
-g++ -o darttest darttest.cpp `pkg-config --cflags --libs dart`
+g++ -o darttest darttest.cpp `pkg-config --cflags --libs dart` -std=c++17
 echo "build: OK"
 [ -x darttest ]
 ./darttest


More information about the debian-science-maintainers mailing list