Skip to content
Open
Show file tree
Hide file tree
Changes from 16 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
124aa3c
Start August 2026 Jazzy full rebuild
wolfv Aug 2, 2026
752d872
Refresh platform patches for updated sources
wolfv Aug 2, 2026
af739cd
Fix BehaviorTree.CPP build with Apple libc++
wolfv Aug 2, 2026
bfe66d2
Update migration pins and ARM smoke test
wolfv Aug 2, 2026
edc08d5
Apply jsoncpp 1.9.8 migration
wolfv Aug 4, 2026
5ae53ef
Resume CI builds from cache
wolfv Aug 8, 2026
abfba6e
Keep Protobuf compatible with OpenCV
wolfv Aug 8, 2026
e6988a4
Require Protobuf 7 OpenCV builds
wolfv Aug 8, 2026
307df6b
Fix OpenCV mutex match specs
wolfv Aug 8, 2026
222b0fb
Use pre-HDF5-2 dependency stack
wolfv Aug 9, 2026
e93c1ad
Keep jsoncpp on pre-HDF5-2 stack
wolfv Aug 9, 2026
d726b43
Restore HDF5 2 dependency stack
wolfv Aug 11, 2026
8895c07
Follow OpenCV FFmpeg 9 rebuild
wolfv Aug 11, 2026
b4fe92c
Retry with split GDAL Gazebo package
wolfv Aug 12, 2026
96d5355
Map GDAL development dependency to core library
wolfv Aug 12, 2026
464ca34
Remove deprecated packages from rosdistro configuration
Tobias-Fischer Aug 12, 2026
787123f
Add navmap and easynav packages on Linux
traversaro Aug 13, 2026
059caa1
Update dependencies.yaml with new hosts
traversaro Aug 13, 2026
492a994
Add missing Qt dependency for swri_console
wolfv Aug 14, 2026
5b4c1db
Address full rebuild review feedback
wolfv Aug 17, 2026
473d73b
Drop upstreamed patches and constrain HDF5 ABI
wolfv Aug 17, 2026
35755f3
Fix refreshed packages on Windows and Linux
wolfv Aug 17, 2026
d923f25
Support libmavconn with libc++ 19
wolfv Aug 17, 2026
7ff0511
Fix swri_console signal macros on macOS
wolfv Aug 17, 2026
69a78c9
Let the solver choose the coherent HDF5 stack
wolfv Aug 18, 2026
9d4b735
Remove temporary mutex cache cleanup
wolfv Aug 18, 2026
d512b59
Disable temporary cache artifact uploads
wolfv Aug 27, 2026
e0638f1
Disable git maintenance during CI builds
wolfv Aug 27, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .github/workflows/testpr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,9 @@ jobs:
- name: Delete specific outdated cache entries
shell: bash -l {0}
run: |
# rm -rf ${{ matrix.folder_cache }}/ros-jazzy-mrt-cmake-modules* || true
# These packages changed ABI constraints without a build-number change.
rm -rf ${{ matrix.folder_cache }}/ros2-distro-mutex* || true
rm -rf ${{ matrix.folder_cache }}/ros-jazzy-gz-*-vendor* || true

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was a temporary workaround for CI, please remove.

pixi run rattler-index fs ${CONDA_BLD_PATH:-output} --force
exit 0

Expand Down
29 changes: 19 additions & 10 deletions conda_build_config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,26 +8,35 @@ cmake:
- 3.*
eigen_abi_devel:
- '5.0.1'
icu:
# icu78 migration is nearly complete on conda-forge.
- '78'
# Apply conda-forge's 2026 Q2 Abseil/gRPC/Protobuf migration.
libabseil:
- 20260526
libgrpc:
- '1.82'
libprotobuf:
- 6.33.5
- 7.35.1
protobuf:
- 6.33.5
- 7.35.1
fmt:
- '12.1'
graphviz:
- '14'
jsoncpp:
- 1.9.7
# jsoncpp 1.9.8 migration is nearly complete on conda-forge.
- 1.9.8
libopencv:
- 4.13.0
libmujoco:
- 3.8.1
- 3.10.0
# Mitigation for
# https://github.com/RoboStack/ros-jazzy/pull/126#issuecomment-3515455380
libcap:
- 2.78
libhwloc:
- 2.12.2
- 2.13.0
libxml2:
- '2.14'
libzenohc:
Expand All @@ -39,13 +48,13 @@ lua:
pugixml:
- '1.15'
shaderc:
- '2026.2'
- '2026.3'
spdlog:
- 1.17
tbb:
- '2022'
- '2023'
tbb_devel:
- '2022'
- '2023'
urdfdom:
- '6.0'
urdfdom_headers:
Expand Down Expand Up @@ -75,8 +84,8 @@ c_stdlib:
- vs # [win]
c_stdlib_version: # [unix]
- 2.17 # [linux]
- 11.0 # [osx and x86_64]
- 11.0 # [osx and arm64]
- 12.0 # [osx and x86_64]
- 12.0 # [osx and arm64]
cxx_compiler:
- gxx # [linux]
- clangxx # [osx]
Expand Down
12 changes: 0 additions & 12 deletions patch/ros-jazzy-apriltag-ros.patch
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,3 @@ index c906851..b48600f 100644
endif()

option(ASAN "use AddressSanitizer to detect memory issues" OFF)
diff --git a/src/conversion.cpp b/src/conversion.cpp
--- a/src/conversion.cpp
+++ b/src/conversion.cpp
@@ -56,7 +56,7 @@ tf2::toMsg(const std::pair<cv::Mat_<double>, cv::Mat_<double>>& pose)

// convert compact rotation vector to angle-axis to quaternion
const Eigen::Map<const Eigen::Vector3d> rvec(reinterpret_cast<double*>(pose.second.data));
- const Eigen::Quaterniond q({rvec.norm(), rvec.normalized()});
+ const Eigen::Quaterniond q(Eigen::AngleAxisd(rvec.norm(), rvec.normalized()));

geometry_msgs::msg::Transform t;
tf2::convert(pose.first, t.translation);
187 changes: 187 additions & 0 deletions patch/ros-jazzy-behaviortree-cpp.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
diff --git a/include/behaviortree_cpp/basic_types.h b/include/behaviortree_cpp/basic_types.h
index eb4920b..eb89602 100644
--- a/include/behaviortree_cpp/basic_types.h
+++ b/include/behaviortree_cpp/basic_types.h
@@ -175,6 +175,23 @@ template <>
template <>
[[nodiscard]] double convertFromString<double>(StringView str);

+/**
+ * @brief Parse a double from a string using the semantics of
+ * std::from_chars(std::chars_format::general): locale-independent (only '.' as
+ * the decimal separator), rejecting leading whitespace, a leading '+', and hex
+ * floats. Includes a thread-safe fallback for standard libraries that lack the
+ * floating-point std::from_chars overload (e.g. Apple libc++).
+ *
+ * @param str the input string.
+ * @param out set to the parsed value on success (left untouched on failure).
+ * @param require_full_consumption when true, the whole string must be a valid
+ * double (trailing characters cause failure); when false, parsing stops
+ * at the first non-numeric character.
+ * @return true on success.
+ */
+[[nodiscard]] bool parseDouble(StringView str, double& out,
+ bool require_full_consumption);
+
// Integer numbers separated by the character ";"
template <>
[[nodiscard]] std::vector<int> convertFromString<std::vector<int>>(StringView str);
diff --git a/src/basic_types.cpp b/src/basic_types.cpp
index f7374ae..0c82b0d 100644
--- a/src/basic_types.cpp
+++ b/src/basic_types.cpp
@@ -6,8 +6,16 @@
#include <algorithm>
#include <array>
#include <charconv>
-#if __cpp_lib_to_chars < 201611L
-#include <clocale>
+// Apple's libc++ lacks the floating-point std::from_chars overload; parseDouble
+// falls back to strtod_l with a private "C" locale, which needs these headers.
+#if !defined(__cpp_lib_to_chars) || (__cpp_lib_to_chars < 201611L)
+#include <cctype>
+#include <cerrno>
+
+#include <locale.h>
+#if defined(__APPLE__)
+#include <xlocale.h>
+#endif
#endif
#include <cstdlib>
#include <cstring>
@@ -196,34 +204,88 @@ uint32_t convertFromString<uint32_t>(StringView str)
return ConvertWithBoundCheck<uint32_t>(str);
}

+bool parseDouble(StringView str, double& out, bool require_full_consumption)
+{
+#if defined(__cpp_lib_to_chars) && (__cpp_lib_to_chars >= 201611L)
+ // std::from_chars is locale-independent and thread-safe.
+ const char* begin = str.data();
+ const char* end = begin + str.size();
+ const auto [ptr, ec] = std::from_chars(begin, end, out);
+ if(ec != std::errc())
+ {
+ return false;
+ }
+ return !require_full_consumption || ptr == end;
+#else
+ // Apple's libc++ lacks the floating-point std::from_chars overload. Reproduce
+ // its std::chars_format::general semantics with strtod_l under a "C" locale
+ // created once (thread-safe, no global setlocale mutation), plus a guard that
+ // rejects the leading whitespace, leading '+', and hex floats that strtod
+ // would otherwise accept.
+ if(str.empty())
+ {
+ return false;
+ }
+ const char first = str.front();
+ if(first == '+' || std::isspace(static_cast<unsigned char>(first)) != 0)
+ {
+ return false;
+ }
+ // std::from_chars(general) does not recognise a "0x"/"0X" hex-float prefix; it
+ // parses only the leading "0" and stops at the 'x'. strtod would consume the
+ // whole hex float, so emulate from_chars here: the value is 0, and everything
+ // from the 'x' onward is unparsed (a failure only in the full-consumption case).
+ const std::size_t mantissa = (first == '-') ? 1u : 0u;
+ if(str.size() > mantissa + 1 && str[mantissa] == '0' &&
+ (str[mantissa + 1] == 'x' || str[mantissa + 1] == 'X'))
+ {
+ if(require_full_consumption)
+ {
+ return false;
+ }
+ out = (first == '-') ? -0.0 : 0.0;
+ return true;
+ }
+ static ::locale_t c_locale =
+ ::newlocale(LC_NUMERIC_MASK, "C", static_cast<::locale_t>(0));
+ if(c_locale == static_cast<::locale_t>(0))
+ {
+ return false;
+ }
+ // strtod_l needs a null-terminated buffer.
+ const std::string buffer(str.data(), str.size());
+ errno = 0;
+ char* parse_end = nullptr;
+ const double value = ::strtod_l(buffer.c_str(), &parse_end, c_locale);
+ if(parse_end == buffer.c_str() || errno == ERANGE)
+ {
+ return false;
+ }
+ if(require_full_consumption && parse_end != buffer.c_str() + buffer.size())
+ {
+ return false;
+ }
+ out = value;
+ return true;
+#endif
+}
+
template <>
double convertFromString<double>(StringView str)
{
-#if __cpp_lib_to_chars >= 201611L
- // from_chars is locale-independent and thread-safe
double result = 0;
- const auto [ptr, ec] = std::from_chars(str.data(), str.data() + str.size(), result);
- if(ec != std::errc())
+ if(!parseDouble(str, result, /*require_full_consumption=*/false))
{
throw RuntimeError(StrCat("Can't convert string [", str, "] to double"));
}
return result;
-#else
- // Fallback: stod is locale-dependent, so force "C" locale.
- // See issue #120. Note: setlocale is not thread-safe.
- const std::string old_locale = setlocale(LC_NUMERIC, nullptr);
- std::ignore = setlocale(LC_NUMERIC, "C");
- const std::string str_copy(str.data(), str.size());
- const double val = std::stod(str_copy);
- std::ignore = setlocale(LC_NUMERIC, old_locale.c_str());
- return val;
-#endif
}

template <>
float convertFromString<float>(StringView str)
{
#if __cpp_lib_to_chars >= 201611L
+ // Parse directly as float to preserve std::from_chars<float> range semantics.
float result = 0;
const auto [ptr, ec] = std::from_chars(str.data(), str.data() + str.size(), result);
if(ec != std::errc())
@@ -232,12 +294,12 @@ float convertFromString<float>(StringView str)
}
return result;
#else
- const std::string old_locale = setlocale(LC_NUMERIC, nullptr);
- std::ignore = setlocale(LC_NUMERIC, "C");
- const std::string str_copy(str.data(), str.size());
- const double val = std::stod(str_copy);
- std::ignore = setlocale(LC_NUMERIC, old_locale.c_str());
- return static_cast<float>(val);
+ double result = 0;
+ if(!parseDouble(str, result, /*require_full_consumption=*/false))
+ {
+ throw RuntimeError(StrCat("Can't convert string [", str, "] to float"));
+ }
+ return static_cast<float>(result);
#endif
}

diff --git a/src/xml_parsing.cpp b/src/xml_parsing.cpp
index 73e06dc..132ebbf 100644
--- a/src/xml_parsing.cpp
+++ b/src/xml_parsing.cpp
@@ -1189,8 +1189,7 @@ void BT::XMLParser::PImpl::recursivelyCreateSubtree(
if(!stored)
{
double dbl_val = 0;
- auto [ptr, ec] = std::from_chars(begin, end, dbl_val);
- if(ec == std::errc() && ptr == end)
+ if(parseDouble(str_value, dbl_val, /*require_full_consumption=*/true))
{
new_bb->set(attr_name, dbl_val);
stored = true;
Loading
Loading