diff --git a/.github/scripts/summarize_rattler_build.py b/.github/scripts/summarize_rattler_build.py new file mode 100644 index 000000000..008ca3c4f --- /dev/null +++ b/.github/scripts/summarize_rattler_build.py @@ -0,0 +1,98 @@ +#!/usr/bin/env python3 +"""Write a compact rattler-build diagnostic for the GitHub job summary.""" + +from __future__ import annotations + +import argparse +import os +import re +from pathlib import Path + + +ANSI_ESCAPE = re.compile(r"\x1b(?:[@-_][0-?]*[ -/]*[@-~]|\][^\x07]*(?:\x07|\x1b\\))") +TIMESTAMP = re.compile(r"^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d+Z\s*") +DIAGNOSTIC = re.compile( + r"(?:Error:\s+×|fatal error(?:\s+[A-Z]+\d+)?:|\berror(?:\s+[A-Z]+\d+)?:|" + r"CMake Error(?::|\s+at\b)|FAILED:|Patch application error|" + r"Failed to resolve dependencies|Cannot solve the request)", + re.IGNORECASE, +) +RECIPE_START = re.compile(r"Running build for recipe:|Build variant:") + + +def parse_args() -> argparse.Namespace: + parser = argparse.ArgumentParser() + parser.add_argument("--log", type=Path, required=True) + parser.add_argument("--platform", required=True) + parser.add_argument("--outcome", required=True) + return parser.parse_args() + + +def clean(line: str) -> str: + cleaned = TIMESTAMP.sub("", ANSI_ESCAPE.sub("", line)).rstrip() + if len(cleaned) > 1_000: + return cleaned[:1_000] + " … [line truncated]" + return cleaned + + +def diagnostic_excerpt(lines: list[str]) -> list[str]: + matches = [index for index, line in enumerate(lines) if DIAGNOSTIC.search(line)] + if not matches: + return [] + + # Keep context around the last diagnostics. This includes multiline solver + # explanations without flooding the GitHub summary with the complete log. + selected: set[int] = set() + for index in matches[-20:]: + selected.update(range(max(0, index - 2), min(len(lines), index + 14))) + + # Name the recipe that produced the final diagnostic even when dependency + # solver output has pushed its heading far outside the context window. + first_diagnostic = matches[max(0, len(matches) - 20)] + for index in range(first_diagnostic, -1, -1): + if RECIPE_START.search(lines[index]): + selected.add(index) + break + + excerpt: list[str] = [] + previous = -2 + for index in sorted(selected): + if previous >= 0 and index > previous + 1: + excerpt.append("...") + excerpt.append(lines[index]) + previous = index + return excerpt[-160:] + + +def main() -> None: + args = parse_args() + run_url = ( + f"{os.environ.get('GITHUB_SERVER_URL', 'https://github.com')}/" + f"{os.environ.get('GITHUB_REPOSITORY', '')}/actions/runs/" + f"{os.environ.get('GITHUB_RUN_ID', '')}" + ) + symbol = "✅" if args.outcome == "success" else "❌" + + print(f"## {symbol} rattler-build: `{args.platform}`") + print() + print(f"Outcome: **{args.outcome}** · [Open workflow run]({run_url})") + + if not args.log.is_file(): + print("\nNo build log was produced.") + return + + lines = [clean(line) for line in args.log.read_text(encoding="utf-8", errors="replace").splitlines()] + excerpt = diagnostic_excerpt(lines) + if not excerpt: + print("\nNo error diagnostics were found in the build log.") + return + + print("\n### Final diagnostics\n") + print("```text") + print("\n".join(excerpt)) + print("```") + print("\nThe complete `rattler-build.log` is available in this run's artifacts.") + + +if __name__ == "__main__": + main() diff --git a/.github/workflows/testpr.yml b/.github/workflows/testpr.yml index 7c8019ef9..dafe37965 100644 --- a/.github/workflows/testpr.yml +++ b/.github/workflows/testpr.yml @@ -2,6 +2,14 @@ on: pull_request: workflow_dispatch: +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +permissions: + actions: read + contents: read + env: ROS_VERSION: 2 # Change to 'true' to enable the cache upload as artifacts @@ -42,6 +50,7 @@ jobs: - uses: prefix-dev/setup-pixi@v0.10.2 with: frozen: true + pixi-version: v0.75.0 - name: Check sorting if: matrix.platform == 'linux-64' @@ -57,6 +66,33 @@ jobs: echo "CONDA_BLD_PATH=C:\\bld\\" >> $GITHUB_ENV mkdir /c/bld + - name: Enable Windows long path support + if: matrix.platform == 'win-64' + shell: pwsh + run: | + # MSVC/MSBuild (VS 2019 16.0+, which windows-2022's toolset is well past) + # honor the Win32 long-path opt-in via this registry key. Without it, + # cl.exe can fail with a cryptic "fatal error C1083: Cannot open + # compiler generated file: ''" once a target's generated intermediate + # (.obj/.tlog) path exceeds the legacy 260-char MAX_PATH, which is easy + # to hit given how deeply nested and long rosidl-generated target names + # can get even under the shortened C:\bld\ prefix above. + New-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\FileSystem" -Name "LongPathsEnabled" -Value 1 -PropertyType DWORD -Force + + - name: Exclude build directories from Windows Defender scanning + if: matrix.platform == 'win-64' + shell: pwsh + run: | + # win-64 jobs have repeatedly gone silent for 10-20+ minutes at points + # with no legitimate reason to be slow -- recipe enumeration (a pure + # local YAML-parse, no network, over ~2000 small files) and library + # linking (many small .obj/.pdb reads/writes) -- then either recover + # very late or run out the 6-hour job timeout. Both are exactly the + # I/O pattern real-time Defender scanning is known to silently stall + # on GH Actions Windows runners. Exclude the checkout and build dirs. + Add-MpPreference -ExclusionPath "${{ github.workspace }}" + Add-MpPreference -ExclusionPath "C:\bld" + # Workaround for https://github.com/RoboStack/ros-humble/pull/141#issuecomment-1941919816 - name: Clean up PATH if: contains(matrix.os, 'windows') @@ -84,9 +120,30 @@ jobs: - name: Generate recipes shell: bash -l {0} + env: + # vinca fetches additional packages' package.xml from + # raw.githubusercontent.com over ~12 concurrent requests; unauthenticated, + # that's subject to GitHub's much lower anonymous rate limit shared across + # every GH Actions runner's IP pool, which manifests as sporadic 404s that + # even the retry loop below doesn't reliably clear. vinca already knows to + # send this as an Authorization header when present (see distro.py's + # _get_auth_headers) -- it just was never wired up here. + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | - mkdir -p recipes - pixi run -v vinca --platform ${{ matrix.platform }} -m -n + set -e + for attempt in 1 2 3; do + rm -rf recipes + mkdir -p recipes + if pixi run -v vinca --platform ${{ matrix.platform }} -m -n; then + break + fi + if [[ "${attempt}" == "3" ]]; then + echo "Recipe generation failed after ${attempt} attempts" >&2 + exit 1 + fi + echo "Recipe generation attempt ${attempt} failed; retrying..." >&2 + sleep 15 + done - name: Check patches shell: bash -l {0} @@ -114,9 +171,21 @@ jobs: shell: bash -l {0} run: | # rm -rf ${{ matrix.folder_cache }}/ros-jazzy-mrt-cmake-modules* || true + mkdir -p ${{ matrix.folder_cache }} rm -rf ${{ matrix.folder_cache }}/ros2-python-qt-binding* || true rm -rf ${{ matrix.folder_cache }}/ros2-qt-gui-cpp* || true - pixi run rattler-index fs ${CONDA_BLD_PATH:-output} --force + # Stale pre-patch build: this PR's cache persists across every commit, so + # --skip-existing was reusing the libg2o built before its CSparse + # INSTALL_INTERFACE fix landed, and rtabmap kept failing to find cs.h + # against that old artifact. Force a rebuild so the patch actually applies. + rm -rf ${{ matrix.folder_cache }}/ros2-libg2o* ${{ matrix.folder_cache }}/ros-jazzy-libg2o* || true + # Corrupt ~38KB cached artifact (same recurring pattern: a cancelled + # run's cache-save step caught it mid-write) missing its installed + # cmake config -- nav2_rviz_plugins' find_package(nav2_route) failed + # against it. Almost certainly from one of today's many win-64 + # cancellations while chasing an unrelated runner hang. + rm -rf ${{ matrix.folder_cache }}/ros2-nav2-route* ${{ matrix.folder_cache }}/ros-jazzy-nav2-route* || true + pixi run rattler-index fs ${{ matrix.folder_cache }}/.. --force exit 0 - name: See packages restored by cache @@ -125,9 +194,44 @@ jobs: ls ${{ matrix.folder_cache }} || true - name: Build recipes + id: build-recipes + shell: bash -l {0} + run: | + set +e + EXTRA_BUILD_ARGS="" + if [ "${{ matrix.platform }}" == "win-64" ]; then + # Drop the timestamp suffix from the per-package build work dir + # (rattler-build__ -> rattler-build_) to claw + # back headroom under Windows' MAX_PATH for long package names, e.g. + # rosbag2_performance_benchmarking_msgs's generated rosidl Python + # typesupport targets (see error C1083 "Cannot open compiler + # generated file: ''"). + EXTRA_BUILD_ARGS="--no-build-id" + fi + # --channel-priority disabled: resolvo would otherwise refuse a just-built local package once any other-channel build of the same name exists. + pixi run rattler-build build --recipe-dir recipes --target-platform ${{ matrix.platform }} -m ./conda_build_config.yaml -c conda-forge -c robostack-jazzy --skip-existing --channel-priority disabled $EXTRA_BUILD_ARGS 2>&1 | tee rattler-build.log + build_status=${PIPESTATUS[0]} + echo "exit-code=${build_status}" >> "$GITHUB_OUTPUT" + exit "$build_status" + + - name: Summarize build result + if: always() shell: bash -l {0} run: | - pixi run rattler-build build --recipe-dir recipes --target-platform ${{ matrix.platform }} -m ./conda_build_config.yaml -c conda-forge -c robostack-jazzy --skip-existing + pixi run python .github/scripts/summarize_rattler_build.py \ + --log rattler-build.log \ + --platform "${{ matrix.platform }}" \ + --outcome "${{ steps.build-recipes.outcome }}" \ + >> "$GITHUB_STEP_SUMMARY" + + - name: Upload build log + if: always() + uses: actions/upload-artifact@v6 + with: + name: build-log-${{ matrix.platform }}-${{ github.run_id }}-${{ github.run_attempt }} + path: rattler-build.log + if-no-files-found: warn + retention-days: 7 - name: See packages that will be saved in cache shell: bash -l {0} @@ -137,7 +241,8 @@ jobs: - name: Save build cache uses: actions/cache/save@v5 - if: always() + # Save partial output when the build fails or is cancelled by the job timeout; do not save when it was skipped. + if: ${{ always() && (steps.build-recipes.outcome == 'success' || steps.build-recipes.outcome == 'failure' || steps.build-recipes.outcome == 'cancelled') }} with: path: | ${{ matrix.folder_cache }} @@ -146,10 +251,11 @@ jobs: - name: Generate GitHub Actions workflows to catch post-PR problems shell: bash -l {0} run: | - pixi run vinca-gha --platform ${{ matrix.platform }} --trigger-branch dummy_build_branch_as_it_is_unused -d ./recipes + pixi run vinca-gha --platform ${{ matrix.platform }} --trigger-branch dummy_build_branch_as_it_is_unused -d ./recipes --batch_size 25 - name: Upload build cache as artifact - if: ${{ always() && env.SAVE_CACHE_AS_ARTIFACT == 'true' }} + # Keep artifacts consistent with the cache: retain partial output from failed or cancelled builds, but not skipped builds. + if: ${{ always() && env.SAVE_CACHE_AS_ARTIFACT == 'true' && (steps.build-recipes.outcome == 'success' || steps.build-recipes.outcome == 'failure' || steps.build-recipes.outcome == 'cancelled') }} uses: actions/upload-artifact@v6 with: name: cache-${{ matrix.platform }}-${{ github.run_id }} diff --git a/AGENTS.md b/AGENTS.md index ea0bde625..cfbff8a38 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,6 +1,6 @@ # AGENTS.md -Working notes for future coding agents in a RoboStack repo. Replace $DISTRO with e.g. noetic/humble/jazzy/kilted and so forth; you can check the working directory. +Working notes for future coding agents in a RoboStack repo. Replace $DISTRO with e.g. noetic/humble/kilted and so forth; you can check the working directory. ## Session defaults for this repo @@ -17,7 +17,7 @@ Working notes for future coding agents in a RoboStack repo. Replace $DISTRO with ```bash # single package (preferred for debugging) -pixi run build-one ros-jazzy- +pixi run build-one ros-$DISTRO- # broad pass when needed pixi run build_continue_on_failure @@ -91,7 +91,7 @@ bash -x conda_build.sh 2>&1 | less ### 7. Rebuild package ```bash -pixi run build-one ros-jazzy- +pixi run build-one ros-$DISTRO- ``` ## Create a patch from build-directory edits @@ -131,13 +131,13 @@ For faster iteration on one package patch, run the script directly with a recipe ```bash # prepare + check only one recipe -python check_patches_clean_apply.py --recipe ros-jazzy- +python check_patches_clean_apply.py --recipe ros-$DISTRO- # prepare only (no build), useful while editing -python check_patches_clean_apply.py --dry --recipe ros-jazzy- +python check_patches_clean_apply.py --dry --recipe ros-$DISTRO- # multiple focused recipes -python check_patches_clean_apply.py --recipe ros-jazzy- --recipe ros-jazzy- +python check_patches_clean_apply.py --recipe ros-$DISTRO- --recipe ros-$DISTRO- ``` What it does: @@ -148,14 +148,14 @@ What it does: ## Patch placement and recipe wiring -- Canonical patch location: `patch/ros-jazzy-.patch` -- Keep recipe copy in `recipes/ros-jazzy-/patch/` if this repo flow expects it. -- Ensure `recipes/ros-jazzy-/recipe.yaml` has: +- Canonical patch location: `patch/ros-$DISTRO-.patch` +- Keep recipe copy in `recipes/ros-$DISTRO-/patch/` if this repo flow expects it. +- Ensure `recipes/ros-$DISTRO-/recipe.yaml` has: ```yaml source: patches: - - patch/ros-jazzy-.patch + - patch/ros-$DISTRO-.patch ``` ## Parallelization and dependency-aware scheduling @@ -164,11 +164,19 @@ It is worth splitting work across multiple agents, but only for independent pack Rules: - Do not build dependent packages in parallel. -- Infer dependency relationships from `recipes/ros-jazzy-/recipe.yaml` (`requirements.host` and `requirements.run`). +- Infer dependency relationships from `recipes/ros-$DISTRO-/recipe.yaml` (`requirements.host` and `requirements.run`). - If package A depends on package B (for example `rosmon` -> `rosmon-core`), build/fix B first. - Run parallel lanes only for packages that do not depend on each other. - If unsure, serialize the builds. +## Cross-distribution sync + +- Work from the clean checked-out heads of rolling, lyrical, kilted, jazzy, and humble; create `codex/cross-distro-sync` in each repo and never merge their independent histories. +- Classify every candidate before editing: portable shared tooling/CI/metadata, conditional package fix requiring a compatible source and refreshed patch, or excluded distro-owned state. +- Keep rosdistro snapshots, mutex/build numbers, ABI/compiler/Python pins, channels/upload targets, package selection, generated recipes, and temporary rebuild controls distro-owned. +- Port patches only for an existing compatible package, using `patch/ros-$DISTRO-.patch` and matching recipe wiring; do not copy a patch solely because its filename exists elsewhere. +- Validate changed patch metadata with `pixi run check-patches` and each changed package with `pixi run build-one ros-$DISTRO-`; inspect final diffs for protected state. + ## Inspect a built conda package ```bash @@ -193,12 +201,64 @@ Check: ## `vinca.yaml` maintenance guidelines +Three distinct ways to exclude a package (vinca revision pinned in `pixi.toml`; re-check `vinca/main.py` + `vinca/resolve.py` if that pin moves): + +1. `packages_select_by_deps`, wrapped in `if: not then: [...]` — the primary way to exclude a package's own recipe. `get_selected_packages` adds every name here to `selected_packages` unconditionally, so simply not listing it for a platform keeps its recipe from being generated. +2. `packages_skip_by_deps` only affects transitive pull-in (`ignore_pkgs` passed to `distro.get_depends()`). It does not stop a package listed directly in `packages_select_by_deps`. +3. `packages_remove_from_deps` is checked by `resolve.py::should_skip_pkg` both for a package's own recipe generation and when resolving other packages' host/run dependency names — using it strips both simultaneously, inseparably. Wrong tool if another selected package legitimately needs the dependency; use (1)+(2) instead. + - Add package seeds under `packages_select_by_deps` using ROS package names (dash/underscore accepted). - Use platform conditions for Linux-only packages; avoid temporary macOS comment blocks. - Keep `packages_skip_by_deps` and `packages_remove_from_deps` coherent with platform constraints. - When `build_gap_report.py` shows built artifacts without recipe directories, add those package seeds to `vinca.yaml`. - After `vinca.yaml` edits, regenerate recipes before expecting `build_gap_report.py` results to change. +## Check dependency pins before building anything + +Incompatible pins (mutex `run_constraints` in `vinca.yaml`, the rendered +`conda_build_config.yaml`, and what conda-forge actually ships) used to surface only +after hundreds of packages had been built. `check_dependency_compat.py` finds them up +front by solving one fake package that requires every non-ROS `host`/`run` dependency +of the generated recipes plus the mutex constraints; nothing is built. + +```bash +# regenerate recipes, then solve the fake package for the current platform +pixi run check-deps + +# other platforms / options (recipes must already be generated) +pixi run python check_dependency_compat.py --platform linux-64 +pixi run python check_dependency_compat.py --no-migrations --json conflicts.json +``` + +What it reports: +- `PIN MISMATCH`: a mutex `run_constraints` entry contradicts the rendered pin (e.g. mutex + `vtk 9.6.2.*` while `vinca_pinning.yaml` applies `vtk970`). Fix `vinca.yaml` or the + migration list; never edit `conda_build_config.yaml` by hand. +- Per conflicting package: which recipes need it, which pin it clashes with (bisected + when it only fails in combination), the solver explanation, and the conda-forge + migration status of its feedstock (done / in-pr / awaiting-parents). That status list + is the conda-forge to-do list; "no migration" means the feedstock simply needs a rebuild. +- Exit code 1 when anything conflicts, so it can gate CI. + +### Rebuild only the packages built with an outdated pin + +```bash +# local artifacts (output/) built against pins that no longer match +pixi run python check_dependency_compat.py --stale +# only violations of the mutex run_constraints (ignore conda_build_config.yaml drift) +pixi run python check_dependency_compat.py --stale --mutex-only +# the published channel +pixi run python check_dependency_compat.py --stale --repodata https://conda.anaconda.org/robostack-staging +# delete the stale local artifacts and re-index; `pixi run build` then rebuilds just those +pixi run python check_dependency_compat.py --stale --delete +``` + +When the stale builds are already on the channel, the report prints a +`pkg_additional_info.yaml` build-number snippet for exactly those packages plus a +`mutex_package: build_number:` bump for `vinca.yaml` (so the mutex is re-published with +the new `run_constraints` while keeping its version), and the `anaconda remove` commands +for the old files. Only those packages are then regenerated and rebuilt. + ## Local contribution workflow (RoboStack) ```bash @@ -208,7 +268,14 @@ pixi run build ## Full rebuilds For full rebuilds also remember: - refresh snapshot: `pixi run create_snapshot` -- update `conda_build_config.yaml` for active migrations. You can use https://github.com/conda-forge/conda-forge-pinning-feedstock/blob/main/recipe/conda_build_config.yaml as a base, and then also apply migrations that are mostly done; you can check the status at https://conda-forge.org/status/. +- update the pins: `conda_build_config.yaml` is generated from `vinca_pinning.yaml` (exact + `conda-forge-pinning` version + list of applied migrations + local overrides). Run + `pixi run vinca-pinning-update --render` to move to the latest pinning and select the + migrations that are complete for our dependencies (status: https://conda-forge.org/status/), + or edit `vinca_pinning.yaml` and run `pixi run vinca-pinning-render`. Never edit + `conda_build_config.yaml` directly. +- keep `mutex_package.run_constraints` in `vinca.yaml` consistent with the rendered pins + and verify with `pixi run check-deps` before starting the rebuild. - bump `build_number` - bump mutex minor and update hardcoded mutex refs where needed - clear stale `pkg_additional_info.yaml` build-number overrides unless intentional diff --git a/build_gap_report.py b/build_gap_report.py index 47c671996..774c02f34 100644 --- a/build_gap_report.py +++ b/build_gap_report.py @@ -2,18 +2,43 @@ """Report gaps between generated recipes and built conda artifacts. Default behavior is platform-agnostic: it inspects all output/ folders that -contain conda artifacts and reports gaps per platform. +contain conda artifacts and reports gaps per platform. Only artifacts built with the +CURRENT build_number (and, for the mutex package, its own build_number) are counted — +older-build_number leftovers from a previous full rebuild are ignored, since counting +them makes the report claim far more packages are done than the current build actually +has. """ from __future__ import annotations import argparse +import re from pathlib import Path from typing import Iterable, Set CONDA_SUFFIX = ".conda" TARBZ2_SUFFIX = ".tar.bz2" +# Matches known conda platform directory names (osx-arm64, linux-64, win-64, …) +_PLATFORM_RE = re.compile(r'^(osx|linux|win|emscripten)-') + +# Strips distro prefix so ros-jazzy-rclcpp, ros2-rclcpp, ros-kilted-rclcpp all +# normalise to "rclcpp" for cross-naming-style comparison. +# Handles two forms: ros-- and ros- +_DISTRO_PREFIX_RE = re.compile(r'^(?:ros-[a-z]+-|ros\d+-)') + +# check_patches_clean_apply.py builds throwaway "-check-patches[-]" +# packages into this same output/ folder to verify patches apply (the +# platform suffix was added later; older leftover artifacts may lack it). They +# never have a matching recipes/ directory and would otherwise show up as false +# "built but no recipe" gaps. +_CHECK_PATCHES_RE = re.compile(r'-check-patches(?:-(?:linux|osx|win|emscripten|any))?$') + +_TOP_LEVEL_BUILD_NUMBER_RE = re.compile(r'^build_number:\s*(\d+)\s*$') +_MUTEX_HEADER_RE = re.compile(r'^mutex_package:\s*$') +_MUTEX_NAME_RE = re.compile(r'^\s+name:\s*"?([\w.-]+)"?\s*$') +_MUTEX_BUILD_NUMBER_RE = re.compile(r'^\s+build_number:\s*(\d+)\s*$') + def parse_args() -> argparse.Namespace: parser = argparse.ArgumentParser( @@ -41,9 +66,38 @@ def parse_args() -> argparse.Namespace: "If omitted, all detected platform folders are inspected." ), ) + parser.add_argument( + "--vinca-yaml", + default="vinca.yaml", + help="vinca.yaml to read the current build_number/mutex from (default: vinca.yaml)", + ) + parser.add_argument( + "--build-number", + type=int, + default=None, + help="Override the build_number to filter artifacts by (default: parsed from --vinca-yaml)", + ) + parser.add_argument( + "--any-build-number", + action="store_true", + help="Don't filter by build_number at all (count every artifact regardless of age)", + ) + parser.add_argument( + "--pkg-additional-info", + default="pkg_additional_info.yaml", + help=( + "pkg_additional_info.yaml to read per-package build_number overrides from " + "(default: pkg_additional_info.yaml)" + ), + ) return parser.parse_args() +def normalize_name(name: str) -> str: + """Strip ros-- / ros2- prefix for cross-naming-style comparison.""" + return _DISTRO_PREFIX_RE.sub("", name) + + def is_conda_artifact(filename: str) -> bool: return filename.endswith(CONDA_SUFFIX) or filename.endswith(TARBZ2_SUFFIX) @@ -60,7 +114,109 @@ def package_name_from_artifact(filename: str) -> str | None: parts = stem.rsplit("-", 2) if len(parts) != 3: return None - return parts[0] + name = parts[0] + if _CHECK_PATCHES_RE.search(name): + return None + return name + + +def build_number_from_artifact(filename: str) -> int | None: + """Extract the trailing _ build number from a conda artifact's build string.""" + stem = filename + if stem.endswith(CONDA_SUFFIX): + stem = stem[: -len(CONDA_SUFFIX)] + elif stem.endswith(TARBZ2_SUFFIX): + stem = stem[: -len(TARBZ2_SUFFIX)] + else: + return None + + parts = stem.rsplit("-", 2) + if len(parts) != 3: + return None + build_string = parts[2] + suffix = build_string.rsplit("_", 1)[-1] + return int(suffix) if suffix.isdigit() else None + + +def read_vinca_config(vinca_yaml: Path) -> tuple[int | None, str | None, int | None]: + """Parse (build_number, mutex_package_name, mutex_build_number) out of vinca.yaml + without requiring a YAML library, since this script has no other dependencies.""" + if not vinca_yaml.is_file(): + return None, None, None + + build_number: int | None = None + mutex_name: str | None = None + mutex_build_number: int | None = None + in_mutex_block = False + + for line in vinca_yaml.read_text().splitlines(): + if in_mutex_block: + if line.startswith((" ", "\t")): + m = _MUTEX_NAME_RE.match(line) + if m: + mutex_name = m.group(1) + m = _MUTEX_BUILD_NUMBER_RE.match(line) + if m: + mutex_build_number = int(m.group(1)) + continue + in_mutex_block = False # fall through: this line starts the next top-level key + + m = _TOP_LEVEL_BUILD_NUMBER_RE.match(line) + if m: + build_number = int(m.group(1)) + continue + if _MUTEX_HEADER_RE.match(line): + in_mutex_block = True + + return build_number, mutex_name, mutex_build_number + + +_PKG_INFO_TOP_LEVEL_KEY_RE = re.compile(r'^([A-Za-z0-9_.]+):\s*(?:#.*)?$') +_PKG_INFO_BUILD_NUMBER_RE = re.compile(r'^\s+build_number:\s*(\d+)\s*$') + + +def read_pkg_build_number_overrides(pkg_info_yaml: Path) -> dict[str, int]: + """Parse per-package `build_number:` overrides out of pkg_additional_info.yaml — + a surgical way to force a rebuild of just one package without bumping vinca.yaml's + global build_number for everything. Keyed by the ROS package name as written there + (underscores), same convention as normalize_name(...).replace('-', '_').""" + overrides: dict[str, int] = {} + if not pkg_info_yaml.is_file(): + return overrides + + current_key: str | None = None + for line in pkg_info_yaml.read_text().splitlines(): + if not line.strip() or line.lstrip().startswith("#"): + continue + if not line[0].isspace(): + m = _PKG_INFO_TOP_LEVEL_KEY_RE.match(line) + current_key = m.group(1) if m else None + continue + if current_key is None: + continue + m = _PKG_INFO_BUILD_NUMBER_RE.match(line) + if m: + overrides[current_key] = int(m.group(1)) + + return overrides + + +def expected_build_number( + norm_name: str, + build_number: int | None, + mutex_norm_name: str | None, + mutex_build_number: int | None, + pkg_build_number_overrides: dict[str, int], +) -> int | None: + """The build_number a package's artifact must carry to count as "current": + the mutex's own build_number for the mutex package, a per-package override from + pkg_additional_info.yaml if one exists for it, otherwise the global build_number.""" + if mutex_norm_name is not None and norm_name == mutex_norm_name and mutex_build_number is not None: + return mutex_build_number + override = pkg_build_number_overrides.get(norm_name.replace("-", "_")) + if override is not None: + return override + return build_number def discover_platform_dirs(output_root: Path) -> list[str]: @@ -71,6 +227,8 @@ def discover_platform_dirs(output_root: Path) -> list[str]: for child in sorted(output_root.iterdir()): if not child.is_dir(): continue + if not _PLATFORM_RE.match(child.name): + continue try: has_artifact = any( entry.is_file() and is_conda_artifact(entry.name) @@ -84,7 +242,14 @@ def discover_platform_dirs(output_root: Path) -> list[str]: return platforms -def built_packages_for_platform(output_root: Path, platform: str) -> Set[str]: +def built_packages_for_platform( + output_root: Path, + platform: str, + build_number: int | None, + mutex_norm_name: str | None, + mutex_build_number: int | None, + pkg_build_number_overrides: dict[str, int], +) -> Set[str]: platform_dir = output_root / platform packages: Set[str] = set() if not platform_dir.exists() or not platform_dir.is_dir(): @@ -94,8 +259,19 @@ def built_packages_for_platform(output_root: Path, platform: str) -> Set[str]: if not artifact.is_file() or not is_conda_artifact(artifact.name): continue package_name = package_name_from_artifact(artifact.name) - if package_name: - packages.add(package_name) + if not package_name: + continue + norm_name = normalize_name(package_name) + + if build_number is not None: + artifact_build_number = build_number_from_artifact(artifact.name) + expected = expected_build_number( + norm_name, build_number, mutex_norm_name, mutex_build_number, pkg_build_number_overrides + ) + if artifact_build_number != expected: + continue + + packages.add(norm_name) return packages @@ -132,22 +308,62 @@ def main() -> int: ) return 1 + if args.any_build_number: + build_number, mutex_name, mutex_build_number = None, None, None + pkg_build_number_overrides: dict[str, int] = {} + else: + build_number, mutex_name, mutex_build_number = read_vinca_config(Path(args.vinca_yaml)) + if args.build_number is not None: + build_number = args.build_number + if build_number is None: + print( + f"Warning: could not read build_number from {args.vinca_yaml} " + "(pass --build-number or --any-build-number) — counting artifacts " + "from every build_number, including stale ones from earlier rebuilds.\n" + ) + pkg_build_number_overrides = read_pkg_build_number_overrides(Path(args.pkg_additional_info)) + mutex_norm_name = normalize_name(mutex_name) if mutex_name else None + + if build_number is not None: + mutex_note = ( + f", mutex build_number {mutex_build_number}" if mutex_build_number is not None else "" + ) + override_note = ( + f", {len(pkg_build_number_overrides)} per-package override(s) from {args.pkg_additional_info}" + if pkg_build_number_overrides + else "" + ) + print(f"Filtering to build_number {build_number}{mutex_note}{override_note}\n") + for idx, platform in enumerate(selected_platforms): - built = built_packages_for_platform(output_root, platform) + built = built_packages_for_platform( + output_root, platform, build_number, mutex_norm_name, mutex_build_number, pkg_build_number_overrides + ) + + # Normalize recipe names for comparison so ros-jazzy-X and ros2-X match. + # Iterate in sorted (not set-hash) order so the displayed name for a + # dual-named package is deterministic across runs, not whichever of the + # two happens to come last per Python's randomized set iteration order — + # "ros2-X" sorts after "ros--X" (- < digit in ASCII) so the + # shared ros2- convention consistently wins when both exist. + norm_to_recipe: dict[str, str] = {normalize_name(r): r for r in sorted(recipes)} + norm_recipes = set(norm_to_recipe) print(f"Platform: {platform}") - print_list( - "Built package artifacts without matching recipe directory", - built - recipes, - ) + extra_norm = built - norm_recipes + extra_display = sorted(extra_norm) + print(f"Built package artifacts without matching recipe directory: {len(extra_display)}") + for name in extra_display: + print(f" - {name}") print() - missing = recipes - built + missing_norm = norm_recipes - built + missing_display = sorted(norm_to_recipe[n] for n in missing_norm) print( - f"Recipe directories without built artifact on this platform: " - f"{len(missing)} out of {len(recipes)}" + f"Recipe directories without built artifact on {platform} platform: " + f"{len(missing_display)} out of {len(norm_recipes)}" ) - if missing: - for recipe in sorted(missing): + if missing_display: + for recipe in missing_display: print(f" - {recipe}") if idx != len(selected_platforms) - 1: diff --git a/check_dependency_compat.py b/check_dependency_compat.py new file mode 100644 index 000000000..fec282555 --- /dev/null +++ b/check_dependency_compat.py @@ -0,0 +1,1032 @@ +#!/usr/bin/env python3 +"""Detect incompatible dependency pins before (or after) building ROS packages. + +Three modes, all platform-agnostic (default platform: the current machine): + +1. ``solve`` (default): collect every non-ROS ``host``/``run`` dependency from the + generated ``recipes/`` tree, add the ``mutex_package.run_constraints`` from + ``vinca.yaml`` as hard requirements, write them into a single fake recipe and + solve it with ``rattler-build --render-only --with-solve`` against the real + ``conda_build_config.yaml``. Nothing is built or downloaded except repodata. + If the solve fails, the offending dependencies are removed iteratively so that + *all* conflicts are reported, each with a focused explanation and the list of + generated recipes that need it. + +2. ``--migrations`` (on by default when conflicts are found): for every conflict, + look up which conda-forge migration touches the pinned library and where the + culprit's feedstock stands in that migration (done / in-pr / awaiting-parents …). + This is the to-do list for conda-forge. + +3. ``--stale``: inspect already-built artifacts (``output//repodata.json`` + or a channel URL) and list ROS packages whose ``depends`` cannot be satisfied + under the current mutex constraints / pins. With ``--delete`` the local + artifacts are removed (and the local index refreshed) so that a subsequent + ``pixi run build`` (``--skip-existing``) rebuilds only those packages. A + ``pkg_additional_info.yaml`` build-number snippet is printed for the case where + the stale builds are already on the channel. + +Run inside the pixi environment, e.g. ``pixi run python check_dependency_compat.py``. +""" + +from __future__ import annotations + +import argparse +import json +import os +import platform as _platform +import re +import shutil +import subprocess +import sys +import tomllib +from collections import defaultdict +from pathlib import Path +from typing import Any, Iterable, Iterator, Optional +from urllib.request import urlopen + +import ruamel.yaml + +ROS_PREFIXES = ("ros-", "ros2-") +DEFAULT_CHANNELS = ["https://repo.prefix.dev/conda-forge"] +FAKE_PACKAGE_NAME = "robostack-dependency-compat-check" +DEFAULT_GLIBC = "2.17" # fallback when c_stdlib_version is not in the variant config +DEFAULT_OSX = "15.0" +# "Platform: linux-64 [__unix=0=0, __linux=0=0, __glibc=0=0, ...]" -> a version of 0 means the +# virtual package is unknown for this (foreign) platform and every solve is meaningless. +_MISSING_VIRTUAL_RE = re.compile(r"Platform: \S+ \[[^\]]*?(__glibc|__osx|__cuda)=0=0") +_GLIBC_NEED_RE = re.compile(r"__glibc >=([0-9.]+)") +STATUS_CATEGORIES = ( + "done", + "in-pr", + "awaiting-pr", + "awaiting-parents", + "not-solvable", + "bot-error", +) + + +# --------------------------------------------------------------------------- utils +def _yaml() -> ruamel.yaml.YAML: + yaml = ruamel.yaml.YAML() + yaml.width = 4096 + yaml.indent(mapping=2, sequence=4, offset=2) + return yaml + + +def load_yaml(path: Path) -> Any: + with path.open(encoding="utf-8") as stream: + return _yaml().load(stream) or {} + + +def detect_platform() -> str: + machine = _platform.machine() + if sys.platform.startswith("linux"): + return "linux-aarch64" if machine == "aarch64" else "linux-64" + if sys.platform == "darwin": + return "osx-arm64" if machine == "arm64" else "osx-64" + if sys.platform == "win32": + return "win-64" + raise RuntimeError(f"Cannot detect conda platform for {sys.platform}/{machine}") + + +def normalized(name: str) -> str: + return name.lower().replace("_", "-") + + +def spec_name(spec: str) -> str: + return spec.split()[0] + + +def is_ros_dependency(name: str) -> bool: + return name.startswith(ROS_PREFIXES) + + +def channels_from_pixi(pixi_toml: Path) -> list[str]: + """Take the channels of the ``build`` task so the check matches real builds.""" + try: + with pixi_toml.open("rb") as stream: + data = tomllib.load(stream) + cmd = data["tasks"]["build"]["cmd"] + if isinstance(cmd, list): + cmd = " ".join(cmd) + except (OSError, KeyError, tomllib.TOMLDecodeError): + return list(DEFAULT_CHANNELS) + channels = re.findall(r"(?:^|\s)-c\s+(\S+)", cmd) + return channels or list(DEFAULT_CHANNELS) + + +def platform_flags(platform: str) -> dict[str, Any]: + """Selector namespace for the v0-style ``# [sel]`` comments in conda_build_config.yaml.""" + try: + from vinca.v1_selectors import _platform_flags # type: ignore + + flags: dict[str, Any] = dict(_platform_flags(platform)) + except ImportError: + os_name, _, arch = platform.partition("-") + flags = { + "target_platform": platform, + "linux": os_name == "linux", + "osx": os_name == "osx", + "win": os_name == "win", + "unix": os_name in ("linux", "osx", "emscripten"), + "emscripten": os_name == "emscripten", + "wasm32": arch == "wasm32", + "x86_64": arch == "64", + "x86": arch == "64", + "aarch64": arch in ("aarch64", "arm64"), + "arm64": arch in ("aarch64", "arm64"), + "ppc64le": arch == "ppc64le", + "riscv64": arch == "riscv64", + } + flags.setdefault("win64", platform == "win-64") + flags.setdefault("os", os) + return flags + + +def eval_selector(selector: str, flags: dict[str, Any]) -> bool: + try: + from vinca.v1_selectors import _eval_condition # type: ignore + + return bool(_eval_condition(selector, flags)) + except Exception: # fall back to a plain python eval of the selector + try: + return bool(eval(selector, {"__builtins__": {}}, dict(flags))) # noqa: S307 + except Exception: + return False + + +# ----------------------------------------------------------------- requirements +def walk_requirements( + value: Any, condition: Optional[str] = None +) -> Iterator[tuple[Optional[str], str]]: + """Yield ``(condition, spec)`` for every requirement, keeping if/then/else.""" + if isinstance(value, str): + yield condition, value.strip() + elif isinstance(value, list): + for item in value: + yield from walk_requirements(item, condition) + elif isinstance(value, dict): + if "if" in value: + cond = str(value["if"]).strip() + then_cond = cond if condition is None else f"({condition}) and ({cond})" + else_cond = f"not ({cond})" if condition is None else f"({condition}) and not ({cond})" + yield from walk_requirements(value.get("then"), then_cond) + if value.get("else") is not None: + yield from walk_requirements(value.get("else"), else_cond) + else: + for item in value.values(): + yield from walk_requirements(item, condition) + + +def collect_requirements( + recipes_dir: Path, sections: Iterable[str] = ("host", "run") +) -> dict[tuple[Optional[str], str], set[str]]: + """Map ``(condition, spec)`` to the recipe names that require it.""" + yaml = _yaml() + requirements: dict[tuple[Optional[str], str], set[str]] = defaultdict(set) + for recipe_path in sorted(recipes_dir.glob("*/recipe.yaml")): + with recipe_path.open(encoding="utf-8") as stream: + recipe = yaml.load(stream) or {} + name = recipe.get("package", {}).get("name", recipe_path.parent.name) + reqs = recipe.get("requirements", {}) or {} + for section in sections: + for condition, spec in walk_requirements(reqs.get(section)): + if not spec or "${{" in spec: + continue + if is_ros_dependency(spec_name(spec)): + continue + requirements[(condition, spec)].add(name) + return requirements + + +def mutex_constraints(vinca_conf: dict[str, Any]) -> list[str]: + mutex = vinca_conf.get("mutex_package") + if isinstance(mutex, dict): + return [str(item) for item in mutex.get("run_constraints", []) or []] + return [] + + +def write_fake_recipe( + path: Path, + pins: list[str], + requirements: Iterable[tuple[Optional[str], str]], + version: str = "0.0.0", +) -> None: + grouped: dict[Optional[str], list[str]] = defaultdict(list) + for condition, spec in requirements: + if spec not in grouped[condition]: + grouped[condition].append(spec) + host: list[Any] = list(pins) + host.extend(sorted(grouped.pop(None, []))) + for condition in sorted(grouped, key=str): + host.append({"if": condition, "then": sorted(grouped[condition])}) + recipe = { + "package": {"name": FAKE_PACKAGE_NAME, "version": version}, + "build": {"number": 0, "script": ""}, + "requirements": {"build": [], "host": host, "run": []}, + "about": { + "summary": "Synthetic package used to check that all RoboStack " + "dependencies are co-installable under the current pins. Never built." + }, + } + path.parent.mkdir(parents=True, exist_ok=True) + with path.open("w", encoding="utf-8") as stream: + _yaml().dump(recipe, stream) + + +# ------------------------------------------------------------------------ solve +def glibc_floor(variant_config: Path, platform: str) -> str: + """The glibc floor the packages are built for (``c_stdlib_version`` on linux).""" + if os.environ.get("CONDA_OVERRIDE_GLIBC"): + return os.environ["CONDA_OVERRIDE_GLIBC"] + try: + return variant_pins(variant_config, platform).get("c-stdlib-version", DEFAULT_GLIBC) + except OSError: + return DEFAULT_GLIBC + + +def rattler_build_executable() -> list[str]: + exe = shutil.which("rattler-build") + if exe: + return [exe] + if shutil.which("pixi"): + return ["pixi", "run", "rattler-build"] + raise SystemExit("rattler-build not found; run this script via `pixi run python ...`") + + +def run_solve( + recipe: Path, + variant_config: Path, + channels: list[str], + platform: str, + output_dir: Path, + *, + verbose: bool = False, +) -> tuple[bool, str]: + cmd = rattler_build_executable() + [ + "build", + "--recipe", + str(recipe), + "-m", + str(variant_config), + "--render-only", + "--with-solve", + "--target-platform", + platform, + "--build-platform", + platform, + "--output-dir", + str(output_dir), + "--color", + "never", + ] + for channel in channels: + cmd += ["-c", channel] + env = dict(os.environ, COLUMNS="500", NO_COLOR="1", RATTLER_BUILD_NO_SPINNER="1") + # Solving for a foreign platform yields __glibc=0 / __osx=0 virtual packages, which + # makes every package look uninstallable. Provide sane defaults unless overridden. + if platform.startswith("linux"): + env.setdefault("CONDA_OVERRIDE_GLIBC", glibc_floor(variant_config, platform)) + elif platform.startswith("osx") and sys.platform != "darwin": + env.setdefault("CONDA_OVERRIDE_OSX", DEFAULT_OSX) + if verbose: + print(" $", " ".join(cmd), file=sys.stderr) + proc = subprocess.run(cmd, capture_output=True, text=True, env=env) + text = proc.stdout + "\n" + proc.stderr + failed = proc.returncode != 0 or "Cannot solve the request" in text + return (not failed), text + + +_ANSI_RE = re.compile(r"\x1b\[[0-9;]*m") +_TREE_RE = re.compile(r"^(?P[\s│]*)(?:├─|└─)\s+(?P[A-Za-z0-9_.+-]+)") + + +def solver_block(text: str) -> str: + """Return the final 'Cannot solve the request because of:' tree, cleaned.""" + text = _ANSI_RE.sub("", text) + marker = "Cannot solve the request because of:" + index = text.rfind(marker) + if index == -1: + return text.strip() + return text[index:].strip() + + +def collapse_versions(text: str) -> str: + """Collapse '7.6.0 | 7.6.0 | 7.6.0 ...' noise into '7.6.0 (x12)'.""" + + def repl(match: re.Match[str]) -> str: + items = [item.strip() for item in match.group(0).split("|")] + return f"{items[0]} (x{len(items)})" + + return re.sub(r"(\S+)(?:\s*\|\s*\1)+", repl, text) + + +def parse_culprits(text: str, candidates: set[str], protected: set[str]) -> set[str]: + """Names of directly requested (top-level) specs that the solver blames.""" + block = solver_block(text) + lines = block.splitlines() + entries: list[tuple[int, str]] = [] + for line in lines[1:]: + match = _TREE_RE.match(line) + if match: + entries.append((len(match.group("indent")), match.group("name"))) + culprits: set[str] = set() + if entries: + # Top level of the tree = the requested specs the solver blames. + min_indent = min(indent for indent, _ in entries) + for indent, name in entries: + if indent == min_indent and name in candidates and name not in protected: + culprits.add(name) + # The first line names one requested spec too ("because of: ... cannot be + # installed"), unless it is the generic "The following packages are incompatible". + first = re.match(r"Cannot solve the request because of:\s*([A-Za-z0-9_.+-]+)", lines[0]) if lines else None + if first and first.group(1) in candidates and first.group(1) not in protected: + culprits.add(first.group(1)) + # "No candidates were found for " (spec does not exist at all on the channels). + for match in re.finditer(r"No candidates were found for\s+([A-Za-z0-9_.+-]+)", block): + if match.group(1) in candidates and match.group(1) not in protected: + culprits.add(match.group(1)) + if not culprits: + # Fallback: any requested dependency the solver mentions as uninstallable. + for match in re.finditer(r"([A-Za-z0-9_.+-]+)\s+\S[^\n]*?cannot be installed", block): + name = match.group(1) + if name in candidates and name not in protected: + culprits.add(name) + return culprits + + +def pin_consistency(pins: list[str], variant: dict[str, str]) -> list[tuple[str, str]]: + """Mutex run_constraints that contradict the rendered conda_build_config.yaml pins.""" + problems = [] + for spec in pins: + parts = spec.split() + if len(parts) < 2: + continue + pinned = variant.get(normalized(parts[0])) + if pinned is not None and not constraint_compatible(parts[1], pinned): + problems.append((spec, f"{parts[0]} {pinned}")) + return problems + + +def _by_name(requirements: Iterable[tuple[Optional[str], str]]) -> dict[str, list[tuple[Optional[str], str]]]: + grouped: dict[str, list[tuple[Optional[str], str]]] = defaultdict(list) + for condition, spec in requirements: + grouped[spec_name(spec)].append((condition, spec)) + return grouped + + +class Solver: + """Thin wrapper that writes a fake recipe and solves it with rattler-build.""" + + def __init__(self, args: argparse.Namespace, channels: list[str], workdir: Path) -> None: + self.args = args + self.channels = channels + self.workdir = workdir + self.calls = 0 + + def solve(self, label: str, pins: list[str], requirements: Iterable[tuple[Optional[str], str]]) -> tuple[bool, str]: + recipe = self.workdir / label / "recipe.yaml" + write_fake_recipe(recipe, pins, requirements) + self.calls += 1 + return run_solve( + recipe, + Path(self.args.variant_config), + self.channels, + self.args.platform, + self.workdir / "output", + verbose=self.args.verbose, + ) + + def find_partner( + self, + culprit: str, + culprit_specs: list[tuple[Optional[str], str]], + pins: list[str], + others: dict[str, list[tuple[Optional[str], str]]], + ) -> Optional[list[str]]: + """Bisect the other dependencies down to the (few) names the culprit clashes with.""" + candidates = sorted(others) + + def fails(names: list[str]) -> bool: + specs = list(culprit_specs) + for name in names: + specs.extend(others[name]) + ok, _ = self.solve(f"bisect-{culprit}", pins, specs) + return not ok + + if not fails(candidates): + return None + while len(candidates) > 1: + half = len(candidates) // 2 + first, second = candidates[:half], candidates[half:] + if fails(first): + candidates = first + elif fails(second): + candidates = second + else: + return candidates # the clash needs members of both halves + return candidates + + +def solve_mode(args: argparse.Namespace) -> int: + recipes_dir = Path(args.recipes_dir) + if not any(recipes_dir.glob("*/recipe.yaml")): + raise SystemExit( + f"No recipes found in {recipes_dir}; run `pixi run generate-recipes` first." + ) + vinca_conf = load_yaml(Path(args.vinca)) + pins = mutex_constraints(vinca_conf) + list(args.pin) + variant = variant_pins(Path(args.variant_config), args.platform) + requirements = collect_requirements(recipes_dir) + names = {spec_name(spec) for _, spec in requirements} + channels = args.channel or channels_from_pixi(Path("pixi.toml")) + workdir = Path(args.workdir) + workdir.mkdir(parents=True, exist_ok=True) + solver = Solver(args, channels, workdir) + + print(f"Platform: {args.platform}") + print(f"Channels: {' '.join(channels)}") + print(f"Variant config: {args.variant_config} ({len(variant)} single-valued pins)") + print(f"Recipes: {len(list(recipes_dir.glob('*/recipe.yaml')))} in {recipes_dir}") + print(f"Dependencies: {len(names)} distinct non-ROS packages, {len(requirements)} specs") + print(f"Hard pins: {', '.join(pins) if pins else '(none)'}") + print() + + # 1. static check: mutex constraints vs. rendered conda_build_config.yaml + pin_conflicts: dict[str, dict[str, Any]] = {} + for spec, pinned in pin_consistency(pins, variant): + print(f"PIN MISMATCH: mutex run_constraint '{spec}' vs {args.variant_config} '{pinned}'") + pin_conflicts[spec_name(spec)] = {"mutex": spec, "variant": pinned, "explanation": "static"} + if pin_conflicts: + print(" -> align mutex_package.run_constraints in vinca.yaml with the rendered pins" + " (or drop the migration from vinca_pinning.yaml).\n") + + # 2. iterative solve of the whole dependency set + protected = {spec_name(spec) for spec in pins} + active_pins = list(pins) + excluded: dict[str, str] = {} + active = dict(requirements) + solved = False + for iteration in range(1, args.max_iterations + 1): + count = len({spec_name(s) for _, s in active}) + print(f"[{iteration}] solving {count} dependencies + {len(active_pins)} pins ...", flush=True) + ok, text = solver.solve(FAKE_PACKAGE_NAME, active_pins, active.keys()) + if ok: + solved = True + break + virtual = _MISSING_VIRTUAL_RE.search(_ANSI_RE.sub("", text)) + if virtual: + print(f"\nThe solver lacks the virtual package {virtual.group(1)} for {args.platform}.") + print("Set CONDA_OVERRIDE_GLIBC / CONDA_OVERRIDE_OSX / CONDA_OVERRIDE_CUDA and retry.\n") + return 2 + blamed = parse_culprits(text, names | protected, set()) + removable = blamed - protected + blamed_pins = blamed & protected + if removable: + for culprit in sorted(removable): + print(f" conflict: {culprit}") + excluded[culprit] = text + active = {key: value for key, value in active.items() if spec_name(key[1]) != culprit} + elif blamed_pins: + for name in sorted(blamed_pins): + mutex_spec = next(s for s in active_pins if spec_name(s) == name) + print(f" pin conflict: {mutex_spec} (dropping it to continue)") + pin_conflicts.setdefault(name, {"mutex": mutex_spec, "variant": variant.get(normalized(name))}) + pin_conflicts[name]["explanation"] = collapse_versions(solver_block(text)) + active_pins = [s for s in active_pins if spec_name(s) != name] + protected.discard(name) + else: + print("\nSolver failed but no removable culprit could be identified:\n") + print(collapse_versions(solver_block(text))) + break + else: + print(f"Stopped after {args.max_iterations} iterations; raise --max-iterations.") + + print() + if solved and not excluded and not pin_conflicts: + print("OK: every dependency is co-installable under the current pins.") + return 0 + + report_conflicts(args, solver, excluded, pin_conflicts, requirements, active_pins, variant, solved) + return 1 + + +def report_conflicts( + args: argparse.Namespace, + solver: Solver, + excluded: dict[str, str], + pin_conflicts: dict[str, dict[str, Any]], + requirements: dict[tuple[Optional[str], str], set[str]], + pins: list[str], + variant: dict[str, str], + solved: bool, +) -> None: + protected = {spec_name(spec) for spec in pins} + if pin_conflicts: + print(f"{len(pin_conflicts)} mutex constraint(s) contradict {args.variant_config}:") + for name, info in pin_conflicts.items(): + if info.get("variant") is None: + print(f"== {info['mutex']} was blamed by the solver for {args.platform} (no rendered pin to compare):") + else: + print(f"== {info['mutex']} vs {info['variant']}") + if info.get("explanation") not in (None, "static"): + for line in info["explanation"].splitlines()[: args.max_lines]: + print(" | " + line) + print() + if solved: + print(f"Dependencies solvable only after removing {len(excluded)} package(s):") + else: + print(f"Unsolvable; {len(excluded)} conflicting package(s) identified so far:") + print() + + by_name = _by_name(requirements) + details: dict[str, dict[str, Any]] = {} + for culprit in sorted(excluded): + specs = by_name[culprit] + recipes = sorted(set().union(*(requirements[key] for key in specs))) + ok, text = solver.solve(f"focus-{culprit}", pins, specs) + partners: list[str] = [] + partner_specs: list[tuple[Optional[str], str]] = [] + if ok: + others = {name: by_name[name] for name in by_name if name != culprit and name not in excluded} + print(f" {culprit}: installs alone; bisecting {len(others)} other dependencies for the clash ...", flush=True) + partners = solver.find_partner(culprit, specs, pins, others) or [] + partner_specs = [spec for name in partners for spec in by_name[name]] + ok, text = solver.solve(f"focus-{culprit}", pins, specs + partner_specs) + block = collapse_versions(solver_block(text)) if not ok else ( + "(no clash reproducible in isolation; it only appears in the full set)" + ) + # Precise attribution: which single mutex pin, when dropped, makes it solvable? + blamed_pins: list[str] = [] + if not ok: + for pin in pins: + relaxed = [other for other in pins if other != pin] + if solver.solve(f"attr-{culprit}", relaxed, specs + partner_specs)[0]: + blamed_pins.append(spec_name(pin)) + if not blamed_pins: # several pins at once, or a pin-independent problem + blamed_pins = sorted( + name for name in protected + if re.search(rf"(? 8 else ''}") + if clash: + print(f" clashes with: {'; '.join(clash)}") + if any(len(spec.split()) > 1 for _, spec in specs): + print(" note: the spec is version-restricted (dummy package in pkg_additional_info.yaml?);" + " a newer conda-forge version may already be built against the pinned libraries.") + glibc_needs = sorted({m.group(1) for m in _GLIBC_NEED_RE.finditer(block)}, key=version_tuple) + if glibc_needs and args.platform.startswith("linux"): + floor = glibc_floor(Path(args.variant_config), args.platform) + print(f" note: needs glibc >= {glibc_needs[-1]} but the build floor (c_stdlib_version /" + f" CONDA_OVERRIDE_GLIBC) is {floor}; conda-forge is moving to a newer sysroot.") + lines = block.splitlines() + for line in lines[: args.max_lines]: + print(" | " + line) + if len(lines) > args.max_lines: + print(f" | … ({len(lines) - args.max_lines} more lines)") + print() + + if args.json: + Path(args.json).write_text( + json.dumps({"pin_conflicts": pin_conflicts, "conflicts": details}, indent=2), encoding="utf-8" + ) + print(f"Wrote {args.json}") + print(f"({solver.calls} solver runs)") + + if args.migrations: + report_migrations(details, pin_conflicts, pins, Path(args.pinning)) + + +# ------------------------------------------------------------------- migrations +def _fetch_json(url: str) -> Optional[Any]: + try: + with urlopen(url, timeout=60) as response: # noqa: S310 + return json.load(response) + except Exception: + return None + + +def report_migrations( + details: dict[str, dict[str, Any]], + pin_conflicts: dict[str, dict[str, Any]], + pins: list[str], + pinning_path: Path, +) -> None: + try: + from vinca.pinning import ( # type: ignore + _migration_pin_keys, + download_pinning_package, + get_migration_status, + package_feedstocks, + ) + except ImportError: + print("vinca is not importable; skipping conda-forge migration lookup.") + return + if not pinning_path.exists(): + print(f"{pinning_path} not found; skipping conda-forge migration lookup.") + return + spec = load_yaml(pinning_path) + version = str(spec.get("conda_forge_pinning_version", "")) + applied = {str(name).removesuffix(".yaml") for name in spec.get("migrations", []) or []} + print(f"conda-forge migration status (conda-forge-pinning {version}):") + try: + _, payloads = download_pinning_package(version) + except Exception as exc: + print(f" could not download conda-forge-pinning {version}: {exc}") + return + migration_keys = {name: _migration_pin_keys(payload) for name, payload in payloads.items()} + status_cache: dict[str, Optional[dict[str, Any]]] = {} + + for name, info in pin_conflicts.items(): + if info.get("variant") is None: + print(f" mutex '{info['mutex']}' has no installable candidate together with the other pins and" + " dependencies (see explanation above); relax or drop the constraint, or fix the feedstock.") + continue + lib = normalized(name) + setters = sorted( + migration for migration, keys in migration_keys.items() + if any(key == lib or key.startswith(lib + "-") for key in keys) + ) + origin = ", ".join( + f"{m} ({'applied' if m in applied else 'not applied'} in {pinning_path.name})" for m in setters + ) or "the conda-forge-pinning base file" + print(f" mutex '{info['mutex']}' vs rendered pin '{info['variant']}' set by {origin}") + print(f" -> either update mutex_package.run_constraints in vinca.yaml to '{name} " + f"{str(info['variant']).split()[-1]}.*' (mutex build-number bump), or remove the migration.") + + for culprit, info in details.items(): + libs = [normalized(name) for name in info["pins"]] or [normalized(spec_name(p)) for p in pins] + relevant = sorted( + name + for name, keys in migration_keys.items() + if any(key == lib or key.startswith(lib + "-") or key.startswith(lib + "_") for key in keys for lib in libs) + ) + feedstocks = sorted(package_feedstocks(culprit)) + print(f" {culprit} (feedstock: {', '.join(feedstocks)}; pinned libs: {', '.join(libs)})") + if not relevant: + print( + " no active conda-forge migration touches these pins -> the feedstock's latest " + "build is simply behind; it needs a rerender/rebuild or version bump on conda-forge." + ) + for feedstock in feedstocks: + print(f" https://github.com/conda-forge/{feedstock}-feedstock") + continue + for migration in relevant: + if migration not in status_cache: + try: + status_cache[migration] = get_migration_status(migration) + except Exception: + status_cache[migration] = None + status = status_cache[migration] + tag = "applied locally" if migration in applied else "NOT applied locally" + if status is None: + print(f" {migration} [{tag}]: no status record on conda-forge") + continue + for feedstock in feedstocks: + category = next( + (cat for cat in STATUS_CATEGORIES if feedstock in {normalized(n) for n in status.get(cat, [])}), + None, + ) + pr_url = (status.get("_feedstock_status", {}).get(feedstock) or {}).get("pr_url", "") + where = category or "not part of this migration" + print(f" {migration} [{tag}]: {feedstock} -> {where} {pr_url}".rstrip()) + print() + print("Legend: 'done' but still conflicting = the pin here is ahead of/behind conda-forge;") + print(" 'in-pr'/'awaiting-parents' = wait for or help land the conda-forge PR;") + print(" no migration = open a rebuild/version-bump PR on the feedstock.") + + +# ----------------------------------------------------------------------- stale +_VERSION_PART_RE = re.compile(r"^(\d+)(.*)$") + + +def version_tuple(version: str) -> tuple[int, ...]: + parts: list[int] = [] + for part in version.strip().split("."): + match = _VERSION_PART_RE.match(part) + if not match: + break + parts.append(int(match.group(1))) + if match.group(2): # pre-release suffix such as '0a0': stop here + break + return tuple(parts) + + +def _pad(t: tuple[int, ...], n: int) -> tuple[int, ...]: + return t + (0,) * (n - len(t)) + + +def _cmp(a: tuple[int, ...], b: tuple[int, ...]) -> int: + n = max(len(a), len(b)) + a, b = _pad(a, n), _pad(b, n) + return (a > b) - (a < b) + + +def pin_range(pin_version: str) -> tuple[tuple[int, ...], tuple[int, ...], bool]: + """Return (lowest, upper_exclusive, exact) for a pin such as '1.90', '7.35.1.*' or '11.*'.""" + text = pin_version.strip() + exact = not text.endswith(".*") and "*" not in text + prefix = version_tuple(text.rstrip("*").rstrip(".")) + if not prefix: + return (0,), (10**9,), False + upper = prefix[:-1] + (prefix[-1] + 1,) + return prefix, upper, exact + + +def constraint_compatible(constraint: str, pin_version: str) -> bool: + """Whether some version can satisfy both the dependency constraint and the pin.""" + low, upper_excl, _ = pin_range(pin_version) + constraint = constraint.strip() + if constraint in ("", "*"): + return True + if "|" in constraint: + return any(constraint_compatible(part, pin_version) for part in constraint.split("|")) + for clause in [c.strip() for c in constraint.split(",") if c.strip()]: + if clause.startswith(">="): + if _cmp(upper_excl, version_tuple(clause[2:])) <= 0: + return False + elif clause.startswith(">"): + if _cmp(upper_excl, version_tuple(clause[1:])) <= 0: + return False + elif clause.startswith("<="): + if _cmp(low, version_tuple(clause[2:])) > 0: + return False + elif clause.startswith("<"): + if _cmp(low, version_tuple(clause[1:])) >= 0: + return False + elif clause.startswith("!="): + continue + else: + other = clause[2:] if clause.startswith("==") else clause + other_low, other_upper, _ = pin_range(other) + n = max(len(low), len(other_low)) + a, b = _pad(low, n), _pad(other_low, n) + k = min(len(low), len(other_low)) + if a[:k] != b[:k]: + return False + return True + + +_CBC_KEY_RE = re.compile(r"^([A-Za-z0-9_.-]+):\s*(?:#\s*\[(.+?)\])?\s*$") +_CBC_ITEM_RE = re.compile(r"^\s+-\s*(?P.*?)\s*(?:#\s*\[(?P.+?)\])?\s*$") + + +def variant_pins(variant_config: Path, platform: str) -> dict[str, str]: + """Single-valued pins from conda_build_config.yaml for this platform, keyed by dep name. + + The file is scanned line by line (not YAML-loaded) so that values such as ``2.10`` + keep their exact spelling and the ``# [selector]`` comments stay attached. + """ + flags = platform_flags(platform) + pins: dict[str, str] = {} + key: Optional[str] = None + key_active = False + chosen: list[str] = [] + + def flush() -> None: + if key and key_active and len(chosen) == 1: + pins[normalized(key)] = chosen[0].split()[0] + + for raw in variant_config.read_text(encoding="utf-8").splitlines(): + line = raw.rstrip() + if not line or line.lstrip().startswith("#"): + continue + key_match = _CBC_KEY_RE.match(line) + if key_match: + flush() + key, key_selector = key_match.group(1), key_match.group(2) + key_active = not key.startswith(("__", "zip_keys", "pin_run_as_build", "channel")) and ( + not key_selector or eval_selector(key_selector, flags) + ) + chosen = [] + continue + item_match = _CBC_ITEM_RE.match(line) + if item_match and key_active: + selector = item_match.group("sel") + if selector and not eval_selector(selector, flags): + continue + value = item_match.group("value").strip().strip("'\"") + if value and not value.startswith(("-", "[", "{")): + chosen.append(value) + flush() + return pins + + +def load_repodata(source: str, platform: str) -> tuple[dict[str, Any], bool]: + remote = "://" in source + if remote: + url = source.rstrip("/") + if not url.endswith("repodata.json"): + url = f"{url}/{platform}/repodata.json" + with urlopen(url, timeout=300) as response: # noqa: S310 + data = json.load(response) + else: + path = Path(source) + if path.is_dir(): + path = path / "repodata.json" + data = json.loads(path.read_text(encoding="utf-8")) + packages = dict(data.get("packages", {})) + packages.update(data.get("packages.conda", {})) + return packages, remote + + +def ros_name_map(vinca_conf: dict[str, Any]) -> dict[str, str]: + """Map normalized conda suffix (e.g. 'cartographer-ros') to ROS names ('cartographer_ros').""" + mapping: dict[str, str] = {} + for key in ("rosdistro_snapshot", "rosdistro_additional_recipes"): + path = vinca_conf.get(key) + if path and Path(path).exists(): + for ros_name in load_yaml(Path(path)): + mapping[normalized(str(ros_name))] = str(ros_name) + return mapping + + +def stale_mode(args: argparse.Namespace) -> int: + vinca_conf = load_yaml(Path(args.vinca)) + distro = vinca_conf.get("ros_distro", "") + prefix = f"ros-{distro}-" + pins: dict[str, str] = {} + if not args.mutex_only: + pins.update(variant_pins(Path(args.variant_config), args.platform)) + mutex_pins = {} + for spec in mutex_constraints(vinca_conf) + list(args.pin): + parts = spec.split() + if len(parts) >= 2: + mutex_pins[normalized(parts[0])] = parts[1] + pins.update(mutex_pins) # mutex constraints win + mutex_name = (vinca_conf.get("mutex_package") or {}).get("name") if isinstance( + vinca_conf.get("mutex_package"), dict) else None + + source = args.repodata or f"output/{args.platform}" + packages, remote = load_repodata(source, args.platform) + packages = { + filename: record + for filename, record in packages.items() + if record.get("name", "").startswith(prefix) or record.get("name") == mutex_name + } + if not args.all_builds: + # Only the newest build of every package matters for what users install now. + newest: dict[str, int] = defaultdict(lambda: -1) + for record in packages.values(): + newest[record["name"]] = max(newest[record["name"]], int(record.get("build_number", 0))) + packages = { + filename: record + for filename, record in packages.items() + if int(record.get("build_number", 0)) == newest[record["name"]] + } + scope = "all build numbers" if args.all_builds else "newest build of each package (see --all-builds)" + print(f"Platform: {args.platform} repodata: {source} {distro} packages: {len(packages)} ({scope})") + print(f"Pins checked: {', '.join(f'{k} {v}' for k, v in sorted(mutex_pins.items()))}") + if not args.mutex_only: + print(f" + {len(pins) - len(mutex_pins)} single-valued pins from {args.variant_config}") + print() + + stale: dict[str, list[tuple[str, str, str]]] = {} + for filename, record in sorted(packages.items()): + name = record.get("name", "") + problems = [] + for dep in record.get("depends", []) + record.get("constrains", []): + parts = dep.split() + if len(parts) < 2: + continue + key = normalized(parts[0]) + pin = pins.get(key) + if pin is None or is_ros_dependency(parts[0]): + continue + if not constraint_compatible(parts[1], pin): + severity = "CONFLICT" if key in mutex_pins else "drift" + problems.append((dep, f"{parts[0]} {pin}", severity)) + if problems: + stale[filename] = problems + + if not stale: + print("OK: no built package conflicts with the current pins.") + return 0 + + print(f"{len(stale)} stale artifact(s) whose dependencies conflict with the current pins") + print("(CONFLICT = violates a mutex run_constraint, i.e. not installable next to the new mutex;") + print(" drift = built against an older conda_build_config.yaml pin, rebuild recommended):\n") + by_dep: dict[str, int] = defaultdict(int) + for filename, problems in stale.items(): + print(f" {filename}") + for dep, pin, severity in problems: + print(f" {severity:8s} has: {dep:45s} pin: {pin}") + by_dep[pin] += 1 + print() + print("Summary by pin: " + ", ".join(f"{pin} ({count})" for pin, count in sorted(by_dep.items()))) + print() + + names = sorted({packages[f]["name"] for f in stale}) + mapping = ros_name_map(vinca_conf) + ros_names = [] + for name in names: + if name == mutex_name: + continue + suffix = name[len(prefix):] if name.startswith(prefix) else name + ros_names.append(mapping.get(normalized(suffix), suffix.replace("-", "_"))) + + build_number = int(vinca_conf.get("build_number", 0)) + 1 + print("Rebuild only these packages") + print("---------------------------") + print("A) artifacts only exist locally: delete them (see --delete) and run `pixi run build`;") + print(" --skip-existing then rebuilds exactly the missing packages.") + print("B) artifacts are already on the channel: bump the build number of just these packages") + print(" (and of the mutex, so its run_constraints are refreshed) and rebuild, then remove the") + print(" old files from the channel. pkg_additional_info.yaml snippet:\n") + for ros_name in ros_names: + print(f"{ros_name}:\n build_number: {build_number}") + if mutex_name: + print(f"\n# vinca.yaml -> mutex_package:\n# build_number: {build_number}") + print() + if remote: + channel = source.split("://", 1)[1].split("/")[1] if "anaconda.org" in source else source + print("Channel removal commands (anaconda.org):") + for filename in stale: + record = packages[filename] + print(f" anaconda remove {channel}/{record['name']}/{record['version']}/{args.platform}/{filename}") + print() + + if args.delete: + if remote: + print("--delete only removes local artifacts; use the commands above for the channel.") + return 1 + root = Path(source) + root = root if root.is_dir() else root.parent + removed = 0 + for filename in stale: + target = root / filename + if target.exists(): + target.unlink() + removed += 1 + print(f"deleted {target}") + print(f"\nDeleted {removed} artifact(s) from {root}.") + index_root = root.parent + rattler_index = shutil.which("rattler-index") + if rattler_index: + subprocess.run([rattler_index, "fs", str(index_root), "--force"], check=False) + print(f"Re-indexed {index_root}.") + else: + print(f"Run `pixi run rattler-index fs {index_root} --force` to refresh the local index.") + print("Now run `pixi run build` (skip-existing rebuilds only the deleted packages).") + return 1 + + +# ------------------------------------------------------------------------- main +def parse_args() -> argparse.Namespace: + parser = argparse.ArgumentParser( + description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter + ) + parser.add_argument("--platform", default=detect_platform(), help="conda platform (default: current machine)") + parser.add_argument("--recipes-dir", default="recipes") + parser.add_argument("--vinca", default="vinca.yaml") + parser.add_argument("--variant-config", default="conda_build_config.yaml") + parser.add_argument("--pinning", default="vinca_pinning.yaml", help="used for migration lookup") + parser.add_argument("--channel", "-c", action="append", default=[], help="override channels (repeatable)") + parser.add_argument("--pin", action="append", default=[], help="extra hard pin, e.g. 'libboost 1.90.*'") + parser.add_argument("--workdir", default="output/compat_check", help="where fake recipes are written") + parser.add_argument("--max-iterations", type=int, default=25) + parser.add_argument("--max-lines", type=int, default=30, help="solver explanation lines per conflict") + parser.add_argument("--json", help="write conflict details to this JSON file") + parser.add_argument("--no-migrations", dest="migrations", action="store_false", help="skip conda-forge lookups") + parser.add_argument("--verbose", action="store_true") + parser.add_argument("--stale", action="store_true", help="check built artifacts instead of recipes") + parser.add_argument("--repodata", help="repodata source for --stale: output/, a channel URL or repodata.json") + parser.add_argument("--delete", action="store_true", help="with --stale: delete stale local artifacts") + parser.add_argument( + "--all-builds", + action="store_true", + help="with --stale: inspect every build number, not just the current vinca.yaml build_number", + ) + parser.add_argument( + "--mutex-only", + action="store_true", + help="with --stale: only check the mutex run_constraints, ignore conda_build_config.yaml drift", + ) + return parser.parse_args() + + +def main() -> int: + args = parse_args() + if args.stale: + return stale_mode(args) + return solve_mode(args) + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/check_orphaned_platform_patches.py b/check_orphaned_platform_patches.py new file mode 100644 index 000000000..3f3ff0de7 --- /dev/null +++ b/check_orphaned_platform_patches.py @@ -0,0 +1,159 @@ +#!/usr/bin/env python3 +""" +check_orphaned_platform_patches.py +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Detect patch files in ``patch/`` that vinca will silently never wire +into any recipe's ``patches:`` list. + +Background +---------- +vinca (see ``vinca/main.py`` around the ``patch_dir`` glob, and +``vinca/utils.py::add_package_name_variants``) builds a dict keyed by +the patch filename's prefix (everything before an optional +``.osx``/``.win``/``.linux``/``.unix``/``.emscripten`` suffix), then +cross-links name-prefix variants of the *same* logical package +(``X`` <-> ``ros-X`` <-> ``ros2-X`` <-> ``ros--X``) via +``dict.setdefault()``. + +``setdefault`` only fills in a key that is still *absent*. If a +package has a plain patch under one prefix (say ``ros2-foo.patch``) +and a platform-specific patch under a *different* prefix (say +``ros-jazzy-foo.osx.patch``), both prefixes already exist as their own +dict entries by the time the cross-link step runs, so the two never +merge. Whichever prefix vinca does *not* resolve as the package's +final conda name for a given recipe simply never appears in that +recipe's ``patches:`` list -- with no error and no warning. This +exact bug orphaned ``ros-jazzy-sick-scan-xd.osx.patch`` for months +before it was renamed to ``ros2-sick-scan-xd.osx.patch`` (matching the +prefix jazzy actually resolves sick_scan_xd's own patch under). + +``check_patches_clean_apply.py`` does not catch this: it verifies that +every patch file on disk applies cleanly to source, but never checks +whether vinca's real name-resolution would actually attach that file +to any package's generated recipe at all. + +What this script does +---------------------- +Replicates vinca's exact patch-dict-construction and +``add_package_name_variants`` shortname-stripping logic (kept in sync +with whatever revision this repo's ``pixi.toml`` pins vinca to -- if +that mechanism ever changes upstream, re-check this script). It groups +patch-file prefixes by their computed "shortname" and flags any group +where more than one *distinct* literal prefix was actually used by a +file on disk: only one of those prefixes can ever be the resolved +package name for a given recipe, so content under the others is dead. + +Exit code is non-zero (and the offending groups are printed) if any +such collision is found. +""" + +from __future__ import annotations + +import glob +import os +import re +import sys +from pathlib import Path + +REPO_ROOT = Path(__file__).resolve().parent +PATCH_DIR = REPO_ROOT / "patch" + +_ROS_DISTRO_RE = re.compile(r"^ros_distro:\s*(\S+)\s*$", re.MULTILINE) + + +def get_ros_distro() -> str: + vinca_yaml = (REPO_ROOT / "vinca.yaml").read_text() + match = _ROS_DISTRO_RE.search(vinca_yaml) + if not match: + print("Could not find 'ros_distro:' in vinca.yaml", file=sys.stderr) + sys.exit(2) + return match.group(1) + + +def build_patches_dict(patch_dir: Path) -> dict[str, dict[str, list[str]]]: + """Mirrors the glob loop in vinca/main.py that builds vinca_conf['_patches'].""" + patches: dict[str, dict[str, list[str]]] = {} + for x in sorted(glob.glob(os.path.join(str(patch_dir), "*.patch"))): + splitted = os.path.basename(x).split(".") + if splitted[0] not in patches: + patches[splitted[0]] = { + "any": [], + "osx": [], + "linux": [], + "win": [], + "emscripten": [], + } + if len(splitted) == 3: + if splitted[1] in ("osx", "linux", "win", "emscripten"): + patches[splitted[0]][splitted[1]].append(x) + continue + if splitted[1] == "unix": + patches[splitted[0]]["linux"].append(x) + patches[splitted[0]]["osx"].append(x) + continue + patches[splitted[0]]["any"].append(x) + return patches + + +def shortname_of(name: str, ros_distro: str) -> str: + """Mirrors the prefix-stripping in vinca/utils.py::add_package_name_variants.""" + legacy_prefix = f"ros-{ros_distro}-" + if name.startswith(legacy_prefix): + return name[len(legacy_prefix):] + elif name.startswith("ros2-"): + return name[len("ros2-"):] + elif name.startswith("ros-"): + return name[len("ros-"):] + else: + return name + + +def main() -> int: + ros_distro = get_ros_distro() + patches = build_patches_dict(PATCH_DIR) + + groups: dict[str, list[str]] = {} + for prefix in patches: + groups.setdefault(shortname_of(prefix, ros_distro), []).append(prefix) + + collisions = { + shortname: prefixes + for shortname, prefixes in groups.items() + if len(prefixes) > 1 + } + + if not collisions: + print(f"OK: no orphaned platform-specific patches ({len(patches)} patch-file prefixes scanned).") + return 0 + + print( + "ORPHANED PLATFORM PATCH RISK: the following packages have patch files " + "spread across more than one name-prefix variant. vinca's " + "add_package_name_variants() cross-links prefix variants via " + "dict.setdefault(), which is a no-op once a variant already exists as its " + "own entry -- so only ONE of the prefixes below will end up attached to " + "the package's real generated recipe; any platform-specific patch under " + "the others is silently never applied.\n", + file=sys.stderr, + ) + for shortname, prefixes in sorted(collisions.items()): + print(f" {shortname}:", file=sys.stderr) + for prefix in sorted(prefixes): + files = [ + os.path.basename(f) + for platform_files in patches[prefix].values() + for f in platform_files + ] + print(f" {prefix}: {', '.join(sorted(files))}", file=sys.stderr) + print( + "\nFix: rename the patch file(s) so every file for a given package shares " + "the SAME name prefix (matching whichever prefix that package's own " + "recipe.yaml actually resolves to -- check recipes//*/recipe.yaml's " + "source.patches entries, or regenerate recipes locally and inspect).", + file=sys.stderr, + ) + return 1 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/check_patches_clean_apply.py b/check_patches_clean_apply.py index 244369a22..32946be7a 100644 --- a/check_patches_clean_apply.py +++ b/check_patches_clean_apply.py @@ -4,7 +4,7 @@ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Scan *all* recipes inside the **recipes/** folder, keep only the parts needed to verify that every declared *patch* still applies, and then -run **rattler-build** so the patch phase is executed -- nothing else. +run **rattler-build** so the patch phase is executed – nothing else. Usage ----- @@ -23,7 +23,7 @@ ---------------------- * Accepts both mapping or list forms of *source*. -* Strips out *requirements*, *test*, *outputs*... -- only *package*, +* Strips out *requirements*, *test*, *outputs*… – only *package*, *source* and a stub *build* section remain. * Automatically invokes ``rattler-build build`` if *--dry* is **not** given. @@ -49,7 +49,7 @@ try: sys.stdout.reconfigure(encoding="utf-8", errors="replace") sys.stderr.reconfigure(encoding="utf-8", errors="replace") -except Exception: +except AttributeError: pass ROOT_DIR = Path.cwd() @@ -127,7 +127,7 @@ def copy_patch_files( patches = [patches] for p in patches: if p.startswith(("http://", "https://")): - # Remote patches -- nothing to copy + # Remote patches – nothing to copy continue src_patch = (orig_recipe_dir / p).resolve() dest_patch = dest_recipe_dir / p @@ -189,6 +189,12 @@ def run_rattler_build_individually(recipes: List[Path]) -> None: print("\n Running:", " ".join(cmd), "\n", flush=True) try: proc = subprocess.run(cmd, text=True, capture_output=True, errors="replace", encoding="utf-8") + # rattler-build's shared Git source cache can occasionally retain + # tag refs whose objects were not fetched. Retry from a clean Git + # cache rather than reporting a spurious patch failure. + if proc.returncode != 0 and "Git error: Git fetch failed" in proc.stderr: + shutil.rmtree(ROOT_DIR / "output" / "src_cache" / "git", ignore_errors=True) + proc = subprocess.run(cmd, text=True, capture_output=True, errors="replace", encoding="utf-8") success = proc.returncode == 0 results.append( { @@ -238,14 +244,14 @@ def run_rattler_build_individually(recipes: List[Path]) -> None: print(r["stderr"].rstrip()) print("\n----------------------------------------------------\n") - sys.exit(2) + sys.exit(2 if failed else 0) def main() -> None: args = parse_args() if not RECIPES_DIR.is_dir(): - print("recipes/ folder not found -- abort.") + print("recipes/ folder not found – abort.") sys.exit(1) if args.clean: @@ -254,7 +260,7 @@ def main() -> None: return if PATCH_RECIPES_DIR.exists(): - print("Refreshing recipes_only_patch/ ...") + print("Refreshing recipes_only_patch/ …") shutil.rmtree(PATCH_RECIPES_DIR) recipe_files = resolve_requested_recipe_files(args.recipe) @@ -263,7 +269,7 @@ def main() -> None: recreated = prepare_patch_recipes(recipe_files) if not recreated: - print("No recipes with patches found -- nothing to test.") + print("No recipes with patches found – nothing to test.") return print(f"Prepared {len(recreated)} minimal recipe(s) in {PATCH_RECIPES_DIR}/") @@ -271,7 +277,7 @@ def main() -> None: if not args.dry: run_rattler_build_individually(recreated) else: - print("--dry given -- rattler-build not executed.") + print("--dry given – rattler-build not executed.") if __name__ == "__main__": diff --git a/conda_build_config.yaml b/conda_build_config.yaml index 624d7347d..9c0cd9c6f 100644 --- a/conda_build_config.yaml +++ b/conda_build_config.yaml @@ -1,103 +1,1185 @@ -numpy: - - 2 +# Generated by vinca-pinning-render from vinca_pinning.yaml. +# Do not edit this file directly. +c_compiler: + - gcc # [linux] + - clang # [osx] + - vs2022 # [win] +# Please remember to update gcc_compiler_version & clang_compiler_version too. +c_compiler_version: # [unix] + - 15 # [linux] + - 21 # [osx] + - 14 # [linux and (x86_64 or aarch64) and os.environ.get("CF_CUDA_ENABLED", "False") == "True"] +c_stdlib: + - sysroot # [linux] + - macosx_deployment_target # [osx] + - vs # [win] +m2w64_c_stdlib: # [win] + - m2w64-sysroot # [win] +m2w64_c_stdlib_version: # [win] + - 12 # [win] +c_stdlib_version: # [unix] + - 2.28 # [linux and not riscv64] + - 2.39 # [linux and riscv64] + - 2.28 # [linux and (x86_64 or aarch64) and os.environ.get("CF_CUDA_ENABLED", "False") == "True"] + - 14.0 # [osx] +cxx_compiler: + - gxx # [linux] + - clangxx # [osx] + - vs2022 # [win] +# Please remember to update gxx_compiler_version & clangxx_compiler_version too. +cxx_compiler_version: # [unix] + - 15 # [linux] + - 21 # [osx] + - 14 # [linux and (x86_64 or aarch64) and os.environ.get("CF_CUDA_ENABLED", "False") == "True"] +llvm_openmp: # [osx] + - 21 # [osx] +fortran_compiler: # [unix or win] + - gfortran # [unix] + - flang # [win] +fortran_compiler_version: # [unix or win] + - 15 # [unix] + - 5 # [win64] + - 22 # [win and arm64] + - 14 # [linux and (x86_64 or aarch64) and os.environ.get("CF_CUDA_ENABLED", "False") == "True"] +m2w64_c_compiler: # [win] + - gcc # [win] +m2w64_c_compiler_version: # [win] + - 15 # [win] +m2w64_cxx_compiler: # [win] + - gxx # [win] +m2w64_cxx_compiler_version: # [win] + - 15 # [win] +m2w64_fortran_compiler: # [win] + - gfortran # [win] +m2w64_fortran_compiler_version: # [win] + - 15 # [win] + +# enable `{{ compiler("gcc") }}`, `{{ compiler("clang") }}` & co. +gcc_compiler: + - gcc +gcc_compiler_version: + - 15 +gxx_compiler: + - gxx +gxx_compiler_version: + - 15 +clang_compiler: + - clang # [unix] + # stay compatible with MSVC + - clang-cl # [win] +clang_compiler_version: + - 21 +clangxx_compiler: + - clangxx # [unix] + # stay compatible with MSVC + - clang-cl # [win] +clangxx_compiler_version: + - 21 + +cuda_compiler: + - cuda-nvcc +cuda_compiler_version: + - None + - 12.9 # [((linux and (x86_64 or aarch64)) or win64) and os.environ.get("CF_CUDA_ENABLED", "False") == "True"] +cuda_compiler_version_min: + - None # [not ((linux and (x86_64 or aarch64)) or win64)] + - 12.9 # [((linux and (x86_64 or aarch64)) or win64)] + +arm_variant_type: # [aarch64 and os.environ.get("CF_CUDA_ENABLED", "False") == "True"] + - sbsa # [aarch64 and os.environ.get("CF_CUDA_ENABLED", "False") == "True"] + +_libgcc_mutex: + - 0.1 conda_forge +# +# Go Compiler Options +# + +# The basic go-compiler with CGO disabled, +# It generates fat binaries without libc dependencies +# The activation scripts will set your CC,CXX and related flags +# to invalid values. +go_compiler: + - go-nocgo +# The go compiler build with CGO enabled. +# It can generate fat binaries that depend on conda's libc. +# You should use this compiler if the underlying +# program needs to link against other C libraries, in which +# case make sure to add 'c,cpp,fortran_compiler' for unix +# and the m2w64 equivalent for windows. +cgo_compiler: + - go-cgo +# The following are helpful variables to simplify go meta.yaml files. +target_goos: + - linux # [linux] + - darwin # [osx] + - windows # [win] +target_goarch: + - amd64 # [x86_64] + - arm64 # [arm64 or aarch64] + - ppc64le # [ppc64le] +target_goexe: + - # [unix] + - .exe # [win] +target_gobin: + - ${PREFIX}/bin/ # [unix] + - '%PREFIX%\bin\' # [win] + +# Rust Compiler Options +rust_compiler: + - rust + +# the numbers here are the Darwin Kernel version for macOS 10.9 & 11.0; +# this is used to form our target triple on osx, and nothing else. After +# we bumped the minimum macOS version to 10.13, this was left unchanged, +# since it is not essential, and long-term we'd like to remove the version. +# see https://github.com/conda-forge/conda-forge.github.io/issues/2695 +macos_machine: # [osx] + - x86_64-apple-darwin13.4.0 # [osx and x86_64] + - arm64-apple-darwin20.0.0 # [osx and arm64] + +VERBOSE_AT: + - V=1 +VERBOSE_CM: + - VERBOSE=1 + +channel_sources: +channel_targets: +cdt_name: # [linux] + - conda # [linux] + +docker_image: # [os.environ.get("BUILD_PLATFORM", "").startswith("linux-")] + # builds on CentOS 7 + - quay.io/condaforge/linux-anvil-x86_64:cos7 # [os.environ.get("BUILD_PLATFORM") == "linux-64" and os.environ.get("DEFAULT_LINUX_VERSION", "alma10") == "cos7"] + - quay.io/condaforge/linux-anvil-aarch64:cos7 # [os.environ.get("BUILD_PLATFORM") == "linux-aarch64" and os.environ.get("DEFAULT_LINUX_VERSION", "alma10") == "cos7"] + - quay.io/condaforge/linux-anvil-ppc64le:cos7 # [os.environ.get("BUILD_PLATFORM") == "linux-ppc64le" and os.environ.get("DEFAULT_LINUX_VERSION", "alma10") == "cos7"] + + # builds on AlmaLinux 8 + - quay.io/condaforge/linux-anvil-x86_64:alma8 # [os.environ.get("BUILD_PLATFORM") == "linux-64" and os.environ.get("DEFAULT_LINUX_VERSION", "alma10") in ("alma8", "ubi8")] + - quay.io/condaforge/linux-anvil-aarch64:alma8 # [os.environ.get("BUILD_PLATFORM") == "linux-aarch64" and os.environ.get("DEFAULT_LINUX_VERSION", "alma10") in ("alma8", "ubi8")] + - quay.io/condaforge/linux-anvil-ppc64le:alma8 # [os.environ.get("BUILD_PLATFORM") == "linux-ppc64le" and os.environ.get("DEFAULT_LINUX_VERSION", "alma10") in ("alma8", "ubi8")] + + # builds on AlmaLinux 9 + - quay.io/condaforge/linux-anvil-x86_64:alma9 # [os.environ.get("BUILD_PLATFORM") == "linux-64" and os.environ.get("DEFAULT_LINUX_VERSION", "alma10") == "alma9"] + - quay.io/condaforge/linux-anvil-aarch64:alma9 # [os.environ.get("BUILD_PLATFORM") == "linux-aarch64" and os.environ.get("DEFAULT_LINUX_VERSION", "alma10") == "alma9"] + - quay.io/condaforge/linux-anvil-ppc64le:alma9 # [os.environ.get("BUILD_PLATFORM") == "linux-ppc64le" and os.environ.get("DEFAULT_LINUX_VERSION", "alma10") == "alma9"] + # builds on AlmaLinux 10 + - quay.io/condaforge/linux-anvil-x86_64:alma10 # [os.environ.get("BUILD_PLATFORM") == "linux-64" and os.environ.get("DEFAULT_LINUX_VERSION", "alma10") == "alma10"] + - quay.io/condaforge/linux-anvil-aarch64:alma10 # [os.environ.get("BUILD_PLATFORM") == "linux-aarch64" and os.environ.get("DEFAULT_LINUX_VERSION", "alma10") == "alma10"] + - quay.io/condaforge/linux-anvil-ppc64le:alma10 # [os.environ.get("BUILD_PLATFORM") == "linux-ppc64le" and os.environ.get("DEFAULT_LINUX_VERSION", "alma10") == "alma10"] + +zip_keys: + # [unix] + - - c_compiler_version # [unix] + - cxx_compiler_version # [unix] + - fortran_compiler_version # [unix] + # CUDA 13.x requires newer glibc than our current baseline + - c_stdlib_version # [linux and os.environ.get("CF_CUDA_ENABLED", "False") == "True"] + - cuda_compiler_version # [linux and os.environ.get("CF_CUDA_ENABLED", "False") == "True"] + - - python + - is_python_min + - - libarrow + - libarrow_all + - - root_base + - root_cxx_standard + +# armv7l specifics because conda-build sets many things to centos 6 +# this can probably be removed when conda-build gets updated defaults +# for aarch64 +cdt_arch: armv7l # [armv7l] +BUILD: armv7-conda_cos7-linux-gnueabihf # [armv7l] + +pin_run_as_build: + libblst: + max_pin: x.x + netcdf-cxx4: + max_pin: x.x + vlfeat: + max_pin: x.x.x + +# Pinning packages + +# blas +libblas: + - 3.9.* *netlib +libcblas: + - 3.9.* *netlib +liblapack: + - 3.9.* *netlib +liblapacke: + - 3.9.* *netlib +blas_impl: + - openblas + - mkl # [x86 or x86_64] + - blis # [x86 or x86_64] + +ace: + - 8.0.6 +alsa_lib: + - '1.2' +antic: + - 0.2 +aom: + - '3.14' +arb: + - '2.23' +arpack: + - '3.9' assimp: - 6 -# Workaround for https://github.com/RoboStack/ros-jazzy/pull/40#issuecomment-2782226697 -cmake: - - 3.* +attr: + - 2.5 +aws_c_auth: + - 0.10.4 +aws_c_cal: + - 0.9.15 +aws_c_common: + - 0.14.3 +aws_c_compression: + - 0.3.2 +aws_c_event_stream: + - 0.7.1 +aws_c_http: + - 0.11.0 +aws_c_io: + - 0.27.5 +aws_c_mqtt: + - 0.16.0 +aws_c_s3: + - 0.13.1 +aws_c_sdkutils: + - 0.2.7 +aws_checksums: + - 0.2.10 +aws_crt_cpp: + - 0.42.3 +aws_sdk_cpp: + - 1.11.833 +azure_core_cpp: + - 1.16.3 +azure_identity_cpp: + - 1.13.3 +azure_storage_blobs_cpp: + - 12.18.0 +azure_storage_common_cpp: + - 12.14.0 +azure_storage_files_datalake_cpp: + - 12.16.0 +azure_storage_files_shares_cpp: + - 12.18.0 +azure_storage_queues_cpp: + - 12.7.0 +brotli: + - '1.2' +bullet_cpp: + - 3.25 +bxdecay0: + - 1.2.0 +bzip2: + - 1 +c_ares: + - 1 +c_blosc2: + - '3.3' +cairo: + - 1 +calchep: + - '3.8' +capnproto: + - 1.5.0 +casadi: + - 3.7 +ccr: + - 1.3 +cfitsio: + - 4.6.4 +clhep: + - 2.4.4.0 + - 2.4.7.1 + - 2.4.7.2 +cmocka: + - 2.0.1 +coin_or_cbc: + - 2.10 +coincbc: + - 2.10 +coin_or_cgl: + - 0.60 +coin_or_clp: + - 1.17 +coin_or_osi: + - 0.108 +coin_or_utils: + - 2.11 +collier: + - '1.2' +console_bridge: + - 1.0 +cran_mirror: + - https://cloud.r-project.org +# match with libcudnn-dev +cudnn: + - '9' +cutensor: + - 2 +curl: + - 8 +dartsim_cpp: + - '6.19' +dav1d: + - 1.2.1 +dav1d_devel: + - 1.2.1 +davix: + - '0.8' +dbus: + - 1 +dcap: + - 2.47 +delphes: + - 3.5.1 +eclib: + - '20250627' 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: - - 7.35.1 -protobuf: - - 7.35.1 + - 5.0.1 +elfutils: + - '0.194' +emela: + - '1.0' +exiv2: + - '0.28' +expat: + - 2 +fastbdt: + - '5.6' +fastjet_contrib: + - '1' +fastjet_cxx: + - '3.5' +feynhiggs: + - '2.19' +ffmpeg: + - '9' +fftw: + - 3 +flann: + - 1.9.2 +flatbuffers: + - 25.9.23 fmt: - '12.1' +fontconfig: + - 2 +freetype: + - 2 +gaudi: + - '40.4' +gct: + - 6.2.1705709074 +gf2x: + - '1.3' +gdk_pixbuf: + - 2 +gnuradio_core: + - 3.10.12 +gnutls: + - '3.8' +gsl: + - 2.7 +gsoap: + - 2.8.123 +gstreamer: + - '1.28' +gst_plugins_base: + - '1.28' +gdal: + - '3.13' +libgdal: + - '3.13' +libgdal_core: + - '3.13' +geant4: + - 11.4.2 +geos: + - 3.14.1 +geotiff: + - '1.7' +gfal2: + - '2.23' +gflags: + - '2.3' +giflib: + - '6' +givaro: + - 4.2.2 +glew: + - '2.3' +glib: + - '2' +glog: + - '0.7' +glpk: + - '5.0' +gm2calc: + - '2.3' +gmp: + - 6 +google_cloud_cpp: + - '3.8' +google_cloud_cpp_common: + - 0.25.0 +googleapis_cpp: + - '0.10' +gpgme: + - '1.24' graphviz: - '14' +# Harfbuzz guarantees total ABI compatibiblity +# The first version to have this new ABI pin is 11.0.1 +# https://github.com/conda-forge/harfbuzz-feedstock/pull/125 +# But as of 2025/08/03, 11.0.1 is quite "old" and it is pretty safe +# to release the pin +# We are leaving this comment here to discourage others from adding +# a harfbuzz global pin, as it is not needed. +# harfbuzz: +# - '11' +hepmc2: + - '2.06' +hepmc3: + - '3.3' +hdf4: + - 4.2.15 +hdf5: + - '2' + - 1.14.6 +hdrhistogram_c: + - 0.11.9 +icu: + - '78' +idyntree: + - '15' +imath: + - 3.2.2 +impi_devel: + - 2021.16.0 +ipopt: + - 3.14.19 +isl: + - '0.26' +jasper: + - 4 +jpeg: + - 9 +lcms2: + - 2 +lerc: + - '4' +lhapdf: + - '6.5' +libjpeg_turbo: + - '3' +libjxl: + - '0.12' +libev: + - 4.33 +json_c: + - '0.18' jsoncpp: - # jsoncpp 1.9.8 migration is nearly complete on conda-forge. - 1.9.8 -libopencv: - - 4.13.0 -libmujoco: - - 3.10.0 -# Mitigation for -# https://github.com/RoboStack/ros-jazzy/pull/126#issuecomment-3515455380 +kealib: + - '2.0' +krb5: + - '1.22' +ldas_tools_framecpp: + - '2.9' +libabseil: + - 20260526 +libaec: + - '1' +libamd: + - '3' +libarchive: + - '3.8' +libarrow: + - '25.0' + - '24.0' + - '23.0' + - '22.0' +libarrow_all: + - '25.0' + - '24.0' + - '23.0' + - '22.0' +libattr: + - 2.6 +libavif: + - 1 +libblitz: + - 1.0.2 +libblst: + - '0.3' +libboost_devel: + - '1.90' +libboost_headers: + - '1.90' +libboost_python_devel: + - '1.90' +libbrotlicommon: + - '1.2' +libbrotlidec: + - '1.2' +libbrotlienc: + - '1.2' +libbtf: + - '2' +libcamd: + - '3' libcap: - - 2.78 + - '2.78' +libcint: + - '6.1' +libccolamd: + - '3' +libcholmod: + - '5' +libcolamd: + - '3' +libcurl: + - 8 +# match with cudnn +libcudnn_dev: + - '9' +libcrc32c: + - 1.1 +libcxsparse: + - '4' +libdap4: + - 3.20.6 +libdeflate: + - '1.25' +libdovi: + - '3' +libduckdb_devel: + - '1' +libeantic: + - '2' +libevent: + - 2.1.12 +libexactreal: + - '4' +libffi: + - '3.5' +libflac: + - '1.5' +libflatsurf: + - 3 +libflint: + - '3.5' +libframel: + - '8.41' +# hmaarrfk - Aug 30, 2025 +# https://github.com/conda-forge/libfuse-feedstock/pull/29 +# Although some libfuse packages exist with version 3, we decided +# to pin libfuse to 2 to allow co-installation between libfuse (version 2) and libfuse3 +libfuse: + - '2' +libfuse3: + - '3' +libgit2: + - '1.9' +libgoogle_cloud: + - '3.8' +libgoogle_cloud_devel: + - '3.8' +libgoogle_cloud_all_devel: + - '3.8' +libgoogle_cloud_aiplatform_devel: + - '3.8' +libgoogle_cloud_automl_devel: + - '3.8' +libgoogle_cloud_bigquery_devel: + - '3.8' +libgoogle_cloud_bigtable_devel: + - '3.8' +libgoogle_cloud_compute_devel: + - '3.8' +libgoogle_cloud_dialogflow_cx_devel: + - '3.8' +libgoogle_cloud_dialogflow_es_devel: + - '3.8' +libgoogle_cloud_discoveryengine_devel: + - '3.8' +libgoogle_cloud_dlp_devel: + - '3.8' +libgoogle_cloud_iam_devel: + - '3.8' +libgoogle_cloud_oauth2_devel: + - '3.8' +libgoogle_cloud_policytroubleshooter_devel: + - '3.8' +libgoogle_cloud_pubsub_devel: + - '3.8' +libgoogle_cloud_spanner_devel: + - '3.8' +libgoogle_cloud_speech_devel: + - '3.8' +libgoogle_cloud_storage_devel: + - '3.8' +libgrpc: + - '1.82' +libgsasl: + - '2' +libheif: + - '1.23' +libhugetlbfs: + - 2 libhwloc: - 2.13.0 +libhwy: + - '1.4' +libiconv: + - 1 +libidn2: + - 2 +libintervalxt: + - 3 +libitk_devel: + - 5.4 +libklu: + - '2' +libkml: + - 1.3 +libkml_devel: + - 1.3 +liblzma_devel: + - 5 +libiio: + - 0 +libldl: + - '3' +libmagma: + - 2.10.0 +libmagma_devel: + - 2.10.0 +libmagma_sparse: + - 2.10.0 +libmed: + - '4.2' +libmatio: + - 1.5.30 +libmatio_cpp: + - 0.3.0 +libmicrohttpd: + - '1.0' +libnetcdf: + - 4.10.1 +libntlm: + - 1 +libode: + - 0.16.6 +libogg: + - 1.3 +libopencolorio: + - '2.5' +libopenimageio: + - '3.1' +libopencv: + - 5.0.0 +libopentelemetry_cpp: + - '1.27' +libosqp: + - 1.0.0 +libopenvino: + - 2026.3.1 +libopenvino_dev: + - 2026.3.1 +libparu: + - '1' +libpcap: + - '1.10' +libplacebo: + - '7.360' +libpnetcdf: + - 1.15.0 +libpng: + - 1.6 +libprotobuf: + - 7.35.1 +libpq: + - '18' +libpsl: + - '0.23' +libpulsar: + - 4.2.0 +libraqm: + - '0.11' +libraqm_devel: + - '0.11' +libraw: + - '0.22' +librbio: + - '4' +librdkafka: + - '2.15' +librdkit: + - 2026.03.2 +librealsense: + - '2.58' +librerun_sdk: + - 0.35.0 +librsvg: + - 2 +libsecret: + - '0.21' +libsentencepiece: + - 0.2.1 +libsndfile: + - '1.2' +libsodium: + - 1.0.22 +libsoup: + - 3 +libspatialindex: + - 2.1.0 +libspex: + - '3' +libspqr: + - '4' +libsuitesparseconfig: + - '7' +libsuperiso: + - '5.0' +libssh: + - '0.12' +libssh2: + - 1 +libsvm: + - '337' +libsqlite: + - 3 +libsystemd: + - '257' +libtensorflow: + - '2.16' +libtensorflow_cc: + - '2.16' +libtheora: + - '1.2' +libthrift: + - 0.22.0 +libtiff: + - '4.7' +libtorch: + - '2.12' +libudev: + - '257' +libumfpack: + - '6' +libunwind: + - '1.8' +libutf8proc: + - '2.11' +libv8: + - 8.9.83 +libvigra: + - '1.12' +libvips: + - 8 +libvpl: + - '2.16' +libwebp: + - 1 +libwebp_base: + - 1 +libx86emu: + - 3.7 +libxcb: + - '1' libxml2: + - '2.15' +libxml2_devel: + - '2.15' +libxrootd_devel: + - '6' +libxsmm: + - '2' +liburing: + - 2.14 +libuuid: + - 2 +libyarp: + - 3.12.2 +libzip: + - 1 +lmdb: + - '0.9' +log4cxx: + - 1.8.0 +lol_html: + - 3.0.1 +ls_hpack: + - 2.3.5 +lwtnn: - '2.14' -libzenohc: - - 1.9.0 -libzenohcxx: - - 1.9.0 -lua: - - 5.4 +lz4_c: + - '1.10' +lzo: + - 2 +magma: + - '2.9' +metis: + - 5.1.0 +mimalloc: + - 3.4.1 +mkl: + - '2026' # [not osx] + - '2023' # [osx] +mkl_devel: + - '2026' # [not osx] + - '2023' # [osx] +mpg123: + - '1.33' +mpich: + - 4 +mpfr: + - 4 +mpfun90: + - '2026' +mppp: + - '2.0' +msgpack_c: + - 6 +msgpack_cxx: + - '7' +mumps_mpi: + - 5.8.2 +mumps_seq: + - 5.8.2 +mysql_devel: + - '9.7' +nccl: + - 2 +ncurses: + - 6 +netcdf_cxx4: + - 4.3 +netcdf_fortran: + - '4.6' +nettle: + - '3.10' +ninja_hep_ph: + - '1.2' +nodejs: + - '26' + - '24' +nss: + - 3 +nspr: + - 4 +nlopt: + - '2.11' +ntl: + - 11.6.0 +# we build using the latest minor version; numpy has generous backwards compatibility +# even so, and this is reflected through the run-exports of the package; see also +# https://github.com/conda-forge/conda-forge-pinning-feedstock/issues/4816 +numpy: + - 2 +obake_devel: + - '0.9' +occt: + - 8.0.0 +oneloop: + - '3.7' +openblas: + - 0.3.* +openexr: + - '3.4' +openh264: + - 2.6.0 +openjpeg: + - '2' +openjph: + - '0.31' +openmpi: + - '5' +openslide: + - 4 +# although openssl follows SemVer for ABI/API stability, we stay on +# LTS version at build time to avoid forcing newer version at runtime +openssl: + - '3.5' +orc: + - 2.3.1 +osqp_eigen: + - '0.11' +pango: + - '1' +pari: + - 2.17.* *_pthread +pcl: + - 1.15.1 +perl: + - 5.32.1 +petsc: + - '3.25' +petsc4py: + - '3.25' +plutovg: + - 1.3.3 +plutosvg: + - 0.0.8 pugixml: - '1.15' +slepc: + - '3.25' +slepc4py: + - '3.25' +svt_av1: + - 4.2.0 +p11_kit: + - '0.26' +pcre: + - '8' +pcre2: + - '10.47' +pdal: + - '2.10' +libpdal: + - '2.10' +libpdal_core: + - '2.10' +pixman: + - 0 +poco: + - 1.15.3 +poppler: + - '26.07' +portaudio: + - '19.7' +postgresql: + - '18' +postgresql_plpython: + - '18' +proj: + - '9.8' +pulseaudio: + - '17.0' +pulseaudio_client: + - '17.0' +pulseaudio_daemon: + - '17.0' +pybind11_abi: + - '11' +pythia8: + - '8.312' +python: + # conda-forge supports only 3.14+ for win-arm64 and linux-riscv64 + # part of a zip_keys: python, is_python_min + - 3.12.* *_cpython +python_impl: + - cpython + +python_min: + # minimum supported python version per CFEP-25 + # bump to next minor version when we drop python versions + - '3.11' # [not ((win and arm64) or riscv64)] + - '3.14' # [(win and arm64) or riscv64] +is_freethreading: + - false +is_python_min: + # part of a zip_keys: python, is_python_min + - false +is_abi3: + - true +pytorch: + - '2.12' +pyqt: + - 5.15 +pyqtwebengine: + - 5.15 +pyqtchart: + - 5.15 +qcdloop: + - '2.1' +qhull: + - 2020.2 +qpdf: + - '12' +qt: + - 5.15 +qt_main: + - 5.15 +qt6_main: + - '6' +qtkeychain: + - '0.17' +rav1e: + - '0.8' +rdma_core: + - '63' +re2: + - 2025.11.05 +readline: + - '8' +rivet: + - '4.1' +rocksdb: + - '11.0' +root_base: + - 6.36.10 + - 6.38.4 + - 6.38.4 + - 6.40.2 + - 6.40.2 +root_cxx_standard: + - 20 + - 20 + - 23 + - 20 + - 23 +r_base: + - 4.4 + - 4.5 +libscotch: + - 7.0.11 +libptscotch: + - 7.0.11 +scotch: + - 7.0.11 +ptscotch: + - 7.0.11 +s2geography: + - 0.1.2 +s2geometry: + - '0.14' +s2n: + - 1.7.6 +sdl2: + - '2' +sdl2_image: + - '2' +sdl2_mixer: + - '2' +sdl2_net: + - '2' +sdl2_ttf: + - '2' shaderc: - '2026.3' +sherpa: + - '3.0' +singular: + - 4.4.1 +siscone: + - '3.1' +snappy: + - 1.2 +soapysdr: + - '0.8' +softsusy: + - '4.1' +sox: + - 14.4.2 spdlog: - - 1.17 + - '1.17' +spirv_tools: + - '2026' +sqlite: + - 3 +srm_ifce: + - 1.24.6 +starlink_ast: + - 9.3.1 +suitesparse: + - '7' +suitesparse_mongoose: + - '3' +sundials: + - '7.8' +superlu_dist: + - '9' +swig_abi: + - '5' tbb: - '2023' tbb_devel: - '2023' +tensorflow: + - '2.16' +thrift_cpp: + - 0.22.0 +tinyxml2: + - '11.0' +tk: + - 8.6 # [not ppc64le] +tiledb: + - '2.30' +ucc: + - 1 +ucx: + - '1.22' +uhd: + - 4.10.0 urdfdom: - - '6.0' -urdfdom_headers: - - '3.0' + - '6' +vc: # [win] + - 14 # [win] +vgm: + - '5.4' +vigra: + - '1.12' +vlfeat: + - 0.9.21 +vmc: + - '2.2' +volk: + - '3.3' vtk: - - 9.6.2 + - 9.7.0 +vtk_base: + - 9.7.0 +wcslib: + - '8' +wxwidgets: + - 3.3.3 +x264: + - 1!164.* +x265: + - '3.5' +xerces_c: + - '3.3' +xrootd: + - '6' +xxhash: + - 0.8.3 +xz: + - 5 +yoda: + - '2.1' +zeromq: + - 4.3.5 +zfp: + - 1.0 +zlib: + - 1 +zlib_ng: + - '2.3' +zstd: + - '1.5' +libzenohc: + - 1.9.0 +libzenohcxx: + - 1.9.0 + # conda-forge's sip 6.16.x (6.16.1 uploaded 2026-09-08) regressed ABI + # targeting for PyQt5-based bindings: sip-build now fails with "ABI v12 + # is being targeted but the module doesn't support it" for + # packages like qt_gui_cpp_sip, which build against pyqt5-sip's fixed + # ABI v12. Pin back to the last known-good line until upstream fixes it. +sip: + - 6.15 + # nav2_mppi_controller needs xtensor 0.25.0's API; robostack.yaml maps + # the plain (unpinned) xtensor name so this variant pin controls the + # actual version instead of a hardcoded exact-version dependency name. xtensor: - 0.25.0 - -cdt_name: # [linux] - - conda # [linux] - -python: - - 3.12.* *_cpython -python_impl: - - cpython - -c_compiler: - - gcc # [linux] - - clang # [osx] - - vs2022 # [win] -c_compiler_version: # [unix] - - 14 # [linux] - - 19 # [osx] -c_stdlib: - - sysroot # [linux] - - macosx_deployment_target # [osx] - - vs # [win] -c_stdlib_version: # [unix] - - 2.17 # [linux] - - 12.0 # [osx and x86_64] - - 12.0 # [osx and arm64] -cxx_compiler: - - gxx # [linux] - - clangxx # [osx] - - vs2022 # [win] -cxx_compiler_version: # [unix] - - 14 # [linux] - - 19 # [osx] - -lbr_fri_client_sdk: - - '1.11' - - '1.14' - - '1.15' - - '1.16' - - '1.17' diff --git a/patch/dependencies.yaml b/patch/dependencies.yaml index 60f511433..1875f0e56 100644 --- a/patch/dependencies.yaml +++ b/patch/dependencies.yaml @@ -4,7 +4,24 @@ foxglove_bridge: add_host: ["ros-jazzy-ament-cmake"] ros_ign_interfaces: add_host: ["ros-jazzy-rcl-interfaces"] +cartographer: + # cartographer's own package.xml pulls in lua5.2-dev (mapped to bare "lua" + # via robostack.yaml, so unpinned) to build from source, but this recipe's + # dummy-package run constraint ("cartographer >=2.0.0,<2.1.0a0") also pulls + # in conda-forge's own separately-published "cartographer" package into the + # same solve for compatibility -- and that package is currently built + # against lua 5.4.x (pinned <5.5.0a0 via its own run_exports). Without a + # matching pin here, the solver can pick an incompatible newer lua (5.5.0) + # for our own build and fail to solve the two together. + add_host: ["lua 5.4.*"] cartographer_ros: + # package.xml's cartographer auto-resolves to the + # ros2-cartographer dummy package (see the cartographer entry above), + # but add_host below also pulls in conda-forge's cartographer directly + # for the same lua-pin reason -- vinca doesn't dedupe the two, so drop + # the dummy and keep only the direct conda-forge dependency. + remove_host: ["ros2-cartographer"] + remove_run: ["ros2-cartographer"] add_host: ["cartographer 2.*", "libboost-devel"] libyaml_vendor: add_host: ["yaml-cpp", "yaml"] @@ -80,7 +97,7 @@ tvm_vendor: libphidget22: add_host: ["libusb"] libg2o: - add_host: ["qt", "${{ 'libglu' if linux }}", "${{ 'freeglut' if not osx }}"] + add_host: ["${{ 'libglu' if linux }}", "${{ 'freeglut' if not osx }}"] fmilibrary_vendor: add_host: ["fmilib"] mrpt2: @@ -93,7 +110,7 @@ ros1_rosbag_storage_vendor: popf: add_host: ["perl"] rtabmap: - add_host: ["${{ 'libgl-devel' if linux }}", "${{ 'libopengl-devel' if linux }}", "ceres-solver", "libdc1394", "libusb", "vtk"] + add_host: ["${{ 'libgl-devel' if linux }}", "${{ 'libopengl-devel' if linux }}", "ceres-solver", "${{ 'libdc1394' if not win }}", "libusb", "vtk"] backward_ros: # binutils is added only on linux to avoid the -liberty library not found in macos # see https://github.com/RoboStack/ros-jazzy/pull/95#issuecomment-3113166166 @@ -113,11 +130,23 @@ pybind11_vendor: add_host: ["pybind11"] add_run: ["pybind11"] python_qt_binding: - add_host: ["pyqt-builder"] + # This package's own real dependency on `pyqt` (PyQt5) already pulls in + # pyqt5-sip, which pins sip to its own range -- an *exact* "sip 6.15.*" + # pin conflicted with that range for every python version and made the + # environment unsolvable ("pyqt 5.15.* cannot be installed... would + # require python >=3.7,<3.8"). But leaving sip fully unpinned isn't safe + # either: conda-forge has since published a pyqt5-sip build whose range + # does include the broken 6.16.x line, and the solver picked it (ABI v12 + # regression again). An upper bound avoids both failure modes. + add_host: ["pyqt-builder", "sip <6.16"] add_run: ["pyqt-builder"] qt_gui_cpp: add_build: ["${{ 'pyqt' if (build_platform != target_platform) }}", "${{ 'qt-main' if (build_platform != target_platform) }}"] - add_host: ["${{ 'libgl-devel' if linux }}", "${{ 'libopengl-devel' if linux }}", "pyqt-builder", "pep517", "pyside2"] + # qt_gui_cpp's own package.xml depends on python_qt_binding, which pulls + # real pyqt5/pyqt5-sip into this same host solve too (verified: "Resolving + # host environment" for this recipe lists ros2-python-qt-binding directly). + # Same fix as python_qt_binding above, for the same reason. + add_host: ["${{ 'libgl-devel' if linux }}", "${{ 'libopengl-devel' if linux }}", "pyqt-builder", "pep517", "pyside2", "sip <6.16"] add_run: ["pyqt-builder", "pep517"] rqt_gui_cpp: add_host: ["${{ 'libgl-devel' if linux }}", "${{ 'libopengl-devel' if linux }}"] diff --git a/patch/ros-jazzy-ament-cmake-python.patch b/patch/ros-jazzy-ament-cmake-python.patch new file mode 100644 index 000000000..3ae3ed9be --- /dev/null +++ b/patch/ros-jazzy-ament-cmake-python.patch @@ -0,0 +1,51 @@ +diff -ruN a/cmake/ament_python_install_package.cmake b/cmake/ament_python_install_package.cmake +--- a/cmake/ament_python_install_package.cmake ++++ b/cmake/ament_python_install_package.cmake +@@ -190,12 +190,20 @@ setup( + + if(NOT ARG_SKIP_COMPILE) + get_executable_path(python_interpreter_config Python3::Interpreter CONFIGURE) ++ # Embedding a raw Windows path (with backslashes) into an install(CODE ++ # "...") string bakes it into cmake_install.cmake as literal source, ++ # where CMake's own string-escape parser can misinterpret sequences like ++ # "\b" (e.g. from a prefix such as C:\bld\...) as invalid escapes. Convert ++ # to forward slashes, which CMake accepts on Windows too, before ++ # embedding. ++ file(TO_CMAKE_PATH "${python_interpreter_config}" python_interpreter_config) ++ file(TO_CMAKE_PATH "${CMAKE_INSTALL_PREFIX}" install_prefix_config) + # compile Python files + install(CODE + "execute_process( + COMMAND + \"${python_interpreter_config}\" \"-m\" \"compileall\" +- \"${CMAKE_INSTALL_PREFIX}/${ARG_DESTINATION}/${package_name}\" ++ \"${install_prefix_config}/${ARG_DESTINATION}/${package_name}\" + )" + ) + endif() + +diff -ruN a/cmake/ament_python_install_module.cmake b/cmake/ament_python_install_module.cmake +--- a/cmake/ament_python_install_module.cmake ++++ b/cmake/ament_python_install_module.cmake +@@ -60,12 +60,20 @@ function(_ament_cmake_python_install_module module_file) + get_filename_component(module_file "${module_file}" NAME) + if(NOT ARG_SKIP_COMPILE) + get_executable_path(python_interpreter Python3::Interpreter CONFIGURE) ++ # Embedding a raw Windows path (with backslashes) into an install(CODE ++ # "...") string bakes it into cmake_install.cmake as literal source, ++ # where CMake's own string-escape parser can misinterpret sequences like ++ # "\b" (e.g. from a prefix such as C:\bld\...) as invalid escapes. Convert ++ # to forward slashes, which CMake accepts on Windows too, before ++ # embedding. ++ file(TO_CMAKE_PATH "${python_interpreter}" python_interpreter) ++ file(TO_CMAKE_PATH "${CMAKE_INSTALL_PREFIX}" install_prefix_config) + # compile Python files + install(CODE + "execute_process( + COMMAND + \"${python_interpreter}\" \"-m\" \"compileall\" +- \"${CMAKE_INSTALL_PREFIX}/${destination}/${module_file}\" ++ \"${install_prefix_config}/${destination}/${module_file}\" + )" + ) + endif() diff --git a/patch/ros-jazzy-apriltag-mit.patch b/patch/ros-jazzy-apriltag-mit.patch new file mode 100644 index 000000000..c051ce447 --- /dev/null +++ b/patch/ros-jazzy-apriltag-mit.patch @@ -0,0 +1,51 @@ +diff -ruN a/CMakeLists.txt b/CMakeLists.txt +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -12,12 +12,20 @@ + # set(CMAKE_CXX_CLANG_TIDY clang-tidy) + + find_package(Eigen3 REQUIRED) +-find_package(OpenCV REQUIRED core calib3d) ++find_package(OpenCV REQUIRED core imgproc) ++if(OpenCV_VERSION VERSION_LESS 5) ++ find_package(OpenCV REQUIRED calib3d) ++ set(APRILTAG_MIT_OPENCV_CALIB opencv_calib3d) ++else() ++ # OpenCV 5 moved findHomography into the geometry module ++ find_package(OpenCV REQUIRED geometry) ++ set(APRILTAG_MIT_OPENCV_CALIB opencv_geometry) ++endif() + find_package(Boost REQUIRED headers) + + file(GLOB CC_FILES ${PROJECT_SOURCE_DIR}/src/*.cc) + add_library(${PROJECT_NAME} SHARED ${CC_FILES}) +-target_link_libraries(${PROJECT_NAME} PUBLIC opencv_core opencv_calib3d Eigen3::Eigen Boost::headers) ++target_link_libraries(${PROJECT_NAME} PUBLIC opencv_core opencv_imgproc ${APRILTAG_MIT_OPENCV_CALIB} Eigen3::Eigen Boost::headers) + set_target_properties(${PROJECT_NAME} PROPERTIES CXX_STANDARD 14) + + target_include_directories( +diff -ruN a/src/Quad.cc b/src/Quad.cc +--- a/src/Quad.cc ++++ b/src/Quad.cc +@@ -2,7 +2,7 @@ + #include "apriltag_mit/AprilTags/Line2D.h" + #include "apriltag_mit/AprilTags/MathUtil.h" + #include "apriltag_mit/AprilTags/Segment.h" +-#include ++#include + + namespace AprilTags { + +diff -ruN a/src/TagDetection.cc b/src/TagDetection.cc +--- a/src/TagDetection.cc ++++ b/src/TagDetection.cc +@@ -1,6 +1,9 @@ + #include "apriltag_mit/AprilTags/TagDetection.h" + #include "apriltag_mit/AprilTags/MathUtil.h" + #include "opencv2/opencv.hpp" ++#if CV_VERSION_MAJOR >= 5 ++#include ++#endif + #include + + namespace AprilTags { diff --git a/patch/ros-jazzy-apriltag-ros.patch b/patch/ros-jazzy-apriltag-ros.patch deleted file mode 100644 index 35aac4cee..000000000 --- a/patch/ros-jazzy-apriltag-ros.patch +++ /dev/null @@ -1,17 +0,0 @@ -diff --git a/CMakeLists.txt b/CMakeLists.txt -index c906851..b48600f 100644 ---- a/CMakeLists.txt -+++ b/CMakeLists.txt -@@ -5,8 +5,10 @@ project(apriltag_ros) - set(CMAKE_CXX_STANDARD 14) - - if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") -- add_compile_options(-Werror -Wall -Wextra -Wpedantic) -- add_link_options("-Wl,-z,relro,-z,now,-z,defs") -+ if(NOT APPLE) -+ add_compile_options(-Werror -Wall -Wextra -Wpedantic) -+ add_link_options("-Wl,-z,relro,-z,now,-z,defs") -+ endif() - endif() - - option(ASAN "use AddressSanitizer to detect memory issues" OFF) diff --git a/patch/ros-jazzy-autoware-ekf-localizer.patch b/patch/ros-jazzy-autoware-ekf-localizer.patch new file mode 100644 index 000000000..1a5259e71 --- /dev/null +++ b/patch/ros-jazzy-autoware-ekf-localizer.patch @@ -0,0 +1,15 @@ +diff -ruN a/CMakeLists.txt b/CMakeLists.txt +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -33,7 +33,10 @@ + ROS2_EXECUTOR SingleThreadedExecutor + ) + +-target_link_libraries(${PROJECT_NAME} Eigen3::Eigen) ++# warning_message.cpp/ekf_module.cpp call fmt::vformat() directly; link it ++# explicitly since it's not header-only in this build. ++find_package(fmt REQUIRED) ++target_link_libraries(${PROJECT_NAME} Eigen3::Eigen fmt::fmt) + + function(add_testcase filepath) + get_filename_component(filename ${filepath} NAME) diff --git a/patch/ros-jazzy-autoware-ground-filter.patch b/patch/ros-jazzy-autoware-ground-filter.patch new file mode 100644 index 000000000..776cdfde0 --- /dev/null +++ b/patch/ros-jazzy-autoware-ground-filter.patch @@ -0,0 +1,16 @@ +diff -ruN a/src/grid.hpp b/src/grid.hpp +--- a/src/grid.hpp ++++ b/src/grid.hpp +@@ -25,6 +25,12 @@ + #include + #include + ++#ifndef M_PIf ++#define M_PIf 3.14159265358979324f ++#define M_PI_2f (M_PIf / 2.0f) ++#define M_PI_4f (M_PIf / 4.0f) ++#endif ++ + namespace + { + diff --git a/patch/ros-jazzy-autoware-kalman-filter.patch b/patch/ros-jazzy-autoware-kalman-filter.patch new file mode 100644 index 000000000..6e53f8041 --- /dev/null +++ b/patch/ros-jazzy-autoware-kalman-filter.patch @@ -0,0 +1,24 @@ +diff -ruN a/CMakeLists.txt b/CMakeLists.txt +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -7,17 +7,15 @@ + find_package(eigen3_cmake_module REQUIRED) + find_package(Eigen3 REQUIRED) + +-include_directories( +- SYSTEM +- ${EIGEN3_INCLUDE_DIR} +-) +- + ament_auto_add_library(${PROJECT_NAME} SHARED + src/kalman_filter.cpp + src/time_delay_kalman_filter.cpp + include/autoware/kalman_filter/kalman_filter.hpp + include/autoware/kalman_filter/time_delay_kalman_filter.hpp + ) ++# Eigen3Config.cmake (the modern conda-forge package config, as opposed to the legacy ++# FindEigen3.cmake module) only exports the Eigen3::Eigen target, not EIGEN3_INCLUDE_DIR. ++target_link_libraries(${PROJECT_NAME} PUBLIC Eigen3::Eigen) + + if(BUILD_TESTING) + file(GLOB_RECURSE test_files test/*.cpp) diff --git a/patch/ros-jazzy-autoware-osqp-interface.patch b/patch/ros-jazzy-autoware-osqp-interface.patch new file mode 100644 index 000000000..15b710326 --- /dev/null +++ b/patch/ros-jazzy-autoware-osqp-interface.patch @@ -0,0 +1,43 @@ +diff -ruN a/CMakeLists.txt b/CMakeLists.txt +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -34,9 +34,11 @@ + "${EIGEN3_INCLUDE_DIR}" + ) + +-ament_target_dependencies(${PROJECT_NAME} +- Eigen3 +- osqp_vendor ++# Eigen3Config.cmake (the modern conda-forge package config) only exports the ++# Eigen3::Eigen target, not EIGEN3_INCLUDE_DIR used above. ++target_link_libraries(${PROJECT_NAME} ++ Eigen3::Eigen ++ osqp::osqp + ) + + # crucial so downstream package builds because autoware_osqp_interface exposes osqp.hpp +diff -ruN a/src/csc_matrix_conv.cpp b/src/csc_matrix_conv.cpp +--- a/src/csc_matrix_conv.cpp ++++ b/src/csc_matrix_conv.cpp +@@ -25,9 +25,9 @@ + { + CSC_Matrix calCSCMatrix(const Eigen::MatrixXd & mat) + { +- const size_t elem = static_cast(mat.nonZeros()); + const Eigen::Index rows = mat.rows(); + const Eigen::Index cols = mat.cols(); ++ const size_t elem = static_cast(rows * cols); + + std::vector vals; + vals.reserve(elem); +@@ -66,9 +66,9 @@ + + CSC_Matrix calCSCMatrixTrapezoidal(const Eigen::MatrixXd & mat) + { +- const size_t elem = static_cast(mat.nonZeros()); + const Eigen::Index rows = mat.rows(); + const Eigen::Index cols = mat.cols(); ++ const size_t elem = static_cast(rows * (rows + 1) / 2); + + if (rows != cols) { + throw std::invalid_argument("Matrix must be square (n, n)"); diff --git a/patch/ros-jazzy-autoware-qp-interface.patch b/patch/ros-jazzy-autoware-qp-interface.patch new file mode 100644 index 000000000..63654b8a2 --- /dev/null +++ b/patch/ros-jazzy-autoware-qp-interface.patch @@ -0,0 +1,44 @@ +diff -ruN a/CMakeLists.txt b/CMakeLists.txt +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -38,9 +38,13 @@ + "${EIGEN3_INCLUDE_DIR}" + ) + ++# Eigen3Config.cmake (the modern conda-forge package config) only exports the ++# Eigen3::Eigen target, not EIGEN3_INCLUDE_DIR used above. ++target_link_libraries(${PROJECT_NAME} ++ Eigen3::Eigen ++ osqp::osqp ++) + ament_target_dependencies(${PROJECT_NAME} +- Eigen3 +- osqp_vendor + proxsuite + ) + +diff -ruN a/src/osqp_csc_matrix_conv.cpp b/src/osqp_csc_matrix_conv.cpp +--- a/src/osqp_csc_matrix_conv.cpp ++++ b/src/osqp_csc_matrix_conv.cpp +@@ -25,9 +25,9 @@ + { + CSC_Matrix calCSCMatrix(const Eigen::MatrixXd & mat) + { +- const size_t elem = static_cast(mat.nonZeros()); + const Eigen::Index rows = mat.rows(); + const Eigen::Index cols = mat.cols(); ++ const size_t elem = static_cast(rows * cols); + + std::vector vals; + vals.reserve(elem); +@@ -66,9 +66,9 @@ + + CSC_Matrix calCSCMatrixTrapezoidal(const Eigen::MatrixXd & mat) + { +- const size_t elem = static_cast(mat.nonZeros()); + const Eigen::Index rows = mat.rows(); + const Eigen::Index cols = mat.cols(); ++ const size_t elem = static_cast(rows * (rows + 1) / 2); + + if (rows != cols) { + throw std::invalid_argument("Matrix must be square (n, n)"); diff --git a/patch/ros-jazzy-cartographer-ros.patch b/patch/ros-jazzy-cartographer-ros.patch index b5e82e42c..a7bf8cdb3 100644 --- a/patch/ros-jazzy-cartographer-ros.patch +++ b/patch/ros-jazzy-cartographer-ros.patch @@ -2,6 +2,19 @@ diff --git a/CMakeLists.txt b/CMakeLists.txt index f7f476296..0725a05d5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt +@@ -26,6 +26,12 @@ + add_compile_options(-Wall -Wextra) + endif() + ++# node.cpp's object file exceeds MSVC's default section-count limit due to ++# heavy Boost/Eigen/protobuf template instantiation. ++if(MSVC) ++ add_compile_options(/bigobj) ++endif() ++ + set(CMAKE_POSITION_INDEPENDENT_CODE ON) + + find_package(builtin_interfaces REQUIRED) @@ -50,6 +50,16 @@ find_package(urdf REQUIRED) find_package(urdfdom_headers REQUIRED) find_package(visualization_msgs REQUIRED) diff --git a/patch/ros-jazzy-clearpath-diagnostics.patch b/patch/ros-jazzy-clearpath-diagnostics.patch index 034f74cbb..794258a7f 100644 --- a/patch/ros-jazzy-clearpath-diagnostics.patch +++ b/patch/ros-jazzy-clearpath-diagnostics.patch @@ -1,14 +1,6 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: RoboStack -Date: Wed, 13 May 2026 23:30:00 +0000 -Subject: [PATCH] Undef glibc major/minor macros before Version class - -glibc's (pulled in transitively on aarch64) defines -major()/minor() as macros that expand to gnu_dev_major/gnu_dev_minor, -colliding with clearpath::Version's int members. ---- ---- a/include/clearpath_diagnostics/clearpath_diagnostic_updater.hpp 2026-05-13 23:40:50.389941101 -0700 -+++ b/include/clearpath_diagnostics/clearpath_diagnostic_updater.hpp 2026-05-13 23:43:40.451520115 -0700 +diff --git a/include/clearpath_diagnostics/clearpath_diagnostic_updater.hpp b/include/clearpath_diagnostics/clearpath_diagnostic_updater.hpp +--- a/include/clearpath_diagnostics/clearpath_diagnostic_updater.hpp ++++ b/include/clearpath_diagnostics/clearpath_diagnostic_updater.hpp @@ -47,6 +47,16 @@ #include "clearpath_platform_msgs/msg/status.hpp" #include "clearpath_platform_msgs/msg/stop_status.hpp" @@ -25,4 +17,20 @@ colliding with clearpath::Version's int members. + namespace clearpath { + +diff --git a/CMakeLists.txt b/CMakeLists.txt +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -5,6 +5,12 @@ + add_compile_options(-Wall -Wextra -Wpedantic) + endif() ++# clearpath_diagnostic_updater.cpp's object file exceeds MSVC's default ++# section-count limit due to heavy template instantiation. ++if(MSVC) ++ add_compile_options(/bigobj) ++endif() ++ + # find dependencies + find_package(ament_cmake REQUIRED) + find_package(clearpath_platform_msgs REQUIRED) diff --git a/patch/ros-jazzy-compressed-image-transport.patch b/patch/ros-jazzy-compressed-image-transport.patch new file mode 100644 index 000000000..ee6e96cea --- /dev/null +++ b/patch/ros-jazzy-compressed-image-transport.patch @@ -0,0 +1,38 @@ +diff -ruN a/src/compressed_subscriber.cpp b/src/compressed_subscriber.cpp +--- a/src/compressed_subscriber.cpp ++++ b/src/compressed_subscriber.cpp +@@ -140,28 +140,28 @@ + if (compressed_bgr_image) { + // if necessary convert colors from bgr to rgb + if ((image_encoding == enc::RGB8) || (image_encoding == enc::RGB16)) { +- cv::cvtColor(cv_ptr->image, cv_ptr->image, CV_BGR2RGB); ++ cv::cvtColor(cv_ptr->image, cv_ptr->image, cv::COLOR_BGR2RGB); + } + + if ((image_encoding == enc::RGBA8) || (image_encoding == enc::RGBA16)) { +- cv::cvtColor(cv_ptr->image, cv_ptr->image, CV_BGR2RGBA); ++ cv::cvtColor(cv_ptr->image, cv_ptr->image, cv::COLOR_BGR2RGBA); + } + + if ((image_encoding == enc::BGRA8) || (image_encoding == enc::BGRA16)) { +- cv::cvtColor(cv_ptr->image, cv_ptr->image, CV_BGR2BGRA); ++ cv::cvtColor(cv_ptr->image, cv_ptr->image, cv::COLOR_BGR2BGRA); + } + } else { + // if necessary convert colors from rgb to bgr + if ((image_encoding == enc::BGR8) || (image_encoding == enc::BGR16)) { +- cv::cvtColor(cv_ptr->image, cv_ptr->image, CV_RGB2BGR); ++ cv::cvtColor(cv_ptr->image, cv_ptr->image, cv::COLOR_RGB2BGR); + } + + if ((image_encoding == enc::BGRA8) || (image_encoding == enc::BGRA16)) { +- cv::cvtColor(cv_ptr->image, cv_ptr->image, CV_RGB2BGRA); ++ cv::cvtColor(cv_ptr->image, cv_ptr->image, cv::COLOR_RGB2BGRA); + } + + if ((image_encoding == enc::RGBA8) || (image_encoding == enc::RGBA16)) { +- cv::cvtColor(cv_ptr->image, cv_ptr->image, CV_RGB2RGBA); ++ cv::cvtColor(cv_ptr->image, cv_ptr->image, cv::COLOR_RGB2RGBA); + } + } + } diff --git a/patch/ros-jazzy-cv-bridge.patch b/patch/ros-jazzy-cv-bridge.patch new file mode 100644 index 000000000..87d014aa6 --- /dev/null +++ b/patch/ros-jazzy-cv-bridge.patch @@ -0,0 +1,52 @@ +diff -ruN a/CMakeLists.txt b/CMakeLists.txt +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -51,6 +51,15 @@ + CONFIG + ) + if(NOT OpenCV_FOUND) ++ find_package(OpenCV 5 QUIET ++ COMPONENTS ++ opencv_core ++ opencv_imgproc ++ opencv_imgcodecs ++ CONFIG ++ ) ++endif() ++if(NOT OpenCV_FOUND) + find_package(OpenCV 3 REQUIRED + COMPONENTS + opencv_core +diff -ruN a/include/cv_bridge/cv_bridge.hpp b/include/cv_bridge/cv_bridge.hpp +--- a/include/cv_bridge/cv_bridge.hpp ++++ b/include/cv_bridge/cv_bridge.hpp +@@ -42,7 +42,6 @@ + #include + #include + #include +-#include + #include + + #include +diff -ruN a/src/module_opencv4.cpp b/src/module_opencv4.cpp +--- a/src/module_opencv4.cpp ++++ b/src/module_opencv4.cpp +@@ -2,7 +2,6 @@ + + #include "module.hpp" + +-#include "opencv2/core/types_c.h" + + #include "opencv2/opencv_modules.hpp" + +@@ -99,8 +98,8 @@ + NumpyAllocator() {stdAllocator = Mat::getStdAllocator();} + ~NumpyAllocator() {} + +-// To compile openCV3 with OpenCV4 APIs. +-#ifndef OPENCV_VERSION_4 ++// To compile openCV3 with OpenCV4/5 APIs. ++#if CV_MAJOR_VERSION < 4 + #define AccessFlag int + #endif + diff --git a/patch/ros-jazzy-depthai.patch b/patch/ros-jazzy-depthai.patch index 34ed73b2a..0c5cdac9c 100644 --- a/patch/ros-jazzy-depthai.patch +++ b/patch/ros-jazzy-depthai.patch @@ -1,26 +1,26 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Esteve Fernandez -Date: Tue, 12 May 2026 14:01:42 +0100 -Subject: [PATCH] fix(depthai): make conda builds use bundled release sources - -Signed-off-by: Esteve Fernandez - ---- - CMakeLists.txt | 2 ++ - shared/depthai-bootloader-shared.cmake | 37 ++++++++++++++++++---------------- - shared/depthai-shared.cmake | 35 +++++++++++++++++--------------- - 3 files changed, 41 insertions(+), 33 deletions(-) - diff --git a/CMakeLists.txt b/CMakeLists.txt -index 109d9da..24d9aff 100644 +index 109d9da..4d68b21 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt -@@ -60,6 +60,8 @@ else() +@@ -1,4 +1,4 @@ +-cmake_minimum_required(VERSION 3.4) # For Hunter ++cmake_minimum_required(VERSION 3.5) # For Hunter + + # MSVC variable isn't available before 'project' call + # Generalize to Win32 platform for now +@@ -60,6 +60,15 @@ else() message(STATUS "Using toolchain file: ${CMAKE_TOOLCHAIN_FILE}") endif() +set(HUNTER_ROOT "${CMAKE_BINARY_DIR}/.hunter" CACHE PATH "Hunter package cache") +set(DEPTHAI_ENABLE_CURL OFF CACHE BOOL "Enable CURL support" FORCE) ++# Hunter's own vendored CMakeLists.txt (downloaded by HunterGate below and ++# configured via its own nested `cmake -H... -B...` subprocess) declares a ++# cmake_minimum_required below CMake 4's floor of 3.5 too, and we can't patch ++# a file that only exists after being downloaded at build time. Setting this ++# as a real environment variable (not just a -D cache arg) is what actually ++# reaches that nested cmake invocation. ++set(ENV{CMAKE_POLICY_VERSION_MINIMUM} "3.5") include("cmake/HunterGate.cmake") HunterGate( URL "https://github.com/cpp-pm/hunter/archive/9d9242b60d5236269f894efd3ddd60a9ca83dd7f.tar.gz" @@ -129,5 +129,3 @@ index 414e1eb..94a007d 100644 endif() endif() --- -2.54.0 diff --git a/patch/ros-jazzy-grid-map-cv.patch b/patch/ros-jazzy-grid-map-cv.patch new file mode 100644 index 000000000..5e1c1153d --- /dev/null +++ b/patch/ros-jazzy-grid-map-cv.patch @@ -0,0 +1,24 @@ +diff -ruN a/include/grid_map_cv/GridMapCvConverter.hpp b/include/grid_map_cv/GridMapCvConverter.hpp +--- a/include/grid_map_cv/GridMapCvConverter.hpp ++++ b/include/grid_map_cv/GridMapCvConverter.hpp +@@ -87,9 +87,9 @@ + + cv::Mat imageMono; + if (isColor && !hasAlpha) { +- cv::cvtColor(image, imageMono, CV_BGR2GRAY); ++ cv::cvtColor(image, imageMono, cv::COLOR_BGR2GRAY); + } else if (isColor && hasAlpha) { +- cv::cvtColor(image, imageMono, CV_BGRA2GRAY); ++ cv::cvtColor(image, imageMono, cv::COLOR_BGRA2GRAY); + } else if (!isColor && !hasAlpha) { + imageMono = image; + } else { +@@ -156,7 +156,7 @@ + + cv::Mat imageRGB; + if (hasAlpha) { +- cv::cvtColor(image, imageRGB, CV_BGRA2RGB); ++ cv::cvtColor(image, imageRGB, cv::COLOR_BGRA2RGB); + } else { + imageRGB = image; + } diff --git a/patch/ros-jazzy-iceoryx-binding-c.win.patch b/patch/ros-jazzy-iceoryx-binding-c.win.patch deleted file mode 100644 index 35404a3e2..000000000 --- a/patch/ros-jazzy-iceoryx-binding-c.win.patch +++ /dev/null @@ -1,13 +0,0 @@ -diff --git a/CMakeLists.txt b/CMakeLists.txt -index 7863ddb..5f361df 100644 ---- a/CMakeLists.txt -+++ b/CMakeLists.txt -@@ -32,6 +32,8 @@ include(IceoryxPoshDeployment) - - if(CMAKE_SYSTEM_NAME MATCHES Linux OR CMAKE_SYSTEM_NAME MATCHES Darwin) - option(BUILD_SHARED_LIBS "Create shared libraries by default" ON) -+else() -+ set(BUILD_SHARED_LIBS OFF CACHE BOOL "" FORCE) - endif() - - set(PREFIX iceoryx/v${CMAKE_PROJECT_VERSION}) diff --git a/patch/ros-jazzy-iceoryx-hoofs.win.patch b/patch/ros-jazzy-iceoryx-hoofs.win.patch deleted file mode 100644 index dc3b9052e..000000000 --- a/patch/ros-jazzy-iceoryx-hoofs.win.patch +++ /dev/null @@ -1,25 +0,0 @@ -diff --git a/CMakeLists.txt b/CMakeLists.txt -index f7cb43b..115964a 100644 ---- a/CMakeLists.txt -+++ b/CMakeLists.txt -@@ -26,6 +26,8 @@ include("${CMAKE_CURRENT_LIST_DIR}/cmake/IceoryxPlatform.cmake") - - if(CMAKE_SYSTEM_NAME MATCHES Linux OR CMAKE_SYSTEM_NAME MATCHES Darwin) - option(BUILD_SHARED_LIBS "Create shared libraries by default" ON) -+else() -+ set(BUILD_SHARED_LIBS OFF CACHE BOOL "" FORCE) - endif() - - set(PREFIX iceoryx/v${CMAKE_PROJECT_VERSION}) -diff --git a/platform/win/source/time.cpp b/platform/win/source/time.cpp -index 4c2ab2d..4a7074b 100644 ---- a/platform/win/source/time.cpp -+++ b/platform/win/source/time.cpp -@@ -16,6 +16,7 @@ - // SPDX-License-Identifier: Apache-2.0 - - #include "iceoryx_hoofs/platform/time.hpp" -+#include - - static std::chrono::nanoseconds getNanoSeconds(const timespec& value) - { diff --git a/patch/ros-jazzy-iceoryx-posh.win.patch b/patch/ros-jazzy-iceoryx-posh.win.patch deleted file mode 100644 index 2a0969e5e..000000000 --- a/patch/ros-jazzy-iceoryx-posh.win.patch +++ /dev/null @@ -1,44 +0,0 @@ -diff --git a/iceoryx_posh/CMakeLists.txt b/iceoryx_posh/CMakeLists.txt -index 57e84cdd0..d7781cbb9 100644 ---- a/iceoryx_posh/CMakeLists.txt -+++ b/iceoryx_posh/CMakeLists.txt -@@ -42,6 +42,8 @@ include(cmake/IceoryxPoshDeployment.cmake) - - if(CMAKE_SYSTEM_NAME MATCHES Linux OR CMAKE_SYSTEM_NAME MATCHES Darwin) - option(BUILD_SHARED_LIBS "Create shared libraries by default" ON) -+else() -+ set(BUILD_SHARED_LIBS OFF CACHE BOOL "" FORCE) - endif() - - set(PREFIX iceoryx/v${CMAKE_PROJECT_VERSION}) -diff --git a/iceoryx_posh/cmake/cpptoml/CMakeLists.txt b/iceoryx_posh/cmake/cpptoml/CMakeLists.txt -index e770e4fdba..a548376f1a 100644 ---- a/iceoryx_posh/cmake/cpptoml/CMakeLists.txt -+++ b/iceoryx_posh/cmake/cpptoml/CMakeLists.txt -@@ -75,23 +75,13 @@ if(DEFINED CMAKE_TOOLCHAIN_FILE) - endif() - - execute_process( -- COMMAND git apply -R -p1 --ignore-space-change --whitespace=nowarn --check -+ COMMAND patch -p1 --forward --ignore-whitespace --fuzz=3 - INPUT_FILE "${CMAKE_CURRENT_LIST_DIR}/0001-cpptoml-cmake-version.patch" - WORKING_DIRECTORY "${SOURCE_DIR}" -- OUTPUT_QUIET -- ERROR_QUIET - RESULT_VARIABLE result) --if(result) -- message(STATUS "Applying patch for minimal cmake version to cpptoml") - -- execute_process( -- COMMAND git apply -p1 --ignore-space-change --whitespace=nowarn -- INPUT_FILE "${CMAKE_CURRENT_LIST_DIR}/0001-cpptoml-cmake-version.patch" -- WORKING_DIRECTORY "${SOURCE_DIR}" -- RESULT_VARIABLE result) -- if(result) -- message(FATAL_ERROR "CMake step [patch] for '${PROJECT_NAME}' failed! Error code: ${result}!") -- endif() -+if(result) -+ message(FATAL_ERROR "CMake step [patch] for '${PROJECT_NAME}' failed! Error code: ${result}!") - endif() - - execute_process(COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" "-DENABLE_LIBCXX=off" "-DCPPTOML_BUILD_EXAMPLES=off" "-DCMAKE_INSTALL_PREFIX=${INSTALL_DIR}" "${SOURCE_DIR}" ${CMAKE_ADDITIONAL_OPTIONS} diff --git a/patch/ros-jazzy-image-geometry.patch b/patch/ros-jazzy-image-geometry.patch new file mode 100644 index 000000000..267b14f95 --- /dev/null +++ b/patch/ros-jazzy-image-geometry.patch @@ -0,0 +1,33 @@ +diff -ruN a/CMakeLists.txt b/CMakeLists.txt +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -15,7 +15,7 @@ + add_compile_options(-Wall -Wextra) + endif() + +-find_package(OpenCV REQUIRED COMPONENTS calib3d core highgui imgproc) ++find_package(OpenCV REQUIRED COMPONENTS calib core highgui imgproc) + find_package(sensor_msgs REQUIRED) + + add_library(${PROJECT_NAME} +@@ -26,7 +26,7 @@ + "$" + "$") + target_link_libraries(${PROJECT_NAME} PUBLIC +- opencv_calib3d ++ opencv_calib + opencv_core + opencv_highgui + opencv_imgproc +diff -ruN a/include/image_geometry/pinhole_camera_model.hpp b/include/image_geometry/pinhole_camera_model.hpp +--- a/include/image_geometry/pinhole_camera_model.hpp ++++ b/include/image_geometry/pinhole_camera_model.hpp +@@ -6,7 +6,7 @@ + #include + #include + #include +-#include ++#include + #include + #include + #include diff --git a/patch/ros-jazzy-image-proc.patch b/patch/ros-jazzy-image-proc.patch new file mode 100644 index 000000000..46f64349a --- /dev/null +++ b/patch/ros-jazzy-image-proc.patch @@ -0,0 +1,108 @@ +diff -ruN a/include/image_proc/track_marker.hpp b/include/image_proc/track_marker.hpp +--- a/include/image_proc/track_marker.hpp ++++ b/include/image_proc/track_marker.hpp +@@ -36,7 +36,11 @@ + + #include + #include ++#if CV_VERSION_MAJOR >= 5 ++#include ++#else + #include ++#endif + #include + #include + #include +@@ -60,6 +64,9 @@ + + cv::Ptr detector_params_; + cv::Ptr dictionary_; ++#if CV_VERSION_MAJOR >= 5 ++ cv::aruco::ArucoDetector detector_; ++#endif + + void imageCb( + const sensor_msgs::msg::Image::ConstSharedPtr & image_msg, +diff -ruN a/src/crop_non_zero.cpp b/src/crop_non_zero.cpp +--- a/src/crop_non_zero.cpp ++++ b/src/crop_non_zero.cpp +@@ -40,6 +40,9 @@ + + #include + #include ++#if CV_VERSION_MAJOR >= 5 ++#include ++#endif + #include + #include + #include +@@ -112,7 +115,7 @@ + cv_ptr->image.convertTo(m, CV_8U, 255. / ra, -minVal * 255. / ra); + } + +- cv::findContours(m, cnt, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE); ++ cv::findContours(m, cnt, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_NONE); + + if (cnt.empty()) { + RCLCPP_WARN( +diff -ruN a/src/track_marker.cpp b/src/track_marker.cpp +--- a/src/track_marker.cpp ++++ b/src/track_marker.cpp +@@ -39,6 +39,9 @@ + #include + #include + #include ++#if CV_VERSION_MAJOR >= 5 ++#include ++#endif + #include + #include + #include +@@ -75,6 +78,12 @@ + dictionary_ = cv::aruco::getPredefinedDictionary(dict_id); + #endif + ++ #if CV_VERSION_MAJOR >= 5 ++ // OpenCV 5 removed the free cv::aruco::detectMarkers() function in favor of ++ // the ArucoDetector class. ++ detector_ = cv::aruco::ArucoDetector(*dictionary_, *detector_params_); ++ #endif ++ + // Setup lazy subscriber using publisher connection callback + rclcpp::PublisherOptions pub_options; + pub_options.event_callbacks.matched_callback = +@@ -114,7 +123,11 @@ + + std::vector marker_ids; + std::vector> marker_corners; ++ #if CV_VERSION_MAJOR >= 5 ++ detector_.detectMarkers(cv_ptr->image, marker_corners, marker_ids); ++ #else + cv::aruco::detectMarkers(cv_ptr->image, dictionary_, marker_corners, marker_ids); ++ #endif + + for (size_t i = 0; i < marker_ids.size(); ++i) { + if (marker_ids[i] == marker_id_) { +@@ -131,9 +144,22 @@ + cv::Mat dist_coeffs(info_msg->d.size(), 1, CV_64FC1, reinterpret_cast(d.data())); + + // Estimate pose ++ #if CV_VERSION_MAJOR >= 5 ++ // OpenCV 5 removed cv::aruco::estimatePoseSingleMarkers(); solve for the ++ // marker pose directly against its known square corner geometry instead. ++ const std::vector obj_points{ ++ cv::Point3f(-marker_size_ / 2.f, marker_size_ / 2.f, 0), ++ cv::Point3f(marker_size_ / 2.f, marker_size_ / 2.f, 0), ++ cv::Point3f(marker_size_ / 2.f, -marker_size_ / 2.f, 0), ++ cv::Point3f(-marker_size_ / 2.f, -marker_size_ / 2.f, 0)}; ++ cv::Vec3d sp_rvec, sp_tvec; ++ cv::solvePnP(obj_points, corners[0], intrinsics, dist_coeffs, sp_rvec, sp_tvec); ++ std::vector rvecs{sp_rvec}, tvecs{sp_tvec}; ++ #else + std::vector rvecs, tvecs; + cv::aruco::estimatePoseSingleMarkers( + corners, marker_size_, intrinsics, dist_coeffs, rvecs, tvecs); ++ #endif + + // Publish pose of marker + geometry_msgs::msg::PoseStamped pose; diff --git a/patch/ros-jazzy-image-rotate.patch b/patch/ros-jazzy-image-rotate.patch new file mode 100644 index 000000000..bdc102c87 --- /dev/null +++ b/patch/ros-jazzy-image-rotate.patch @@ -0,0 +1,34 @@ +diff -ruN a/CMakeLists.txt b/CMakeLists.txt +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -14,9 +14,16 @@ + ament_auto_find_build_dependencies() + + find_package(OpenCV REQUIRED core imgproc) ++if(OpenCV_VERSION VERSION_LESS 5) ++ set(IMAGE_ROTATE_OPENCV_GEOMETRY) ++else() ++ # OpenCV 5 moved getRotationMatrix2D into the geometry module ++ find_package(OpenCV REQUIRED geometry) ++ set(IMAGE_ROTATE_OPENCV_GEOMETRY opencv_geometry) ++endif() + + ament_auto_add_library(${PROJECT_NAME} SHARED src/image_rotate_node.cpp) +-target_link_libraries(${PROJECT_NAME} ${OpenCV_LIBRARIES}) ++target_link_libraries(${PROJECT_NAME} ${OpenCV_LIBRARIES} ${IMAGE_ROTATE_OPENCV_GEOMETRY}) + rclcpp_components_register_nodes(${PROJECT_NAME} "${PROJECT_NAME}::ImageRotateNode") + set(node_plugins "${node_plugins}${PROJECT_NAME}::ImageRotateNode;$\n") + +diff -ruN a/src/image_rotate_node.cpp b/src/image_rotate_node.cpp +--- a/src/image_rotate_node.cpp ++++ b/src/image_rotate_node.cpp +@@ -54,6 +54,9 @@ + #include + #include + #include ++#if CV_VERSION_MAJOR >= 5 ++#include ++#endif + + #include + #include diff --git a/patch/ros-jazzy-libg2o.patch b/patch/ros-jazzy-libg2o.patch index 60daf35bf..b31928b2e 100644 --- a/patch/ros-jazzy-libg2o.patch +++ b/patch/ros-jazzy-libg2o.patch @@ -1,5 +1,5 @@ diff --git a/CMakeLists.txt b/CMakeLists.txt -index 1b86088..8aad22e 100644 +index 1b86088..ca7eca6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -477,7 +477,7 @@ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${g2o_C_FLAGS}") @@ -7,7 +7,46 @@ index 1b86088..8aad22e 100644 # fall back to the using the module form. # See https://eigen.tuxfamily.org/dox/TopicCMakeGuide.html for details -find_package(Eigen3 3.3 REQUIRED) -+find_package(Eigen3 REQUIRED CONFIG) ++find_package(Eigen3 REQUIRED NO_MODULE) if (TARGET Eigen3::Eigen) set(G2O_EIGEN3_EIGEN_TARGET Eigen3::Eigen) else() +diff --git a/g2o/examples/sphere/create_sphere.cpp b/g2o/examples/sphere/create_sphere.cpp +index 8c4b0fd..f83e5e0 100644 +--- a/g2o/examples/sphere/create_sphere.cpp ++++ b/g2o/examples/sphere/create_sphere.cpp +@@ -166,8 +166,8 @@ int main(int argc, char** argv) { + cerr << "using seeds:"; + for (size_t i = 0; i < seeds.size(); ++i) cerr << " " << seeds[i]; + cerr << endl; +- transSampler.seed(seeds[0]); +- rotSampler.seed(seeds[1]); ++ transSampler.seed(static_cast(seeds[0])); ++ rotSampler.seed(static_cast(seeds[1])); + } + + // noise for all the edges +diff --git a/g2o/solvers/csparse/CMakeLists.txt b/g2o/solvers/csparse/CMakeLists.txt +index e3a3980..e60f6bd 100644 +--- a/g2o/solvers/csparse/CMakeLists.txt ++++ b/g2o/solvers/csparse/CMakeLists.txt +@@ -37,6 +37,7 @@ endif() + + target_include_directories(solver_csparse PUBLIC + $ ++ $ + $ + $) + target_compile_features(solver_csparse PUBLIC cxx_std_17) +diff --git a/g2o/stuff/misc.h b/g2o/stuff/misc.h +index 58a1afd..cd14ccc 100644 +--- a/g2o/stuff/misc.h ++++ b/g2o/stuff/misc.h +@@ -27,6 +27,7 @@ + #ifndef G2O_STUFF_MISC_H + #define G2O_STUFF_MISC_H + ++#include + #include + + /** @addtogroup utils **/ diff --git a/patch/ros-jazzy-libnabo.patch b/patch/ros-jazzy-libnabo.patch new file mode 100644 index 000000000..49d97abf7 --- /dev/null +++ b/patch/ros-jazzy-libnabo.patch @@ -0,0 +1,91 @@ +diff -ruN a/CMakeLists.txt b/CMakeLists.txt +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -83,7 +83,9 @@ + set (CMAKE_CXX_FLAGS "-std=c++11 ${CMAKE_CXX_FLAGS}") + endif () + else () +- set (CMAKE_CXX_STANDARD 11) ++ # Modern Eigen (bundled by conda-forge) requires C++14 (std::enable_if_t, ++ # std::integer_sequence); C++11 no longer compiles against it. ++ set (CMAKE_CXX_STANDARD 14) + endif () + + #======================== External Dependencies =============================== +@@ -168,6 +170,9 @@ + if (CMAKE_COMPILER_IS_GNUCC) + target_link_libraries(${LIB_NAME} PUBLIC gomp) + endif() ++ # Clang (e.g. on macOS) needs the OpenMP runtime linked explicitly too; ++ # PUBLIC so it propagates to the tests/examples that link libnabo. ++ target_link_libraries(${LIB_NAME} PUBLIC OpenMP::OpenMP_CXX) + endif() + endif () + +@@ -194,7 +199,10 @@ + add_subdirectory(tests) + endif() + +-option(LIBNABO_BUILD_PYTHON "Build libnabo python" ON) ++# python/nabo.cpp uses the pre-NumPy-1.7 C API (PyArray_DOUBLE, PyArray_INT, ++# NPY_C_CONTIGUOUS, ...) which was removed outright in modern NumPy; the ROS ++# package only needs the C++ library, so leave these bindings off by default. ++option(LIBNABO_BUILD_PYTHON "Build libnabo python" OFF) + if(LIBNABO_BUILD_PYTHON) + add_subdirectory(python) + endif() +diff -ruN a/libnaboConfig.cmake.in b/libnaboConfig.cmake.in +--- a/libnaboConfig.cmake.in ++++ b/libnaboConfig.cmake.in +@@ -4,6 +4,11 @@ + # libnabo_LIBRARIES - libraries to link against + @PACKAGE_INIT@ + ++# libnabo-targets.cmake exports a PUBLIC link dependency on OpenMP::OpenMP_CXX ++# (see CMakeLists.txt); consumers need that imported target in scope too. ++include(CMakeFindDependencyMacro) ++find_dependency(OpenMP) ++ + include(${CMAKE_CURRENT_LIST_DIR}/libnabo-targets.cmake) + + # This causes catkin_simple to link against these libraries +diff -ruN a/nabo/kdtree_cpu.cpp b/nabo/kdtree_cpu.cpp +--- a/nabo/kdtree_cpu.cpp ++++ b/nabo/kdtree_cpu.cpp +@@ -31,6 +31,7 @@ + + #include "nabo_private.h" + #include "index_heap.h" ++#include + #include + #include + #include +diff -ruN a/python/CMakeLists.txt b/python/CMakeLists.txt +--- a/python/CMakeLists.txt ++++ b/python/CMakeLists.txt +@@ -48,7 +48,13 @@ + find_package_handle_standard_args(numpy DEFAULT_MSG PY_NUMPY) + if (Boost_FOUND AND NUMPY_FOUND) + message("numpy and boost::python found, generating python bindings") +- include_directories(${PYTHON_INCLUDE_DIRS} ${PY_NUMPY}/core/include) ++ # numpy >= 2.0 moved its C headers from core/include to _core/include ++ if (EXISTS "${PY_NUMPY}/_core/include") ++ set(NUMPY_INCLUDE_DIR "${PY_NUMPY}/_core/include") ++ else () ++ set(NUMPY_INCLUDE_DIR "${PY_NUMPY}/core/include") ++ endif () ++ include_directories(${PYTHON_INCLUDE_DIRS} ${NUMPY_INCLUDE_DIR}) + if (SHARED_LIBS) + python_add_module(pynabo SHARED nabo.cpp) + target_link_libraries(pynabo ${LIB_NAME} ${Boost_LIBRARIES} ${PYTHON_LIBRARIES}) +diff -ruN a/tests/knnvalidate.cpp b/tests/knnvalidate.cpp +--- a/tests/knnvalidate.cpp ++++ b/tests/knnvalidate.cpp +@@ -32,6 +32,7 @@ + #include "nabo/nabo.h" + #include "helpers.h" + //#include "experimental/nabo_experimental.h" ++#include + #include + #include + #include diff --git a/patch/ros-jazzy-libpointmatcher.patch b/patch/ros-jazzy-libpointmatcher.patch new file mode 100644 index 000000000..82d0a92fa --- /dev/null +++ b/patch/ros-jazzy-libpointmatcher.patch @@ -0,0 +1,66 @@ +diff -ruN a/CMakeLists.txt b/CMakeLists.txt +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -126,9 +126,9 @@ + #-------------------- + # DEPENDENCY: boost + #-------------------- +-find_package(Boost REQUIRED COMPONENTS thread filesystem system program_options date_time) ++find_package(Boost REQUIRED COMPONENTS thread filesystem program_options date_time) + if (Boost_MINOR_VERSION GREATER 47) +- find_package(Boost REQUIRED COMPONENTS thread filesystem system program_options date_time chrono) ++ find_package(Boost REQUIRED COMPONENTS thread filesystem program_options date_time chrono) + endif () + + #-------------------- +diff -ruN a/libpointmatcherConfig.cmake.in b/libpointmatcherConfig.cmake.in +--- a/libpointmatcherConfig.cmake.in ++++ b/libpointmatcherConfig.cmake.in +@@ -6,9 +6,9 @@ + + include(CMakeFindDependencyMacro) + find_dependency(libnabo REQUIRED) +-find_package(Boost COMPONENTS thread filesystem system program_options date_time REQUIRED) ++find_package(Boost COMPONENTS thread filesystem program_options date_time REQUIRED) + if (Boost_MINOR_VERSION GREATER 47) +- find_package(Boost COMPONENTS thread filesystem system program_options date_time chrono REQUIRED) ++ find_package(Boost COMPONENTS thread filesystem program_options date_time chrono REQUIRED) + endif () + include(${CMAKE_CURRENT_LIST_DIR}/libpointmatcher-config.cmake) + +diff -ruN a/pointmatcher/IO.cpp b/pointmatcher/IO.cpp +--- a/pointmatcher/IO.cpp ++++ b/pointmatcher/IO.cpp +@@ -360,12 +360,12 @@ + if (!ifs.good() || !boost::filesystem::is_regular_file(fullPath)) + #if BOOST_FILESYSTEM_VERSION >= 3 + #if BOOST_VERSION >= 105000 +- throw runtime_error(string("Cannot open file ") + boost::filesystem::complete(fullPath).generic_string()); ++ throw runtime_error(string("Cannot open file ") + boost::filesystem::absolute(fullPath).generic_string()); + #else + throw runtime_error(string("Cannot open file ") + boost::filesystem3::complete(fullPath).generic_string()); + #endif + #else +- throw runtime_error(string("Cannot open file ") + boost::filesystem::complete(fullPath).native_file_string()); ++ throw runtime_error(string("Cannot open file ") + boost::filesystem::absolute(fullPath).string()); + #endif + } + +@@ -375,7 +375,7 @@ + typename PointMatcher::DataPoints PointMatcher::DataPoints::load(const std::string& fileName) + { + const boost::filesystem::path path(fileName); +- const string& ext(boost::filesystem::extension(path)); ++ const string ext(path.extension().string()); + if (boost::iequals(ext, ".vtk")) + return PointMatcherIO::loadVTK(fileName); + else if (boost::iequals(ext, ".csv")) +@@ -809,7 +809,7 @@ + void PointMatcher::DataPoints::save(const std::string& fileName, bool binary, unsigned precision) const + { + const boost::filesystem::path path(fileName); +- const string& ext(boost::filesystem::extension(path)); ++ const string ext(path.extension().string()); + if (boost::iequals(ext, ".vtk")) + return PointMatcherIO::saveVTK(*this, fileName, binary, precision); + diff --git a/patch/ros-jazzy-libpointmatcher.win.patch b/patch/ros-jazzy-libpointmatcher.win.patch new file mode 100644 index 000000000..88dde43e4 --- /dev/null +++ b/patch/ros-jazzy-libpointmatcher.win.patch @@ -0,0 +1,156 @@ +diff --git a/pointmatcher/Timer.h b/pointmatcher/Timer.h +index 316dbe2..ed85931 100644 +--- a/pointmatcher/Timer.h ++++ b/pointmatcher/Timer.h +@@ -74,10 +74,24 @@ namespace PointMatcherSupport + }; + } // namespace PointMatcherSupport + #else // _POSIX_TIMERS +-#include ++// boost::timer (v1) is deprecated and, as of Boost 1.90, ++// hard-errors unless BOOST_TIMER_ENABLE_DEPRECATED is defined. Avoid the ++// dependency entirely with a minimal std::chrono-based replacement that ++// keeps the same interface (default-construct starts, restart(), elapsed()). ++#include + namespace PointMatcherSupport + { +- typedef boost::timer timer; ++ struct timer ++ { ++ timer() { restart(); } ++ void restart() { _start = std::chrono::steady_clock::now(); } ++ double elapsed() const ++ { ++ return std::chrono::duration(std::chrono::steady_clock::now() - _start).count(); ++ } ++ private: ++ std::chrono::steady_clock::time_point _start; ++ }; + } + #endif // _POSIX_TIMERS + +diff --git a/pointmatcher/DataPointsFilters/utils/sparsetv.hpp b/pointmatcher/DataPointsFilters/utils/sparsetv.hpp +index b75e990..8f3fd48 100644 +--- a/pointmatcher/DataPointsFilters/utils/sparsetv.hpp ++++ b/pointmatcher/DataPointsFilters/utils/sparsetv.hpp +@@ -62,7 +62,7 @@ void TensorVoting::encode(const DP& pts, Encoding encoding) + case Encoding::ZERO: + { + #pragma omp parallel for +- for(std::size_t i = 0; i < nbPts; ++i) ++ for(std::ptrdiff_t i = 0; i < static_cast(nbPts); ++i) + tensors(i) = Tensor::Zero(); + break; + } +@@ -71,7 +71,7 @@ void TensorVoting::encode(const DP& pts, Encoding encoding) + case Encoding::BALL: + { + #pragma omp parallel for +- for(std::size_t i = 0; i < nbPts; ++i) ++ for(std::ptrdiff_t i = 0; i < static_cast(nbPts); ++i) + tensors(i) = Tensor::Identity(); + break; + } +@@ -83,7 +83,7 @@ void TensorVoting::encode(const DP& pts, Encoding encoding) + + const auto& balls_ = pts.getDescriptorViewByName("balls"); + #pragma omp parallel for +- for(std::size_t i = 0; i < nbPts; ++i) ++ for(std::ptrdiff_t i = 0; i < static_cast(nbPts); ++i) + tensors(i) = Tensor::Identity() * balls_(0,i); + + break; +@@ -92,7 +92,7 @@ void TensorVoting::encode(const DP& pts, Encoding encoding) + case Encoding::UPLATE: + { + #pragma omp parallel for +- for(std::size_t i = 0; i < nbPts; ++i) ++ for(std::ptrdiff_t i = 0; i < static_cast(nbPts); ++i) + tensors(i) << + 1., 0., 0., + 0., 1., 0., +@@ -108,7 +108,7 @@ void TensorVoting::encode(const DP& pts, Encoding encoding) + + const auto& plates_ = pts.getDescriptorViewByName("plates"); + #pragma omp parallel for +- for(std::size_t i = 0; i < nbPts; ++i) ++ for(std::ptrdiff_t i = 0; i < static_cast(nbPts); ++i) + { + const Vector3 n1 = plates_.col(i).segment(1,3); + const Vector3 n2 = plates_.col(i).tail(3); +@@ -121,7 +121,7 @@ void TensorVoting::encode(const DP& pts, Encoding encoding) + case Encoding::USTICK: + { + #pragma omp parallel for +- for(std::size_t i = 0; i < nbPts; ++i) ++ for(std::ptrdiff_t i = 0; i < static_cast(nbPts); ++i) + tensors(i) << + 1., 0., 0., + 0., 0., 0., +@@ -137,7 +137,7 @@ void TensorVoting::encode(const DP& pts, Encoding encoding) + + const auto& sticks_ = pts.getDescriptorViewByName("sticks"); + #pragma omp parallel for +- for(std::size_t i = 0; i < nbPts; ++i) ++ for(std::ptrdiff_t i = 0; i < static_cast(nbPts); ++i) + { + const Vector3 n = sticks_.col(i).tail(3); + tensors(i) = (encoding == Encoding::SSTICK ? sticks_(0,i) : 1.) * (n * n.transpose()); +@@ -157,7 +157,7 @@ void TensorVoting::encode(const DP& pts, Encoding encoding) + const auto& sticks_ = pts.getDescriptorViewByName("sticks"); + const auto& plates_ = pts.getDescriptorViewByName("plates"); + #pragma omp parallel for +- for(std::size_t i = 0; i < nbPts; ++i) ++ for(std::ptrdiff_t i = 0; i < static_cast(nbPts); ++i) + { + const Tensor S = sticks_.col(i).tail(3) * sticks_.col(i).tail(3).transpose(); + const Tensor P = plates_.col(i).segment(1,3) * plates_.col(i).segment(1,3).transpose() + plates_.col(i).tail(3) * plates_.col(i).tail(3).transpose(); +@@ -174,7 +174,7 @@ void TensorVoting::disableBallComponent() + { + const std::size_t nbPts = tensors.rows(); + #pragma omp parallel for +- for(std::size_t i = 0; i < nbPts; ++i) ++ for(std::ptrdiff_t i = 0; i < static_cast(nbPts); ++i) + { + const Tensor S = sticks.col(i).tail(3) * sticks.col(i).tail(3).transpose(); + const Tensor P = plates.col(i).segment(1,3) * plates.col(i).segment(1,3).transpose() + plates.col(i).tail(3) * plates.col(i).tail(3).transpose(); +@@ -388,7 +388,7 @@ void TensorVoting::cfvote(const DP& pts, bool doKnn) + encode(pts, Encoding::ZERO); //all tensors are zero + + #pragma omp parallel for +- for(std::size_t votee = 0; votee < nbPts; ++votee) //vote sites ++ for(std::ptrdiff_t votee = 0; votee < static_cast(nbPts); ++votee) //vote sites + { + const Vector3 x_i = pts.features.col(votee).head(3); + +@@ -433,7 +433,7 @@ void TensorVoting::decompose() + sparseBall.resize(nbPts); + + #pragma omp parallel for +- for(std::size_t i = 0; i < nbPts; ++i) ++ for(std::ptrdiff_t i = 0; i < static_cast(nbPts); ++i) + { + Eigen::SelfAdjointEigenSolver solver(tensors(i)); + +@@ -487,7 +487,7 @@ void TensorVoting::toDescriptors() + balls = PM::Matrix::Zero(1, nbPts); + + #pragma omp parallel for +- for(std::size_t i = 0; i < nbPts; i++) ++ for(std::ptrdiff_t i = 0; i < static_cast(nbPts); i++) + { + surfaceness(i) = sparseStick(i)(0) / k; + curveness(i) = sparsePlate(i)(0) / k; +diff --git a/pointmatcher/DataPointsFilters/SpectralDecomposition.cpp b/pointmatcher/DataPointsFilters/SpectralDecomposition.cpp +index cddcbbc..9a1100e 100644 +--- a/pointmatcher/DataPointsFilters/SpectralDecomposition.cpp ++++ b/pointmatcher/DataPointsFilters/SpectralDecomposition.cpp +@@ -143,7 +143,7 @@ void SpectralDecompositionDataPointsFilter::addDescriptor(DataPoints& pts, co + if(keepLabels_ or keepLambdas_) + { + #pragma omp parallel for +- for(std::size_t i = 0; i < nbPts; ++i) ++ for(std::ptrdiff_t i = 0; i < static_cast(nbPts); ++i) + { + const T lambda1 = tv.surfaceness(i) + tv.curveness(i) + tv.pointness(i); + const T lambda2 = tv.curveness(i) + tv.pointness(i); diff --git a/patch/ros-jazzy-moveit-ros-perception.patch b/patch/ros-jazzy-moveit-ros-perception.patch new file mode 100644 index 000000000..e9e0ae9c7 --- /dev/null +++ b/patch/ros-jazzy-moveit-ros-perception.patch @@ -0,0 +1,13 @@ +diff -ruN a/semantic_world/src/semantic_world.cpp b/semantic_world/src/semantic_world.cpp +--- a/semantic_world/src/semantic_world.cpp ++++ b/semantic_world/src/semantic_world.cpp +@@ -43,6 +43,9 @@ + #include + // OpenCV + #include ++#if CV_VERSION_MAJOR >= 5 ++#include ++#endif + #include + #include + #include diff --git a/patch/ros-jazzy-mrt-cmake-modules.patch b/patch/ros-jazzy-mrt-cmake-modules.patch index 3a58f235a..4cecdc60b 100644 --- a/patch/ros-jazzy-mrt-cmake-modules.patch +++ b/patch/ros-jazzy-mrt-cmake-modules.patch @@ -1,5 +1,17 @@ -diff --git a/cmake/Modules/FindBoostPython.cmake b/cmake/Modules/FindBoostPython.cmake -index 409cfaf..a3d9984 100644 +diff -ruN a/CMakeLists.txt b/CMakeLists.txt +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -1,7 +1,7 @@ +-cmake_minimum_required(VERSION 3.0.2) ++cmake_minimum_required(VERSION 3.5) + project(mrt_cmake_modules) + +-if($ENV{ROS_VERSION} EQUAL 1) ++if(2 EQUAL 1) + find_package(catkin REQUIRED) + catkin_package(CFG_EXTRAS mrt_cmake_modules-extras.cmake) + else() +diff -ruN a/cmake/Modules/FindBoostPython.cmake b/cmake/Modules/FindBoostPython.cmake --- a/cmake/Modules/FindBoostPython.cmake +++ b/cmake/Modules/FindBoostPython.cmake @@ -8,7 +8,7 @@ @@ -11,24 +23,10 @@ index 409cfaf..a3d9984 100644 endif() if(_python_version VERSION_EQUAL 3 AND CMAKE_VERSION VERSION_GREATER 3.15) # we also need the subversion -diff --git a/CMakeLists.txt b/CMakeLists.txt -index aa99d8d..8327d4e 100644 ---- a/CMakeLists.txt -+++ b/CMakeLists.txt -@@ -1,7 +1,7 @@ - cmake_minimum_required(VERSION 3.0.2) - project(mrt_cmake_modules) - --if($ENV{ROS_VERSION} EQUAL 1) -+if(2 EQUAL 1) - find_package(catkin REQUIRED) - catkin_package(CFG_EXTRAS mrt_cmake_modules-extras.cmake) - else() -diff --git a/yaml/cmake.yaml b/yaml/cmake.yaml -index 6a2a6dc..1846d27 100644 +diff -ruN a/yaml/cmake.yaml b/yaml/cmake.yaml --- a/yaml/cmake.yaml +++ b/yaml/cmake.yaml -@@ -19,7 +19,7 @@ benchmark: +@@ -19,7 +19,7 @@ targets: ['benchmark::benchmark'] boost: components: [wserialization thread random serialization log_setup prg_exec_monitor diff --git a/patch/ros-jazzy-osqp-vendor.patch b/patch/ros-jazzy-osqp-vendor.patch new file mode 100644 index 000000000..2fbaa2849 --- /dev/null +++ b/patch/ros-jazzy-osqp-vendor.patch @@ -0,0 +1,12 @@ +diff -ruN a/CMakeLists.txt b/CMakeLists.txt +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -13,6 +13,8 @@ + macro(build_osqp) + set(git_tag "v0.6.2") + set(extra_cmake_args) ++ # osqp v0.6.2 declares cmake_minimum_required < 3.5, rejected by CMake >= 4 ++ list(APPEND extra_cmake_args -DCMAKE_POLICY_VERSION_MINIMUM=3.5) + + get_property(multi_config GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) + if(NOT multi_config AND DEFINED CMAKE_BUILD_TYPE) diff --git a/patch/ros-jazzy-point-cloud-msg-wrapper.patch b/patch/ros-jazzy-point-cloud-msg-wrapper.patch new file mode 100644 index 000000000..a0b8eff09 --- /dev/null +++ b/patch/ros-jazzy-point-cloud-msg-wrapper.patch @@ -0,0 +1,23 @@ +diff --git a/include/point_cloud_msg_wrapper/point_cloud_msg_wrapper.hpp b/include/point_cloud_msg_wrapper/point_cloud_msg_wrapper.hpp +index 3768346..db9e048 100644 +--- a/include/point_cloud_msg_wrapper/point_cloud_msg_wrapper.hpp ++++ b/include/point_cloud_msg_wrapper/point_cloud_msg_wrapper.hpp +@@ -24,7 +24,7 @@ + #include + #include + +-#include ++#include + #include + + #include +@@ -223,7 +223,7 @@ public: + { + const auto find_missing_field = []( + const auto & query_fields, +- const auto & source_fields) -> std::experimental::optional { ++ const auto & source_fields) -> std::optional { + for (const auto & query_field : query_fields) { + // Note that we use find on a vector here. This is intended. The number of fields is + // usually very limited, so the O(n^2) complexity is ok here. This operation also only + diff --git a/patch/ros-jazzy-proxsuite.patch b/patch/ros-jazzy-proxsuite.patch new file mode 100644 index 000000000..2c6f55366 --- /dev/null +++ b/patch/ros-jazzy-proxsuite.patch @@ -0,0 +1,37 @@ +diff -ruN --exclude=.git a/test/CMakeLists.txt b/test/CMakeLists.txt +--- a/test/CMakeLists.txt ++++ b/test/CMakeLists.txt +@@ -1,5 +1,7 @@ + include(../cmake-external/doctest.cmake) +-find_package(Matio REQUIRED) ++# Matio is not packaged for this build; only the maros_meszaros benchmark ++# tests need it, so make it optional instead of hard-requiring it. ++find_package(Matio QUIET) + + add_library(${PROJECT_NAME}-doctest STATIC doctest/doctest.cpp) + target_include_directories(${PROJECT_NAME}-doctest PUBLIC ./doctest) +@@ -19,10 +21,13 @@ + ) + target_include_directories(proxsuite-test-util PUBLIC ./include) + if(BUILD_WITH_VECTORIZATION_SUPPORT) +- target_link_libraries(proxsuite-test-util proxsuite-vectorized matio) ++ target_link_libraries(proxsuite-test-util proxsuite-vectorized) + else() +- target_link_libraries(proxsuite-test-util proxsuite matio) ++ target_link_libraries(proxsuite-test-util proxsuite) + endif() ++if(MATIO_FOUND) ++ target_link_libraries(proxsuite-test-util matio) ++endif() + + macro(proxsuite_test name path) + set(target_name ${PROJECT_NAME}-test-cpp-${name}) +@@ -85,7 +90,7 @@ + ) + endif() + +-if(NOT CMAKE_BUILD_TYPE STREQUAL "Debug" AND NOT MSVC) ++if(NOT CMAKE_BUILD_TYPE STREQUAL "Debug" AND NOT MSVC AND MATIO_FOUND) + proxsuite_test(dense_maros_meszaros src/dense_maros_meszaros.cpp) + proxsuite_test(sparse_maros_meszaros src/sparse_maros_meszaros.cpp) + endif() diff --git a/patch/ros-jazzy-robot-localization.win.patch b/patch/ros-jazzy-robot-localization.win.patch index 478e6e5e3..54ada1b87 100644 --- a/patch/ros-jazzy-robot-localization.win.patch +++ b/patch/ros-jazzy-robot-localization.win.patch @@ -2,6 +2,19 @@ diff --git a/CMakeLists.txt b/CMakeLists.txt index 0da52adc..35b5b185 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt +@@ -6,6 +6,12 @@ + if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") + add_compile_options(-Wall -Wextra -Wpedantic) + endif() + ++# ros_filter.cpp's object file exceeds MSVC's default section-count limit ++# due to heavy Eigen template instantiation. ++if(MSVC) ++ add_compile_options(/bigobj) ++endif() ++ + if(NOT CMAKE_CONFIGURATION_TYPES AND NOT CMAKE_BUILD_TYPE) + message(STATUS "${PROJECT_NAME}: You did not request a specific build type: selecting 'RelWithDebInfo'.") @@ -100,6 +100,8 @@ target_link_libraries(${library_name} PRIVATE ${GeographicLib_LIBRARIES} yaml-cpp::yaml-cpp diff --git a/patch/ros-jazzy-ros-gz-bridge.win.patch b/patch/ros-jazzy-ros-gz-bridge.win.patch index 3d5c60fcc..7c52723cd 100644 --- a/patch/ros-jazzy-ros-gz-bridge.win.patch +++ b/patch/ros-jazzy-ros-gz-bridge.win.patch @@ -1,12 +1,1370 @@ diff --git a/CMakeLists.txt b/CMakeLists.txt -index 44911577..76779457 100644 +index 03e3d83..f8db5fc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt -@@ -11,4 +11,7 @@ if(NOT CMAKE_CXX_STANDARD) +@@ -8,8 +8,19 @@ if(NOT CMAKE_CXX_STANDARD) + endif() + if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wpedantic") +elseif(MSVC) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /bigobj") endif() -+set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON) ++# The shared Windows ament_cmake build script passes ++# -DCMAKE_WINDOWS_EXPORT_ALL_SYMBOLS=ON as a cache default for every ++# package, which would otherwise silently re-enable blanket symbol ++# export and reintroduce the original LNK1189 problem -- explicitly ++# override it back to OFF so the GenerateExportHeader-based approach ++# below (which relies on only ROS_GZ_BRIDGE_VISIBLE-marked symbols ++# being exported) actually takes effect. ++set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS OFF) ++ find_package(ament_cmake REQUIRED) find_package(rclcpp REQUIRED) + find_package(rclcpp_components REQUIRED) +@@ -98,6 +109,13 @@ add_library(${bridge_lib} + ${generated_files} + ) + ++include(GenerateExportHeader) ++generate_export_header(${bridge_lib} ++ EXPORT_FILE_NAME ++ "${CMAKE_CURRENT_BINARY_DIR}/include/${PROJECT_NAME}/visibility_control.hpp" ++ EXPORT_MACRO_NAME ROS_GZ_BRIDGE_VISIBLE ++) ++ + target_link_libraries(${bridge_lib} + PUBLIC + gz-msgs::core +@@ -116,12 +134,18 @@ ament_target_dependencies(${bridge_lib} + target_include_directories(${bridge_lib} + PUBLIC + "$" ++ "$" + "$" + PRIVATE + "$" + "$" + ) + ++# Many tests do not link ${bridge_lib} even if they include its headers, ++# ensure that ${CMAKE_CURRENT_BINARY_DIR}/include that includes the visibility_control.hpp header ++# is properly visible ++include_directories(${CMAKE_CURRENT_BINARY_DIR}/include) ++ + rclcpp_components_register_node( + ${bridge_lib} + PLUGIN ros_gz_bridge::RosGzBridge +@@ -137,6 +161,11 @@ install( + DESTINATION include/${PROJECT_NAME} + ) + ++install( ++ FILES "${CMAKE_CURRENT_BINARY_DIR}/include/${PROJECT_NAME}/visibility_control.hpp" ++ DESTINATION include/${PROJECT_NAME}/${PROJECT_NAME} ++) ++ + install( + DIRECTORY launch/ + DESTINATION share/${PROJECT_NAME}/launch +diff --git a/include/ros_gz_bridge/bridge_config.hpp b/include/ros_gz_bridge/bridge_config.hpp +index 086f1b3..b54faab 100644 +--- a/include/ros_gz_bridge/bridge_config.hpp ++++ b/include/ros_gz_bridge/bridge_config.hpp +@@ -21,6 +21,8 @@ + + #include + ++#include "ros_gz_bridge/visibility_control.hpp" ++ + namespace ros_gz_bridge + { + +@@ -49,9 +51,9 @@ static constexpr BridgeDirection kDefaultDirection = BridgeDirection::BIDIRECTIO + /// \param[in] qos_profile Uppercase string, e.g. "SENSOR_DATA". + /// \return The corresponding QoS profile. + /// \throws std::invalid_argument if the profile cannot be parsed. +-rclcpp::QoS parseQoS(const std::string & qos_profile); ++ROS_GZ_BRIDGE_VISIBLE rclcpp::QoS parseQoS(const std::string & qos_profile); + +-struct BridgeConfig ++struct ROS_GZ_BRIDGE_VISIBLE BridgeConfig + { + /// \brief The ROS message type (eg std_msgs/msg/String) + std::string ros_type_name; +@@ -104,12 +106,12 @@ struct BridgeConfig + /// \brief Generate a group of BridgeConfigs from a YAML String + /// \param[in] data string containing YAML of bridge configurations + /// \return Vector of bridge configurations +-std::vector readFromYamlString(const std::string & data); ++ROS_GZ_BRIDGE_VISIBLE std::vector readFromYamlString(const std::string & data); + + /// \brief Generate a group of BridgeConfigs from a YAML File + /// \param[in] filename name of file containing YAML of bridge configurations + /// \return Vector of bridge configurations +-std::vector readFromYamlFile(const std::string & filename); ++ROS_GZ_BRIDGE_VISIBLE std::vector readFromYamlFile(const std::string & filename); + + } // namespace ros_gz_bridge + +diff --git a/include/ros_gz_bridge/convert/actuator_msgs.hpp b/include/ros_gz_bridge/convert/actuator_msgs.hpp +index ea4055b..14d27d6 100644 +--- a/include/ros_gz_bridge/convert/actuator_msgs.hpp ++++ b/include/ros_gz_bridge/convert/actuator_msgs.hpp +@@ -27,13 +27,13 @@ namespace ros_gz_bridge + { + // actuator_msgs + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_ros_to_gz( + const actuator_msgs::msg::Actuators & ros_msg, + gz::msgs::Actuators & gz_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_gz_to_ros( + const gz::msgs::Actuators & gz_msg, + actuator_msgs::msg::Actuators & ros_msg); +diff --git a/include/ros_gz_bridge/convert/builtin_interfaces.hpp b/include/ros_gz_bridge/convert/builtin_interfaces.hpp +index 04c47ba..c2c06ca 100644 +--- a/include/ros_gz_bridge/convert/builtin_interfaces.hpp ++++ b/include/ros_gz_bridge/convert/builtin_interfaces.hpp +@@ -25,13 +25,13 @@ namespace ros_gz_bridge + { + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_ros_to_gz( + const builtin_interfaces::msg::Time & ros_msg, + gz::msgs::Time & gz_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_gz_to_ros( + const gz::msgs::Time & gz_msg, + builtin_interfaces::msg::Time & ros_msg); +diff --git a/include/ros_gz_bridge/convert/geometry_msgs.hpp b/include/ros_gz_bridge/convert/geometry_msgs.hpp +index 6416fa3..960cb20 100644 +--- a/include/ros_gz_bridge/convert/geometry_msgs.hpp ++++ b/include/ros_gz_bridge/convert/geometry_msgs.hpp +@@ -48,193 +48,193 @@ namespace ros_gz_bridge + + // geometry_msgs + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_ros_to_gz( + const geometry_msgs::msg::Quaternion & ros_msg, + gz::msgs::Quaternion & gz_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_gz_to_ros( + const gz::msgs::Quaternion & gz_msg, + geometry_msgs::msg::Quaternion & ros_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_ros_to_gz( + const geometry_msgs::msg::Vector3 & ros_msg, + gz::msgs::Vector3d & gz_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_gz_to_ros( + const gz::msgs::Vector3d & gz_msg, + geometry_msgs::msg::Vector3 & ros_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_ros_to_gz( + const geometry_msgs::msg::Point & ros_msg, + gz::msgs::Vector3d & gz_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_gz_to_ros( + const gz::msgs::Vector3d & gz_msg, + geometry_msgs::msg::Point & ros_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_ros_to_gz( + const geometry_msgs::msg::Pose & ros_msg, + gz::msgs::Pose & gz_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_gz_to_ros( + const gz::msgs::Pose & gz_msg, + geometry_msgs::msg::Pose & ros_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_ros_to_gz( + const geometry_msgs::msg::PoseArray & ros_msg, + gz::msgs::Pose_V & gz_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_gz_to_ros( + const gz::msgs::Pose_V & gz_msg, + geometry_msgs::msg::PoseArray & ros_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_ros_to_gz( + const geometry_msgs::msg::PoseWithCovariance & ros_msg, + gz::msgs::PoseWithCovariance & gz_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_gz_to_ros( + const gz::msgs::PoseWithCovariance & gz_msg, + geometry_msgs::msg::PoseWithCovarianceStamped & ros_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_ros_to_gz( + const geometry_msgs::msg::PoseWithCovarianceStamped & ros_msg, + gz::msgs::PoseWithCovariance & gz_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_gz_to_ros( + const gz::msgs::PoseWithCovariance & gz_msg, + geometry_msgs::msg::PoseWithCovariance & ros_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_ros_to_gz( + const geometry_msgs::msg::PoseStamped & ros_msg, + gz::msgs::Pose & gz_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_gz_to_ros( + const gz::msgs::Pose & gz_msg, + geometry_msgs::msg::PoseStamped & ros_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_ros_to_gz( + const geometry_msgs::msg::Transform & ros_msg, + gz::msgs::Pose & gz_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_gz_to_ros( + const gz::msgs::Pose & gz_msg, + geometry_msgs::msg::Transform & ros_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_ros_to_gz( + const geometry_msgs::msg::TransformStamped & ros_msg, + gz::msgs::Pose & gz_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_gz_to_ros( + const gz::msgs::Pose & gz_msg, + geometry_msgs::msg::TransformStamped & ros_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_ros_to_gz( + const geometry_msgs::msg::Twist & ros_msg, + gz::msgs::Twist & gz_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_gz_to_ros( + const gz::msgs::Twist & gz_msg, + geometry_msgs::msg::Twist & ros_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_ros_to_gz( + const geometry_msgs::msg::TwistStamped & ros_msg, + gz::msgs::Twist & gz_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_gz_to_ros( + const gz::msgs::Twist & gz_msg, + geometry_msgs::msg::TwistStamped & ros_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_ros_to_gz( + const geometry_msgs::msg::TwistWithCovariance & ros_msg, + gz::msgs::TwistWithCovariance & gz_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_gz_to_ros( + const gz::msgs::TwistWithCovariance & gz_msg, + geometry_msgs::msg::TwistWithCovariance & ros_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_ros_to_gz( + const geometry_msgs::msg::TwistWithCovarianceStamped & ros_msg, + gz::msgs::TwistWithCovariance & gz_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_gz_to_ros( + const gz::msgs::TwistWithCovariance & gz_msg, + geometry_msgs::msg::TwistWithCovarianceStamped & ros_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_ros_to_gz( + const geometry_msgs::msg::Wrench & ros_msg, + gz::msgs::Wrench & gz_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_gz_to_ros( + const gz::msgs::Wrench & gz_msg, + geometry_msgs::msg::Wrench & ros_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_ros_to_gz( + const geometry_msgs::msg::WrenchStamped & ros_msg, + gz::msgs::Wrench & gz_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_gz_to_ros( + const gz::msgs::Wrench & gz_msg, + geometry_msgs::msg::WrenchStamped & ros_msg); +diff --git a/include/ros_gz_bridge/convert/gps_msgs.hpp b/include/ros_gz_bridge/convert/gps_msgs.hpp +index d6cf194..fda4568 100644 +--- a/include/ros_gz_bridge/convert/gps_msgs.hpp ++++ b/include/ros_gz_bridge/convert/gps_msgs.hpp +@@ -26,13 +26,13 @@ + namespace ros_gz_bridge + { + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_ros_to_gz( + const gps_msgs::msg::GPSFix & ros_msg, + gz::msgs::NavSat & gz_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_gz_to_ros( + const gz::msgs::NavSat & gz_msg, + gps_msgs::msg::GPSFix & ros_msg); +diff --git a/include/ros_gz_bridge/convert/marine_acoustic_msgs.hpp b/include/ros_gz_bridge/convert/marine_acoustic_msgs.hpp +index ed46e87..f796435 100644 +--- a/include/ros_gz_bridge/convert/marine_acoustic_msgs.hpp ++++ b/include/ros_gz_bridge/convert/marine_acoustic_msgs.hpp +@@ -27,13 +27,13 @@ namespace ros_gz_bridge + { + // marine_acoustic_msgs + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_ros_to_gz( + const marine_acoustic_msgs::msg::Dvl & ros_msg, + gz::msgs::DVLVelocityTracking & gz_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_gz_to_ros( + const gz::msgs::DVLVelocityTracking & gz_msg, + marine_acoustic_msgs::msg::Dvl & ros_msg); +diff --git a/include/ros_gz_bridge/convert/nav_msgs.hpp b/include/ros_gz_bridge/convert/nav_msgs.hpp +index 91c0f1a..fad3eb3 100644 +--- a/include/ros_gz_bridge/convert/nav_msgs.hpp ++++ b/include/ros_gz_bridge/convert/nav_msgs.hpp +@@ -28,25 +28,25 @@ namespace ros_gz_bridge + { + // nav_msgs + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_ros_to_gz( + const nav_msgs::msg::Odometry & ros_msg, + gz::msgs::Odometry & gz_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_gz_to_ros( + const gz::msgs::Odometry & gz_msg, + nav_msgs::msg::Odometry & ros_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_ros_to_gz( + const nav_msgs::msg::Odometry & ros_msg, + gz::msgs::OdometryWithCovariance & gz_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_gz_to_ros( + const gz::msgs::OdometryWithCovariance & gz_msg, + nav_msgs::msg::Odometry & ros_msg); +diff --git a/include/ros_gz_bridge/convert/rcl_interfaces.hpp b/include/ros_gz_bridge/convert/rcl_interfaces.hpp +index a81e35a..b7c359d 100644 +--- a/include/ros_gz_bridge/convert/rcl_interfaces.hpp ++++ b/include/ros_gz_bridge/convert/rcl_interfaces.hpp +@@ -29,13 +29,13 @@ namespace ros_gz_bridge + { + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_ros_to_gz( + const rcl_interfaces::msg::ParameterValue & ros_msg, + gz::msgs::Any & ign_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_gz_to_ros( + const gz::msgs::Any & ign_msg, + rcl_interfaces::msg::ParameterValue & ros_msg); +diff --git a/include/ros_gz_bridge/convert/ros_gz_interfaces.hpp b/include/ros_gz_bridge/convert/ros_gz_interfaces.hpp +index 65f58fa..654f013 100644 +--- a/include/ros_gz_bridge/convert/ros_gz_interfaces.hpp ++++ b/include/ros_gz_bridge/convert/ros_gz_interfaces.hpp +@@ -70,284 +70,284 @@ namespace ros_gz_bridge + { + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_ros_to_gz( + const ros_gz_interfaces::msg::JointWrench & ros_msg, + gz::msgs::JointWrench & gz_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_gz_to_ros( + const gz::msgs::JointWrench & gz_msg, + ros_gz_interfaces::msg::JointWrench & ros_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_ros_to_gz( + const ros_gz_interfaces::msg::Altimeter & ros_msg, + gz::msgs::Altimeter & gz_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_gz_to_ros( + const gz::msgs::Altimeter & gz_msg, + ros_gz_interfaces::msg::Altimeter & ros_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_ros_to_gz( + const ros_gz_interfaces::msg::Entity & ros_msg, + gz::msgs::Entity & gz_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_ros_to_gz( + const ros_gz_interfaces::msg::Entity & ros_msg, + gz::msgs::Pose & gz_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_gz_to_ros( + const gz::msgs::Entity & gz_msg, + ros_gz_interfaces::msg::Entity & ros_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_ros_to_gz( + const ros_gz_interfaces::msg::EntityFactory & ros_msg, + gz::msgs::EntityFactory & gz_msg); + + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_gz_to_ros( + const gz::msgs::EntityFactory & gz_msg, + ros_gz_interfaces::msg::EntityFactory & ros_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_ros_to_gz( + const ros_gz_interfaces::msg::EntityWrench & ros_msg, + gz::msgs::EntityWrench & gz_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_gz_to_ros( + const gz::msgs::EntityWrench & gz_msg, + ros_gz_interfaces::msg::EntityWrench & ros_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_ros_to_gz( + const ros_gz_interfaces::msg::Contact & ros_msg, + gz::msgs::Contact & gz_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_gz_to_ros( + const gz::msgs::Contact & gz_msg, + ros_gz_interfaces::msg::Contact & ros_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_ros_to_gz( + const ros_gz_interfaces::msg::Contacts & ros_msg, + gz::msgs::Contacts & gz_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_gz_to_ros( + const gz::msgs::Contacts & gz_msg, + ros_gz_interfaces::msg::Contacts & ros_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_ros_to_gz( + const ros_gz_interfaces::msg::Dataframe & ros_msg, + gz::msgs::Dataframe & ign_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_gz_to_ros( + const gz::msgs::Dataframe & ign_msg, + ros_gz_interfaces::msg::Dataframe & ros_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_ros_to_gz( + const ros_gz_interfaces::msg::GuiCamera & ros_msg, + gz::msgs::GUICamera & gz_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_gz_to_ros( + const gz::msgs::GUICamera & gz_msg, + ros_gz_interfaces::msg::GuiCamera & ros_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_ros_to_gz( + const ros_gz_interfaces::msg::Light & ros_msg, + gz::msgs::Light & gz_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_gz_to_ros( + const gz::msgs::Light & gz_msg, + ros_gz_interfaces::msg::Light & ros_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_ros_to_gz( + const ros_gz_interfaces::msg::MaterialColor & ros_msg, + gz::msgs::MaterialColor & gz_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_gz_to_ros( + const gz::msgs::MaterialColor & gz_msg, + ros_gz_interfaces::msg::MaterialColor & ros_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_ros_to_gz( + const ros_gz_interfaces::msg::SensorNoise & ros_msg, + gz::msgs::SensorNoise & gz_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_gz_to_ros( + const gz::msgs::SensorNoise & gz_msg, + ros_gz_interfaces::msg::SensorNoise & ros_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_ros_to_gz( + const ros_gz_interfaces::msg::StringVec & ros_msg, + gz::msgs::StringMsg_V & gz_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_gz_to_ros( + const gz::msgs::StringMsg_V & gz_msg, + ros_gz_interfaces::msg::StringVec & ros_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_ros_to_gz( + const ros_gz_interfaces::msg::ParamVec & ros_msg, + gz::msgs::Param & gz_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_gz_to_ros( + const gz::msgs::Param & gz_msg, + ros_gz_interfaces::msg::ParamVec & ros_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_ros_to_gz( + const ros_gz_interfaces::msg::ParamVec & ros_msg, + gz::msgs::Param_V & gz_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_gz_to_ros( + const gz::msgs::Param_V & gz_msg, + ros_gz_interfaces::msg::ParamVec & ros_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_ros_to_gz( + const ros_gz_interfaces::msg::TrackVisual & ros_msg, + gz::msgs::TrackVisual & gz_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_gz_to_ros( + const gz::msgs::TrackVisual & gz_msg, + ros_gz_interfaces::msg::TrackVisual & ros_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_ros_to_gz( + const ros_gz_interfaces::msg::VideoRecord & ros_msg, + gz::msgs::VideoRecord & gz_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_gz_to_ros( + const gz::msgs::VideoRecord & gz_msg, + ros_gz_interfaces::msg::VideoRecord & ros_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_ros_to_gz( + const ros_gz_interfaces::msg::WorldControl & ros_msg, + gz::msgs::WorldControl & gz_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_gz_to_ros( + const gz::msgs::WorldControl & gz_msg, + ros_gz_interfaces::msg::WorldControl & ros_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_ros_to_gz( + const ros_gz_interfaces::msg::WorldReset & ros_msg, + gz::msgs::WorldReset & gz_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_gz_to_ros( + const gz::msgs::WorldReset & gz_msg, + ros_gz_interfaces::msg::WorldReset & ros_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_gz_to_ros( + const gz::msgs::WorldStatistics & gz_msg, + ros_gz_interfaces::msg::WorldStatistics & ros_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_ros_to_gz( + const ros_gz_interfaces::msg::WorldStatistics & ros_msg, + gz::msgs::WorldStatistics & gz_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_ros_to_gz( + const ros_gz_interfaces::msg::Float32Array & ros_msg, + gz::msgs::Float_V & gz_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_gz_to_ros( + const gz::msgs::Float_V & gz_msg, + ros_gz_interfaces::msg::Float32Array & ros_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_ros_to_gz( + const ros_gz_interfaces::msg::LogicalCameraImage & ros_msg, + gz::msgs::LogicalCameraImage & gz_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_gz_to_ros( + const gz::msgs::LogicalCameraImage & gz_msg, + ros_gz_interfaces::msg::LogicalCameraImage & ros_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_ros_to_gz( + const ros_gz_interfaces::msg::LogPlaybackStatistics & ros_msg, + gz::msgs::LogPlaybackStatistics & gz_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_gz_to_ros( + const gz::msgs::LogPlaybackStatistics & gz_msg, + ros_gz_interfaces::msg::LogPlaybackStatistics & ros_msg); +diff --git a/include/ros_gz_bridge/convert/rosgraph_msgs.hpp b/include/ros_gz_bridge/convert/rosgraph_msgs.hpp +index d4d7d51..e8f6af8 100644 +--- a/include/ros_gz_bridge/convert/rosgraph_msgs.hpp ++++ b/include/ros_gz_bridge/convert/rosgraph_msgs.hpp +@@ -27,13 +27,13 @@ namespace ros_gz_bridge + { + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_gz_to_ros( + const gz::msgs::Clock & gz_msg, + rosgraph_msgs::msg::Clock & ros_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_ros_to_gz( + const rosgraph_msgs::msg::Clock & ros_msg, + gz::msgs::Clock & gz_msg); +diff --git a/include/ros_gz_bridge/convert/sensor_msgs.hpp b/include/ros_gz_bridge/convert/sensor_msgs.hpp +index 53fc1bc..a1410f7 100644 +--- a/include/ros_gz_bridge/convert/sensor_msgs.hpp ++++ b/include/ros_gz_bridge/convert/sensor_msgs.hpp +@@ -49,133 +49,133 @@ namespace ros_gz_bridge + + // sensor_msgs + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_ros_to_gz( + const sensor_msgs::msg::Joy & ros_msg, + gz::msgs::Joy & gz_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_gz_to_ros( + const gz::msgs::Joy & gz_msg, + sensor_msgs::msg::Joy & ros_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_ros_to_gz( + const sensor_msgs::msg::FluidPressure & ros_msg, + gz::msgs::FluidPressure & gz_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_gz_to_ros( + const gz::msgs::FluidPressure & gz_msg, + sensor_msgs::msg::FluidPressure & ros_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_ros_to_gz( + const sensor_msgs::msg::Image & ros_msg, + gz::msgs::Image & gz_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_gz_to_ros( + const gz::msgs::Image & gz_msg, + sensor_msgs::msg::Image & ros_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_ros_to_gz( + const sensor_msgs::msg::CameraInfo & ros_msg, + gz::msgs::CameraInfo & gz_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_gz_to_ros( + const gz::msgs::CameraInfo & gz_msg, + sensor_msgs::msg::CameraInfo & ros_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_ros_to_gz( + const sensor_msgs::msg::Imu & ros_msg, + gz::msgs::IMU & gz_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_gz_to_ros( + const gz::msgs::IMU & gz_msg, + sensor_msgs::msg::Imu & ros_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_ros_to_gz( + const sensor_msgs::msg::JointState & ros_msg, + gz::msgs::Model & gz_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_gz_to_ros( + const gz::msgs::Model & gz_msg, + sensor_msgs::msg::JointState & ros_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_ros_to_gz( + const sensor_msgs::msg::LaserScan & ros_msg, + gz::msgs::LaserScan & gz_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_gz_to_ros( + const gz::msgs::LaserScan & gz_msg, + sensor_msgs::msg::LaserScan & ros_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_ros_to_gz( + const sensor_msgs::msg::MagneticField & ros_msg, + gz::msgs::Magnetometer & gz_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_gz_to_ros( + const gz::msgs::Magnetometer & gz_msg, + sensor_msgs::msg::MagneticField & ros_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_ros_to_gz( + const sensor_msgs::msg::NavSatFix & ros_msg, + gz::msgs::NavSat & gz_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_gz_to_ros( + const gz::msgs::NavSat & gz_msg, + sensor_msgs::msg::NavSatFix & ros_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_ros_to_gz( + const sensor_msgs::msg::PointCloud2 & ros_msg, + gz::msgs::PointCloudPacked & gz_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_gz_to_ros( + const gz::msgs::PointCloudPacked & gz_msg, + sensor_msgs::msg::PointCloud2 & ros_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_ros_to_gz( + const sensor_msgs::msg::BatteryState & ros_msg, + gz::msgs::BatteryState & gz_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_gz_to_ros( + const gz::msgs::BatteryState & gz_msg, + sensor_msgs::msg::BatteryState & ros_msg); +diff --git a/include/ros_gz_bridge/convert/std_msgs.hpp b/include/ros_gz_bridge/convert/std_msgs.hpp +index 78d3f11..652c4f9 100644 +--- a/include/ros_gz_bridge/convert/std_msgs.hpp ++++ b/include/ros_gz_bridge/convert/std_msgs.hpp +@@ -43,109 +43,109 @@ namespace ros_gz_bridge + { + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_ros_to_gz( + const std_msgs::msg::Bool & ros_msg, + gz::msgs::Boolean & gz_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_gz_to_ros( + const gz::msgs::Boolean & gz_msg, + std_msgs::msg::Bool & ros_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_ros_to_gz( + const std_msgs::msg::ColorRGBA & ros_msg, + gz::msgs::Color & gz_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_gz_to_ros( + const gz::msgs::Color & gz_msg, + std_msgs::msg::ColorRGBA & ros_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_ros_to_gz( + const std_msgs::msg::Empty & ros_msg, + gz::msgs::Empty & gz_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_gz_to_ros( + const gz::msgs::Empty & gz_msg, + std_msgs::msg::Empty & ros_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_ros_to_gz( + const std_msgs::msg::UInt32 & ros_msg, + gz::msgs::UInt32 & gz_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_gz_to_ros( + const gz::msgs::UInt32 & gz_msg, + std_msgs::msg::UInt32 & ros_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_ros_to_gz( + const std_msgs::msg::Float32 & ros_msg, + gz::msgs::Float & gz_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_gz_to_ros( + const gz::msgs::Float & gz_msg, + std_msgs::msg::Float32 & ros_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_ros_to_gz( + const std_msgs::msg::Float64 & ros_msg, + gz::msgs::Double & gz_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_gz_to_ros( + const gz::msgs::Double & gz_msg, + std_msgs::msg::Float64 & ros_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_ros_to_gz( + const std_msgs::msg::Header & ros_msg, + gz::msgs::Header & gz_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_gz_to_ros( + const gz::msgs::Header & gz_msg, + std_msgs::msg::Header & ros_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_ros_to_gz( + const std_msgs::msg::Int32 & ros_msg, + gz::msgs::Int32 & gz_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_gz_to_ros( + const gz::msgs::Int32 & gz_msg, + std_msgs::msg::Int32 & ros_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_ros_to_gz( + const std_msgs::msg::String & ros_msg, + gz::msgs::StringMsg & gz_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_gz_to_ros( + const gz::msgs::StringMsg & gz_msg, + std_msgs::msg::String & ros_msg); +diff --git a/include/ros_gz_bridge/convert/tf2_msgs.hpp b/include/ros_gz_bridge/convert/tf2_msgs.hpp +index a7df9e0..64f852e 100644 +--- a/include/ros_gz_bridge/convert/tf2_msgs.hpp ++++ b/include/ros_gz_bridge/convert/tf2_msgs.hpp +@@ -27,13 +27,13 @@ namespace ros_gz_bridge + { + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_ros_to_gz( + const tf2_msgs::msg::TFMessage & ros_msg, + gz::msgs::Pose_V & gz_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_gz_to_ros( + const gz::msgs::Pose_V & gz_msg, + tf2_msgs::msg::TFMessage & ros_msg); +diff --git a/include/ros_gz_bridge/convert/trajectory_msgs.hpp b/include/ros_gz_bridge/convert/trajectory_msgs.hpp +index d2120db..4d575d6 100644 +--- a/include/ros_gz_bridge/convert/trajectory_msgs.hpp ++++ b/include/ros_gz_bridge/convert/trajectory_msgs.hpp +@@ -27,25 +27,25 @@ namespace ros_gz_bridge + { + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_ros_to_gz( + const trajectory_msgs::msg::JointTrajectoryPoint & ros_msg, + gz::msgs::JointTrajectoryPoint & gz_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_gz_to_ros( + const gz::msgs::JointTrajectoryPoint & gz_msg, + trajectory_msgs::msg::JointTrajectoryPoint & ros_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_ros_to_gz( + const trajectory_msgs::msg::JointTrajectory & ros_msg, + gz::msgs::JointTrajectory & gz_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_gz_to_ros( + const gz::msgs::JointTrajectory & gz_msg, + trajectory_msgs::msg::JointTrajectory & ros_msg); +diff --git a/include/ros_gz_bridge/convert/vision_msgs.hpp b/include/ros_gz_bridge/convert/vision_msgs.hpp +index b1556f6..4e0c8a2 100644 +--- a/include/ros_gz_bridge/convert/vision_msgs.hpp ++++ b/include/ros_gz_bridge/convert/vision_msgs.hpp +@@ -27,49 +27,49 @@ + namespace ros_gz_bridge + { + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_ros_to_gz( + const vision_msgs::msg::Detection2D & ros_msg, + gz::msgs::AnnotatedAxisAligned2DBox & gz_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_gz_to_ros( + const gz::msgs::AnnotatedAxisAligned2DBox & gz_msg, + vision_msgs::msg::Detection2D & ros_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_ros_to_gz( + const vision_msgs::msg::Detection2DArray & ros_msg, + gz::msgs::AnnotatedAxisAligned2DBox_V & gz_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_gz_to_ros( + const gz::msgs::AnnotatedAxisAligned2DBox_V & gz_msg, + vision_msgs::msg::Detection2DArray & ros_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_ros_to_gz( + const vision_msgs::msg::Detection3D & ros_msg, + gz::msgs::AnnotatedOriented3DBox & gz_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_gz_to_ros( + const gz::msgs::AnnotatedOriented3DBox & gz_msg, + vision_msgs::msg::Detection3D & ros_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_ros_to_gz( + const vision_msgs::msg::Detection3DArray & ros_msg, + gz::msgs::AnnotatedOriented3DBox_V & gz_msg); + + template<> +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_gz_to_ros( + const gz::msgs::AnnotatedOriented3DBox_V & gz_msg, + vision_msgs::msg::Detection3DArray & ros_msg); +diff --git a/include/ros_gz_bridge/convert_decl.hpp b/include/ros_gz_bridge/convert_decl.hpp +index 3141997..5d2ca98 100644 +--- a/include/ros_gz_bridge/convert_decl.hpp ++++ b/include/ros_gz_bridge/convert_decl.hpp +@@ -15,17 +15,19 @@ + #ifndef ROS_GZ_BRIDGE__CONVERT_DECL_HPP_ + #define ROS_GZ_BRIDGE__CONVERT_DECL_HPP_ + ++#include "ros_gz_bridge/visibility_control.hpp" ++ + namespace ros_gz_bridge + { + + template +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_ros_to_gz( + const ROS_T & ros_msg, + GZ_T & gz_msg); + + template +-void ++ROS_GZ_BRIDGE_VISIBLE void + convert_gz_to_ros( + const GZ_T & gz_msg, + ROS_T & ros_msg); +diff --git a/include/ros_gz_bridge/ros_gz_bridge.hpp b/include/ros_gz_bridge/ros_gz_bridge.hpp +index 735cdec..3ec0dce 100644 +--- a/include/ros_gz_bridge/ros_gz_bridge.hpp ++++ b/include/ros_gz_bridge/ros_gz_bridge.hpp +@@ -23,6 +23,7 @@ + #include + #include + #include "ros_gz_bridge/bridge_config.hpp" ++#include "ros_gz_bridge/visibility_control.hpp" + + namespace ros_gz_bridge + { +@@ -30,7 +31,7 @@ namespace ros_gz_bridge + class BridgeHandle; + + /// \brief Component container for the ROS-GZ Bridge +-class RosGzBridge : public rclcpp::Node ++class ROS_GZ_BRIDGE_VISIBLE RosGzBridge : public rclcpp::Node + { + public: + /// \brief Constructor +diff --git a/src/factory_interface.hpp b/src/factory_interface.hpp +index d1797df..fd6c4f6 100644 +--- a/src/factory_interface.hpp ++++ b/src/factory_interface.hpp +@@ -25,11 +25,12 @@ + #include + + #include "bridge_handle_gz_to_ros_parameters.hpp" ++#include "ros_gz_bridge/visibility_control.hpp" + + namespace ros_gz_bridge + { + +-class FactoryInterface ++class ROS_GZ_BRIDGE_VISIBLE FactoryInterface + { + public: + virtual ~FactoryInterface() = 0; +diff --git a/src/get_factory.hpp b/src/get_factory.hpp +index 6215a02..495b65d 100644 +--- a/src/get_factory.hpp ++++ b/src/get_factory.hpp +@@ -20,16 +20,17 @@ + + #include "factory_interface.hpp" + #include "service_factory_interface.hpp" ++#include "ros_gz_bridge/visibility_control.hpp" + + namespace ros_gz_bridge + { + +-std::shared_ptr ++ROS_GZ_BRIDGE_VISIBLE std::shared_ptr + get_factory( + const std::string & ros_type_name, + const std::string & gz_type_name); + +-std::shared_ptr ++ROS_GZ_BRIDGE_VISIBLE std::shared_ptr + get_service_factory( + const std::string & ros_type_name, + const std::string & gz_req_type_name, +diff --git a/src/get_mappings.hpp b/src/get_mappings.hpp +index f26ae20..1c699cf 100644 +--- a/src/get_mappings.hpp ++++ b/src/get_mappings.hpp +@@ -18,16 +18,18 @@ + #include + #include + ++#include "ros_gz_bridge/visibility_control.hpp" ++ + namespace ros_gz_bridge + { + +-bool ++ROS_GZ_BRIDGE_VISIBLE bool + get_gz_to_ros_mapping(const std::string & gz_type_name, std::string & ros_type_name); + +-bool ++ROS_GZ_BRIDGE_VISIBLE bool + get_ros_to_gz_mapping(const std::string & ros_type_name, std::string & gz_type_name); + +-std::multimap ++ROS_GZ_BRIDGE_VISIBLE std::multimap + get_all_message_mappings_ros_to_gz(); + + } // namespace ros_gz_bridge +diff --git a/src/service_factory_interface.hpp b/src/service_factory_interface.hpp +index 766ce51..afa06e6 100644 +--- a/src/service_factory_interface.hpp ++++ b/src/service_factory_interface.hpp +@@ -23,10 +23,12 @@ + #include + #include + ++#include "ros_gz_bridge/visibility_control.hpp" ++ + namespace ros_gz_bridge + { + +-class ServiceFactoryInterface ++class ROS_GZ_BRIDGE_VISIBLE ServiceFactoryInterface + { + public: + virtual ~ServiceFactoryInterface() = 0; diff --git a/patch/ros-jazzy-rqt-image-view.patch b/patch/ros-jazzy-rqt-image-view.patch new file mode 100644 index 000000000..fede12eba --- /dev/null +++ b/patch/ros-jazzy-rqt-image-view.patch @@ -0,0 +1,21 @@ +diff -ruN a/src/rqt_image_view/image_view.cpp b/src/rqt_image_view/image_view.cpp +--- a/src/rqt_image_view/image_view.cpp ++++ b/src/rqt_image_view/image_view.cpp +@@ -571,7 +571,7 @@ + conversion_mat_ = cv_ptr->image; + } else if (msg->encoding == "8UC1") { + // convert gray to rgb +- cv::cvtColor(cv_ptr->image, conversion_mat_, CV_GRAY2RGB); ++ cv::cvtColor(cv_ptr->image, conversion_mat_, cv::COLOR_GRAY2RGB); + } else if (msg->encoding == "16UC1" || msg->encoding == "32FC1") { + // scale / quantify + double min = 0; +@@ -589,7 +589,7 @@ + } + cv::Mat img_scaled_8u; + cv::Mat(cv_ptr->image-min).convertTo(img_scaled_8u, CV_8UC1, 255. / (max - min)); +- cv::cvtColor(img_scaled_8u, conversion_mat_, CV_GRAY2RGB); ++ cv::cvtColor(img_scaled_8u, conversion_mat_, cv::COLOR_GRAY2RGB); + } else { + qWarning("ImageView.callback_image() could not convert image from '%s' to 'rgb8' (%s)", msg->encoding.c_str(), e.what()); + ui_.image_frame->setImage(QImage()); diff --git a/patch/ros-jazzy-rtabmap.patch b/patch/ros-jazzy-rtabmap.patch new file mode 100644 index 000000000..3f235069c --- /dev/null +++ b/patch/ros-jazzy-rtabmap.patch @@ -0,0 +1,2990 @@ +diff -ruN a/CMakeLists.txt b/CMakeLists.txt +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -1,7 +1,10 @@ + # Top-Level CmakeLists.txt +-cmake_minimum_required(VERSION 3.14) ++cmake_minimum_required(VERSION 3.18) + + PROJECT( RTABMap ) ++if(POLICY CMP0167) ++ cmake_policy(SET CMP0167 NEW) ++endif() + SET(PROJECT_PREFIX rtabmap) + + # Catkin doesn't support multiarch library path, +@@ -241,8 +244,26 @@ + set(RTABMAP_QT_VERSION AUTO CACHE STRING "Force a specific Qt version.") + set_property(CACHE RTABMAP_QT_VERSION PROPERTY STRINGS AUTO 4 5 6) + +-FIND_PACKAGE(OpenCV REQUIRED QUIET COMPONENTS core calib3d imgproc highgui stitching photo video videoio OPTIONAL_COMPONENTS aruco objdetect xfeatures2d nonfree gpu cudafeatures2d cudaoptflow cudaimgproc) ++# OpenCV components. calib3d was split into "calib" + "geometry" in OpenCV 5. ++# These lists are reused below to generate RTABMapConfig.cmake so downstream ++# find_package(RTABMap) requests the same components this build used. ++SET(RTABMAP_OpenCV_COMPONENTS_5 core imgproc highgui stitching photo video videoio calib geometry) ++SET(RTABMAP_OpenCV_COMPONENTS_4 core imgproc highgui stitching photo video videoio calib3d) ++SET(RTABMAP_OpenCV_OPTIONAL_COMPONENTS_5 objdetect xfeatures2d nonfree gpu cudafeatures2d cudaoptflow cudaimgproc) ++SET(RTABMAP_OpenCV_OPTIONAL_COMPONENTS_4 aruco objdetect xfeatures2d nonfree gpu cudafeatures2d cudaoptflow cudaimgproc) + ++# Probe OpenCV without a version constraint first, then request the components ++# matching the detected major version. A version-constrained find that fails to ++# match (e.g. asking for 5 when only 4 is present) resets OpenCV_DIR to NOTFOUND, ++# which breaks toolchain builds that rely on a -DOpenCV_DIR hint (e.g. Android, ++# where CMAKE_FIND_ROOT_PATH restricts the search). ++FIND_PACKAGE(OpenCV REQUIRED QUIET COMPONENTS core) ++IF(OpenCV_VERSION_MAJOR GREATER 4) ++ FIND_PACKAGE(OpenCV REQUIRED QUIET COMPONENTS ${RTABMAP_OpenCV_COMPONENTS_5} OPTIONAL_COMPONENTS ${RTABMAP_OpenCV_OPTIONAL_COMPONENTS_5}) ++ELSE() ++ FIND_PACKAGE(OpenCV REQUIRED QUIET COMPONENTS ${RTABMAP_OpenCV_COMPONENTS_4} OPTIONAL_COMPONENTS ${RTABMAP_OpenCV_OPTIONAL_COMPONENTS_4}) ++ENDIF() ++ + IF(WITH_QT) + FIND_PACKAGE(PCL 1.7 REQUIRED QUIET COMPONENTS common io kdtree search surface filters registration sample_consensus segmentation visualization) + ELSE() +@@ -501,7 +522,10 @@ + ENDIF(WITH_DC1394) + + IF(WITH_G2O) ++ SET(_RTABMAP_CMAKE_FIND_PACKAGE_PREFER_CONFIG ${CMAKE_FIND_PACKAGE_PREFER_CONFIG}) ++ SET(CMAKE_FIND_PACKAGE_PREFER_CONFIG TRUE) + FIND_PACKAGE(g2o NO_MODULE) ++ SET(CMAKE_FIND_PACKAGE_PREFER_CONFIG ${_RTABMAP_CMAKE_FIND_PACKAGE_PREFER_CONFIG}) + IF(g2o_FOUND) + MESSAGE(STATUS "Found g2o (targets)") + SET(G2O_FOUND ${g2o_FOUND}) +@@ -536,8 +560,10 @@ + ENDIF(WITH_G2O) + + IF(WITH_GTSAM) +- # Force config mode to ignore PCL's findGTSAM.cmake file ++ SET(_RTABMAP_CMAKE_FIND_PACKAGE_PREFER_CONFIG ${CMAKE_FIND_PACKAGE_PREFER_CONFIG}) ++ SET(CMAKE_FIND_PACKAGE_PREFER_CONFIG TRUE) + FIND_PACKAGE(GTSAM CONFIG QUIET) ++ SET(CMAKE_FIND_PACKAGE_PREFER_CONFIG ${_RTABMAP_CMAKE_FIND_PACKAGE_PREFER_CONFIG}) + IF(GTSAM_FOUND) + # For issue https://github.com/introlab/rtabmap/pull/1626 + FIND_FILE(GTSAM_NOISE_MODEL_FACTOR_N_FILE gtsam/nonlinear/NoiseModelFactorN.h +@@ -1318,6 +1344,18 @@ + #### + # Setup RTABMapConfig.cmake + #### ++IF(OpenCV_VERSION_MAJOR GREATER 4) ++ SET(CONF_OPENCV_COMPONENTS ${RTABMAP_OpenCV_COMPONENTS_5}) ++ SET(CONF_OPENCV_OPTIONAL_COMPONENTS ${RTABMAP_OpenCV_OPTIONAL_COMPONENTS_5}) ++ELSE() ++ SET(CONF_OPENCV_COMPONENTS ${RTABMAP_OpenCV_COMPONENTS_4}) ++ SET(CONF_OPENCV_OPTIONAL_COMPONENTS ${RTABMAP_OpenCV_OPTIONAL_COMPONENTS_4}) ++ENDIF() ++STRING(REPLACE ";" " " CONF_OPENCV_COMPONENTS "${CONF_OPENCV_COMPONENTS}") ++STRING(REPLACE ";" " " CONF_OPENCV_OPTIONAL_COMPONENTS "${CONF_OPENCV_OPTIONAL_COMPONENTS}") ++# Pin the OpenCV major version so downstream projects find the same major RTAB-Map was ++# built against ++SET(CONF_OPENCV_VERSION_MAJOR ${OpenCV_VERSION_MAJOR}) + include(CMakePackageConfigHelpers) + write_basic_package_version_file( + "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake" +diff -ruN a/RTABMapConfig.cmake.in b/RTABMapConfig.cmake.in +--- a/RTABMapConfig.cmake.in ++++ b/RTABMapConfig.cmake.in +@@ -1,7 +1,7 @@ + include(CMakeFindDependencyMacro) + + # Mandatory dependencies +-find_dependency(OpenCV COMPONENTS core calib3d imgproc highgui stitching photo video OPTIONAL_COMPONENTS aruco objdetect xfeatures2d nonfree gpu cudafeatures2d) ++find_dependency(OpenCV @CONF_OPENCV_VERSION_MAJOR@ COMPONENTS @CONF_OPENCV_COMPONENTS@ OPTIONAL_COMPONENTS @CONF_OPENCV_OPTIONAL_COMPONENTS@) + + if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/RTABMap_guiTargets.cmake") + find_dependency(PCL 1.7 COMPONENTS common io kdtree search surface filters registration sample_consensus segmentation visualization) +diff -ruN a/corelib/include/rtabmap/core/DBDriverSqlite3.h b/corelib/include/rtabmap/core/DBDriverSqlite3.h +--- a/corelib/include/rtabmap/core/DBDriverSqlite3.h ++++ b/corelib/include/rtabmap/core/DBDriverSqlite3.h +@@ -30,7 +30,11 @@ + + #include "rtabmap/core/rtabmap_core_export.h" // DLL export/import defines + #include "rtabmap/core/DBDriver.h" ++#if CV_MAJOR_VERSION < 5 + #include ++#else ++#include ++#endif + + typedef struct sqlite3_stmt sqlite3_stmt; + typedef struct sqlite3 sqlite3; +diff -ruN a/corelib/include/rtabmap/core/EpipolarGeometry.h b/corelib/include/rtabmap/core/EpipolarGeometry.h +--- a/corelib/include/rtabmap/core/EpipolarGeometry.h ++++ b/corelib/include/rtabmap/core/EpipolarGeometry.h +@@ -31,7 +31,14 @@ + #include "rtabmap/core/Parameters.h" + #include "rtabmap/utilite/UStl.h" + #include ++#if CV_MAJOR_VERSION < 5 + #include ++#else ++#include ++#if CV_MAJOR_VERSION >= 5 ++#include ++#endif ++#endif + #include + #include + #include +diff -ruN a/corelib/include/rtabmap/core/Features2d.h b/corelib/include/rtabmap/core/Features2d.h +--- a/corelib/include/rtabmap/core/Features2d.h ++++ b/corelib/include/rtabmap/core/Features2d.h +@@ -32,7 +32,11 @@ + + #include + #include ++#if CV_MAJOR_VERSION < 5 + #include ++#else ++#include ++#endif + #include + #include + #include "rtabmap/core/Parameters.h" +@@ -70,6 +74,10 @@ + class SIFT; + #endif + class SURF; ++#if (CV_MAJOR_VERSION == 5) ++class BRISK; ++class KAZE; ++#endif + } + namespace cuda { + class FastFeatureDetector; +@@ -89,7 +97,13 @@ + typedef cv::xfeatures2d::DAISY CV_DAISY; + typedef cv::GFTTDetector CV_GFTT; + typedef cv::xfeatures2d::BriefDescriptorExtractor CV_BRIEF; ++#if (CV_MAJOR_VERSION < 5) + typedef cv::BRISK CV_BRISK; ++typedef cv::KAZE CV_KAZE; ++#else ++typedef cv::xfeatures2d::BRISK CV_BRISK; ++typedef cv::xfeatures2d::KAZE CV_KAZE; ++#endif + typedef cv::ORB CV_ORB; + typedef cv::cuda::SURF_CUDA CV_SURF_GPU; + typedef cv::cuda::ORB CV_ORB_GPU; +@@ -578,7 +592,7 @@ + int diffusivity_; + + #if CV_MAJOR_VERSION > 2 +- cv::Ptr kaze_; ++ cv::Ptr kaze_; + #endif + }; + +diff -ruN a/corelib/include/rtabmap/core/Memory.h b/corelib/include/rtabmap/core/Memory.h +--- a/corelib/include/rtabmap/core/Memory.h ++++ b/corelib/include/rtabmap/core/Memory.h +@@ -41,7 +41,11 @@ + #include + #include "rtabmap/utilite/UStl.h" + #include ++#if CV_MAJOR_VERSION < 5 + #include ++#else ++#include ++#endif + #include + + namespace rtabmap { +diff -ruN a/corelib/include/rtabmap/core/OdometryInfo.h b/corelib/include/rtabmap/core/OdometryInfo.h +--- a/corelib/include/rtabmap/core/OdometryInfo.h ++++ b/corelib/include/rtabmap/core/OdometryInfo.h +@@ -34,7 +34,11 @@ + #include "rtabmap/core/RegistrationInfo.h" + #include "rtabmap/core/CameraModel.h" + #include "rtabmap/core/LaserScan.h" ++#if CV_MAJOR_VERSION < 5 + #include ++#else ++#include ++#endif + + namespace rtabmap { + +diff -ruN a/corelib/include/rtabmap/core/SensorData.h b/corelib/include/rtabmap/core/SensorData.h +--- a/corelib/include/rtabmap/core/SensorData.h ++++ b/corelib/include/rtabmap/core/SensorData.h +@@ -34,7 +34,11 @@ + #include + #include + #include ++#if CV_MAJOR_VERSION < 5 + #include ++#else ++#include ++#endif + #include + #include + #include +diff -ruN a/corelib/include/rtabmap/core/Signature.h b/corelib/include/rtabmap/core/Signature.h +--- a/corelib/include/rtabmap/core/Signature.h ++++ b/corelib/include/rtabmap/core/Signature.h +@@ -31,7 +31,11 @@ + + #include + #include ++#if CV_MAJOR_VERSION < 5 + #include ++#else ++#include ++#endif + #include + #include + #include +diff -ruN a/corelib/include/rtabmap/core/Statistics.h b/corelib/include/rtabmap/core/Statistics.h +--- a/corelib/include/rtabmap/core/Statistics.h ++++ b/corelib/include/rtabmap/core/Statistics.h +@@ -31,7 +31,11 @@ + #include "rtabmap/core/rtabmap_core_export.h" // DLL export/import defines + + #include ++#if CV_MAJOR_VERSION < 5 + #include ++#else ++#include ++#endif + #include + #include + #include +diff -ruN a/corelib/include/rtabmap/core/VWDictionary.h b/corelib/include/rtabmap/core/VWDictionary.h +--- a/corelib/include/rtabmap/core/VWDictionary.h ++++ b/corelib/include/rtabmap/core/VWDictionary.h +@@ -31,7 +31,11 @@ + + #include + #include ++#if CV_MAJOR_VERSION < 5 + #include ++#else ++#include ++#endif + #include + #include + #include "rtabmap/core/Parameters.h" +diff -ruN a/corelib/include/rtabmap/core/stereo/stereoRectifyFisheye.h b/corelib/include/rtabmap/core/stereo/stereoRectifyFisheye.h +--- a/corelib/include/rtabmap/core/stereo/stereoRectifyFisheye.h ++++ b/corelib/include/rtabmap/core/stereo/stereoRectifyFisheye.h +@@ -32,12 +32,24 @@ + #ifndef CORELIB_SRC_OPENCV_STEREORECTIFYFISHEYE_H_ + #define CORELIB_SRC_OPENCV_STEREORECTIFYFISHEYE_H_ + ++// This header relies on the OpenCV C API (cvRodrigues2, cvProjectPoints2, ...) ++// which was removed in OpenCV 5. Pull in only the version macros (available in ++// all OpenCV versions) so we can fail early with a clear message rather than ++// with cryptic errors from the includes below. ++#include ++#if CV_MAJOR_VERSION >= 5 ++#error "stereoRectifyFisheye.h is not supported with OpenCV 5 or later (it uses the removed OpenCV C API). Use cv::fisheye::stereoRectify() instead, or guard your include with '#if CV_MAJOR_VERSION < 5'." ++#endif ++ + #include + #if CV_MAJOR_VERSION >= 3 + #include + + #if CV_MAJOR_VERSION >= 4 + #include ++#if CV_MAJOR_VERSION >= 5 ++#include ++#endif + + // Opencv4 doesn't expose those functions below anymore, we should recopy all of them! + int cvRodrigues2( const CvMat* src, CvMat* dst, CvMat* jacobian CV_DEFAULT(0)) +diff -ruN a/corelib/include/rtabmap/core/util3d_correspondences.h b/corelib/include/rtabmap/core/util3d_correspondences.h +--- a/corelib/include/rtabmap/core/util3d_correspondences.h ++++ b/corelib/include/rtabmap/core/util3d_correspondences.h +@@ -32,7 +32,12 @@ + + #include + #include ++#include ++#if CV_MAJOR_VERSION < 5 + #include ++#else ++#include ++#endif + #include + #include + #include +diff -ruN a/corelib/include/rtabmap/core/util3d_features.h b/corelib/include/rtabmap/core/util3d_features.h +--- a/corelib/include/rtabmap/core/util3d_features.h ++++ b/corelib/include/rtabmap/core/util3d_features.h +@@ -30,7 +30,12 @@ + + #include + ++#include ++#if CV_MAJOR_VERSION < 5 + #include ++#else ++#include ++#endif + #include + #include + #include +diff -ruN a/corelib/src/CameraModel.cpp b/corelib/src/CameraModel.cpp +--- a/corelib/src/CameraModel.cpp ++++ b/corelib/src/CameraModel.cpp +@@ -34,6 +34,9 @@ + #include + #include + #include ++#if CV_MAJOR_VERSION >= 5 ++#include ++#endif + + namespace rtabmap { + +diff -ruN a/corelib/src/EpipolarGeometry.cpp b/corelib/src/EpipolarGeometry.cpp +--- a/corelib/src/EpipolarGeometry.cpp ++++ b/corelib/src/EpipolarGeometry.cpp +@@ -33,8 +33,11 @@ + #include "rtabmap/utilite/UMath.h" + + #include +-#include ++#if CV_MAJOR_VERSION < 5 + #include ++#else ++#include ++#endif + #include + + namespace rtabmap +diff -ruN a/corelib/src/Features2d.cpp b/corelib/src/Features2d.cpp +--- a/corelib/src/Features2d.cpp ++++ b/corelib/src/Features2d.cpp +@@ -36,7 +36,6 @@ + #include "rtabmap/utilite/UMath.h" + #include "rtabmap/utilite/ULogger.h" + #include "rtabmap/utilite/UTimer.h" +-#include + #include + #include + +@@ -865,7 +864,7 @@ + cv::cornerSubPix( image, corners, + cv::Size( _subPixWinSize, _subPixWinSize ), + cv::Size( -1, -1 ), +- cv::TermCriteria( CV_TERMCRIT_ITER | CV_TERMCRIT_EPS, _subPixIterations, _subPixEps ) ); ++ cv::TermCriteria( cv::TermCriteria::MAX_ITER | cv::TermCriteria::EPS, _subPixIterations, _subPixEps ) ); + + for(unsigned int i=0;i 4 ++#ifdef HAVE_OPENCV_XFEATURES2D ++ brisk_ = CV_BRISK::create(thresh_, octaves_, patternScale_); ++#else ++ UWARN("RTAB-Map is not built with OpenCV xfeatures2d module so BRISK cannot be used!"); ++#endif ++#elif CV_MAJOR_VERSION < 3 + brisk_ = cv::Ptr(new CV_BRISK(thresh_, octaves_, patternScale_)); + #else + brisk_ = CV_BRISK::create(thresh_, octaves_, patternScale_); +@@ -2389,6 +2393,7 @@ + { + UASSERT(!image.empty() && image.channels() == 1 && image.depth() == CV_8U); + std::vector keypoints; ++#if CV_MAJOR_VERSION < 5 || (CV_MAJOR_VERSION > 4 && defined(HAVE_OPENCV_XFEATURES2D)) + cv::Mat imgRoi(image, roi); + cv::Mat maskRoi; + if(!mask.empty()) +@@ -2396,6 +2401,9 @@ + maskRoi = cv::Mat(mask, roi); + } + brisk_->detect(imgRoi, keypoints, maskRoi); // Opencv keypoints ++#else ++ UWARN("RTAB-Map is not built with BRISK feature support!"); ++#endif + return keypoints; + } + +@@ -2403,7 +2411,11 @@ + { + UASSERT(!image.empty() && image.channels() == 1 && image.depth() == CV_8U); + cv::Mat descriptors; ++#if CV_MAJOR_VERSION < 5 || (CV_MAJOR_VERSION > 4 && defined(HAVE_OPENCV_XFEATURES2D)) + brisk_->compute(image, keypoints, descriptors); ++#else ++ UWARN("RTAB-Map is not built with BRISK feature support!"); ++#endif + return descriptors; + } + +@@ -2436,10 +2448,16 @@ + Parameters::parse(parameters, Parameters::kKAZENOctaveLayers(), nOctaveLayers_); + Parameters::parse(parameters, Parameters::kKAZEDiffusivity(), diffusivity_); + +-#if CV_MAJOR_VERSION > 3 +- kaze_ = cv::KAZE::create(extended_, upright_, threshold_, nOctaves_, nOctaveLayers_, (cv::KAZE::DiffusivityType)diffusivity_); ++#if CV_MAJOR_VERSION > 4 ++#ifdef HAVE_OPENCV_XFEATURES2D ++ kaze_ = CV_KAZE::create(extended_, upright_, threshold_, nOctaves_, nOctaveLayers_, (CV_KAZE::DiffusivityType)diffusivity_); ++#else ++ UWARN("RTAB-Map is not built with OpenCV xfeatures2d module so KAZE cannot be used!"); ++#endif ++#elif CV_MAJOR_VERSION > 3 ++ kaze_ = CV_KAZE::create(extended_, upright_, threshold_, nOctaves_, nOctaveLayers_, (CV_KAZE::DiffusivityType)diffusivity_); + #elif CV_MAJOR_VERSION > 2 +- kaze_ = cv::KAZE::create(extended_, upright_, threshold_, nOctaves_, nOctaveLayers_, diffusivity_); ++ kaze_ = CV_KAZE::create(extended_, upright_, threshold_, nOctaves_, nOctaveLayers_, diffusivity_); + #else + UWARN("RTAB-Map is not built with OpenCV3 so Kaze feature cannot be used!"); + #endif +@@ -2449,7 +2467,7 @@ + { + UASSERT(!image.empty() && image.channels() == 1 && image.depth() == CV_8U); + std::vector keypoints; +-#if CV_MAJOR_VERSION > 2 ++#if (CV_MAJOR_VERSION > 2 && CV_MAJOR_VERSION < 5) || (CV_MAJOR_VERSION > 4 && defined(HAVE_OPENCV_XFEATURES2D)) + cv::Mat imgRoi(image, roi); + cv::Mat maskRoi; + if (!mask.empty()) +@@ -2458,7 +2476,7 @@ + } + kaze_->detect(imgRoi, keypoints, maskRoi); // Opencv keypoints + #else +- UWARN("RTAB-Map is not built with OpenCV3 so Kaze feature cannot be used!"); ++ UWARN("RTAB-Map is not built with Kaze feature support!"); + #endif + return keypoints; + } +@@ -2467,10 +2485,10 @@ + { + UASSERT(!image.empty() && image.channels() == 1 && image.depth() == CV_8U); + cv::Mat descriptors; +-#if CV_MAJOR_VERSION > 2 ++#if (CV_MAJOR_VERSION > 2 && CV_MAJOR_VERSION < 5) || (CV_MAJOR_VERSION > 4 && defined(HAVE_OPENCV_XFEATURES2D)) + kaze_->compute(image, keypoints, descriptors); + #else +- UWARN("RTAB-Map is not built with OpenCV3 so Kaze feature cannot be used!"); ++ UWARN("RTAB-Map is not built with Kaze feature support!"); + #endif + return descriptors; + } +diff -ruN a/corelib/src/MarkerDetector.cpp b/corelib/src/MarkerDetector.cpp +--- a/corelib/src/MarkerDetector.cpp ++++ b/corelib/src/MarkerDetector.cpp +@@ -29,6 +29,9 @@ + #include + #include + #include ++#if CV_MAJOR_VERSION >= 5 ++#include ++#endif + + #ifdef HAVE_OPENCV_ARUCO + #if CV_MAJOR_VERSION < 4 || (CV_MAJOR_VERSION == 4 && CV_MINOR_VERSION <8) +diff -ruN a/corelib/src/Memory.cpp b/corelib/src/Memory.cpp +--- a/corelib/src/Memory.cpp ++++ b/corelib/src/Memory.cpp +@@ -26,6 +26,9 @@ + */ + + #include ++#if CV_MAJOR_VERSION >= 5 ++#include ++#endif + #include + #include + #include +@@ -62,7 +65,6 @@ + #include + #include + #include +-#include + #include + + namespace rtabmap { +@@ -5373,7 +5375,7 @@ + cv::Mat imageMono; + if(decimatedData.imageRaw().channels() == 3) + { +- cv::cvtColor(decimatedData.imageRaw(), imageMono, CV_BGR2GRAY); ++ cv::cvtColor(decimatedData.imageRaw(), imageMono, cv::COLOR_BGR2GRAY); + } + else + { +@@ -5681,7 +5683,7 @@ + cv::Mat imageMono; + if(data.imageRaw().channels() == 3) + { +- cv::cvtColor(data.imageRaw(), imageMono, CV_BGR2GRAY); ++ cv::cvtColor(data.imageRaw(), imageMono, cv::COLOR_BGR2GRAY); + } + else + { +diff -ruN a/corelib/src/RegistrationVis.cpp b/corelib/src/RegistrationVis.cpp +--- a/corelib/src/RegistrationVis.cpp ++++ b/corelib/src/RegistrationVis.cpp +@@ -43,7 +43,9 @@ + #include + #include + #include +-#include ++#if CV_MAJOR_VERSION > 4 ++#include ++#endif + + #if defined(HAVE_OPENCV_XFEATURES2D) && (CV_MAJOR_VERSION > 3 || (CV_MAJOR_VERSION==3 && CV_MINOR_VERSION >=4 && CV_SUBMINOR_VERSION >= 1)) + #include // For GMS matcher +@@ -52,7 +54,10 @@ + #ifdef HAVE_OPENCV_CUDAOPTFLOW + #include + #include ++#if CV_MAJOR_VERSION >= 5 ++#include + #endif ++#endif + + #include + +@@ -2172,7 +2177,7 @@ + if(!transform.isNull() && !pcaData.empty()) + { + cv::Mat pcaEigenVectors, pcaEigenValues; +- cv::PCA pca_analysis(pcaData, cv::Mat(), CV_PCA_DATA_AS_ROW); ++ cv::PCA pca_analysis(pcaData, cv::Mat(), cv::PCA::DATA_AS_ROW); + // We take the second eigen value + info.inliersDistribution = pca_analysis.eigenvalues.at(0, 1); + +diff -ruN a/corelib/src/SensorCaptureThread.cpp b/corelib/src/SensorCaptureThread.cpp +--- a/corelib/src/SensorCaptureThread.cpp ++++ b/corelib/src/SensorCaptureThread.cpp +@@ -39,7 +39,6 @@ + #include "rtabmap/core/IMUFilter.h" + #include "rtabmap/core/Features2d.h" + #include "rtabmap/core/clams/discrete_depth_distortion_model.h" +-#include + #include + #include + #include +@@ -742,11 +741,11 @@ + else if(data.imageRaw().type() == CV_8UC3) + { + cv::Mat channels[3]; +- cv::cvtColor(data.imageRaw(), image, CV_BGR2YCrCb); ++ cv::cvtColor(data.imageRaw(), image, cv::COLOR_BGR2YCrCb); + cv::split(image, channels); + cv::equalizeHist(channels[0], channels[0]); + cv::merge(channels, 3, image); +- cv::cvtColor(image, image, CV_YCrCb2BGR); ++ cv::cvtColor(image, image, cv::COLOR_YCrCb2BGR); + } + if(!data.depthRaw().empty()) + { +@@ -762,11 +761,11 @@ + else if(data.rightRaw().type() == CV_8UC3) + { + cv::Mat channels[3]; +- cv::cvtColor(data.rightRaw(), right, CV_BGR2YCrCb); ++ cv::cvtColor(data.rightRaw(), right, cv::COLOR_BGR2YCrCb); + cv::split(right, channels); + cv::equalizeHist(channels[0], channels[0]); + cv::merge(channels, 3, right); +- cv::cvtColor(right, right, CV_YCrCb2BGR); ++ cv::cvtColor(right, right, cv::COLOR_YCrCb2BGR); + } + data.setStereoImage(image, right, data.stereoCameraModels()[0]); + } +@@ -781,11 +780,11 @@ + else if(data.imageRaw().type() == CV_8UC3) + { + cv::Mat channels[3]; +- cv::cvtColor(data.imageRaw(), image, CV_BGR2YCrCb); ++ cv::cvtColor(data.imageRaw(), image, cv::COLOR_BGR2YCrCb); + cv::split(image, channels); + clahe->apply(channels[0], channels[0]); + cv::merge(channels, 3, image); +- cv::cvtColor(image, image, CV_YCrCb2BGR); ++ cv::cvtColor(image, image, cv::COLOR_YCrCb2BGR); + } + if(!data.depthRaw().empty()) + { +@@ -801,11 +800,11 @@ + else if(data.rightRaw().type() == CV_8UC3) + { + cv::Mat channels[3]; +- cv::cvtColor(data.rightRaw(), right, CV_BGR2YCrCb); ++ cv::cvtColor(data.rightRaw(), right, cv::COLOR_BGR2YCrCb); + cv::split(right, channels); + clahe->apply(channels[0], channels[0]); + cv::merge(channels, 3, right); +- cv::cvtColor(right, right, CV_YCrCb2BGR); ++ cv::cvtColor(right, right, cv::COLOR_YCrCb2BGR); + } + data.setStereoImage(image, right, data.stereoCameraModels()[0]); + } +diff -ruN a/corelib/src/StereoCameraModel.cpp b/corelib/src/StereoCameraModel.cpp +--- a/corelib/src/StereoCameraModel.cpp ++++ b/corelib/src/StereoCameraModel.cpp +@@ -32,8 +32,11 @@ + #include + #include + #include ++#if CV_MAJOR_VERSION >= 5 ++#include ++#endif + +-#if CV_MAJOR_VERSION > 2 or (CV_MAJOR_VERSION == 2 and (CV_MINOR_VERSION >4 or (CV_MINOR_VERSION == 4 and CV_SUBMINOR_VERSION >=10))) ++#if (CV_MAJOR_VERSION > 2 and CV_MAJOR_VERSION < 5) or (CV_MAJOR_VERSION == 2 and (CV_MINOR_VERSION >4 or (CV_MINOR_VERSION == 4 and CV_SUBMINOR_VERSION >=10))) + #include + #endif + +@@ -179,12 +182,20 @@ + { + cv::Vec4d D_left(left_.D_raw().at(0,0), left_.D_raw().at(0,1), left_.D_raw().at(0,4), left_.D_raw().at(0,5)); + cv::Vec4d D_right(right_.D_raw().at(0,0), right_.D_raw().at(0,1), right_.D_raw().at(0,4), right_.D_raw().at(0,5)); +- ++#if CV_MAJOR_VERSION < 5 + stereoRectifyFisheye( + left_.K_raw(), D_left, + right_.K_raw(), D_right, + left_.imageSize(), R_, T_, R1, R2, P1, P2, Q, + cv::CALIB_ZERO_DISPARITY, 0, left_.imageSize()); ++#else ++ double balance = 0.0, fov_scale = 1.0; ++ cv::fisheye::stereoRectify( ++ left_.K_raw(), D_left, ++ right_.K_raw(), D_right, ++ left_.imageSize(), R_, T_, R1, R2, P1, P2, Q, ++ cv::CALIB_ZERO_DISPARITY, left_.imageSize(), balance, fov_scale); ++#endif + + // Re-zoom to original focal distance + if(P1.at(0,0) < 0) +diff -ruN a/corelib/src/camera/CameraDepthAI.cpp b/corelib/src/camera/CameraDepthAI.cpp +--- a/corelib/src/camera/CameraDepthAI.cpp ++++ b/corelib/src/camera/CameraDepthAI.cpp +@@ -32,7 +32,11 @@ + #include + #include + #include +- ++#if CV_MAJOR_VERSION < 5 ++#include ++#else ++#include ++#endif + + namespace rtabmap { + +diff -ruN a/corelib/src/camera/CameraFreenect.cpp b/corelib/src/camera/CameraFreenect.cpp +--- a/corelib/src/camera/CameraFreenect.cpp ++++ b/corelib/src/camera/CameraFreenect.cpp +@@ -28,7 +28,6 @@ + #include + #include + #include +-#include + + #ifdef RTABMAP_FREENECT + #include +@@ -183,7 +182,7 @@ + + if(color_) + { +- cv::cvtColor(rgbIrBuffer_, rgbIrLastFrame_, CV_RGB2BGR); ++ cv::cvtColor(rgbIrBuffer_, rgbIrLastFrame_, cv::COLOR_RGB2BGR); + } + else // IrDepth + { +diff -ruN a/corelib/src/camera/CameraFreenect2.cpp b/corelib/src/camera/CameraFreenect2.cpp +--- a/corelib/src/camera/CameraFreenect2.cpp ++++ b/corelib/src/camera/CameraFreenect2.cpp +@@ -29,7 +29,6 @@ + #include + #include + #include +-#include + + #ifdef RTABMAP_FREENECT2 + #include +@@ -430,11 +429,11 @@ + cv::Mat rgbMat; // rtabmap uses 3 channels RGB + #ifdef LIBFREENECT2_WITH_TEGRAJPEG_SUPPORT + +- cv::cvtColor(rgbMatC4, rgbMat, CV_RGBA2BGR); ++ cv::cvtColor(rgbMatC4, rgbMat, cv::COLOR_RGBA2BGR); + + #else + +- cv::cvtColor(rgbMatC4, rgbMat, CV_BGRA2BGR); ++ cv::cvtColor(rgbMatC4, rgbMat, cv::COLOR_BGRA2BGR); + + #endif + cv::flip(rgbMat, rgb, 1); +@@ -490,11 +489,11 @@ + cv::Mat rgbMat; // rtabmap uses 3 channels RGB + #ifdef LIBFREENECT2_WITH_TEGRAJPEG_SUPPORT + +- cv::cvtColor(rgbMatC4, rgbMat, CV_RGB2BGR); ++ cv::cvtColor(rgbMatC4, rgbMat, cv::COLOR_RGB2BGR); + + #else + +- cv::cvtColor(rgbMatC4, rgbMat, CV_BGRA2BGR); ++ cv::cvtColor(rgbMatC4, rgbMat, cv::COLOR_BGRA2BGR); + + #endif + cv::flip(rgbMat, rgb, 1); +@@ -607,11 +606,11 @@ + // rtabmap uses 3 channels RGB + #ifdef LIBFREENECT2_WITH_TEGRAJPEG_SUPPORT + +- cv::cvtColor(rgbMatBGRA, rgb, CV_RGBA2BGR); ++ cv::cvtColor(rgbMatBGRA, rgb, cv::COLOR_RGBA2BGR); + + #else + +- cv::cvtColor(rgbMatBGRA, rgb, CV_BGRA2BGR); ++ cv::cvtColor(rgbMatBGRA, rgb, cv::COLOR_BGRA2BGR); + + #endif + cv::flip(rgb, rgb, 1); +@@ -629,11 +628,11 @@ + // rtabmap uses 3 channels RGB + #ifdef LIBFREENECT2_WITH_TEGRAJPEG_SUPPORT + +- cv::cvtColor(rgbMatBGRA, rgb, CV_RGBA2BGR); ++ cv::cvtColor(rgbMatBGRA, rgb, cv::COLOR_RGBA2BGR); + + #else + +- cv::cvtColor(rgbMatBGRA, rgb, CV_BGRA2BGR); ++ cv::cvtColor(rgbMatBGRA, rgb, cv::COLOR_BGRA2BGR); + + #endif + cv::flip(rgb, rgb, 1); +diff -ruN a/corelib/src/camera/CameraImages.cpp b/corelib/src/camera/CameraImages.cpp +--- a/corelib/src/camera/CameraImages.cpp ++++ b/corelib/src/camera/CameraImages.cpp +@@ -34,7 +34,7 @@ + #include + #include + #include +-#include ++#include + #include + + namespace rtabmap +@@ -933,7 +933,7 @@ + { + UWARN("Conversion from 4 channels to 3 channels (file=%s)", imageFilePath.c_str()); + cv::Mat out; +- cv::cvtColor(img, out, CV_BGRA2BGR); ++ cv::cvtColor(img, out, cv::COLOR_BGRA2BGR); + img = out; + } + else if(!img.empty() && _bayerMode >= 0 && _bayerMode <=3) +@@ -941,7 +941,7 @@ + cv::Mat debayeredImg; + try + { +- cv::cvtColor(img, debayeredImg, CV_BayerBG2BGR + _bayerMode); ++ cv::cvtColor(img, debayeredImg, cv::COLOR_BayerBG2BGR + _bayerMode); + img = debayeredImg; + } + catch(const cv::Exception & e) +diff -ruN a/corelib/src/camera/CameraK4A.cpp b/corelib/src/camera/CameraK4A.cpp +--- a/corelib/src/camera/CameraK4A.cpp ++++ b/corelib/src/camera/CameraK4A.cpp +@@ -29,7 +29,6 @@ + #include + #include + #include +-#include + + #ifdef RTABMAP_K4A + #include +@@ -508,7 +507,7 @@ + CV_8UC4, + (void*)k4a_image_get_buffer(rgb_image_)); + +- cv::cvtColor(bgra, bgrCV, CV_BGRA2BGR); ++ cv::cvtColor(bgra, bgrCV, cv::COLOR_BGRA2BGR); + } + bgrCV = model_.rectifyImage(bgrCV); + +diff -ruN a/corelib/src/camera/CameraK4W2.cpp b/corelib/src/camera/CameraK4W2.cpp +--- a/corelib/src/camera/CameraK4W2.cpp ++++ b/corelib/src/camera/CameraK4W2.cpp +@@ -28,7 +28,6 @@ + #include + #include + #include +-#include + + #ifdef RTABMAP_K4W2 + #include +@@ -486,11 +485,11 @@ + { + cv::Mat tmp; + cv::resize(cv::Mat(nColorHeight, nColorWidth, CV_8UC4, pColorBuffer), tmp, cv::Size(), 0.5, 0.5, cv::INTER_AREA); +- cv::cvtColor(tmp, imageColor, CV_BGRA2BGR); ++ cv::cvtColor(tmp, imageColor, cv::COLOR_BGRA2BGR); + } + else + { +- cv::cvtColor(cv::Mat(nColorHeight, nColorWidth, CV_8UC4, pColorBuffer), imageColor, CV_BGRA2BGR); ++ cv::cvtColor(cv::Mat(nColorHeight, nColorWidth, CV_8UC4, pColorBuffer), imageColor, cv::COLOR_BGRA2BGR); + } + // loop over output pixels + for (int depthIndex = 0; depthIndex < (nDepthWidth*nDepthHeight); ++depthIndex) +diff -ruN a/corelib/src/camera/CameraOpenNI2.cpp b/corelib/src/camera/CameraOpenNI2.cpp +--- a/corelib/src/camera/CameraOpenNI2.cpp ++++ b/corelib/src/camera/CameraOpenNI2.cpp +@@ -29,7 +29,6 @@ + #include + #include + #include +-#include + + #ifdef RTABMAP_OPENNI2 + #include +@@ -514,7 +513,7 @@ + cv::Mat tmp(h, w, CV_8UC3, (void *)colorFrame.getData()); + if(_type==kTypeColorDepth) + { +- cv::cvtColor(tmp, rgb, CV_RGB2BGR); ++ cv::cvtColor(tmp, rgb, cv::COLOR_RGB2BGR); + } + else // IR + { +diff -ruN a/corelib/src/camera/CameraOpenNICV.cpp b/corelib/src/camera/CameraOpenNICV.cpp +--- a/corelib/src/camera/CameraOpenNICV.cpp ++++ b/corelib/src/camera/CameraOpenNICV.cpp +@@ -26,9 +26,7 @@ + + #include + #include +-#if CV_MAJOR_VERSION > 3 +-#include +-#endif ++#include + + namespace rtabmap + { +@@ -59,30 +57,34 @@ + } + + ULOGGER_DEBUG("Camera::init()"); +- _capture.open( _asus?CV_CAP_OPENNI_ASUS:CV_CAP_OPENNI ); ++#if CV_MAJOR_VERSION < 5 ++ _capture.open( _asus?cv::CAP_OPENNI_ASUS:cv::CAP_OPENNI ); ++#else ++ _capture.open( _asus?cv::CAP_OPENNI2_ASUS:cv::CAP_OPENNI2 ); ++#endif + if(_capture.isOpened()) + { +- _capture.set( CV_CAP_OPENNI_IMAGE_GENERATOR_OUTPUT_MODE, CV_CAP_OPENNI_VGA_30HZ ); +- _depthFocal = _capture.get( CV_CAP_OPENNI_DEPTH_GENERATOR_FOCAL_LENGTH ); ++ _capture.set( cv::CAP_OPENNI_IMAGE_GENERATOR_OUTPUT_MODE, cv::CAP_OPENNI_VGA_30HZ ); ++ _depthFocal = _capture.get( cv::CAP_OPENNI_DEPTH_GENERATOR_FOCAL_LENGTH ); + // Print some avalible device settings. + UINFO("Depth generator output mode:"); +- UINFO("FRAME_WIDTH %f", _capture.get( CV_CAP_PROP_FRAME_WIDTH )); +- UINFO("FRAME_HEIGHT %f", _capture.get( CV_CAP_PROP_FRAME_HEIGHT )); +- UINFO("FRAME_MAX_DEPTH %f mm", _capture.get( CV_CAP_PROP_OPENNI_FRAME_MAX_DEPTH )); +- UINFO("BASELINE %f mm", _capture.get( CV_CAP_PROP_OPENNI_BASELINE )); +- UINFO("FPS %f", _capture.get( CV_CAP_PROP_FPS )); +- UINFO("Focal %f", _capture.get( CV_CAP_OPENNI_DEPTH_GENERATOR_FOCAL_LENGTH )); +- UINFO("REGISTRATION %f", _capture.get( CV_CAP_PROP_OPENNI_REGISTRATION )); +- if(_capture.get( CV_CAP_PROP_OPENNI_REGISTRATION ) == 0.0) ++ UINFO("FRAME_WIDTH %f", _capture.get( cv::CAP_PROP_FRAME_WIDTH )); ++ UINFO("FRAME_HEIGHT %f", _capture.get( cv::CAP_PROP_FRAME_HEIGHT )); ++ UINFO("FRAME_MAX_DEPTH %f mm", _capture.get( cv::CAP_PROP_OPENNI_FRAME_MAX_DEPTH )); ++ UINFO("BASELINE %f mm", _capture.get( cv::CAP_PROP_OPENNI_BASELINE )); ++ UINFO("FPS %f", _capture.get( cv::CAP_PROP_FPS )); ++ UINFO("Focal %f", _capture.get( cv::CAP_OPENNI_DEPTH_GENERATOR_FOCAL_LENGTH )); ++ UINFO("REGISTRATION %f", _capture.get( cv::CAP_PROP_OPENNI_REGISTRATION )); ++ if(_capture.get( cv::CAP_PROP_OPENNI_REGISTRATION ) == 0.0) + { + UERROR("Depth registration is not activated on this device!"); + } +- if( _capture.get( CV_CAP_OPENNI_IMAGE_GENERATOR_PRESENT ) ) ++ if( _capture.get( cv::CAP_OPENNI_IMAGE_GENERATOR_PRESENT ) ) + { + UINFO("Image generator output mode:"); +- UINFO("FRAME_WIDTH %f", _capture.get( CV_CAP_OPENNI_IMAGE_GENERATOR+CV_CAP_PROP_FRAME_WIDTH )); +- UINFO("FRAME_HEIGHT %f", _capture.get( CV_CAP_OPENNI_IMAGE_GENERATOR+CV_CAP_PROP_FRAME_HEIGHT )); +- UINFO("FPS %f", _capture.get( CV_CAP_OPENNI_IMAGE_GENERATOR+CV_CAP_PROP_FPS )); ++ UINFO("FRAME_WIDTH %f", _capture.get( cv::CAP_OPENNI_IMAGE_GENERATOR+cv::CAP_PROP_FRAME_WIDTH )); ++ UINFO("FRAME_HEIGHT %f", _capture.get( cv::CAP_OPENNI_IMAGE_GENERATOR+cv::CAP_PROP_FRAME_HEIGHT )); ++ UINFO("FPS %f", _capture.get( cv::CAP_OPENNI_IMAGE_GENERATOR+cv::CAP_PROP_FPS )); + } + else + { +@@ -112,8 +114,8 @@ + { + _capture.grab(); + cv::Mat depth, rgb; +- _capture.retrieve(depth, CV_CAP_OPENNI_DEPTH_MAP ); +- _capture.retrieve(rgb, CV_CAP_OPENNI_BGR_IMAGE ); ++ _capture.retrieve(depth, cv::CAP_OPENNI_DEPTH_MAP ); ++ _capture.retrieve(rgb, cv::CAP_OPENNI_BGR_IMAGE ); + + depth = depth.clone(); + rgb = rgb.clone(); +diff -ruN a/corelib/src/camera/CameraOpenni.cpp b/corelib/src/camera/CameraOpenni.cpp +--- a/corelib/src/camera/CameraOpenni.cpp ++++ b/corelib/src/camera/CameraOpenni.cpp +@@ -28,7 +28,6 @@ + #include + #include + #include +-#include + + #ifdef RTABMAP_OPENNI + #include +@@ -94,7 +93,7 @@ + + cv::Mat rgbFrame(rgb->getHeight(), rgb->getWidth(), CV_8UC3); + rgb->fillRGB(rgb->getWidth(), rgb->getHeight(), rgbFrame.data); +- cv::cvtColor(rgbFrame, rgb_, CV_RGB2BGR); ++ cv::cvtColor(rgbFrame, rgb_, cv::COLOR_RGB2BGR); + + depth_ = cv::Mat(rgb->getHeight(), rgb->getWidth(), CV_16UC1); + depth->fillDepthImageRaw(rgb->getWidth(), rgb->getHeight(), (unsigned short*)depth_.data); +diff -ruN a/corelib/src/camera/CameraRealSense.cpp b/corelib/src/camera/CameraRealSense.cpp +--- a/corelib/src/camera/CameraRealSense.cpp ++++ b/corelib/src/camera/CameraRealSense.cpp +@@ -29,7 +29,6 @@ + #include + #include + #include +-#include + + #ifdef RTABMAP_REALSENSE + #include +@@ -938,7 +937,7 @@ + } + else + { +- cv::cvtColor(rgb, bgr, CV_RGB2BGR); ++ cv::cvtColor(rgb, bgr, cv::COLOR_RGB2BGR); + } + + bool rectified = false; +diff -ruN a/corelib/src/camera/CameraRealSense2.cpp b/corelib/src/camera/CameraRealSense2.cpp +--- a/corelib/src/camera/CameraRealSense2.cpp ++++ b/corelib/src/camera/CameraRealSense2.cpp +@@ -31,7 +31,6 @@ + #include + #include + #include +-#include + + #ifdef RTABMAP_REALSENSE2 + #include +diff -ruN a/corelib/src/camera/CameraStereoDC1394.cpp b/corelib/src/camera/CameraStereoDC1394.cpp +--- a/corelib/src/camera/CameraStereoDC1394.cpp ++++ b/corelib/src/camera/CameraStereoDC1394.cpp +@@ -28,7 +28,6 @@ + #include + #include + #include +-#include + + #ifdef RTABMAP_DC1394 + #include +@@ -295,8 +294,8 @@ + + //DC1394_COLOR_CODING_RAW16: + //DC1394_COLOR_FILTER_BGGR +- cv::cvtColor(cv::Mat(frame->size[1], frame->size[0], CV_8UC1, capture_buffer), left, CV_BayerRG2BGR); +- cv::cvtColor(cv::Mat(frame->size[1], frame->size[0], CV_8UC1, capture_buffer+image.total()), right, CV_BayerRG2GRAY); ++ cv::cvtColor(cv::Mat(frame->size[1], frame->size[0], CV_8UC1, capture_buffer), left, cv::COLOR_BayerRG2BGR); ++ cv::cvtColor(cv::Mat(frame->size[1], frame->size[0], CV_8UC1, capture_buffer+image.total()), right, cv::COLOR_BayerRG2GRAY); + + dc1394_capture_enqueue(camera_, frame); + +diff -ruN a/corelib/src/camera/CameraStereoImages.cpp b/corelib/src/camera/CameraStereoImages.cpp +--- a/corelib/src/camera/CameraStereoImages.cpp ++++ b/corelib/src/camera/CameraStereoImages.cpp +@@ -27,7 +27,6 @@ + + #include + #include +-#include + + namespace rtabmap + { +@@ -184,7 +183,7 @@ + if(rightImage.type() != CV_8UC1 && rightGrayScale_) + { + cv::Mat tmp; +- cv::cvtColor(rightImage, tmp, CV_BGR2GRAY); ++ cv::cvtColor(rightImage, tmp, cv::COLOR_BGR2GRAY); + rightImage = tmp; + } + if(this->isImagesRectified() && stereoModel_.isValidForRectification()) +diff -ruN a/corelib/src/camera/CameraStereoTara.cpp b/corelib/src/camera/CameraStereoTara.cpp +--- a/corelib/src/camera/CameraStereoTara.cpp ++++ b/corelib/src/camera/CameraStereoTara.cpp +@@ -34,9 +34,7 @@ + #include + #include + #include +-#if CV_MAJOR_VERSION > 3 +-#include +-#endif ++#include + + namespace rtabmap + { +@@ -81,18 +79,18 @@ + + capture_.open(usbDevice_); + +- capture_.set(CV_CAP_PROP_FOURCC, CV_FOURCC('Y', '1', '6', ' ')); +- capture_.set(CV_CAP_PROP_FPS, 60); +- capture_.set(CV_CAP_PROP_FRAME_WIDTH, 752); +- capture_.set(CV_CAP_PROP_FRAME_HEIGHT, 480); +- capture_.set(CV_CAP_PROP_CONVERT_RGB,false); ++ capture_.set(cv::CAP_PROP_FOURCC, cv::VideoWriter::fourcc('Y', '1', '6', ' ')); ++ capture_.set(cv::CAP_PROP_FPS, 60); ++ capture_.set(cv::CAP_PROP_FRAME_WIDTH, 752); ++ capture_.set(cv::CAP_PROP_FRAME_HEIGHT, 480); ++ capture_.set(cv::CAP_PROP_CONVERT_RGB,false); + + ULOGGER_DEBUG("CameraStereoTara: Usb device initialization on device %d", usbDevice_); + + + if (cameraName_.empty()) + { +- unsigned int guid = (unsigned int)capture_.get(CV_CAP_PROP_GUID); ++ unsigned int guid = (unsigned int)capture_.get(cv::CAP_PROP_GUID); + if (guid != 0 && guid != 0xffffffff) + { + cameraName_ = uFormat("%08x", guid); +diff -ruN a/corelib/src/camera/CameraStereoVideo.cpp b/corelib/src/camera/CameraStereoVideo.cpp +--- a/corelib/src/camera/CameraStereoVideo.cpp ++++ b/corelib/src/camera/CameraStereoVideo.cpp +@@ -28,13 +28,7 @@ + #include + #include + #include +-#include +-#if CV_MAJOR_VERSION > 3 +-#include +-#if CV_MAJOR_VERSION > 4 +-#include +-#endif +-#endif ++#include + + namespace rtabmap + { +@@ -172,7 +166,7 @@ + + if (cameraName_.empty()) + { +- unsigned int guid = (unsigned int)capture_.get(CV_CAP_PROP_GUID); ++ unsigned int guid = (unsigned int)capture_.get(cv::CAP_PROP_GUID); + if (guid != 0 && guid != 0xffffffff) + { + cameraName_ = uFormat("%08x", guid); +@@ -214,17 +208,17 @@ + if(capture_.isOpened()) + { + bool resolutionSet = false; +- resolutionSet = capture_.set(CV_CAP_PROP_FRAME_WIDTH, stereoModel_.left().imageWidth()*(capture2_.isOpened()?1:2)); +- resolutionSet = resolutionSet && capture_.set(CV_CAP_PROP_FRAME_HEIGHT, stereoModel_.left().imageHeight()); ++ resolutionSet = capture_.set(cv::CAP_PROP_FRAME_WIDTH, stereoModel_.left().imageWidth()*(capture2_.isOpened()?1:2)); ++ resolutionSet = resolutionSet && capture_.set(cv::CAP_PROP_FRAME_HEIGHT, stereoModel_.left().imageHeight()); + if(capture2_.isOpened()) + { +- resolutionSet = resolutionSet && capture2_.set(CV_CAP_PROP_FRAME_WIDTH, stereoModel_.right().imageWidth()); +- resolutionSet = resolutionSet && capture2_.set(CV_CAP_PROP_FRAME_HEIGHT, stereoModel_.right().imageHeight()); ++ resolutionSet = resolutionSet && capture2_.set(cv::CAP_PROP_FRAME_WIDTH, stereoModel_.right().imageWidth()); ++ resolutionSet = resolutionSet && capture2_.set(cv::CAP_PROP_FRAME_HEIGHT, stereoModel_.right().imageHeight()); + } + + // Check if the resolution was set successfully +- int actualWidth = int(capture_.get(CV_CAP_PROP_FRAME_WIDTH)); +- int actualHeight = int(capture_.get(CV_CAP_PROP_FRAME_HEIGHT)); ++ int actualWidth = int(capture_.get(cv::CAP_PROP_FRAME_WIDTH)); ++ int actualHeight = int(capture_.get(cv::CAP_PROP_FRAME_HEIGHT)); + if(!resolutionSet || + actualWidth != stereoModel_.left().imageWidth()*(capture2_.isOpened()?1:2) || + actualHeight != stereoModel_.left().imageHeight()) +@@ -244,17 +238,17 @@ + if(capture_.isOpened()) + { + bool resolutionSet = false; +- resolutionSet = capture_.set(CV_CAP_PROP_FRAME_WIDTH, _width*(capture2_.isOpened()?1:2)); +- resolutionSet = resolutionSet && capture_.set(CV_CAP_PROP_FRAME_HEIGHT, _height); ++ resolutionSet = capture_.set(cv::CAP_PROP_FRAME_WIDTH, _width*(capture2_.isOpened()?1:2)); ++ resolutionSet = resolutionSet && capture_.set(cv::CAP_PROP_FRAME_HEIGHT, _height); + if(capture2_.isOpened()) + { +- resolutionSet = resolutionSet && capture2_.set(CV_CAP_PROP_FRAME_WIDTH, _width); +- resolutionSet = resolutionSet && capture2_.set(CV_CAP_PROP_FRAME_HEIGHT, _height); ++ resolutionSet = resolutionSet && capture2_.set(cv::CAP_PROP_FRAME_WIDTH, _width); ++ resolutionSet = resolutionSet && capture2_.set(cv::CAP_PROP_FRAME_HEIGHT, _height); + } + + // Check if the resolution was set successfully +- int actualWidth = int(capture_.get(CV_CAP_PROP_FRAME_WIDTH)); +- int actualHeight = int(capture_.get(CV_CAP_PROP_FRAME_HEIGHT)); ++ int actualWidth = int(capture_.get(cv::CAP_PROP_FRAME_WIDTH)); ++ int actualHeight = int(capture_.get(cv::CAP_PROP_FRAME_HEIGHT)); + if(!resolutionSet || + actualWidth != _width*(capture2_.isOpened()?1:2) || + actualHeight != _height) +@@ -273,10 +267,10 @@ + if (this->getFrameRate() > 0) + { + bool fpsSupported = false; +- fpsSupported = capture_.set(CV_CAP_PROP_FPS, this->getFrameRate()); ++ fpsSupported = capture_.set(cv::CAP_PROP_FPS, this->getFrameRate()); + if (capture2_.isOpened()) + { +- fpsSupported = fpsSupported && capture2_.set(CV_CAP_PROP_FPS, this->getFrameRate()); ++ fpsSupported = fpsSupported && capture2_.set(cv::CAP_PROP_FPS, this->getFrameRate()); + } + if(fpsSupported) + { +@@ -310,14 +304,14 @@ + std::string fourccUpperCase = uToUpperCase(_fourcc); + int fourcc = cv::VideoWriter::fourcc(fourccUpperCase.at(0), fourccUpperCase.at(1), fourccUpperCase.at(2), fourccUpperCase.at(3)); + bool fourccSupported = false; +- fourccSupported = capture_.set(CV_CAP_PROP_FOURCC, fourcc); ++ fourccSupported = capture_.set(cv::CAP_PROP_FOURCC, fourcc); + if (capture2_.isOpened()) + { +- fourccSupported = fourccSupported && capture2_.set(CV_CAP_PROP_FOURCC, fourcc); ++ fourccSupported = fourccSupported && capture2_.set(cv::CAP_PROP_FOURCC, fourcc); + } + + // Check if the FOURCC was set successfully +- int actualFourcc = int(capture_.get(CV_CAP_PROP_FOURCC)); ++ int actualFourcc = int(capture_.get(cv::CAP_PROP_FOURCC)); + + if(!fourccSupported || actualFourcc != fourcc) + { +@@ -386,7 +380,7 @@ + if(rightImage.type() != CV_8UC1 && rightGrayScale_) + { + cv::Mat tmp; +- cv::cvtColor(rightImage, tmp, CV_BGR2GRAY); ++ cv::cvtColor(rightImage, tmp, cv::COLOR_BGR2GRAY); + rightImage = tmp; + rightCvt = true; + } +diff -ruN a/corelib/src/camera/CameraStereoZedOC.cpp b/corelib/src/camera/CameraStereoZedOC.cpp +--- a/corelib/src/camera/CameraStereoZedOC.cpp ++++ b/corelib/src/camera/CameraStereoZedOC.cpp +@@ -38,6 +38,10 @@ + #include + #include "SimpleIni.h" + ++#if CV_MAJOR_VERSION >= 5 ++#include ++#endif ++ + /////////////////////////////////////////////////////////////////////////// + // + // Copyright (c) 2018, STEREOLABS. +diff -ruN a/corelib/src/camera/CameraVideo.cpp b/corelib/src/camera/CameraVideo.cpp +--- a/corelib/src/camera/CameraVideo.cpp ++++ b/corelib/src/camera/CameraVideo.cpp +@@ -28,12 +28,7 @@ + #include + #include + #include +-#if CV_MAJOR_VERSION > 3 +-#include +-#if CV_MAJOR_VERSION > 4 +-#include +-#endif +-#endif ++#include + + namespace rtabmap + { +@@ -105,7 +100,7 @@ + { + if (_guid.empty()) + { +- unsigned int guid = (unsigned int)_capture.get(CV_CAP_PROP_GUID); ++ unsigned int guid = (unsigned int)_capture.get(cv::CAP_PROP_GUID); + if (guid != 0 && guid != 0xffffffff) + { + _guid = uFormat("%08x", guid); +@@ -143,12 +138,12 @@ + } + + bool resolutionSet = false; +- resolutionSet = _capture.set(CV_CAP_PROP_FRAME_WIDTH, _model.imageWidth()); +- resolutionSet = resolutionSet && _capture.set(CV_CAP_PROP_FRAME_HEIGHT, _model.imageHeight()); ++ resolutionSet = _capture.set(cv::CAP_PROP_FRAME_WIDTH, _model.imageWidth()); ++ resolutionSet = resolutionSet && _capture.set(cv::CAP_PROP_FRAME_HEIGHT, _model.imageHeight()); + + // Check if the resolution was set successfully +- int actualWidth = int(_capture.get(CV_CAP_PROP_FRAME_WIDTH)); +- int actualHeight = int(_capture.get(CV_CAP_PROP_FRAME_HEIGHT)); ++ int actualWidth = int(_capture.get(cv::CAP_PROP_FRAME_WIDTH)); ++ int actualHeight = int(_capture.get(cv::CAP_PROP_FRAME_HEIGHT)); + if(!resolutionSet || + actualWidth != _model.imageWidth() || + actualHeight != _model.imageHeight()) +@@ -165,12 +160,12 @@ + else if(_width > 0 && _height > 0) + { + int resolutionSet = false; +- resolutionSet = _capture.set(CV_CAP_PROP_FRAME_WIDTH, _width); +- resolutionSet = resolutionSet && _capture.set(CV_CAP_PROP_FRAME_HEIGHT, _height); ++ resolutionSet = _capture.set(cv::CAP_PROP_FRAME_WIDTH, _width); ++ resolutionSet = resolutionSet && _capture.set(cv::CAP_PROP_FRAME_HEIGHT, _height); + + // Check if the resolution was set successfully +- int actualWidth = int(_capture.get(CV_CAP_PROP_FRAME_WIDTH)); +- int actualHeight = int(_capture.get(CV_CAP_PROP_FRAME_HEIGHT)); ++ int actualWidth = int(_capture.get(cv::CAP_PROP_FRAME_WIDTH)); ++ int actualHeight = int(_capture.get(cv::CAP_PROP_FRAME_HEIGHT)); + if(!resolutionSet || actualWidth != _width || actualHeight != _height) + { + UWARN("Desired resolution (%dx%d) cannot be set to camera driver, " +@@ -182,7 +177,7 @@ + } + + // Set FPS +- if (this->getFrameRate() > 0 && _capture.set(CV_CAP_PROP_FPS, this->getFrameRate())) ++ if (this->getFrameRate() > 0 && _capture.set(cv::CAP_PROP_FPS, this->getFrameRate())) + { + // Check if the FPS was set successfully + double actualFPS = _capture.get(cv::CAP_PROP_FPS); +@@ -213,10 +208,10 @@ + std::string fourccUpperCase = uToUpperCase(_fourcc); + int fourcc = cv::VideoWriter::fourcc(fourccUpperCase.at(0), fourccUpperCase.at(1), fourccUpperCase.at(2), fourccUpperCase.at(3)); + +- bool fourccSupported = _capture.set(CV_CAP_PROP_FOURCC, fourcc); ++ bool fourccSupported = _capture.set(cv::CAP_PROP_FOURCC, fourcc); + + // Check if the FOURCC was set successfully +- int actualFourcc = int(_capture.get(CV_CAP_PROP_FOURCC)); ++ int actualFourcc = int(_capture.get(cv::CAP_PROP_FOURCC)); + + if(!fourccSupported || actualFourcc != fourcc) + { +diff -ruN a/corelib/src/odometry/OdometryDVO.cpp b/corelib/src/odometry/OdometryDVO.cpp +--- a/corelib/src/odometry/OdometryDVO.cpp ++++ b/corelib/src/odometry/OdometryDVO.cpp +@@ -31,7 +31,6 @@ + #include "rtabmap/utilite/ULogger.h" + #include "rtabmap/utilite/UTimer.h" + #include "rtabmap/utilite/UStl.h" +-#include + + #ifdef RTABMAP_DVO + #include +@@ -124,7 +123,7 @@ + { + if(data.imageRaw().type() == CV_8UC3) + { +- cv::cvtColor(data.imageRaw(), grey, CV_BGR2GRAY); ++ cv::cvtColor(data.imageRaw(), grey, cv::COLOR_BGR2GRAY); + } + else + { +diff -ruN a/corelib/src/odometry/OdometryF2M.cpp b/corelib/src/odometry/OdometryF2M.cpp +--- a/corelib/src/odometry/OdometryF2M.cpp ++++ b/corelib/src/odometry/OdometryF2M.cpp +@@ -42,7 +42,11 @@ + #include "rtabmap/utilite/UTimer.h" + #include "rtabmap/utilite/UMath.h" + #include "rtabmap/utilite/UConversion.h" ++#if CV_MAJOR_VERSION < 5 + #include ++#else ++#include ++#endif + #include + #include + +diff -ruN a/corelib/src/odometry/OdometryFovis.cpp b/corelib/src/odometry/OdometryFovis.cpp +--- a/corelib/src/odometry/OdometryFovis.cpp ++++ b/corelib/src/odometry/OdometryFovis.cpp +@@ -31,7 +31,6 @@ + #include "rtabmap/utilite/ULogger.h" + #include "rtabmap/utilite/UTimer.h" + #include "rtabmap/utilite/UStl.h" +-#include + + #ifdef RTABMAP_FOVIS + #include +@@ -137,7 +136,7 @@ + cv::Mat gray; + if(data.imageRaw().type() == CV_8UC3) + { +- cv::cvtColor(data.imageRaw(), gray, CV_BGR2GRAY); ++ cv::cvtColor(data.imageRaw(), gray, cv::COLOR_BGR2GRAY); + } + else if(data.imageRaw().type() == CV_8UC1) + { +@@ -302,7 +301,7 @@ + } + if(data.rightRaw().type() == CV_8UC3) + { +- cv::cvtColor(data.rightRaw(), right, CV_BGR2GRAY); ++ cv::cvtColor(data.rightRaw(), right, cv::COLOR_BGR2GRAY); + } + else if(data.rightRaw().type() == CV_8UC1) + { +diff -ruN a/corelib/src/odometry/OdometryMSCKF.cpp b/corelib/src/odometry/OdometryMSCKF.cpp +--- a/corelib/src/odometry/OdometryMSCKF.cpp ++++ b/corelib/src/odometry/OdometryMSCKF.cpp +@@ -26,13 +26,15 @@ + */ + + #include "rtabmap/core/odometry/OdometryMSCKF.h" ++#if CV_MAJOR_VERSION >= 5 ++#include ++#endif + #include "rtabmap/core/OdometryInfo.h" + #include "rtabmap/core/util3d_transforms.h" + #include "rtabmap/utilite/ULogger.h" + #include "rtabmap/utilite/UTimer.h" + #include "rtabmap/utilite/UStl.h" + #include "rtabmap/utilite/UThread.h" +-#include + + #ifdef RTABMAP_MSCKF_VIO + #include +@@ -867,7 +869,7 @@ + + if(data.imageRaw().type() == CV_8UC3) + { +- cv::cvtColor(data.imageRaw(), cam0.image, CV_BGR2GRAY); ++ cv::cvtColor(data.imageRaw(), cam0.image, cv::COLOR_BGR2GRAY); + } + else + { +@@ -875,7 +877,7 @@ + } + if(data.rightRaw().type() == CV_8UC3) + { +- cv::cvtColor(data.rightRaw(), cam1.image, CV_BGR2GRAY); ++ cv::cvtColor(data.rightRaw(), cam1.image, cv::COLOR_BGR2GRAY); + } + else + { +diff -ruN a/corelib/src/odometry/OdometryMono.cpp b/corelib/src/odometry/OdometryMono.cpp +--- a/corelib/src/odometry/OdometryMono.cpp ++++ b/corelib/src/odometry/OdometryMono.cpp +@@ -43,8 +43,15 @@ + #include "rtabmap/utilite/UStl.h" + #include "rtabmap/utilite/UMath.h" + #include ++#if CV_MAJOR_VERSION < 5 + #include ++#else ++#include ++#endif + #include ++#if CV_MAJOR_VERSION >= 5 ++#include ++#endif + #include + + namespace rtabmap { +diff -ruN a/corelib/src/odometry/OdometryORBSLAM2.cpp b/corelib/src/odometry/OdometryORBSLAM2.cpp +--- a/corelib/src/odometry/OdometryORBSLAM2.cpp ++++ b/corelib/src/odometry/OdometryORBSLAM2.cpp +@@ -33,7 +33,6 @@ + #include "rtabmap/utilite/UStl.h" + #include "rtabmap/utilite/UDirectory.h" + #include +-#include + #include + + #if defined(RTABMAP_ORB_SLAM) and RTABMAP_ORB_SLAM == 2 +@@ -426,7 +425,7 @@ + } + else + { +- cvtColor(mImGray,mImGray,CV_BGR2GRAY); ++ cvtColor(mImGray,mImGray,cv::COLOR_BGR2GRAY); + } + } + else if(mImGray.channels()==4) +@@ -437,7 +436,7 @@ + } + else + { +- cvtColor(mImGray,mImGray,CV_BGRA2GRAY); ++ cvtColor(mImGray,mImGray,cv::COLOR_BGRA2GRAY); + } + } + if(imGrayRight.channels()==3) +@@ -448,7 +447,7 @@ + } + else + { +- cvtColor(imGrayRight,imGrayRight,CV_BGR2GRAY); ++ cvtColor(imGrayRight,imGrayRight,cv::COLOR_BGR2GRAY); + } + } + else if(imGrayRight.channels()==4) +@@ -459,7 +458,7 @@ + } + else + { +- cvtColor(imGrayRight,imGrayRight,CV_BGRA2GRAY); ++ cvtColor(imGrayRight,imGrayRight,cv::COLOR_BGRA2GRAY); + } + } + +@@ -480,14 +479,14 @@ + if(mbRGB) + cvtColor(mImGray,mImGray,CV_RGB2GRAY); + else +- cvtColor(mImGray,mImGray,CV_BGR2GRAY); ++ cvtColor(mImGray,mImGray,cv::COLOR_BGR2GRAY); + } + else if(mImGray.channels()==4) + { + if(mbRGB) + cvtColor(mImGray,mImGray,CV_RGBA2GRAY); + else +- cvtColor(mImGray,mImGray,CV_BGRA2GRAY); ++ cvtColor(mImGray,mImGray,cv::COLOR_BGRA2GRAY); + } + + UASSERT(imDepth.type()==CV_32F); +diff -ruN a/corelib/src/odometry/OdometryORBSLAM3.cpp b/corelib/src/odometry/OdometryORBSLAM3.cpp +--- a/corelib/src/odometry/OdometryORBSLAM3.cpp ++++ b/corelib/src/odometry/OdometryORBSLAM3.cpp +@@ -34,7 +34,6 @@ + #include "rtabmap/utilite/UDirectory.h" + #include "rtabmap/utilite/UFile.h" + #include +-#include + #include + + #if defined(RTABMAP_ORB_SLAM) and RTABMAP_ORB_SLAM == 3 +@@ -469,12 +468,12 @@ + cv::Mat leftMono = data.imageRaw(); + if(data.imageRaw().channels() == 3) { + leftMono = cv::Mat(); +- cv::cvtColor(data.imageRaw(), leftMono, CV_BGR2GRAY); ++ cv::cvtColor(data.imageRaw(), leftMono, cv::COLOR_BGR2GRAY); + } + cv::Mat rightMono = data.rightRaw(); + if(data.rightRaw().channels() == 3) { + rightMono = cv::Mat(); +- cv::cvtColor(data.imageRaw(), rightMono, CV_BGR2GRAY); ++ cv::cvtColor(data.imageRaw(), rightMono, cv::COLOR_BGR2GRAY); + } + UDEBUG("Adding Stereo Frame %f", data.stamp()); + Tcw = orbslam_->TrackStereo(leftMono, rightMono, data.stamp(), orbslamImus_); +diff -ruN a/corelib/src/odometry/OdometryOkvis.cpp b/corelib/src/odometry/OdometryOkvis.cpp +--- a/corelib/src/odometry/OdometryOkvis.cpp ++++ b/corelib/src/odometry/OdometryOkvis.cpp +@@ -34,7 +34,6 @@ + #include "rtabmap/utilite/UThread.h" + #include "rtabmap/utilite/UFile.h" + #include "rtabmap/utilite/UDirectory.h" +-#include + + #ifdef RTABMAP_OKVIS + #include +@@ -427,7 +426,7 @@ + cv::Mat gray; + if(images[i].type() == CV_8UC3) + { +- cv::cvtColor(images[i], gray, CV_BGR2GRAY); ++ cv::cvtColor(images[i], gray, cv::COLOR_BGR2GRAY); + } + else if(images[i].type() == CV_8UC1) + { +diff -ruN a/corelib/src/odometry/OdometryOpenVINS.cpp b/corelib/src/odometry/OdometryOpenVINS.cpp +--- a/corelib/src/odometry/OdometryOpenVINS.cpp ++++ b/corelib/src/odometry/OdometryOpenVINS.cpp +@@ -32,7 +32,6 @@ + #include "rtabmap/utilite/ULogger.h" + #include "rtabmap/utilite/UTimer.h" + #include +-#include + + #ifdef RTABMAP_OPENVINS + #include "core/VioManager.h" +@@ -419,7 +418,7 @@ + + cv::Mat image; + if(data.imageRaw().type() == CV_8UC3) +- cv::cvtColor(data.imageRaw(), image, CV_BGR2GRAY); ++ cv::cvtColor(data.imageRaw(), image, cv::COLOR_BGR2GRAY); + else if(data.imageRaw().type() == CV_8UC1) + image = data.imageRaw().clone(); + else +@@ -450,7 +449,7 @@ + if(!data.rightRaw().empty()) + { + if(data.rightRaw().type() == CV_8UC3) +- cv::cvtColor(data.rightRaw(), image, CV_BGR2GRAY); ++ cv::cvtColor(data.rightRaw(), image, cv::COLOR_BGR2GRAY); + else if(data.rightRaw().type() == CV_8UC1) + image = data.rightRaw().clone(); + else +diff -ruN a/corelib/src/odometry/OdometryVINSFusion.cpp b/corelib/src/odometry/OdometryVINSFusion.cpp +--- a/corelib/src/odometry/OdometryVINSFusion.cpp ++++ b/corelib/src/odometry/OdometryVINSFusion.cpp +@@ -33,7 +33,6 @@ + #include "rtabmap/utilite/UStl.h" + #include "rtabmap/utilite/UThread.h" + #include "rtabmap/utilite/UDirectory.h" +-#include + + #ifdef RTABMAP_VINS_FUSION + #include +diff -ruN a/corelib/src/odometry/OdometryViso2.cpp b/corelib/src/odometry/OdometryViso2.cpp +--- a/corelib/src/odometry/OdometryViso2.cpp ++++ b/corelib/src/odometry/OdometryViso2.cpp +@@ -31,7 +31,6 @@ + #include "rtabmap/utilite/ULogger.h" + #include "rtabmap/utilite/UTimer.h" + #include "rtabmap/utilite/UStl.h" +-#include + + #ifdef RTABMAP_VISO2 + #include +@@ -131,7 +130,7 @@ + cv::Mat leftGray; + if(data.imageRaw().type() == CV_8UC3) + { +- cv::cvtColor(data.imageRaw(), leftGray, CV_BGR2GRAY); ++ cv::cvtColor(data.imageRaw(), leftGray, cv::COLOR_BGR2GRAY); + } + else if(data.imageRaw().type() == CV_8UC1) + { +@@ -144,7 +143,7 @@ + cv::Mat rightGray; + if(data.rightRaw().type() == CV_8UC3) + { +- cv::cvtColor(data.rightRaw(), rightGray, CV_BGR2GRAY); ++ cv::cvtColor(data.rightRaw(), rightGray, cv::COLOR_BGR2GRAY); + } + else if(data.rightRaw().type() == CV_8UC1) + { +diff -ruN a/corelib/src/opencv/ORBextractor.cc b/corelib/src/opencv/ORBextractor.cc +--- a/corelib/src/opencv/ORBextractor.cc ++++ b/corelib/src/opencv/ORBextractor.cc +@@ -64,7 +64,11 @@ + + #include + #include ++#if CV_MAJOR_VERSION < 5 + #include ++#else ++#include ++#endif + #include + #include + #include +diff -ruN a/corelib/src/opencv/ORBextractor.h b/corelib/src/opencv/ORBextractor.h +--- a/corelib/src/opencv/ORBextractor.h ++++ b/corelib/src/opencv/ORBextractor.h +@@ -31,8 +31,6 @@ + + #include + #include +-#include +- + + namespace rtabmap + { +diff -ruN a/corelib/src/opencv/Orb.cpp b/corelib/src/opencv/Orb.cpp +--- a/corelib/src/opencv/Orb.cpp ++++ b/corelib/src/opencv/Orb.cpp +@@ -40,7 +40,6 @@ + + #include "opencv2/features2d/features2d.hpp" + #include "opencv2/imgproc/imgproc.hpp" +-#include "opencv2/imgproc/imgproc_c.h" + #include + #include + +@@ -252,7 +251,7 @@ + } + } + else +- CV_Error( CV_StsBadSize, "Wrong WTA_K. It can be only 2, 3 or 4." ); ++ CV_Error( cv::Error::StsBadSize, "Wrong WTA_K. It can be only 2, 3 or 4." ); + + #undef GET_VALUE + } +@@ -752,7 +751,7 @@ + + Mat image = _image.getMat(), mask = _mask.getMat(); + if( image.type() != CV_8UC1 ) +- cvtColor(_image, image, CV_BGR2GRAY); ++ cvtColor(_image, image, cv::COLOR_BGR2GRAY); + + int levelsNum = this->nlevels; + +diff -ruN a/corelib/src/opencv/five-point.cpp b/corelib/src/opencv/five-point.cpp +--- a/corelib/src/opencv/five-point.cpp ++++ b/corelib/src/opencv/five-point.cpp +@@ -30,6 +30,9 @@ + */ + + #include "solvepnp.h" ++#if CV_MAJOR_VERSION >= 5 ++#include ++#endif + + using namespace cv; + +diff -ruN a/corelib/src/opencv/five-point.h b/corelib/src/opencv/five-point.h +--- a/corelib/src/opencv/five-point.h ++++ b/corelib/src/opencv/five-point.h +@@ -8,6 +8,10 @@ + #ifndef CORELIB_SRC_OPENCV_FIVE_POINT_H_ + #define CORELIB_SRC_OPENCV_FIVE_POINT_H_ + ++#if CV_MAJOR_VERSION > 4 ++#include ++#endif ++ + namespace cv3 + { + +diff -ruN a/corelib/src/opencv/solvepnp.cpp b/corelib/src/opencv/solvepnp.cpp +--- a/corelib/src/opencv/solvepnp.cpp ++++ b/corelib/src/opencv/solvepnp.cpp +@@ -53,7 +53,7 @@ + + public: + +- PnPRansacCallback(Mat _cameraMatrix=Mat(3,3,CV_64F), Mat _distCoeffs=Mat(4,1,CV_64F), int _flags=CV_ITERATIVE, ++ PnPRansacCallback(Mat _cameraMatrix=Mat(3,3,CV_64F), Mat _distCoeffs=Mat(4,1,CV_64F), int _flags=cv::SOLVEPNP_ITERATIVE, + bool _useExtrinsicGuess=false, Mat _rvec=Mat(), Mat _tvec=Mat() ) + : cameraMatrix(_cameraMatrix), distCoeffs(_distCoeffs), flags(_flags), useExtrinsicGuess(_useExtrinsicGuess), + rvec(_rvec), tvec(_tvec) {} +@@ -142,12 +142,12 @@ + Mat cameraMatrix = _cameraMatrix.getMat(), distCoeffs = _distCoeffs.getMat(); + + int model_points = 6; +- int ransac_kernel_method = CV_EPNP; ++ int ransac_kernel_method = cv::SOLVEPNP_EPNP; + + if( npoints == 4 ) + { + model_points = 4; +- ransac_kernel_method = CV_P3P; ++ ransac_kernel_method = cv::SOLVEPNP_P3P; + } + + Ptr cb; // pointer to callback +@@ -178,7 +178,7 @@ + opoints_inliers.resize(npoints1); + ipoints_inliers.resize(npoints1); + result = solvePnP(opoints_inliers, ipoints_inliers, cameraMatrix, +- distCoeffs, rvec, tvec, useExtrinsicGuess, flags == CV_P3P ? CV_EPNP : flags) ? 1 : -1; ++ distCoeffs, rvec, tvec, useExtrinsicGuess, flags == cv::SOLVEPNP_P3P ? cv::SOLVEPNP_EPNP : flags) ? 1 : -1; + } + + if( result <= 0 || _local_model.rows <= 0) +@@ -213,7 +213,7 @@ + int RANSACUpdateNumIters( double p, double ep, int modelPoints, int maxIters ) + { + if( modelPoints <= 0 ) +- CV_Error( 0, "the number of model points should be positive" ); ++ CV_Error( cv::Error::Code::StsBadArg, "the number of model points should be positive" ); + + p = MAX(p, 0.); + p = MIN(p, 1.); +diff -ruN a/corelib/src/opencv/solvepnp.h b/corelib/src/opencv/solvepnp.h +--- a/corelib/src/opencv/solvepnp.h ++++ b/corelib/src/opencv/solvepnp.h +@@ -45,9 +45,10 @@ + #define RTABMAP_CORELIB_SRC_OPENCV_SOLVEPNP_H_ + + #include ++#if CV_MAJOR_VERSION >= 5 ++#include ++#else + #include +-#if CV_MAJOR_VERSION >= 3 +-#include + #endif + + namespace cv3 { +@@ -95,7 +96,7 @@ + cv::OutputArray rvec, cv::OutputArray tvec, + bool useExtrinsicGuess = false, int iterationsCount = 100, + float reprojectionError = 8.0, double confidence = 0.99, +- cv::OutputArray inliers = cv::noArray(), int flags = CV_ITERATIVE ); ++ cv::OutputArray inliers = cv::noArray(), int flags = cv::SOLVEPNP_ITERATIVE ); + + int RANSACUpdateNumIters( double p, double ep, int modelPoints, int maxIters ); + +diff -ruN a/corelib/src/optimizer/OptimizerCeres.cpp b/corelib/src/optimizer/OptimizerCeres.cpp +--- a/corelib/src/optimizer/OptimizerCeres.cpp ++++ b/corelib/src/optimizer/OptimizerCeres.cpp +@@ -26,6 +26,12 @@ + */ + #include "rtabmap/core/Graph.h" + ++#if CV_MAJOR_VERSION < 5 ++#include ++#else ++#include ++#endif ++ + #include + #include + #include +diff -ruN a/corelib/src/stereo/StereoBM.cpp b/corelib/src/stereo/StereoBM.cpp +--- a/corelib/src/stereo/StereoBM.cpp ++++ b/corelib/src/stereo/StereoBM.cpp +@@ -27,9 +27,13 @@ + + #include + #include ++#if CV_MAJOR_VERSION < 5 + #include ++#else ++#include ++#include ++#endif + #include +-#include + + namespace rtabmap { + +@@ -88,7 +92,7 @@ + cv::Mat leftMono; + if(leftImage.channels() == 3) + { +- cv::cvtColor(leftImage, leftMono, CV_BGR2GRAY); ++ cv::cvtColor(leftImage, leftMono, cv::COLOR_BGR2GRAY); + } + else + { +@@ -98,7 +102,7 @@ + cv::Mat rightMono; + if(rightImage.channels() == 3) + { +- cv::cvtColor(rightImage, rightMono, CV_BGR2GRAY); ++ cv::cvtColor(rightImage, rightMono, cv::COLOR_BGR2GRAY); + } + else + { +diff -ruN a/corelib/src/stereo/StereoSGBM.cpp b/corelib/src/stereo/StereoSGBM.cpp +--- a/corelib/src/stereo/StereoSGBM.cpp ++++ b/corelib/src/stereo/StereoSGBM.cpp +@@ -27,9 +27,13 @@ + + #include + #include ++#if CV_MAJOR_VERSION < 5 + #include ++#else ++#include ++#include ++#endif + #include +-#include + + namespace rtabmap { + +@@ -77,7 +81,7 @@ + cv::Mat leftMono; + if(leftImage.channels() == 3) + { +- cv::cvtColor(leftImage, leftMono, CV_BGR2GRAY); ++ cv::cvtColor(leftImage, leftMono, cv::COLOR_BGR2GRAY); + } + else + { +@@ -87,7 +91,7 @@ + cv::Mat rightMono; + if(rightImage.channels() == 3) + { +- cv::cvtColor(rightImage, rightMono, CV_BGR2GRAY); ++ cv::cvtColor(rightImage, rightMono, cv::COLOR_BGR2GRAY); + } + else + { +diff -ruN a/corelib/src/util2d.cpp b/corelib/src/util2d.cpp +--- a/corelib/src/util2d.cpp ++++ b/corelib/src/util2d.cpp +@@ -34,11 +34,9 @@ + #include + #include + #include +-#include + #include + #include + #include +-#include + #include + #include + +@@ -46,6 +44,12 @@ + #include + #endif + ++#if CV_MAJOR_VERSION < 5 ++#include ++#else ++#include ++#endif ++ + namespace rtabmap + { + +@@ -747,7 +751,7 @@ + cv::Mat leftMono; + if(leftImage.channels() == 3) + { +- cv::cvtColor(leftImage, leftMono, CV_BGR2GRAY); ++ cv::cvtColor(leftImage, leftMono, cv::COLOR_BGR2GRAY); + } + else + { +@@ -2042,8 +2046,8 @@ + //to calculate grayscale histogram + cv::Mat gray; + if (src.type() == CV_8UC1) gray = src; +- else if (src.type() == CV_8UC3) cvtColor(src, gray, CV_BGR2GRAY); +- else if (src.type() == CV_8UC4) cvtColor(src, gray, CV_BGRA2GRAY); ++ else if (src.type() == CV_8UC3) cvtColor(src, gray, cv::COLOR_BGR2GRAY); ++ else if (src.type() == CV_8UC4) cvtColor(src, gray, cv::COLOR_BGRA2GRAY); + if (clipLowHistPercent == 0 && clipHighHistPercent == 0) + { + // keep full available range +diff -ruN a/corelib/src/util3d.cpp b/corelib/src/util3d.cpp +--- a/corelib/src/util3d.cpp ++++ b/corelib/src/util3d.cpp +@@ -41,7 +41,6 @@ + #include + #include + #include +-#include + + namespace rtabmap + { +@@ -892,7 +891,7 @@ + cv::Mat leftMono; + if(leftColor.channels() == 3) + { +- cv::cvtColor(leftColor, leftMono, CV_BGR2GRAY); ++ cv::cvtColor(leftColor, leftMono, cv::COLOR_BGR2GRAY); + } + else + { +@@ -902,7 +901,7 @@ + cv::Mat rightMono; + if(rightColor.channels() == 3) + { +- cv::cvtColor(rightColor, rightMono, CV_BGR2GRAY); ++ cv::cvtColor(rightColor, rightMono, cv::COLOR_BGR2GRAY); + } + else + { +@@ -1038,7 +1037,7 @@ + cv::Mat leftMono; + if(sensorData.imageRaw().channels() == 3) + { +- cv::cvtColor(sensorData.imageRaw(), leftMono, CV_BGR2GRAY); ++ cv::cvtColor(sensorData.imageRaw(), leftMono, cv::COLOR_BGR2GRAY); + } + else + { +@@ -1048,7 +1047,7 @@ + cv::Mat rightMono; + if(sensorData.rightRaw().channels() == 3) + { +- cv::cvtColor(sensorData.rightRaw(), rightMono, CV_BGR2GRAY); ++ cv::cvtColor(sensorData.rightRaw(), rightMono, cv::COLOR_BGR2GRAY); + } + else + { +diff -ruN a/corelib/src/util3d_correspondences.cpp b/corelib/src/util3d_correspondences.cpp +--- a/corelib/src/util3d_correspondences.cpp ++++ b/corelib/src/util3d_correspondences.cpp +@@ -30,7 +30,11 @@ + + #include + #include ++#if CV_MAJOR_VERSION < 5 + #include ++#else ++#include ++#endif + #include + #include + +diff -ruN a/corelib/src/util3d_motion_estimation.cpp b/corelib/src/util3d_motion_estimation.cpp +--- a/corelib/src/util3d_motion_estimation.cpp ++++ b/corelib/src/util3d_motion_estimation.cpp +@@ -26,6 +26,9 @@ + */ + + #include "rtabmap/core/util3d_motion_estimation.h" ++#if CV_MAJOR_VERSION >= 5 ++#include ++#endif + + #include "rtabmap/utilite/UStl.h" + #include "rtabmap/utilite/UMath.h" +diff -ruN a/corelib/src/util3d_surface.cpp b/corelib/src/util3d_surface.cpp +--- a/corelib/src/util3d_surface.cpp ++++ b/corelib/src/util3d_surface.cpp +@@ -39,8 +39,6 @@ + #include "rtabmap/utilite/UConversion.h" + #include "rtabmap/utilite/UMath.h" + #include "rtabmap/utilite/UTimer.h" +-#include +-#include + #include + #include + #include +@@ -1745,7 +1743,7 @@ + if(resizedImage.type() == CV_8UC1) + { + cv::Mat resizedImageColor; +- cv::cvtColor(resizedImage, resizedImageColor, CV_GRAY2BGR); ++ cv::cvtColor(resizedImage, resizedImageColor, cv::COLOR_GRAY2BGR); + resizedImage = resizedImageColor; + } + UASSERT(resizedImage.type() == globalTextures.type()); +@@ -2609,7 +2607,7 @@ + if(imageRoi.channels() == 1) + { + cv::Mat imageRoiColor; +- cv::cvtColor(imageRoi, imageRoiColor, CV_GRAY2BGR); ++ cv::cvtColor(imageRoi, imageRoiColor, cv::COLOR_GRAY2BGR); + imageRoi = imageRoiColor; + } + +@@ -3218,7 +3216,7 @@ + } + if(oi>1) + { +- cv::PCA pca_analysis(cv::Mat(data_normals, cv::Range(0, oi*2)), cv::Mat(), CV_PCA_DATA_AS_ROW); ++ cv::PCA pca_analysis(cv::Mat(data_normals, cv::Range(0, oi*2)), cv::Mat(), cv::PCA::DATA_AS_ROW); + + if(pcaEigenVectors) + { +@@ -3279,7 +3277,7 @@ + } + if(oi>1) + { +- cv::PCA pca_analysis(cv::Mat(data_normals, cv::Range(0, oi*2)), cv::Mat(), CV_PCA_DATA_AS_ROW); ++ cv::PCA pca_analysis(cv::Mat(data_normals, cv::Range(0, oi*2)), cv::Mat(), cv::PCA::DATA_AS_ROW); + + if(pcaEigenVectors) + { +@@ -3335,7 +3333,7 @@ + } + if(oi>1) + { +- cv::PCA pca_analysis(cv::Mat(data_normals, cv::Range(0, oi*2)), cv::Mat(), CV_PCA_DATA_AS_ROW); ++ cv::PCA pca_analysis(cv::Mat(data_normals, cv::Range(0, oi*2)), cv::Mat(), cv::PCA::DATA_AS_ROW); + + if(pcaEigenVectors) + { +@@ -3391,7 +3389,7 @@ + } + if(oi>1) + { +- cv::PCA pca_analysis(cv::Mat(data_normals, cv::Range(0, oi*2)), cv::Mat(), CV_PCA_DATA_AS_ROW); ++ cv::PCA pca_analysis(cv::Mat(data_normals, cv::Range(0, oi*2)), cv::Mat(), cv::PCA::DATA_AS_ROW); + + if(pcaEigenVectors) + { +@@ -3447,7 +3445,7 @@ + } + if(oi>1) + { +- cv::PCA pca_analysis(cv::Mat(data_normals, cv::Range(0, oi*2)), cv::Mat(), CV_PCA_DATA_AS_ROW); ++ cv::PCA pca_analysis(cv::Mat(data_normals, cv::Range(0, oi*2)), cv::Mat(), cv::PCA::DATA_AS_ROW); + + if(pcaEigenVectors) + { +diff -ruN a/guilib/include/rtabmap/gui/DatabaseViewer.h b/guilib/include/rtabmap/gui/DatabaseViewer.h +--- a/guilib/include/rtabmap/gui/DatabaseViewer.h ++++ b/guilib/include/rtabmap/gui/DatabaseViewer.h +@@ -1,265 +1,270 @@ +-/* +-Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke +-All rights reserved. +- +-Redistribution and use in source and binary forms, with or without +-modification, are permitted provided that the following conditions are met: +- * Redistributions of source code must retain the above copyright +- notice, this list of conditions and the following disclaimer. +- * Redistributions in binary form must reproduce the above copyright +- notice, this list of conditions and the following disclaimer in the +- documentation and/or other materials provided with the distribution. +- * Neither the name of the Universite de Sherbrooke nor the +- names of its contributors may be used to endorse or promote products +- derived from this software without specific prior written permission. +- +-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY +-DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +-(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +-LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +-ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +-*/ +- +-#ifndef RTABMAP_DATABASEVIEWER_H_ +-#define RTABMAP_DATABASEVIEWER_H_ +- +-#include "rtabmap/gui/rtabmap_gui_export.h" // DLL export/import defines +- +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +- +-#include +-#include +-#include +- +-class Ui_DatabaseViewer; +-class QGraphicsScene; +-class QGraphicsView; +-class QLabel; +-class QToolButton; +-class QDialog; +-class QSpinBox; +- +-namespace rtabmap +-{ +-class DBDriver; +-class ImageView; +-class SensorData; +-class CloudViewer; +-class OctoMap; +-class ExportCloudsDialog; +-class EditDepthArea; +-class EditMapArea; +-class LinkRefiningDialog; +-class Registration; +-class RegistrationIcp; +- +-class RTABMAP_GUI_EXPORT DatabaseViewer : public QMainWindow +-{ +- Q_OBJECT +- +-public: +- DatabaseViewer(const QString & ini = QString(), QWidget * parent = 0); +- virtual ~DatabaseViewer(); +- bool openDatabase(const QString & path, const ParametersMap & overridenParameters = ParametersMap()); +- bool isSavedMaximized() const {return savedMaximized_;} +- void showCloseButton(bool visible = true); +- +-protected: +- virtual void showEvent(QShowEvent* anEvent); +- virtual void moveEvent(QMoveEvent* anEvent); +- virtual void resizeEvent(QResizeEvent* anEvent); +- virtual void keyPressEvent(QKeyEvent *event); +- virtual void closeEvent(QCloseEvent* event); +- virtual bool eventFilter(QObject *obj, QEvent *event); +- +-private Q_SLOTS: +- void writeSettings(); +- void restoreDefaultSettings(); +- void configModified(); +- void openDatabase(); +- bool closeDatabase(); +- void recoverDatabase(); +- void updateInfo(); +- void updateStatistics(); +- void selectObstacleColor(); +- void selectGroundColor(); +- void selectEmptyColor(); +- void selectFrontierColor(); +- void editDepthImage(); +- void generateGraph(); +- void editSaved2DMap(); +- void exportSaved2DMap(); +- void import2DMap(); +- void regenerateSavedMap(); +- void viewOptimizedMesh(); +- void exportOptimizedMesh(); +- void updateOptimizedMesh(); +- void exportDatabase(); +- void extractImages(); +- void exportPosesRaw(); +- void exportPosesRGBDSLAMMotionCapture(); +- void exportPosesRGBDSLAM(); +- void exportPosesRGBDSLAMID(); +- void exportPosesKITTI(); +- void exportPosesTORO(); +- void exportPosesG2O(); +- void exportPosesKML(); +- void exportGPS_TXT(); +- void exportGPS_KML(); +- void generateLocalGraph(); +- void regenerateLocalMaps(); +- void regenerateCurrentLocalMaps(); +- void view3DMap(); +- void generate3DMap(); +- void detectMoreLoopClosures(); +- void updateAllNeighborCovariances(); +- void updateAllLoopClosureCovariances(); +- void updateAllLandmarkCovariances(); +- void refineLinks(); +- void resetAllChanges(); +- void graphNodeSelected(int); +- void graphLinkSelected(int, int); +- void sliderAValueChanged(int); +- void sliderBValueChanged(int); +- void sliderAMoved(int); +- void sliderBMoved(int); +- void update3dView(); +- void sliderNeighborValueChanged(int); +- void sliderLoopValueChanged(int); +- void sliderIterationsValueChanged(int); +- void editConstraint(); +- void updateGrid(); +- void updateOctomapView(); +- void updateGraphRotation(); +- void updateGraphView(); +- void refineConstraint(); +- void addConstraint(); +- void resetConstraint(); +- void rejectConstraint(); +- void updateConstraintView(); +- void updateLoggerLevel(); +- void updateStereo(); +- void notifyParametersChanged(const QStringList &); +- void setupMainLayout(bool vertical); +- void updateConstraintButtons(); +- +-private: +- QString getIniFilePath() const; +- void readSettings(); +- +- void updateIds(); +- void update(int value, +- QSpinBox * spinBoxIndex, +- QLabel * labelParents, +- QLabel * labelChildren, +- QLabel * weight, +- QLabel * label, +- QLabel * stamp, +- rtabmap::ImageView * view, +- QLabel * labelId, +- QLabel * labelMapId, +- QLabel * labelPose, +- QLabel * labelOptPose, +- QLabel * labelVelocity, +- QLabel * labelCalib, +- QLabel * labelScan, +- QLabel * labelGravity, +- QLabel * labelPrior, +- QToolButton * editPriorButton, +- QToolButton * removePriorButton, +- QLabel * labelGps, +- QLabel * labelGt, +- QLabel * labelSensors, +- bool updateConstraintView); +- void updateStereo(const SensorData * data); +- void updateWordsMatching(const std::vector & inliers = std::vector()); +- void updateConstraintView( +- const rtabmap::Link & link, +- bool updateImageSliders = true, +- const Signature & signatureFrom = Signature(0), +- const Signature & signatureTo = Signature(0)); +- Link findActiveLink(int from, int to); +- bool containsLink( +- std::multimap & links, +- int from, +- int to); +- std::multimap updateLinksWithModifications( +- const std::multimap & edgeConstraints); +- void updateNeighborsSlider(int from = 0, int to = 0); +- void updateLoopClosuresSlider(int from = 0, int to = 0); +- void updateCovariances(const QList & links); +- void refineLinks(const QList & links); +- void refineConstraint(int from, int to, Registration * reg, RegistrationIcp * regIcp, bool silent); +- bool addConstraint(int from, int to, Registration * reg, bool silent, bool silentlyUseOptimizedGraphAsGuess = false); +- void exportPoses(int format); +- void exportGPS(int format); +- +-private: +- Ui_DatabaseViewer * ui_; +- CloudViewer * constraintsViewer_; +- CloudViewer * cloudViewer_; +- CloudViewer * stereoViewer_; +- CloudViewer * occupancyGridViewer_; +- QList ids_; +- std::set lastWmIds_; +- std::map mapIds_; +- std::map weights_; +- std::map > wmStates_; +- std::map envSensors_; +- QMap idToIndex_; +- QList neighborLinks_; +- QList loopLinks_; +- int lastSliderIndexBrowsed_; +- rtabmap::DBDriver * dbDriver_; +- QString pathDatabase_; +- std::string databaseFileName_; +- std::list > graphes_; +- std::multimap graphLinks_; +- std::map odomPoses_; +- std::map groundTruthPoses_; +- std::map gpsPoses_; +- std::map gpsValues_; +- std::multimap links_; +- std::multimap linksRefined_; +- std::multimap linksAdded_; +- std::multimap linksRemoved_; +- std::map modifiedLaserScans_; +- std::vector odomMaxInf_; +- LocalGridCache localMaps_; +- LocalGridCache generatedLocalMaps_; +- OctoMap * octomap_; +- ExportCloudsDialog * exportDialog_; +- QDialog * editDepthDialog_; +- EditDepthArea * editDepthArea_; +- QDialog * editMapDialog_; +- EditMapArea * editMapArea_; +- LinkRefiningDialog * linkRefiningDialog_; +- +- bool savedMaximized_; +- bool firstCall_; +- QString iniFilePath_; +- +- bool infoReducedGraph_; +- double infoTotalOdom_; +- double infoTotalTime_; +- int infoSessions_; +-}; +- +-} +- +-#endif /* DATABASEVIEWER_H_ */ ++/* ++Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke ++All rights reserved. ++ ++Redistribution and use in source and binary forms, with or without ++modification, are permitted provided that the following conditions are met: ++ * Redistributions of source code must retain the above copyright ++ notice, this list of conditions and the following disclaimer. ++ * Redistributions in binary form must reproduce the above copyright ++ notice, this list of conditions and the following disclaimer in the ++ documentation and/or other materials provided with the distribution. ++ * Neither the name of the Universite de Sherbrooke nor the ++ names of its contributors may be used to endorse or promote products ++ derived from this software without specific prior written permission. ++ ++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ++ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED ++WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE ++DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY ++DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ++(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; ++LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ++ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS ++SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++*/ ++ ++#ifndef RTABMAP_DATABASEVIEWER_H_ ++#define RTABMAP_DATABASEVIEWER_H_ ++ ++#include "rtabmap/gui/rtabmap_gui_export.h" // DLL export/import defines ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#if CV_MAJOR_VERSION < 5 ++#include ++#else ++#include ++#endif ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++ ++class Ui_DatabaseViewer; ++class QGraphicsScene; ++class QGraphicsView; ++class QLabel; ++class QToolButton; ++class QDialog; ++class QSpinBox; ++ ++namespace rtabmap ++{ ++class DBDriver; ++class ImageView; ++class SensorData; ++class CloudViewer; ++class OctoMap; ++class ExportCloudsDialog; ++class EditDepthArea; ++class EditMapArea; ++class LinkRefiningDialog; ++class Registration; ++class RegistrationIcp; ++ ++class RTABMAP_GUI_EXPORT DatabaseViewer : public QMainWindow ++{ ++ Q_OBJECT ++ ++public: ++ DatabaseViewer(const QString & ini = QString(), QWidget * parent = 0); ++ virtual ~DatabaseViewer(); ++ bool openDatabase(const QString & path, const ParametersMap & overridenParameters = ParametersMap()); ++ bool isSavedMaximized() const {return savedMaximized_;} ++ void showCloseButton(bool visible = true); ++ ++protected: ++ virtual void showEvent(QShowEvent* anEvent); ++ virtual void moveEvent(QMoveEvent* anEvent); ++ virtual void resizeEvent(QResizeEvent* anEvent); ++ virtual void keyPressEvent(QKeyEvent *event); ++ virtual void closeEvent(QCloseEvent* event); ++ virtual bool eventFilter(QObject *obj, QEvent *event); ++ ++private Q_SLOTS: ++ void writeSettings(); ++ void restoreDefaultSettings(); ++ void configModified(); ++ void openDatabase(); ++ bool closeDatabase(); ++ void recoverDatabase(); ++ void updateInfo(); ++ void updateStatistics(); ++ void selectObstacleColor(); ++ void selectGroundColor(); ++ void selectEmptyColor(); ++ void selectFrontierColor(); ++ void editDepthImage(); ++ void generateGraph(); ++ void editSaved2DMap(); ++ void exportSaved2DMap(); ++ void import2DMap(); ++ void regenerateSavedMap(); ++ void viewOptimizedMesh(); ++ void exportOptimizedMesh(); ++ void updateOptimizedMesh(); ++ void exportDatabase(); ++ void extractImages(); ++ void exportPosesRaw(); ++ void exportPosesRGBDSLAMMotionCapture(); ++ void exportPosesRGBDSLAM(); ++ void exportPosesRGBDSLAMID(); ++ void exportPosesKITTI(); ++ void exportPosesTORO(); ++ void exportPosesG2O(); ++ void exportPosesKML(); ++ void exportGPS_TXT(); ++ void exportGPS_KML(); ++ void generateLocalGraph(); ++ void regenerateLocalMaps(); ++ void regenerateCurrentLocalMaps(); ++ void view3DMap(); ++ void generate3DMap(); ++ void detectMoreLoopClosures(); ++ void updateAllNeighborCovariances(); ++ void updateAllLoopClosureCovariances(); ++ void updateAllLandmarkCovariances(); ++ void refineLinks(); ++ void resetAllChanges(); ++ void graphNodeSelected(int); ++ void graphLinkSelected(int, int); ++ void sliderAValueChanged(int); ++ void sliderBValueChanged(int); ++ void sliderAMoved(int); ++ void sliderBMoved(int); ++ void update3dView(); ++ void sliderNeighborValueChanged(int); ++ void sliderLoopValueChanged(int); ++ void sliderIterationsValueChanged(int); ++ void editConstraint(); ++ void updateGrid(); ++ void updateOctomapView(); ++ void updateGraphRotation(); ++ void updateGraphView(); ++ void refineConstraint(); ++ void addConstraint(); ++ void resetConstraint(); ++ void rejectConstraint(); ++ void updateConstraintView(); ++ void updateLoggerLevel(); ++ void updateStereo(); ++ void notifyParametersChanged(const QStringList &); ++ void setupMainLayout(bool vertical); ++ void updateConstraintButtons(); ++ ++private: ++ QString getIniFilePath() const; ++ void readSettings(); ++ ++ void updateIds(); ++ void update(int value, ++ QSpinBox * spinBoxIndex, ++ QLabel * labelParents, ++ QLabel * labelChildren, ++ QLabel * weight, ++ QLabel * label, ++ QLabel * stamp, ++ rtabmap::ImageView * view, ++ QLabel * labelId, ++ QLabel * labelMapId, ++ QLabel * labelPose, ++ QLabel * labelOptPose, ++ QLabel * labelVelocity, ++ QLabel * labelCalib, ++ QLabel * labelScan, ++ QLabel * labelGravity, ++ QLabel * labelPrior, ++ QToolButton * editPriorButton, ++ QToolButton * removePriorButton, ++ QLabel * labelGps, ++ QLabel * labelGt, ++ QLabel * labelSensors, ++ bool updateConstraintView); ++ void updateStereo(const SensorData * data); ++ void updateWordsMatching(const std::vector & inliers = std::vector()); ++ void updateConstraintView( ++ const rtabmap::Link & link, ++ bool updateImageSliders = true, ++ const Signature & signatureFrom = Signature(0), ++ const Signature & signatureTo = Signature(0)); ++ Link findActiveLink(int from, int to); ++ bool containsLink( ++ std::multimap & links, ++ int from, ++ int to); ++ std::multimap updateLinksWithModifications( ++ const std::multimap & edgeConstraints); ++ void updateNeighborsSlider(int from = 0, int to = 0); ++ void updateLoopClosuresSlider(int from = 0, int to = 0); ++ void updateCovariances(const QList & links); ++ void refineLinks(const QList & links); ++ void refineConstraint(int from, int to, Registration * reg, RegistrationIcp * regIcp, bool silent); ++ bool addConstraint(int from, int to, Registration * reg, bool silent, bool silentlyUseOptimizedGraphAsGuess = false); ++ void exportPoses(int format); ++ void exportGPS(int format); ++ ++private: ++ Ui_DatabaseViewer * ui_; ++ CloudViewer * constraintsViewer_; ++ CloudViewer * cloudViewer_; ++ CloudViewer * stereoViewer_; ++ CloudViewer * occupancyGridViewer_; ++ QList ids_; ++ std::set lastWmIds_; ++ std::map mapIds_; ++ std::map weights_; ++ std::map > wmStates_; ++ std::map envSensors_; ++ QMap idToIndex_; ++ QList neighborLinks_; ++ QList loopLinks_; ++ int lastSliderIndexBrowsed_; ++ rtabmap::DBDriver * dbDriver_; ++ QString pathDatabase_; ++ std::string databaseFileName_; ++ std::list > graphes_; ++ std::multimap graphLinks_; ++ std::map odomPoses_; ++ std::map groundTruthPoses_; ++ std::map gpsPoses_; ++ std::map gpsValues_; ++ std::multimap links_; ++ std::multimap linksRefined_; ++ std::multimap linksAdded_; ++ std::multimap linksRemoved_; ++ std::map modifiedLaserScans_; ++ std::vector odomMaxInf_; ++ LocalGridCache localMaps_; ++ LocalGridCache generatedLocalMaps_; ++ OctoMap * octomap_; ++ ExportCloudsDialog * exportDialog_; ++ QDialog * editDepthDialog_; ++ EditDepthArea * editDepthArea_; ++ QDialog * editMapDialog_; ++ EditMapArea * editMapArea_; ++ LinkRefiningDialog * linkRefiningDialog_; ++ ++ bool savedMaximized_; ++ bool firstCall_; ++ QString iniFilePath_; ++ ++ bool infoReducedGraph_; ++ double infoTotalOdom_; ++ double infoTotalTime_; ++ int infoSessions_; ++}; ++ ++} ++ ++#endif /* DATABASEVIEWER_H_ */ +diff -ruN a/guilib/include/rtabmap/gui/ImageView.h b/guilib/include/rtabmap/gui/ImageView.h +--- a/guilib/include/rtabmap/gui/ImageView.h ++++ b/guilib/include/rtabmap/gui/ImageView.h +@@ -34,7 +34,12 @@ + #include + #include + #include ++#include ++#if CV_MAJOR_VERSION < 5 + #include ++#else ++#include ++#endif + #include + #include "rtabmap/utilite/UCv2Qt.h" + #include +diff -ruN a/guilib/include/rtabmap/gui/KeypointItem.h b/guilib/include/rtabmap/gui/KeypointItem.h +--- a/guilib/include/rtabmap/gui/KeypointItem.h ++++ b/guilib/include/rtabmap/gui/KeypointItem.h +@@ -1,70 +1,75 @@ +-/* +-Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke +-All rights reserved. +- +-Redistribution and use in source and binary forms, with or without +-modification, are permitted provided that the following conditions are met: +- * Redistributions of source code must retain the above copyright +- notice, this list of conditions and the following disclaimer. +- * Redistributions in binary form must reproduce the above copyright +- notice, this list of conditions and the following disclaimer in the +- documentation and/or other materials provided with the distribution. +- * Neither the name of the Universite de Sherbrooke nor the +- names of its contributors may be used to endorse or promote products +- derived from this software without specific prior written permission. +- +-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY +-DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +-(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +-LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +-ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +-*/ +- +-#ifndef RTABMAP_KEYPOINTITEM_H_ +-#define RTABMAP_KEYPOINTITEM_H_ +- +-#include "rtabmap/gui/rtabmap_gui_export.h" // DLL export/import defines +- +-#include +-#include +-#include +-#include +-#include +- +-namespace rtabmap { +- +-class RTABMAP_GUI_EXPORT KeypointItem : public QGraphicsEllipseItem +-{ +-public: +- KeypointItem(int id, const cv::KeyPoint & kpt, float depth = 0, const QColor & color = Qt::green, QGraphicsItem * parent = 0); +- virtual ~KeypointItem(); +- +- void setColor(const QColor & color); +- const cv::KeyPoint & keypoint() const {return _kpt;} +- +-protected: +- virtual void hoverEnterEvent ( QGraphicsSceneHoverEvent * event ); +- virtual void hoverLeaveEvent ( QGraphicsSceneHoverEvent * event ); +- virtual void focusInEvent ( QFocusEvent * event ); +- virtual void focusOutEvent ( QFocusEvent * event ); +- +-private: +- void showDescription(); +- void hideDescription(); +- +-private: +- int _id; +- cv::KeyPoint _kpt; +- QGraphicsRectItem * _placeHolder; +- int _width; +- float _depth; +-}; +- +-} +- +-#endif /* KEYPOINTITEM_H_ */ ++/* ++Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke ++All rights reserved. ++ ++Redistribution and use in source and binary forms, with or without ++modification, are permitted provided that the following conditions are met: ++ * Redistributions of source code must retain the above copyright ++ notice, this list of conditions and the following disclaimer. ++ * Redistributions in binary form must reproduce the above copyright ++ notice, this list of conditions and the following disclaimer in the ++ documentation and/or other materials provided with the distribution. ++ * Neither the name of the Universite de Sherbrooke nor the ++ names of its contributors may be used to endorse or promote products ++ derived from this software without specific prior written permission. ++ ++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ++ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED ++WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE ++DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY ++DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ++(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; ++LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ++ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS ++SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++*/ ++ ++#ifndef RTABMAP_KEYPOINTITEM_H_ ++#define RTABMAP_KEYPOINTITEM_H_ ++ ++#include "rtabmap/gui/rtabmap_gui_export.h" // DLL export/import defines ++ ++#include ++#include ++#include ++#include ++#include ++#if CV_MAJOR_VERSION < 5 ++#include ++#else ++#include ++#endif ++ ++namespace rtabmap { ++ ++class RTABMAP_GUI_EXPORT KeypointItem : public QGraphicsEllipseItem ++{ ++public: ++ KeypointItem(int id, const cv::KeyPoint & kpt, float depth = 0, const QColor & color = Qt::green, QGraphicsItem * parent = 0); ++ virtual ~KeypointItem(); ++ ++ void setColor(const QColor & color); ++ const cv::KeyPoint & keypoint() const {return _kpt;} ++ ++protected: ++ virtual void hoverEnterEvent ( QGraphicsSceneHoverEvent * event ); ++ virtual void hoverLeaveEvent ( QGraphicsSceneHoverEvent * event ); ++ virtual void focusInEvent ( QFocusEvent * event ); ++ virtual void focusOutEvent ( QFocusEvent * event ); ++ ++private: ++ void showDescription(); ++ void hideDescription(); ++ ++private: ++ int _id; ++ cv::KeyPoint _kpt; ++ QGraphicsRectItem * _placeHolder; ++ int _width; ++ float _depth; ++}; ++ ++} ++ ++#endif /* KEYPOINTITEM_H_ */ +diff -ruN a/guilib/src/CalibrationDialog.cpp b/guilib/src/CalibrationDialog.cpp +--- a/guilib/src/CalibrationDialog.cpp ++++ b/guilib/src/CalibrationDialog.cpp +@@ -30,13 +30,19 @@ + + #include + #include +-#include ++#if CV_MAJOR_VERSION < 5 + #include +-#if CV_MAJOR_VERSION >= 3 ++#else ++#include ++#include ++// OpenCV 5 moved findChessboardCorners() into the objdetect module. ++#include ++#endif ++#if CV_MAJOR_VERSION >= 3 && CV_MAJOR_VERSION < 5 + #include + #endif + #include +-#if CV_MAJOR_VERSION > 2 or (CV_MAJOR_VERSION == 2 and (CV_MINOR_VERSION >4 or (CV_MINOR_VERSION == 4 and CV_SUBMINOR_VERSION >=10))) ++#if (CV_MAJOR_VERSION > 2 and CV_MAJOR_VERSION < 5) or (CV_MAJOR_VERSION == 2 and (CV_MINOR_VERSION >4 or (CV_MINOR_VERSION == 4 and CV_SUBMINOR_VERSION >=10))) + #include + #endif + +@@ -737,7 +743,7 @@ + cv::Size boardSize(ui_->spinBox_boardWidth->value(), ui_->spinBox_boardHeight->value()); + if(!viewGray.empty()) + { +- int flags = CV_CALIB_CB_ADAPTIVE_THRESH | CV_CALIB_CB_NORMALIZE_IMAGE; ++ int flags = cv::CALIB_CB_ADAPTIVE_THRESH | cv::CALIB_CB_NORMALIZE_IMAGE; + + if(!viewGray.empty()) + { +@@ -748,7 +754,7 @@ + if( scale == 1 ) + timg = viewGray; + else +- cv::resize(viewGray, timg, cv::Size(), scale, scale, CV_INTER_CUBIC); ++ cv::resize(viewGray, timg, cv::Size(), scale, scale, cv::INTER_CUBIC); + + #ifdef HAVE_CHARUCO + if(ui_->comboBox_board_type->currentIndex() >= 1 ) +@@ -833,7 +839,7 @@ + float ratio = ui_->comboBox_board_type->currentIndex() >= 1 ?6.0f:2.0f; + float radius = minSquareDistance==-1.0f?5.0f:(minSquareDistance/ratio); + cv::cornerSubPix( viewGray, pointBuf[id], cv::Size(radius, radius), cv::Size(-1,-1), +- cv::TermCriteria( CV_TERMCRIT_EPS + CV_TERMCRIT_ITER, 30, 0.1 )); ++ cv::TermCriteria( cv::TermCriteria::EPS + cv::TermCriteria::MAX_ITER, 30, 0.1 )); + + // Filter points that drifted to far (caused by reflection or bad subpixel gradient) + float threshold = ui_->doubleSpinBox_subpixel_error->value(); +@@ -1473,7 +1479,7 @@ + { + cv::projectPoints( cv::Mat(objectPoints_[id][i]), rvecs[i], tvecs[i], K, D, imagePoints2); + } +- err = cv::norm(cv::Mat(imagePoints_[id][i]), cv::Mat(imagePoints2), CV_L2); ++ err = cv::norm(cv::Mat(imagePoints_[id][i]), cv::Mat(imagePoints2), cv::NORM_L2); + + int n = (int)objectPoints_[id][i].size(); + reprojErrs[i] = (float) std::sqrt(err*err/n); +@@ -1750,19 +1756,21 @@ + UINFO("Compute stereo rectification"); + + cv::Mat R1, R2, P1, P2, Q; ++#if CV_MAJOR_VERSION < 5 + stereoRectifyFisheye( + left.K_raw(), D_left, + right.K_raw(), D_right, + imageSize, R, Tvec, R1, R2, P1, P2, Q, + cv::CALIB_ZERO_DISPARITY, 0, imageSize); +- +- // Very hard to get good results with this one: +- /*double balance = 0.0, fov_scale = 1.0; ++#else ++ // OpenCV 5 removed the C-API-based stereoRectifyFisheye() helper. ++ double balance = 0.0, fov_scale = 1.0; + cv::fisheye::stereoRectify( + left.K_raw(), D_left, + right.K_raw(), D_right, + imageSize, R, Tvec, R1, R2, P1, P2, Q, +- cv::CALIB_ZERO_DISPARITY, imageSize, balance, fov_scale);*/ ++ cv::CALIB_ZERO_DISPARITY, imageSize, balance, fov_scale); ++#endif + + std::cout << "R1 = " << R1 << std::endl; + std::cout << "R2 = " << R2 << std::endl; +diff -ruN a/guilib/src/DatabaseViewer.cpp b/guilib/src/DatabaseViewer.cpp +--- a/guilib/src/DatabaseViewer.cpp ++++ b/guilib/src/DatabaseViewer.cpp +@@ -43,8 +43,6 @@ + #include + #include + #include +-#include +-#include + #include + #include + #include +@@ -5956,7 +5954,7 @@ + cv::Mat leftMono; + if(data->imageRaw().channels() == 3) + { +- cv::cvtColor(data->imageRaw(), leftMono, CV_BGR2GRAY); ++ cv::cvtColor(data->imageRaw(), leftMono, cv::COLOR_BGR2GRAY); + } + else + { +@@ -5965,7 +5963,7 @@ + cv::Mat rightMono; + if(data->rightRaw().channels() == 3) + { +- cv::cvtColor(data->rightRaw(), rightMono, CV_BGR2GRAY); ++ cv::cvtColor(data->rightRaw(), rightMono, cv::COLOR_BGR2GRAY); + } + else + { +diff -ruN a/guilib/src/MainWindow.cpp b/guilib/src/MainWindow.cpp +--- a/guilib/src/MainWindow.cpp ++++ b/guilib/src/MainWindow.cpp +@@ -126,6 +126,9 @@ + #ifdef HAVE_OPENCV_ARUCO + #include + #endif ++#if CV_MAJOR_VERSION >= 5 ++#include ++#endif + + #define LOG_FILE_NAME "LogRtabmap.txt" + #define SHARE_SHOW_LOG_FILE "share/rtabmap/showlogs.m" +diff -ruN a/tools/Camera/main.cpp b/tools/Camera/main.cpp +--- a/tools/Camera/main.cpp ++++ b/tools/Camera/main.cpp +@@ -32,7 +32,9 @@ + #include "rtabmap/utilite/UDirectory.h" + #include "rtabmap/utilite/UConversion.h" + #include ++#if CV_MAJOR_VERSION < 5 + #include ++#endif + #include + + void showUsage() +@@ -178,7 +180,7 @@ + + cv::Mat rgb; + rgb = camera->takeImage().imageRaw(); +- cv::namedWindow("Video", CV_WINDOW_AUTOSIZE); // create window ++ cv::namedWindow("Video", cv::WINDOW_AUTOSIZE); // create window + while(!rgb.empty()) + { + cv::imshow("Video", rgb); // show frame +diff -ruN a/tools/CameraRGBD/main.cpp b/tools/CameraRGBD/main.cpp +--- a/tools/CameraRGBD/main.cpp ++++ b/tools/CameraRGBD/main.cpp +@@ -40,8 +40,7 @@ + #include "rtabmap/utilite/UEventsManager.h" + #include + #include +-#include +-#if CV_MAJOR_VERSION >= 3 ++#if CV_MAJOR_VERSION >= 3 && CV_MAJOR_VERSION < 5 + #include + #endif + #include +@@ -454,7 +453,7 @@ + { + if(right.channels() == 3) + { +- cv::cvtColor(right, right, CV_BGR2GRAY); ++ cv::cvtColor(right, right, cv::COLOR_BGR2GRAY); + } + pcl::PointCloud::Ptr cloud = rtabmap::util3d::cloudFromStereoImages( + rgb, right, +diff -ruN a/tools/EpipolarGeometry/main.cpp b/tools/EpipolarGeometry/main.cpp +--- a/tools/EpipolarGeometry/main.cpp ++++ b/tools/EpipolarGeometry/main.cpp +@@ -26,7 +26,6 @@ + */ + + #include +-#include + #include + #include + #include +@@ -36,7 +35,11 @@ + #include + #include + #include ++#if CV_MAJOR_VERSION < 5 + #include ++#else ++#include ++#endif + #include "rtabmap/core/Features2d.h" + #include "rtabmap/core/EpipolarGeometry.h" + #include "rtabmap/core/VWDictionary.h" +diff -ruN a/tools/StereoEval/main.cpp b/tools/StereoEval/main.cpp +--- a/tools/StereoEval/main.cpp ++++ b/tools/StereoEval/main.cpp +@@ -37,7 +37,6 @@ + #include + #include + #include +-#include + #include + #include + +@@ -222,7 +221,7 @@ + cv::Mat leftMono; + if(left.channels() == 3) + { +- cv::cvtColor(left, leftMono, CV_BGR2GRAY); ++ cv::cvtColor(left, leftMono, cv::COLOR_BGR2GRAY); + } + else + { +@@ -231,7 +230,7 @@ + cv::Mat rightMono; + if(right.channels() == 3) + { +- cv::cvtColor(right, rightMono, CV_BGR2GRAY); ++ cv::cvtColor(right, rightMono, cv::COLOR_BGR2GRAY); + } + else + { +@@ -266,7 +265,7 @@ + cv::cornerSubPix(leftMono, leftCorners, + cv::Size( subPixWinSize, subPixWinSize ), + cv::Size( -1, -1 ), +- cv::TermCriteria( CV_TERMCRIT_ITER | CV_TERMCRIT_EPS, subPixIterations, subPixEps ) ); ++ cv::TermCriteria( cv::TermCriteria::MAX_ITER | cv::TermCriteria::EPS, subPixIterations, subPixEps ) ); + UDEBUG("cv::cornerSubPix() end"); + } + + +diff -ruN a/app/src/main.cpp b/app/src/main.cpp +--- a/app/src/main.cpp ++++ b/app/src/main.cpp +@@ -25,6 +25,10 @@ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + ++#ifdef WIN32 ++#include ++#endif ++ + #include + #include + #include "rtabmap/utilite/UEventsManager.h" +diff -ruN a/tools/DatabaseViewer/main.cpp b/tools/DatabaseViewer/main.cpp +--- a/tools/DatabaseViewer/main.cpp ++++ b/tools/DatabaseViewer/main.cpp +@@ -25,6 +25,10 @@ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + ++#ifdef WIN32 ++#include ++#endif ++ + #include + #include "rtabmap/gui/DatabaseViewer.h" + #include "rtabmap/utilite/ULogger.h" diff --git a/patch/ros-jazzy-rviz-ogre-vendor.patch b/patch/ros-jazzy-rviz-ogre-vendor.patch index fce0b1dca..defd111f8 100644 --- a/patch/ros-jazzy-rviz-ogre-vendor.patch +++ b/patch/ros-jazzy-rviz-ogre-vendor.patch @@ -1,8 +1,24 @@ -diff --git a/CMakeLists.txt b/CMakeLists.txt -index 8d23a299a..f58c62831 100644 +diff -ruN a/CMakeLists.txt b/CMakeLists.txt --- a/CMakeLists.txt +++ b/CMakeLists.txt -@@ -76,7 +76,11 @@ endif() +@@ -22,6 +22,8 @@ + -DFT_DISABLE_PNG:BOOL=ON + -DFT_DISABLE_HARFBUZZ:BOOL=ON + "-DCMAKE_C_FLAGS=${FREETYPE_C_FLAGS}" ++ # freetype 2.11.1 declares cmake_minimum_required < 3.5, rejected by CMake >= 4 ++ -DCMAKE_POLICY_VERSION_MINIMUM=3.5 + ) + + set(ZLIB_C_FLAGS "${ZLIB_C_FLAGS}") +@@ -72,13 +74,19 @@ + endif() + + set(OGRE_CMAKE_ARGS) ++# OGRE 1.12.10 declares cmake_minimum_required < 3.5, rejected by CMake >= 4 ++list(APPEND OGRE_CMAKE_ARGS -DCMAKE_POLICY_VERSION_MINIMUM=3.5) + if(NOT WIN32) + list(APPEND OGRE_CMAKE_ARGS -DCMAKE_SKIP_INSTALL_RPATH:BOOL=ON) + endif() if(APPLE) list(APPEND OGRE_CMAKE_ARGS -DOGRE_ENABLE_PRECOMPILED_HEADERS:BOOL=OFF) @@ -15,10 +31,8 @@ index 8d23a299a..f58c62831 100644 endif() ament_vendor(ogre_vendor -diff --git a/patches/0005-fix-macos-arm64.patch b/patches/0005-fix-macos-arm64.patch -new file mode 100644 -index 000000000..9494cc9ae ---- /dev/null +diff -ruN a/patches/0005-fix-macos-arm64.patch b/patches/0005-fix-macos-arm64.patch +--- a/patches/0005-fix-macos-arm64.patch +++ b/patches/0005-fix-macos-arm64.patch @@ -0,0 +1,19 @@ +diff --git a/CMakeLists.txt b/CMakeLists.txt @@ -40,10 +54,8 @@ index 000000000..9494cc9ae + # Make sure that the OpenGL render system is selected for non-iOS Apple builds + set(OGRE_BUILD_RENDERSYSTEM_GLES2 FALSE) + endif () -diff --git a/patches/0006-fix-char16.patch b/patches/0006-fix-char16.patch -new file mode 100644 -index 000000000..dfc080bb9 ---- /dev/null +diff -ruN a/patches/0006-fix-char16.patch b/patches/0006-fix-char16.patch +--- a/patches/0006-fix-char16.patch +++ b/patches/0006-fix-char16.patch @@ -0,0 +1,17 @@ +diff --git a/Components/Overlay/include/OgreUTFString.h b/Components/Overlay/include/OgreUTFString.h diff --git a/patch/ros-jazzy-sick-safetyscanners-base.patch b/patch/ros-jazzy-sick-safetyscanners-base.patch new file mode 100644 index 000000000..ebbdd067c --- /dev/null +++ b/patch/ros-jazzy-sick-safetyscanners-base.patch @@ -0,0 +1,316 @@ +diff --git a/CMakeLists.txt b/CMakeLists.txt +index 594088d..869994a 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -9,7 +9,7 @@ add_definitions(-std=c++11 -Wall -Werror) + + + ## Find system libraries +-find_package(Boost REQUIRED COMPONENTS system thread chrono) ++find_package(Boost REQUIRED COMPONENTS thread chrono) + + + ########### +diff --git a/include/sick_safetyscanners_base/SickSafetyscanners.h b/include/sick_safetyscanners_base/SickSafetyscanners.h +index 58509a3..423c630 100644 +--- a/include/sick_safetyscanners_base/SickSafetyscanners.h ++++ b/include/sick_safetyscanners_base/SickSafetyscanners.h +@@ -64,7 +64,7 @@ + + namespace sick { + +-using io_service_ptr = std::shared_ptr; ++using io_service_ptr = std::shared_ptr; + + using namespace sick::datastructure; + +@@ -98,7 +98,7 @@ class SickSafetyscannersBase + SickSafetyscannersBase(sick::types::ip_address_t sensor_ip, + sick::types::port_t sensor_tcp_port, + CommSettings comm_settings, +- boost::asio::io_service& io_service); ++ boost::asio::io_context& io_service); + /*! + * \brief Constructor of the SickSafetyscannersBase class. + * +@@ -262,7 +262,7 @@ class SickSafetyscannersBase + private: + sick::types::ip_address_t m_sensor_ip; + CommSettings m_comm_settings; +- std::unique_ptr m_io_service_ptr; ++ std::unique_ptr m_io_service_ptr; + + /*! + * \brief Helper function to create command objects generically. +@@ -281,7 +281,7 @@ class SickSafetyscannersBase + } + + protected: +- boost::asio::io_service& m_io_service; ++ boost::asio::io_context& m_io_service; + sick::communication::UDPClient m_udp_client; + sick::cola2::Cola2Session m_session; + sick::data_processing::UDPPacketMerger m_packet_merger; +@@ -350,7 +350,7 @@ class AsyncSickSafetyScanner final : public SickSafetyscannersBase + sick::types::port_t sensor_tcp_port, + CommSettings comm_settings, + sick::types::ScanDataCb callback, +- boost::asio::io_service& io_service); ++ boost::asio::io_context& io_service); + + /*! + * \brief Destructor of the AsyncSickSafetyScanner object +@@ -381,9 +381,9 @@ class AsyncSickSafetyScanner final : public SickSafetyscannersBase + void processUDPPacket(const sick::datastructure::PacketBuffer& buffer); + + sick::types::ScanDataCb m_scan_data_cb; +- std::unique_ptr m_io_service_ptr; ++ std::unique_ptr m_io_service_ptr; + boost::thread m_service_thread; +- std::unique_ptr m_work; ++ std::unique_ptr> m_work; + }; + + /*! +@@ -402,7 +402,7 @@ class SyncSickSafetyScanner final : public SickSafetyscannersBase + SyncSickSafetyScanner(sick::types::ip_address_t sensor_ip, + sick::types::port_t sensor_tcp_port, + CommSettings comm_settings, +- boost::asio::io_service& io_service) = delete; ++ boost::asio::io_context& io_service) = delete; + /*! + * \brief Indicates whether sensor data is available in the receiving buffers. + * +diff --git a/include/sick_safetyscanners_base/communication/TCPClient.h b/include/sick_safetyscanners_base/communication/TCPClient.h +index 1a2c880..5505a5f 100644 +--- a/include/sick_safetyscanners_base/communication/TCPClient.h ++++ b/include/sick_safetyscanners_base/communication/TCPClient.h +@@ -38,6 +38,7 @@ + #define SICK_SAFETYSCANNERS_BASE_COMMUNICATION_SYNCTCPCLIENT_H + + #include ++#include + #include + #include + #include +@@ -103,7 +103,7 @@ class TCPClient + receive(sick::types::time_duration_t timeout = boost::posix_time::seconds(5)); + + private: +- boost::asio::io_service m_io_service; ++ boost::asio::io_context m_io_service; + sick::datastructure::PacketBuffer::ArrayBuffer m_recv_buffer; + boost::asio::ip::tcp::socket m_socket; + sick::types::ip_address_t m_server_ip; +diff --git a/include/sick_safetyscanners_base/Types.h b/include/sick_safetyscanners_base/Types.h +index 96c2d27..0af4798 100644 +--- a/include/sick_safetyscanners_base/Types.h ++++ b/include/sick_safetyscanners_base/Types.h +@@ -39,6 +39,7 @@ + #include "sick_safetyscanners_base/datastructure/Data.h" + #include "sick_safetyscanners_base/datastructure/PacketBuffer.h" + #include ++#include + #include + #include + #include +diff --git a/include/sick_safetyscanners_base/communication/UDPClient.h b/include/sick_safetyscanners_base/communication/UDPClient.h +index 02831a5..7d70566 100644 +--- a/include/sick_safetyscanners_base/communication/UDPClient.h ++++ b/include/sick_safetyscanners_base/communication/UDPClient.h +@@ -40,6 +40,7 @@ + #include + + #include ++#include + + #include "sick_safetyscanners_base/Types.h" + #include "sick_safetyscanners_base/datastructure/PacketBuffer.h" +@@ -60,7 +60,7 @@ class UDPClient + * \param io_service Instance of the boost::asio io_service + * \param server_port The local port number on the receiver (this client's) side. + */ +- UDPClient(boost::asio::io_service& io_service, sick::types::port_t server_port); ++ UDPClient(boost::asio::io_context& io_service, sick::types::port_t server_port); + + /*! + * \brief Constructor of a UDPClient object +@@ -71,7 +71,7 @@ class UDPClient + * \param interface_ip The used host (client's) interface IP which is needed to join the + * multicast group. + */ +- UDPClient(boost::asio::io_service& io_service, ++ UDPClient(boost::asio::io_context& io_service, + sick::types::port_t server_port, + boost::asio::ip::address_v4 host_ip, + boost::asio::ip::address_v4 interface_ip); +@@ -139,7 +139,7 @@ class UDPClient + sick::datastructure::PacketBuffer receive(sick::types::time_duration_t timeout); + + private: +- boost::asio::io_service& m_io_service; ++ boost::asio::io_context& m_io_service; + boost::asio::ip::udp::endpoint m_remote_endpoint; + boost::asio::ip::udp::socket m_socket; + types::PacketHandler m_packet_handler; +diff --git a/include/sick_safetyscanners_base/datastructure/CommSettings.h b/include/sick_safetyscanners_base/datastructure/CommSettings.h +index bbbe83b..9dda5d7 100644 +--- a/include/sick_safetyscanners_base/datastructure/CommSettings.h ++++ b/include/sick_safetyscanners_base/datastructure/CommSettings.h +@@ -67,7 +67,7 @@ struct CommSettings + bool enabled{true}; + + sick::types::port_t host_udp_port{0}; +- sick::types::ip_address_t host_ip{boost::asio::ip::address_v4::from_string("192.168.1.100")}; ++ sick::types::ip_address_t host_ip{boost::asio::ip::make_address_v4("192.168.1.100")}; + }; + + std::ostream& operator<<(std::ostream& os, const CommSettings& settings); +diff --git a/src/SickSafetyscanners.cpp b/src/SickSafetyscanners.cpp +index 0d1f9c1..601a14f 100644 +--- a/src/SickSafetyscanners.cpp ++++ b/src/SickSafetyscanners.cpp +@@ -46,7 +46,7 @@ SickSafetyscannersBase::SickSafetyscannersBase(sick::types::ip_address_t sensor_ + CommSettings comm_settings) + : m_sensor_ip(sensor_ip) + , m_comm_settings(comm_settings) +- , m_io_service_ptr(sick::make_unique()) ++ , m_io_service_ptr(sick::make_unique()) + , m_io_service(*m_io_service_ptr) + , m_udp_client(m_io_service, comm_settings.host_udp_port) + , m_session(sick::make_unique(m_sensor_ip, sensor_tcp_port)) +@@ -61,7 +61,7 @@ SickSafetyscannersBase::SickSafetyscannersBase(sick::types::ip_address_t sensor_ + boost::asio::ip::address_v4 interface_ip) + : m_sensor_ip(sensor_ip) + , m_comm_settings(comm_settings) +- , m_io_service_ptr(sick::make_unique()) ++ , m_io_service_ptr(sick::make_unique()) + , m_io_service(*m_io_service_ptr) + , m_udp_client(m_io_service, comm_settings.host_udp_port, comm_settings.host_ip, interface_ip) + , m_session(sick::make_unique(m_sensor_ip, sensor_tcp_port)) +@@ -73,7 +73,7 @@ SickSafetyscannersBase::SickSafetyscannersBase(sick::types::ip_address_t sensor_ + SickSafetyscannersBase::SickSafetyscannersBase(sick::types::ip_address_t sensor_ip, + sick::types::port_t sensor_tcp_port, + CommSettings comm_settings, +- boost::asio::io_service& io_service) ++ boost::asio::io_context& io_service) + : m_sensor_ip(sensor_ip) + , m_comm_settings(comm_settings) + , m_io_service_ptr(nullptr) +@@ -235,7 +235,8 @@ AsyncSickSafetyScanner::AsyncSickSafetyScanner(sick::types::ip_address_t sensor_ + sick::types::ScanDataCb callback) + : SickSafetyscannersBase(sensor_ip, sensor_tcp_port, comm_settings) + , m_scan_data_cb(callback) +- , m_work(sick::make_unique(m_io_service)) ++ , m_work(sick::make_unique>( ++ boost::asio::make_work_guard(m_io_service))) + { + m_service_thread = boost::thread([this] { + try +@@ -256,7 +257,8 @@ AsyncSickSafetyScanner::AsyncSickSafetyScanner(sick::types::ip_address_t sensor_ + sick::types::ScanDataCb callback) + : SickSafetyscannersBase(sensor_ip, sensor_tcp_port, comm_settings, interface_ip) + , m_scan_data_cb(callback) +- , m_work(sick::make_unique(m_io_service)) ++ , m_work(sick::make_unique>( ++ boost::asio::make_work_guard(m_io_service))) + { + m_service_thread = boost::thread([this] { + try +@@ -274,7 +276,7 @@ AsyncSickSafetyScanner::AsyncSickSafetyScanner(sick::types::ip_address_t sensor_ + sick::types::port_t sensor_tcp_port, + CommSettings comm_settings, + sick::types::ScanDataCb callback, +- boost::asio::io_service& io_service) ++ boost::asio::io_context& io_service) + : SickSafetyscannersBase(sensor_ip, sensor_tcp_port, comm_settings, io_service) + , m_scan_data_cb(callback) + , m_work() +@@ -283,8 +285,11 @@ AsyncSickSafetyScanner::AsyncSickSafetyScanner(sick::types::ip_address_t sensor_ + + AsyncSickSafetyScanner::~AsyncSickSafetyScanner() + { ++ if (m_work) ++ { ++ m_work->reset(); ++ } + m_io_service.stop(); +- m_work.reset(); + if (m_service_thread.joinable()) + { + m_service_thread.join(); +diff --git a/src/cola2/ChangeCommSettingsCommand.cpp b/src/cola2/ChangeCommSettingsCommand.cpp +index bbb8b48..46cedba 100644 +--- a/src/cola2/ChangeCommSettingsCommand.cpp ++++ b/src/cola2/ChangeCommSettingsCommand.cpp +@@ -105,7 +105,7 @@ void ChangeCommSettingsCommand::writeEInterfaceTypeToDataPtr( + void ChangeCommSettingsCommand::writeIPAddresstoDataPtr( + std::vector::iterator data_ptr) const + { +- read_write_helper::writeUint32LittleEndian(data_ptr + 8, m_settings.host_ip.to_ulong()); ++ read_write_helper::writeUint32LittleEndian(data_ptr + 8, m_settings.host_ip.to_uint()); + } + + void ChangeCommSettingsCommand::writePortToDataPtr(std::vector::iterator data_ptr) const +diff --git a/src/communication/UDPClient.cpp b/src/communication/UDPClient.cpp +index b2037e1..2e08a11 100644 +--- a/src/communication/UDPClient.cpp ++++ b/src/communication/UDPClient.cpp +@@ -60,7 +60,7 @@ using boost::lambda::_2; + using boost::lambda::bind; + using boost::lambda::var; + +-UDPClient::UDPClient(boost::asio::io_service& io_service, sick::types::port_t server_port) ++UDPClient::UDPClient(boost::asio::io_context& io_service, sick::types::port_t server_port) + : m_io_service(io_service) + , m_socket(io_service, boost::asio::ip::udp::endpoint{boost::asio::ip::udp::v4(), server_port}) + , m_packet_handler() +@@ -71,7 +71,7 @@ UDPClient::UDPClient(boost::asio::io_service& io_service, sick::types::port_t se + checkDeadline(); + } + +-UDPClient::UDPClient(boost::asio::io_service& io_service, ++UDPClient::UDPClient(boost::asio::io_context& io_service, + sick::types::port_t server_port, + boost::asio::ip::address_v4 host_ip, + boost::asio::ip::address_v4 interface_ip) +diff --git a/src/datastructure/ConfigData.cpp b/src/datastructure/ConfigData.cpp +index 0f42f5b..bd96ba4 100644 +--- a/src/datastructure/ConfigData.cpp ++++ b/src/datastructure/ConfigData.cpp +@@ -91,7 +91,7 @@ void ConfigData::setHostIp(const boost::asio::ip::address_v4& host_ip) + + void ConfigData::setHostIp(const std::string& host_ip) + { +- m_host_ip = boost::asio::ip::address_v4::from_string(host_ip); ++ m_host_ip = boost::asio::ip::make_address_v4(host_ip); + } + + uint16_t ConfigData::getHostUdpPort() const + +diff --git a/include/sick_safetyscanners_base/Exceptions.h b/include/sick_safetyscanners_base/Exceptions.h +index bdc42f4..e557d3a 100644 +--- a/include/sick_safetyscanners_base/Exceptions.h ++++ b/include/sick_safetyscanners_base/Exceptions.h +@@ -131,21 +131,6 @@ public: + */ + explicit timeout_error() = delete; + +- /*! +- * \brief Constructor of the timeout error object +- * +- * \param msg A description of the reason for the failure. +- * \param timeout The timeout that has been exceeded represented as timeval-struct. The timeout +- * information is appended as string after the message string. +- */ +- explicit timeout_error(const std::string& msg, timeval timeout) +- : runtime_error(msg) +- { +- std::stringstream ss; +- ss << msg << " (timeout was set to " << timeout.tv_sec + timeout.tv_usec * 1e-6 << " sec)"; +- msg_ = ss.str(); +- } +- + /*! + * \brief Constructor of the timeout error object + * diff --git a/patch/ros-jazzy-theora-image-transport.patch b/patch/ros-jazzy-theora-image-transport.patch new file mode 100644 index 000000000..d76fda704 --- /dev/null +++ b/patch/ros-jazzy-theora-image-transport.patch @@ -0,0 +1,12 @@ +diff -ruN a/src/theora_subscriber.cpp b/src/theora_subscriber.cpp +--- a/src/theora_subscriber.cpp ++++ b/src/theora_subscriber.cpp +@@ -294,7 +294,7 @@ + + // Convert to BGR color + cv::Mat bgr, bgr_padded; +- cv::cvtColor(ycrcb, bgr_padded, CV_YCrCb2BGR); ++ cv::cvtColor(ycrcb, bgr_padded, cv::COLOR_YCrCb2BGR); + // Pull out original (non-padded) image region + bgr = bgr_padded(cv::Rect(header_info_.pic_x, header_info_.pic_y, + header_info_.pic_width, header_info_.pic_height)); diff --git a/patch/ros-jazzy-urg-node.patch b/patch/ros-jazzy-urg-node.patch new file mode 100644 index 000000000..d343493b2 --- /dev/null +++ b/patch/ros-jazzy-urg-node.patch @@ -0,0 +1,11 @@ +diff -ruN a/src/urg_c_wrapper.cpp b/src/urg_c_wrapper.cpp +--- a/src/urg_c_wrapper.cpp ++++ b/src/urg_c_wrapper.cpp +@@ -39,6 +39,7 @@ + #include + #include + #include ++#include + + #include "boost/crc.hpp" + diff --git a/patch/ros2-apriltag-ros.patch b/patch/ros2-apriltag-ros.patch new file mode 100644 index 000000000..60b9af822 --- /dev/null +++ b/patch/ros2-apriltag-ros.patch @@ -0,0 +1,30 @@ +diff --git a/CMakeLists.txt b/CMakeLists.txt +index 75d5822..8eb328e 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -41,7 +41,15 @@ find_package(image_transport REQUIRED) + find_package(cv_bridge REQUIRED) + find_package(Eigen3 REQUIRED NO_MODULE) + find_package(Threads REQUIRED) +-find_package(OpenCV REQUIRED COMPONENTS core calib3d) ++find_package(OpenCV REQUIRED COMPONENTS core) ++if(OpenCV_VERSION_MAJOR GREATER 4) ++ # calib3d was split into "calib" + "geometry" in OpenCV 5. ++ find_package(OpenCV REQUIRED COMPONENTS calib geometry) ++ set(APRILTAG_ROS_OPENCV_CALIB_LIBS opencv_calib opencv_geometry) ++else() ++ find_package(OpenCV REQUIRED COMPONENTS calib3d) ++ set(APRILTAG_ROS_OPENCV_CALIB_LIBS opencv_calib3d) ++endif() + find_package(apriltag 3.2 REQUIRED) + + if(cv_bridge_VERSION VERSION_GREATER_EQUAL 3.3.0) +@@ -98,7 +106,7 @@ target_link_libraries(pose_estimation + PUBLIC + apriltag::apriltag + Eigen3::Eigen +- opencv_calib3d ++ ${APRILTAG_ROS_OPENCV_CALIB_LIBS} + conversion + ${geometry_msgs_TARGETS} + tf2::tf2 diff --git a/patch/ros2-autoware-interpolation.patch b/patch/ros2-autoware-interpolation.patch new file mode 100644 index 000000000..9b3cbac58 --- /dev/null +++ b/patch/ros2-autoware-interpolation.patch @@ -0,0 +1,11 @@ +diff --git a/include/autoware/interpolation/interpolation_utils.hpp b/include/autoware/interpolation/interpolation_utils.hpp +--- a/include/autoware/interpolation/interpolation_utils.hpp ++++ b/include/autoware/interpolation/interpolation_utils.hpp +@@ -18,6 +18,7 @@ + #include + #include + #include ++#include + #include + + namespace autoware::interpolation diff --git a/patch/ros2-autoware-lanelet2-extension.patch b/patch/ros2-autoware-lanelet2-extension.patch new file mode 100644 index 000000000..6660a9da7 --- /dev/null +++ b/patch/ros2-autoware-lanelet2-extension.patch @@ -0,0 +1,14 @@ +diff --git a/CMakeLists.txt b/CMakeLists.txt +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -36,7 +36,9 @@ + # and do not affect the actual functionality of the code. + # Related: https://www.boost.org/doc/libs/latest/libs/utility/doc/html/utility/utilities/value_init.html + # and https://www.boost.org/doc/libs/1_89_0/libs/optional/doc/html/boost_optional/design/gotchas/false_positive_with__wmaybe_uninitialized.html +-target_compile_options(${PROJECT_NAME}_lib PRIVATE -Wno-error=maybe-uninitialized) ++if(NOT MSVC) ++ target_compile_options(${PROJECT_NAME}_lib PRIVATE -Wno-error=maybe-uninitialized) ++endif() + + if(BUILD_TESTING) + ament_add_ros_isolated_gtest(projector-test test/src/test_projector.cpp) diff --git a/patch/ros2-behaviortree-cpp-v3.patch b/patch/ros2-behaviortree-cpp-v3.patch new file mode 100644 index 000000000..acb5801f1 --- /dev/null +++ b/patch/ros2-behaviortree-cpp-v3.patch @@ -0,0 +1,15 @@ +diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt +--- a/tools/CMakeLists.txt ++++ b/tools/CMakeLists.txt +@@ -10,6 +10,11 @@ + if( ZMQ_FOUND ) + add_executable(bt3_recorder bt_recorder.cpp ) + target_link_libraries(bt3_recorder ${BEHAVIOR_TREE_LIBRARY} ${ZMQ_LIBRARIES}) ++ # ${BEHAVIOR_TREE_LIBRARY} only adds ZMQ_INCLUDE_DIRS as PRIVATE, so it ++ # isn't propagated here; harmless on most Unix toolchains since the conda ++ # prefix's include dir is already on the default search path, but MSVC ++ # needs it explicitly or zmq.h (via the vendored cppzmq wrapper) isn't found. ++ target_include_directories(bt3_recorder PRIVATE ${ZMQ_INCLUDE_DIRS}) + install(TARGETS bt3_recorder + DESTINATION ${BEHAVIOR_TREE_BIN_DESTINATION} ) + endif() diff --git a/patch/ros2-depth-image-proc.patch b/patch/ros2-depth-image-proc.patch new file mode 100644 index 000000000..a72dfc636 --- /dev/null +++ b/patch/ros2-depth-image-proc.patch @@ -0,0 +1,22 @@ +diff --git a/src/crop_foremost.cpp b/src/crop_foremost.cpp +index 60901d9..6535c72 100644 +--- a/src/crop_foremost.cpp ++++ b/src/crop_foremost.cpp +@@ -135,7 +135,7 @@ void CropForemostNode::depthCb(const sensor_msgs::msg::Image::ConstSharedPtr & r + case CV_8UC1: + case CV_8SC1: + case CV_32F: +- cv::threshold(cv_ptr->image, cv_ptr->image, minVal + distance_, 0, CV_THRESH_TOZERO_INV); ++ cv::threshold(cv_ptr->image, cv_ptr->image, minVal + distance_, 0, cv::THRESH_TOZERO_INV); + break; + case CV_16UC1: + case CV_16SC1: +@@ -143,7 +143,7 @@ void CropForemostNode::depthCb(const sensor_msgs::msg::Image::ConstSharedPtr & r + case CV_64F: + // 8 bit or 32 bit floating array is required to use cv::threshold + cv_ptr->image.convertTo(cv_ptr->image, CV_32F); +- cv::threshold(cv_ptr->image, cv_ptr->image, minVal + distance_, 1, CV_THRESH_TOZERO_INV); ++ cv::threshold(cv_ptr->image, cv_ptr->image, minVal + distance_, 1, cv::THRESH_TOZERO_INV); + + cv_ptr->image.convertTo(cv_ptr->image, imtype); + break; diff --git a/patch/ros2-depthai-bridge.patch b/patch/ros2-depthai-bridge.patch new file mode 100644 index 000000000..dae8619bb --- /dev/null +++ b/patch/ros2-depthai-bridge.patch @@ -0,0 +1,43 @@ +diff --git a/CMakeLists.txt b/CMakeLists.txt +index b8e3b77..e5af507 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -13,12 +13,12 @@ if(POLICY CMP0057) + cmake_policy(SET CMP0057 NEW) + endif() + +-set(opencv_version 4) +-find_package(OpenCV ${opencv_version} QUIET COMPONENTS imgproc highgui calib3d) +-if(NOT OpenCV_FOUND) +- message(STATUS "----------------Did not find OpenCV 4, trying OpenCV 3--------------") +- set(opencv_version 3) +- find_package(OpenCV ${opencv_version} REQUIRED COMPONENTS imgproc highgui calib3d) ++find_package(OpenCV REQUIRED COMPONENTS core) ++if(OpenCV_VERSION_MAJOR GREATER 4) ++ # calib3d was split into "calib" + "geometry" in OpenCV 5. ++ find_package(OpenCV REQUIRED COMPONENTS imgproc highgui calib geometry) ++else() ++ find_package(OpenCV REQUIRED COMPONENTS imgproc highgui calib3d) + endif() + + +@@ -97,11 +97,18 @@ if($ENV{ROS_DISTRO} STREQUAL "humble") + target_compile_definitions(${PROJECT_NAME} PRIVATE IS_HUMBLE) + endif() + ++if(OpenCV_VERSION_MAJOR GREATER 4) ++ # calib3d was split into "calib" + "geometry" in OpenCV 5. ++ set(DEPTHAI_BRIDGE_OPENCV_CALIB_LIBS opencv_calib opencv_geometry) ++else() ++ set(DEPTHAI_BRIDGE_OPENCV_CALIB_LIBS opencv_calib3d) ++endif() ++ + target_link_libraries(${PROJECT_NAME} + depthai::core + opencv_imgproc + opencv_highgui +- opencv_calib3d) ++ ${DEPTHAI_BRIDGE_OPENCV_CALIB_LIBS}) + + ament_export_targets(depthai_bridgeTargets HAS_LIBRARY_TARGET) + diff --git a/patch/ros2-depthai-examples.patch b/patch/ros2-depthai-examples.patch new file mode 100644 index 000000000..35029c0ab --- /dev/null +++ b/patch/ros2-depthai-examples.patch @@ -0,0 +1,18 @@ +diff --git a/CMakeLists.txt b/CMakeLists.txt +index 273fb04..30b7262 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -11,12 +11,7 @@ if(POLICY CMP0057) + cmake_policy(SET CMP0057 NEW) + endif() + +-set(_opencv_version 4) +-find_package(OpenCV 4 QUIET COMPONENTS imgproc highgui) +-if(NOT OpenCV_FOUND) +- set(_opencv_version 3) +- find_package(OpenCV 3 REQUIRED COMPONENTS imgproc highgui) +-endif() ++find_package(OpenCV REQUIRED COMPONENTS imgproc highgui) + + # find_package(depthai CONFIG REQUIRED PATHS "/home/sachin/Desktop/luxonis/depthai-core/build/install/lib/cmake/depthai") + set(tiny_yolo_v4_blob_name "yolov4_tiny_coco_416x416_openvino_2021.4_6shave_bgr.blob") diff --git a/patch/ros2-orbbec-camera.patch b/patch/ros2-orbbec-camera.patch new file mode 100644 index 000000000..f856c0d7f --- /dev/null +++ b/patch/ros2-orbbec-camera.patch @@ -0,0 +1,24 @@ +diff --git a/src/utils.cpp b/src/utils.cpp +--- a/src/utils.cpp ++++ b/src/utils.cpp +@@ -1117,11 +1117,15 @@ + entry.intrinsic = intrinsic; + entry.distortion = distortion; + +- cv::Mat camera_matrix = (cv::Mat_(3, 3) << intrinsic.fx, 0.0, intrinsic.cx, 0.0, +- intrinsic.fy, intrinsic.cy, 0.0, 0.0, 1.0); +- cv::Mat dist_coeffs = +- (cv::Mat_(8, 1) << distortion.k1, distortion.k2, distortion.p1, distortion.p2, +- distortion.k3, distortion.k4, distortion.k5, distortion.k6); ++ // The Mat_<>comma-initializer operator<< is deprecated in OpenCV 5. ++ std::vector camera_matrix_values = {intrinsic.fx, 0.0, intrinsic.cx, ++ 0.0, intrinsic.fy, intrinsic.cy, ++ 0.0, 0.0, 1.0}; ++ cv::Mat camera_matrix = cv::Mat(camera_matrix_values, true).reshape(1, 3); ++ std::vector dist_coeffs_values = { ++ distortion.k1, distortion.k2, distortion.p1, distortion.p2, ++ distortion.k3, distortion.k4, distortion.k5, distortion.k6}; ++ cv::Mat dist_coeffs(dist_coeffs_values, true); + cv::initUndistortRectifyMap(camera_matrix, dist_coeffs, cv::Mat(), camera_matrix, + cv::Size(image.cols, image.rows), CV_16SC2, entry.map1, + entry.map2); diff --git a/patch/ros2-persist-parameter-server.patch b/patch/ros2-persist-parameter-server.patch new file mode 100644 index 000000000..607daa248 --- /dev/null +++ b/patch/ros2-persist-parameter-server.patch @@ -0,0 +1,71 @@ +diff --git a/server/src/parameter_server.cpp b/server/src/parameter_server.cpp +index 210a80a..14b2ccc 100644 +--- a/server/src/parameter_server.cpp ++++ b/server/src/parameter_server.cpp +@@ -25,6 +25,12 @@ + #include "rclcpp/parameter.hpp" + #include "rclcpp/parameter_map.hpp" + ++#if defined(_MSC_VER) ++#define ROS2_PPS_PRETTY_FUNCTION __FUNCSIG__ ++#else ++#define ROS2_PPS_PRETTY_FUNCTION __PRETTY_FUNCTION__ ++#endif ++ + #define ROS_PARAMETER_KEY "ros__parameters" + #define ROS_PARAMETER_DOT_KEY "ros__parameters." + #define PERSISTENT_KEY "persistent" +@@ -65,7 +71,7 @@ ParameterServer::ParameterServer( + persistent_yaml_file_(persistent_yaml_file), + node_name_(get_name()) + { +- RCLCPP_DEBUG(this->get_logger(), "%s yaml:%s", __PRETTY_FUNCTION__, persistent_yaml_file_.c_str()); ++ RCLCPP_DEBUG(this->get_logger(), "%s yaml:%s", ROS2_PPS_PRETTY_FUNCTION, persistent_yaml_file_.c_str()); + + int storing_period = 0; + // if automatically_declare_parameters_from_overrides is false, then the parameter_overrides will not be declared. +@@ -190,7 +196,7 @@ ParameterServer::ParameterServer( + + ParameterServer::~ParameterServer() + { +- RCLCPP_DEBUG(this->get_logger(), "%s", __PRETTY_FUNCTION__); ++ RCLCPP_DEBUG(this->get_logger(), "%s", ROS2_PPS_PRETTY_FUNCTION); + this->remove_on_set_parameters_callback(callback_handler_.get()); + StoreYamlFile(); + } +@@ -220,7 +226,7 @@ void ParameterServer::CheckYamlFile() { + } + + void ParameterServer::CheckYamlFile(const std::string& file) { +- RCLCPP_DEBUG(this->get_logger(), "%s", __PRETTY_FUNCTION__); ++ RCLCPP_DEBUG(this->get_logger(), "%s", ROS2_PPS_PRETTY_FUNCTION); + YAML::Node parameter_config = YAML::LoadFile(file); + // check format "YAML must be dictionary type and level 1 can only have one key" + if ((parameter_config.size() == 1 && parameter_config.Type() != YAML::NodeType::Map) || +@@ -268,7 +274,7 @@ void ParameterServer::CheckYamlFile(const std::string& file) { + + void ParameterServer::LoadYamlFile() + { +- RCLCPP_DEBUG(this->get_logger(), "%s", __PRETTY_FUNCTION__); ++ RCLCPP_DEBUG(this->get_logger(), "%s", ROS2_PPS_PRETTY_FUNCTION); + // check whether yaml file exist + if (!boost::filesystem::exists(persistent_yaml_file_)) + { +@@ -549,7 +555,7 @@ void ParameterServer::SaveNode(YAML::Emitter& out, YAML::Node node, const std::s + + void ParameterServer::StoreYamlFile() + { +- RCLCPP_DEBUG(this->get_logger(), "%s", __PRETTY_FUNCTION__); ++ RCLCPP_DEBUG(this->get_logger(), "%s", ROS2_PPS_PRETTY_FUNCTION); + + if (param_update_) + { +@@ -757,7 +763,7 @@ void ParameterServer::StoreYamlFile() + + bool ParameterServer::CheckPersistentParam(const std::vector & parameters) + { +- RCLCPP_DEBUG(this->get_logger(), "%s", __PRETTY_FUNCTION__); ++ RCLCPP_DEBUG(this->get_logger(), "%s", ROS2_PPS_PRETTY_FUNCTION); + bool flag = false; + + for (auto& parameter : parameters) { diff --git a/patch/ros-jazzy-sick-scan-xd.osx.patch b/patch/ros2-sick-scan-xd.osx.patch similarity index 100% rename from patch/ros-jazzy-sick-scan-xd.osx.patch rename to patch/ros2-sick-scan-xd.osx.patch diff --git a/patch/ros2-sick-scan-xd.patch b/patch/ros2-sick-scan-xd.patch new file mode 100644 index 000000000..09023654d --- /dev/null +++ b/patch/ros2-sick-scan-xd.patch @@ -0,0 +1,12 @@ +diff --git a/include/sick_scansegment_xd/msgpack11/msgpack11.hpp b/include/sick_scansegment_xd/msgpack11/msgpack11.hpp +index 1c23871..7e0009b 100644 +--- a/include/sick_scansegment_xd/msgpack11/msgpack11.hpp ++++ b/include/sick_scansegment_xd/msgpack11/msgpack11.hpp +@@ -8,6 +8,7 @@ + #include + #include + #include ++#include + + + #ifdef _MSC_VER diff --git a/patch/ros2-stereo-image-proc.patch b/patch/ros2-stereo-image-proc.patch new file mode 100644 index 000000000..68201ce5c --- /dev/null +++ b/patch/ros2-stereo-image-proc.patch @@ -0,0 +1,13 @@ +diff --git a/src/stereo_image_proc/disparity_node.cpp b/src/stereo_image_proc/disparity_node.cpp +index 958f43a..d82a240 100644 +--- a/src/stereo_image_proc/disparity_node.cpp ++++ b/src/stereo_image_proc/disparity_node.cpp +@@ -53,7 +53,7 @@ + #include + #include + +-#include ++#include + + namespace stereo_image_proc + { diff --git a/patch/ros2-system-modes.win.patch b/patch/ros2-system-modes.win.patch new file mode 100644 index 000000000..044b54cd1 --- /dev/null +++ b/patch/ros2-system-modes.win.patch @@ -0,0 +1,18 @@ +diff --git a/CMakeLists.txt b/CMakeLists.txt +index 2c0bf30..523562c 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -15,6 +15,13 @@ if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") + add_compile_options(-Wall -Wextra -Wpedantic) + endif() + ++# The mode library below has no explicit dllexport annotations, so on ++# Windows it builds as a DLL with zero exported symbols -- MSVC doesn't ++# generate an import library (.lib) for a DLL with no exports at all, ++# which then breaks mode_monitor/mode_manager's link step with LNK1181 ++# ("cannot open input file 'mode.lib'"). Auto-export everything instead. ++set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON) ++ + # find dependencies + find_package(ament_cmake REQUIRED) + find_package(builtin_interfaces REQUIRED) diff --git a/pixi.lock b/pixi.lock index ec95d4aee..e00d62977 100644 --- a/pixi.lock +++ b/pixi.lock @@ -41,7 +41,9 @@ environments: - conda: https://prefix.dev/conda-forge/linux-64/c-ares-1.34.8-hebe6cf0_2.conda - conda: https://prefix.dev/conda-forge/linux-64/cffi-2.1.1-py312h703531f_2.conda - conda: https://prefix.dev/conda-forge/linux-64/cmake-3.31.8-hc85cc9f_0.conda + - conda: https://prefix.dev/conda-forge/linux-64/curl-8.21.0-ha042cf0_5.conda - conda: https://prefix.dev/conda-forge/linux-64/git-lfs-3.8.0-h2c09266_0.conda + - conda: https://prefix.dev/conda-forge/linux-64/go-yq-4.53.6-hebe6cf0_0.conda - conda: https://prefix.dev/conda-forge/linux-64/icu-78.3-py310h44b86e0_2.conda - conda: https://prefix.dev/conda-forge/linux-64/keyutils-1.6.3-h7cc23a3_1.conda - conda: https://prefix.dev/conda-forge/linux-64/krb5-1.22.2-hbc21106_2.conda @@ -70,6 +72,7 @@ environments: - conda: https://prefix.dev/conda-forge/linux-64/ncurses-6.6-hdb14827_1.conda - conda: https://prefix.dev/conda-forge/linux-64/openssl-3.6.4-h781a0a9_0.conda - conda: https://prefix.dev/conda-forge/linux-64/patchelf-0.19.1-hee9eb32_1.conda + - conda: https://prefix.dev/conda-forge/linux-64/perl-5.32.1-7_hd590300_perl5.conda - conda: https://prefix.dev/conda-forge/linux-64/python-3.12.14-h8ab3286_0_cpython.conda - conda: https://prefix.dev/conda-forge/linux-64/pyyaml-6.0.3-py312h8a5da7c_1.conda - conda: https://prefix.dev/conda-forge/linux-64/rattler-build-0.57.2-he64ecbb_1.conda @@ -87,6 +90,7 @@ environments: - conda: https://prefix.dev/conda-forge/noarch/catkin_pkg-1.1.0-pyhd8ed1ab_0.conda - conda: https://prefix.dev/conda-forge/noarch/certifi-2026.7.22-pyhd8ed1ab_0.conda - conda: https://prefix.dev/conda-forge/noarch/charset-normalizer-3.5.1-pyhd8ed1ab_0.conda + - conda: https://prefix.dev/conda-forge/noarch/colordiff-1.0.22-hd8ed1ab_0.conda - conda: https://prefix.dev/conda-forge/noarch/distro-1.9.0-pyhd8ed1ab_1.conda - conda: https://prefix.dev/conda-forge/noarch/docutils-0.23-pyhcf101f3_0.conda - conda: https://prefix.dev/conda-forge/noarch/empy-3.3.4-pyh9f0ad1d_1.tar.bz2 @@ -115,7 +119,7 @@ environments: - conda: https://prefix.dev/conda-forge/noarch/typing_extensions-4.16.0-pyhcf101f3_0.conda - conda: https://prefix.dev/conda-forge/noarch/tzdata-2026c-h151e31d_0.conda - conda: https://prefix.dev/conda-forge/noarch/urllib3-2.7.0-pyhd8ed1ab_0.conda - - conda_source: vinca[be849743] @ git+https://github.com/robostack/vinca#4683e080a18be89703b4088c90fca8eaa8620ebe + - conda_source: vinca[c31d34e5] @ git+https://github.com/tobias-fischer/vinca?rev=9e44663eaf17a1a7ae698e3140ff095a78e849e7#9e44663eaf17a1a7ae698e3140ff095a78e849e7 linux-aarch64-glibc-2-17: - conda: https://prefix.dev/conda-forge/linux-aarch64/_openmp_mutex-4.5-20_gnu.conda - conda: https://prefix.dev/conda-forge/linux-aarch64/backports.zstd-1.7.0-py312h22d1088_0.conda @@ -124,7 +128,9 @@ environments: - conda: https://prefix.dev/conda-forge/linux-aarch64/c-ares-1.34.8-h29ee22c_2.conda - conda: https://prefix.dev/conda-forge/linux-aarch64/cffi-2.1.1-py312h563f9cf_2.conda - conda: https://prefix.dev/conda-forge/linux-aarch64/cmake-3.31.8-hc9d863e_0.conda + - conda: https://prefix.dev/conda-forge/linux-aarch64/curl-8.21.0-h86273da_5.conda - conda: https://prefix.dev/conda-forge/linux-aarch64/git-lfs-3.8.0-hcf061c0_0.conda + - conda: https://prefix.dev/conda-forge/linux-aarch64/go-yq-4.53.6-h29ee22c_0.conda - conda: https://prefix.dev/conda-forge/linux-aarch64/icu-78.3-py311h3512406_2.conda - conda: https://prefix.dev/conda-forge/linux-aarch64/keyutils-1.6.3-h5bc82ec_1.conda - conda: https://prefix.dev/conda-forge/linux-aarch64/krb5-1.22.2-h095d8e5_2.conda @@ -153,6 +159,7 @@ environments: - conda: https://prefix.dev/conda-forge/linux-aarch64/ncurses-6.6-h2b6f883_1.conda - conda: https://prefix.dev/conda-forge/linux-aarch64/openssl-3.6.4-he6ad1d5_0.conda - conda: https://prefix.dev/conda-forge/linux-aarch64/patchelf-0.19.1-hfb11796_1.conda + - conda: https://prefix.dev/conda-forge/linux-aarch64/perl-5.32.1-7_h31becfc_perl5.conda - conda: https://prefix.dev/conda-forge/linux-aarch64/python-3.12.14-ha505bbe_0_cpython.conda - conda: https://prefix.dev/conda-forge/linux-aarch64/pyyaml-6.0.3-py312ha4530ae_1.conda - conda: https://prefix.dev/conda-forge/linux-aarch64/rattler-build-0.57.2-hb434046_1.conda @@ -170,6 +177,7 @@ environments: - conda: https://prefix.dev/conda-forge/noarch/catkin_pkg-1.1.0-pyhd8ed1ab_0.conda - conda: https://prefix.dev/conda-forge/noarch/certifi-2026.7.22-pyhd8ed1ab_0.conda - conda: https://prefix.dev/conda-forge/noarch/charset-normalizer-3.5.1-pyhd8ed1ab_0.conda + - conda: https://prefix.dev/conda-forge/noarch/colordiff-1.0.22-hd8ed1ab_0.conda - conda: https://prefix.dev/conda-forge/noarch/distro-1.9.0-pyhd8ed1ab_1.conda - conda: https://prefix.dev/conda-forge/noarch/docutils-0.23-pyhcf101f3_0.conda - conda: https://prefix.dev/conda-forge/noarch/empy-3.3.4-pyh9f0ad1d_1.tar.bz2 @@ -198,13 +206,14 @@ environments: - conda: https://prefix.dev/conda-forge/noarch/typing_extensions-4.16.0-pyhcf101f3_0.conda - conda: https://prefix.dev/conda-forge/noarch/tzdata-2026c-h151e31d_0.conda - conda: https://prefix.dev/conda-forge/noarch/urllib3-2.7.0-pyhd8ed1ab_0.conda - - conda_source: vinca[2f07e57d] @ git+https://github.com/robostack/vinca#4683e080a18be89703b4088c90fca8eaa8620ebe + - conda_source: vinca[45925f45] @ git+https://github.com/tobias-fischer/vinca?rev=9e44663eaf17a1a7ae698e3140ff095a78e849e7#9e44663eaf17a1a7ae698e3140ff095a78e849e7 osx-64: - conda: https://prefix.dev/conda-forge/noarch/boolean.py-5.0-pyhd8ed1ab_0.conda - conda: https://prefix.dev/conda-forge/noarch/ca-certificates-2026.7.22-hbd8a1cb_0.conda - conda: https://prefix.dev/conda-forge/noarch/catkin_pkg-1.1.0-pyhd8ed1ab_0.conda - conda: https://prefix.dev/conda-forge/noarch/certifi-2026.7.22-pyhd8ed1ab_0.conda - conda: https://prefix.dev/conda-forge/noarch/charset-normalizer-3.5.1-pyhd8ed1ab_0.conda + - conda: https://prefix.dev/conda-forge/noarch/colordiff-1.0.22-hd8ed1ab_0.conda - conda: https://prefix.dev/conda-forge/noarch/distro-1.9.0-pyhd8ed1ab_1.conda - conda: https://prefix.dev/conda-forge/noarch/docutils-0.23-pyhcf101f3_0.conda - conda: https://prefix.dev/conda-forge/noarch/empy-3.3.4-pyh9f0ad1d_1.tar.bz2 @@ -239,7 +248,9 @@ environments: - conda: https://prefix.dev/conda-forge/osx-64/c-ares-1.34.8-had63097_2.conda - conda: https://prefix.dev/conda-forge/osx-64/cffi-2.1.1-py312ha4ebf3d_2.conda - conda: https://prefix.dev/conda-forge/osx-64/cmake-3.31.8-h29fc008_0.conda + - conda: https://prefix.dev/conda-forge/osx-64/curl-8.21.0-h5318221_5.conda - conda: https://prefix.dev/conda-forge/osx-64/git-lfs-3.8.0-hb8084c2_0.conda + - conda: https://prefix.dev/conda-forge/osx-64/go-yq-4.53.6-had63097_0.conda - conda: https://prefix.dev/conda-forge/osx-64/icu-78.3-py313hbf1d544_2.conda - conda: https://prefix.dev/conda-forge/osx-64/krb5-1.22.2-h69064fd_2.conda - conda: https://prefix.dev/conda-forge/osx-64/libcurl-8.21.0-h5318221_5.conda @@ -259,6 +270,7 @@ environments: - conda: https://prefix.dev/conda-forge/osx-64/markupsafe-3.0.3-py312heb39f77_1.conda - conda: https://prefix.dev/conda-forge/osx-64/ncurses-6.6-hcc0dc9a_1.conda - conda: https://prefix.dev/conda-forge/osx-64/openssl-3.6.4-h332eb6d_0.conda + - conda: https://prefix.dev/conda-forge/osx-64/perl-5.32.1-7_h10d778d_perl5.conda - conda: https://prefix.dev/conda-forge/osx-64/python-3.12.14-hd04fa83_0_cpython.conda - conda: https://prefix.dev/conda-forge/osx-64/pyyaml-6.0.3-py312h51361c1_1.conda - conda: https://prefix.dev/conda-forge/osx-64/rattler-build-0.57.2-h4728fb8_1.conda @@ -271,13 +283,14 @@ environments: - conda: https://prefix.dev/conda-forge/osx-64/yaml-0.2.5-had63097_3.conda - conda: https://prefix.dev/conda-forge/osx-64/zstandard-0.25.0-py312hdc27ec5_3.conda - conda: https://prefix.dev/conda-forge/osx-64/zstd-1.5.7-hbc1a06c_7.conda - - conda_source: vinca[e231a206] @ git+https://github.com/robostack/vinca#4683e080a18be89703b4088c90fca8eaa8620ebe + - conda_source: vinca[cd13d65b] @ git+https://github.com/tobias-fischer/vinca?rev=9e44663eaf17a1a7ae698e3140ff095a78e849e7#9e44663eaf17a1a7ae698e3140ff095a78e849e7 osx-arm64: - conda: https://prefix.dev/conda-forge/noarch/boolean.py-5.0-pyhd8ed1ab_0.conda - conda: https://prefix.dev/conda-forge/noarch/ca-certificates-2026.7.22-hbd8a1cb_0.conda - conda: https://prefix.dev/conda-forge/noarch/catkin_pkg-1.1.0-pyhd8ed1ab_0.conda - conda: https://prefix.dev/conda-forge/noarch/certifi-2026.7.22-pyhd8ed1ab_0.conda - conda: https://prefix.dev/conda-forge/noarch/charset-normalizer-3.5.1-pyhd8ed1ab_0.conda + - conda: https://prefix.dev/conda-forge/noarch/colordiff-1.0.22-hd8ed1ab_0.conda - conda: https://prefix.dev/conda-forge/noarch/distro-1.9.0-pyhd8ed1ab_1.conda - conda: https://prefix.dev/conda-forge/noarch/docutils-0.23-pyhcf101f3_0.conda - conda: https://prefix.dev/conda-forge/noarch/empy-3.3.4-pyh9f0ad1d_1.tar.bz2 @@ -312,7 +325,9 @@ environments: - conda: https://prefix.dev/conda-forge/osx-arm64/c-ares-1.34.8-h74c22ad_2.conda - conda: https://prefix.dev/conda-forge/osx-arm64/cffi-2.1.1-py312hc892d8b_2.conda - conda: https://prefix.dev/conda-forge/osx-arm64/cmake-3.31.8-h54ad630_0.conda + - conda: https://prefix.dev/conda-forge/osx-arm64/curl-8.21.0-h6651222_5.conda - conda: https://prefix.dev/conda-forge/osx-arm64/git-lfs-3.8.0-h7021a9e_0.conda + - conda: https://prefix.dev/conda-forge/osx-arm64/go-yq-4.53.6-h74c22ad_0.conda - conda: https://prefix.dev/conda-forge/osx-arm64/icu-78.3-py310h579977c_2.conda - conda: https://prefix.dev/conda-forge/osx-arm64/krb5-1.22.2-h34f8a20_2.conda - conda: https://prefix.dev/conda-forge/osx-arm64/libcurl-8.21.0-h6651222_5.conda @@ -332,6 +347,7 @@ environments: - conda: https://prefix.dev/conda-forge/osx-arm64/markupsafe-3.0.3-py312h04c11ed_1.conda - conda: https://prefix.dev/conda-forge/osx-arm64/ncurses-6.6-he64c551_1.conda - conda: https://prefix.dev/conda-forge/osx-arm64/openssl-3.6.4-h55eecbc_0.conda + - conda: https://prefix.dev/conda-forge/osx-arm64/perl-5.32.1-7_h4614cfb_perl5.conda - conda: https://prefix.dev/conda-forge/osx-arm64/python-3.12.14-hd1323d7_0_cpython.conda - conda: https://prefix.dev/conda-forge/osx-arm64/pyyaml-6.0.3-py312h04c11ed_1.conda - conda: https://prefix.dev/conda-forge/osx-arm64/rattler-build-0.57.2-h6fdd925_1.conda @@ -344,13 +360,14 @@ environments: - conda: https://prefix.dev/conda-forge/osx-arm64/yaml-0.2.5-h74c22ad_3.conda - conda: https://prefix.dev/conda-forge/osx-arm64/zstandard-0.25.0-py312hbd136b4_3.conda - conda: https://prefix.dev/conda-forge/osx-arm64/zstd-1.5.7-hf451053_7.conda - - conda_source: vinca[9e613799] @ git+https://github.com/robostack/vinca#4683e080a18be89703b4088c90fca8eaa8620ebe + - conda_source: vinca[68481890] @ git+https://github.com/tobias-fischer/vinca?rev=9e44663eaf17a1a7ae698e3140ff095a78e849e7#9e44663eaf17a1a7ae698e3140ff095a78e849e7 win-64: - conda: https://prefix.dev/conda-forge/noarch/boolean.py-5.0-pyhd8ed1ab_0.conda - conda: https://prefix.dev/conda-forge/noarch/ca-certificates-2026.7.22-h4c7d964_0.conda - conda: https://prefix.dev/conda-forge/noarch/catkin_pkg-1.1.0-pyhd8ed1ab_0.conda - conda: https://prefix.dev/conda-forge/noarch/certifi-2026.7.22-pyhd8ed1ab_0.conda - conda: https://prefix.dev/conda-forge/noarch/charset-normalizer-3.5.1-pyhd8ed1ab_0.conda + - conda: https://prefix.dev/conda-forge/noarch/colordiff-1.0.22-hd8ed1ab_0.conda - conda: https://prefix.dev/conda-forge/noarch/distro-1.9.0-pyhd8ed1ab_1.conda - conda: https://prefix.dev/conda-forge/noarch/docutils-0.23-pyhcf101f3_0.conda - conda: https://prefix.dev/conda-forge/noarch/empy-3.3.4-pyh9f0ad1d_1.tar.bz2 @@ -387,8 +404,10 @@ environments: - conda: https://prefix.dev/conda-forge/win-64/bzip2-1.0.8-h0ad9c76_10.conda - conda: https://prefix.dev/conda-forge/win-64/cffi-2.1.1-py312he06e257_2.conda - conda: https://prefix.dev/conda-forge/win-64/cmake-3.31.8-hdcbee5b_0.conda + - conda: https://prefix.dev/conda-forge/win-64/curl-8.21.0-hdb0ef4a_5.conda - conda: https://prefix.dev/conda-forge/win-64/git-2.55.0-h57928b3_1.conda - conda: https://prefix.dev/conda-forge/win-64/git-lfs-3.8.0-ha70c05e_0.conda + - conda: https://prefix.dev/conda-forge/win-64/go-yq-4.53.6-h6a83c73_0.conda - conda: https://prefix.dev/conda-forge/win-64/icu-78.3-h5112557_2.conda - conda: https://prefix.dev/conda-forge/win-64/krb5-1.22.2-h719d79b_2.conda - conda: https://prefix.dev/conda-forge/win-64/libcurl-8.21.0-hdb0ef4a_5.conda @@ -404,6 +423,7 @@ environments: - conda: https://prefix.dev/conda-forge/win-64/m2-conda-epoch-20250515-0_x86_64.conda - conda: https://prefix.dev/conda-forge/win-64/markupsafe-3.0.3-py312h05f76fc_1.conda - conda: https://prefix.dev/conda-forge/win-64/openssl-3.6.4-hf411b9b_0.conda + - conda: https://prefix.dev/conda-forge/win-64/perl-5.32.1.1-7_h57928b3_strawberry.conda - conda: https://prefix.dev/conda-forge/win-64/python-3.12.14-hb12b558_0_cpython.conda - conda: https://prefix.dev/conda-forge/win-64/pyyaml-6.0.3-py312h05f76fc_1.conda - conda: https://prefix.dev/conda-forge/win-64/rattler-build-0.57.2-h18a1a76_1.conda @@ -418,7 +438,7 @@ environments: - conda: https://prefix.dev/conda-forge/win-64/yaml-0.2.5-h6a83c73_3.conda - conda: https://prefix.dev/conda-forge/win-64/zstandard-0.25.0-py312he5662c2_3.conda - conda: https://prefix.dev/conda-forge/win-64/zstd-1.5.7-h534d264_7.conda - - conda_source: vinca[e5ba8080] @ git+https://github.com/robostack/vinca#4683e080a18be89703b4088c90fca8eaa8620ebe + - conda_source: vinca[2a1cbee0] @ git+https://github.com/tobias-fischer/vinca?rev=9e44663eaf17a1a7ae698e3140ff095a78e849e7#9e44663eaf17a1a7ae698e3140ff095a78e849e7 packages: - conda: https://prefix.dev/conda-forge/linux-64/_openmp_mutex-4.5-20_gnu.conda build_number: 20 @@ -537,6 +557,24 @@ packages: run_exports: {} size: 20991288 timestamp: 1757877168657 +- conda: https://prefix.dev/conda-forge/linux-64/curl-8.21.0-ha042cf0_5.conda + sha256: 0ba202eb4cbf3909d196e919f12e229fbd745e44462e7e3004569d20a26cf02a + md5: 82c2a5fc14064073501f5e1b817f4d80 + depends: + - __glibc >=2.17,<3.0.a0 + - krb5 >=1.22.2,<1.23.0a0 + - libcurl 8.21.0 ha042cf0_5 + - libgcc >=15 + - libpsl >=0.23.1,<0.24.0a0 + - libssh2 >=1.11.1,<2.0a0 + - libzlib >=1.3.2,<2.0a0 + - openssl >=3.5.7,<4.0a0 + - zstd >=1.5.7,<1.6.0a0 + license: curl + license_family: MIT + run_exports: {} + size: 194983 + timestamp: 1787183729323 - conda: https://prefix.dev/conda-forge/linux-64/git-lfs-3.8.0-h2c09266_0.conda sha256: b69ca1136b045256717d34f464ff9ce2b2df48a7d1953cfec8a0d0b9714c57ce md5: 935cbcbc760832a8b79a3e689f89b3ca @@ -545,6 +583,18 @@ packages: run_exports: {} size: 5064192 timestamp: 1787873878517 +- conda: https://prefix.dev/conda-forge/linux-64/go-yq-4.53.6-hebe6cf0_0.conda + sha256: fbbbea16fe906aaf74beaff6cd99928472b9a2ff11ea85298ec6874001451d66 + md5: 0516b22e2246bfb65a9fdf5f71662eca + depends: + - __glibc >=2.17 + - libgcc >=15 + - __glibc >=2.17,<3.0.a0 + license: MIT + license_family: MIT + run_exports: {} + size: 5632638 + timestamp: 1787237308494 - conda: https://prefix.dev/conda-forge/linux-64/icu-78.3-py310h44b86e0_2.conda sha256: 9f07834f0c546ab14d885ce0366285f61f44e326c0edd1fc63b8294e113ae432 md5: 72a381cbad04f24b1c2a43ef707f45b4 @@ -814,18 +864,18 @@ packages: - libpsl >=0.23.1,<0.24.0a0 size: 72519 timestamp: 1786970753847 -- conda: https://prefix.dev/conda-forge/linux-64/libpython-3.14.7-hdc7f604_104_cp314.conda - build_number: 104 - sha256: ea102c446220e9b8ad2125e38e0f4a0d9b04a7fc10193eca8d130bee507ce9e2 - md5: eb63e79ef1ac24c034d5b6ab3bcbd00c +- conda: https://prefix.dev/conda-forge/linux-64/libpython-3.14.7-hdc7f604_106_cp314.conda + build_number: 106 + sha256: 5f879892bd439c3d94f4a97b06c214b9a19c4b92f74d84f0305c6ca1b2b239b2 + md5: 28af2158bb8dbb62e55b0af3b44f9d4a depends: - __glibc >=2.17,<3.0.a0 - libgcc >=15 - libstdcxx >=15 license: Python-2.0 run_exports: {} - size: 10507939 - timestamp: 1788161778972 + size: 10520530 + timestamp: 1788383918299 - conda: https://prefix.dev/conda-forge/linux-64/libsqlite-3.53.4-h13e7031_1.conda sha256: f20d70da54e5b31dd4a51fb1efeaafafd5ab6dd8d7ac9d1438eaa2526ac4ed3d md5: e72bbec309c2b0f37823ee7d4fabfcd3 @@ -885,6 +935,19 @@ packages: - libuuid >=2.42.2,<3.0a0 size: 40017 timestamp: 1781625522462 +- conda: https://prefix.dev/conda-forge/linux-64/libuuid-2.42.3-hcfc3c73_0.conda + sha256: aa58bbba56644ffd062a4a9b358782c5eb7560ccead2ab8f7c5c6ede0a7d33a6 + md5: 74a0a409d9f4561265d36b789d3f398a + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=15 + license: BSD-3-Clause + license_family: BSD + run_exports: + weak: + - libuuid >=2.42.3,<3.0a0 + size: 39998 + timestamp: 1788347719520 - conda: https://prefix.dev/conda-forge/linux-64/libuv-1.52.1-h280c20c_1.conda sha256: 67761d0206f84140047a367eaf9befe03a7e157a29ee25aee0047b40801cc6b6 md5: 01c4ed87826af55996768af6dbc936b4 @@ -983,6 +1046,21 @@ packages: run_exports: {} size: 152278 timestamp: 1787380796884 +- conda: https://prefix.dev/conda-forge/linux-64/perl-5.32.1-7_hd590300_perl5.conda + build_number: 7 + sha256: 9ec32b6936b0e37bcb0ed34f22ec3116e75b3c0964f9f50ecea5f58734ed6ce9 + md5: f2cfec9406850991f4e3d960cc9e3321 + depends: + - libgcc-ng >=12 + - libxcrypt >=4.4.36 + license: GPL-1.0-or-later OR Artistic-1.0-Perl + run_exports: + weak: + - perl >=5.32.1,<5.33.0a0 *_perl5 + noarch: + - perl >=5.32.1,<6.0a0 *_perl5 + size: 13344463 + timestamp: 1703310653947 - conda: https://prefix.dev/conda-forge/linux-64/python-3.12.14-h8ab3286_0_cpython.conda sha256: ceb9c724de53ee3560f121dbfcb00fe8acb22c08691158fce7b6c32425855626 md5: e9dcdd23a1c68738eb3257d23d5f7285 @@ -1015,10 +1093,10 @@ packages: - python size: 31590137 timestamp: 1787353586056 -- conda: https://prefix.dev/conda-forge/linux-64/python-3.14.7-hcd007b5_104_cp314.conda - build_number: 104 - sha256: 5aaf3af8d4f99541fef4e746ae58677acda6ce02cfa5751abc3d1cc29ea8f732 - md5: 663015cba592a7375ca3c465af84186d +- conda: https://prefix.dev/conda-forge/linux-64/python-3.14.7-hcd007b5_106_cp314.conda + build_number: 106 + sha256: 4cd05407d6b07d00fd5b6cc78bd2f60ae5e21f777eb26ead82be2e3751c610a1 + md5: 56ee91e118243e46bfc0c41e4030d354 depends: - __glibc >=2.17,<3.0.a0 - bzip2 >=1.0.8,<2.0a0 @@ -1028,9 +1106,9 @@ packages: - libgcc >=15 - liblzma >=5.8.3,<6.0a0 - libmpdec >=4.0.0,<5.0a0 - - libpython 3.14.7 hdc7f604_104_cp314 + - libpython 3.14.7 hdc7f604_106_cp314 - libsqlite >=3.53.4,<4.0a0 - - libuuid >=2.42.2,<3.0a0 + - libuuid >=2.42.3,<3.0a0 - libzlib >=1.3.2,<2.0a0 - ncurses >=6.6,<7.0a0 - openssl >=3.5.8,<4.0a0 @@ -1045,8 +1123,8 @@ packages: - python_abi 3.14.* *_cp314 noarch: - python - size: 26435588 - timestamp: 1788161824322 + size: 26484459 + timestamp: 1788383955577 python_site_packages_path: lib/python3.14/site-packages - conda: https://prefix.dev/conda-forge/linux-64/pyyaml-6.0.3-py312h8a5da7c_1.conda sha256: cb142bfd92f6e55749365ddc244294fa7b64db6d08c45b018ff1c658907bfcbf @@ -1168,19 +1246,21 @@ packages: - tk >=8.6.13,<8.7.0a0 size: 3566806 timestamp: 1787272857910 -- conda: https://prefix.dev/conda-forge/linux-64/uv-0.12.9-h86a270d_0.conda - sha256: 3cf1d821c0cf527eea0c1d06ce9160aab9405db26329f14c44175f6a28f15064 - md5: 9e70c78fa60e890a2f29af40d4fa7bde +- conda: https://prefix.dev/conda-forge/linux-64/uv-0.12.12-h841d291_0.conda + sha256: 0da9fba742577c9e93020e435eccfdbe62d601aa2f25314c44e2bc13341610ff + md5: ab48164f27bfec8d6624e2c8447e73f5 depends: - - __glibc >=2.17,<3.0.a0 - libstdcxx >=15 - libgcc >=15 + - __glibc >=2.17,<3.0.a0 + - liblzma >=5.8.3,<6.0a0 + - zstd >=1.5.7,<1.6.0a0 constrains: - __glibc >=2.17 license: Apache-2.0 OR MIT run_exports: {} - size: 17510607 - timestamp: 1788302753908 + size: 17422522 + timestamp: 1788980982313 - conda: https://prefix.dev/conda-forge/linux-64/yaml-0.2.5-hebe6cf0_3.conda sha256: d164dfa75ecd538f6fd68765defcc06aa875bc697b9b215362d79a2a73125dd0 md5: e741576fb8f89821ac7c1c537322a33d @@ -1336,6 +1416,23 @@ packages: run_exports: {} size: 20216587 timestamp: 1757877248575 +- conda: https://prefix.dev/conda-forge/linux-aarch64/curl-8.21.0-h86273da_5.conda + sha256: bcc6d11f64815a2c833b77deb1d5865203182c877f21e3c98ee16159c100fc33 + md5: c5c782859c798631fcc4b14cda46d7c9 + depends: + - krb5 >=1.22.2,<1.23.0a0 + - libcurl 8.21.0 h86273da_5 + - libgcc >=15 + - libpsl >=0.23.1,<0.24.0a0 + - libssh2 >=1.11.1,<2.0a0 + - libzlib >=1.3.2,<2.0a0 + - openssl >=3.5.7,<4.0a0 + - zstd >=1.5.7,<1.6.0a0 + license: curl + license_family: MIT + run_exports: {} + size: 200814 + timestamp: 1787183663462 - conda: https://prefix.dev/conda-forge/linux-aarch64/git-lfs-3.8.0-hcf061c0_0.conda sha256: 820cd1ef5792bac4550d49a0319c8597f234294452a4589c0fac8cd509e02e06 md5: 410eac0a18d0b689c40884b9b554ace4 @@ -1344,6 +1441,16 @@ packages: run_exports: {} size: 4574716 timestamp: 1787873866482 +- conda: https://prefix.dev/conda-forge/linux-aarch64/go-yq-4.53.6-h29ee22c_0.conda + sha256: 6da1e77144058851070d8ab179ad26e86cb0a87f0f306914584dd3461d4e4916 + md5: f7e427b3a653f4c1a5868413f9c0998f + depends: + - libgcc >=15 + license: MIT + license_family: MIT + run_exports: {} + size: 5129140 + timestamp: 1787237303216 - conda: https://prefix.dev/conda-forge/linux-aarch64/icu-78.3-py311h3512406_2.conda sha256: 54d921defd947adb58a90e10203d3bfe6c1f209f5f1a1ad2c6a9f7617f2fb59e md5: b35bbb1b957440ed742f35fb96eb7f1c @@ -1595,17 +1702,17 @@ packages: - libpsl >=0.23.1,<0.24.0a0 size: 73118 timestamp: 1786970733378 -- conda: https://prefix.dev/conda-forge/linux-aarch64/libpython-3.14.7-hc71fabe_104_cp314.conda - build_number: 104 - sha256: 9ac7e008d929bf202f4475dfd8a2cbf0c7abf3a181fa10f333015fad42db3e17 - md5: 2b4c97b91d07a4d28d5542fff3b5d156 +- conda: https://prefix.dev/conda-forge/linux-aarch64/libpython-3.14.7-hc71fabe_106_cp314.conda + build_number: 106 + sha256: 59abbd9f7980242f80a0e111376f4b5d4e3defebe1aca5d0b36d2e04c9a5c85f + md5: eeb3bec9c10509463d6d5d90ed98fd7c depends: - libgcc >=15 - libstdcxx >=15 license: Python-2.0 run_exports: {} - size: 9682005 - timestamp: 1788161338350 + size: 9683680 + timestamp: 1788383990335 - conda: https://prefix.dev/conda-forge/linux-aarch64/libsqlite-3.53.4-h399dd60_1.conda sha256: fae75e68e9dbc3c90dcf93d4bae6315f1330c95aaf1404a721e8468266c23475 md5: 27e16aa1f45c787aa181549be6f209f4 @@ -1661,6 +1768,18 @@ packages: - libuuid >=2.42.2,<3.0a0 size: 43248 timestamp: 1781625528371 +- conda: https://prefix.dev/conda-forge/linux-aarch64/libuuid-2.42.3-hd6fdeab_0.conda + sha256: 3530c720c8b9dbb5aba0712d77fbb158e98d7a533ba1cf4968d42a98c41b7f24 + md5: b759892402ee563731fbbb43860cae00 + depends: + - libgcc >=15 + license: BSD-3-Clause + license_family: BSD + run_exports: + weak: + - libuuid >=2.42.3,<3.0a0 + size: 43358 + timestamp: 1788347735193 - conda: https://prefix.dev/conda-forge/linux-aarch64/libuv-1.52.1-h80f16a2_1.conda sha256: 52f4bc6e340bde53bfe38e45f6cb1080a2d5f8891da9a647087f7cc6a6edfc22 md5: 8e2136432f02841b9d8b848045f66d7d @@ -1751,6 +1870,21 @@ packages: run_exports: {} size: 155619 timestamp: 1787380792832 +- conda: https://prefix.dev/conda-forge/linux-aarch64/perl-5.32.1-7_h31becfc_perl5.conda + build_number: 7 + sha256: d78296134263b5bf476cad838ded65451e7162db756f9997c5d06b08122572ed + md5: 17d019cb2a6c72073c344e98e40dfd61 + depends: + - libgcc-ng >=12 + - libxcrypt >=4.4.36 + license: GPL-1.0-or-later OR Artistic-1.0-Perl + run_exports: + weak: + - perl >=5.32.1,<5.33.0a0 *_perl5 + noarch: + - perl >=5.32.1,<6.0a0 *_perl5 + size: 13338804 + timestamp: 1703310557094 - conda: https://prefix.dev/conda-forge/linux-aarch64/python-3.12.14-ha505bbe_0_cpython.conda sha256: 2aad9ec93f36eb001acb79de1ee09218c6b94f8aae0ce8e69b5f8c549007dffd md5: b0d552e86b70de2b8078b6ab4b576d8a @@ -1782,10 +1916,10 @@ packages: - python size: 13671907 timestamp: 1787351861891 -- conda: https://prefix.dev/conda-forge/linux-aarch64/python-3.14.7-hbec3b18_104_cp314.conda - build_number: 104 - sha256: b0cc883bcfe9ef2bd73ade43f3ef018431ab88367b1fa9dc7c4733bea898eac4 - md5: b937ae4b37923feafb98f15f5d1f8730 +- conda: https://prefix.dev/conda-forge/linux-aarch64/python-3.14.7-hbec3b18_106_cp314.conda + build_number: 106 + sha256: 39af053b358d0a6d53549c8cb7fa33b03da4f8a39e966e12a84d1235bdc7023f + md5: 1005503abb4660c19b44701f92f9e023 depends: - bzip2 >=1.0.8,<2.0a0 - ld_impl_linux-aarch64 >=2.36.1 @@ -1794,9 +1928,9 @@ packages: - libgcc >=15 - liblzma >=5.8.3,<6.0a0 - libmpdec >=4.0.0,<5.0a0 - - libpython 3.14.7 hc71fabe_104_cp314 + - libpython 3.14.7 hc71fabe_106_cp314 - libsqlite >=3.53.4,<4.0a0 - - libuuid >=2.42.2,<3.0a0 + - libuuid >=2.42.3,<3.0a0 - libzlib >=1.3.2,<2.0a0 - ncurses >=6.6,<7.0a0 - openssl >=3.5.8,<4.0a0 @@ -1811,8 +1945,8 @@ packages: - python_abi 3.14.* *_cp314 noarch: - python - size: 25424454 - timestamp: 1788161370710 + size: 25455002 + timestamp: 1788384022687 python_site_packages_path: lib/python3.14/site-packages - conda: https://prefix.dev/conda-forge/linux-aarch64/pyyaml-6.0.3-py312ha4530ae_1.conda sha256: 0ba02720b470150a8c6261a86ea4db01dcf121e16a3e3978a84e965d3fe9c39a @@ -1931,18 +2065,20 @@ packages: - tk >=8.6.13,<8.7.0a0 size: 3664220 timestamp: 1787272859143 -- conda: https://prefix.dev/conda-forge/linux-aarch64/uv-0.12.9-h12615e1_0.conda - sha256: 1e9acb7939940ab2ac06066aacebe59bc3b2f37799213c60f2061649b24285b5 - md5: 7105d7a2cc7ea1549c6fd15dc0a1767b +- conda: https://prefix.dev/conda-forge/linux-aarch64/uv-0.12.12-hed74729_0.conda + sha256: 9010ec86c529774185da3d01476ce19e875042e73210201b42d0e6bea5145d87 + md5: ef6cd21447fb177b87b1cd316054c0ca depends: - libstdcxx >=15 - libgcc >=15 + - liblzma >=5.8.3,<6.0a0 + - zstd >=1.5.7,<1.6.0a0 constrains: - __glibc >=2.17 license: Apache-2.0 OR MIT run_exports: {} - size: 17445099 - timestamp: 1788302655004 + size: 17104566 + timestamp: 1788980866890 - conda: https://prefix.dev/conda-forge/linux-aarch64/yaml-0.2.5-h29ee22c_3.conda sha256: 97e0fbe447c8f8bb1789047f37448062ebecda29bd264fcdf6129b8d08f174c9 md5: 6c97c1f44a81be1b4d5ba15a06153256 @@ -2053,6 +2189,16 @@ packages: run_exports: {} size: 64487 timestamp: 1786835648298 +- conda: https://prefix.dev/conda-forge/noarch/colordiff-1.0.22-hd8ed1ab_0.conda + sha256: 8f9305272e3a1b308bafed5062ef9a6cbc76475d4fc0a5461e6feea6601585a7 + md5: 229b525d8fcadd34b354ddae81ed2811 + depends: + - perl + license: GPL-2.0-only + license_family: GPL + run_exports: {} + size: 22064 + timestamp: 1768350136716 - conda: https://prefix.dev/conda-forge/noarch/distro-1.9.0-pyhd8ed1ab_1.conda sha256: 5603c7d0321963bb9b4030eadabc3fd7ca6103a38475b4e0ed13ed6d97c86f4e md5: 0a2014fd9860f8b1eaa0b1f3d3771a08 @@ -2648,6 +2794,23 @@ packages: run_exports: {} size: 17816621 timestamp: 1757878263595 +- conda: https://prefix.dev/conda-forge/osx-64/curl-8.21.0-h5318221_5.conda + sha256: 05542f1e9a1e64d140c1733d9e49efc1d93a251af8e4767dbe0a90e9354370e0 + md5: 782fb7c90c83dfe75051b2ff0316ee34 + depends: + - __osx >=11.0 + - krb5 >=1.22.2,<1.23.0a0 + - libcurl 8.21.0 h5318221_5 + - libpsl >=0.23.1,<0.24.0a0 + - libssh2 >=1.11.1,<2.0a0 + - libzlib >=1.3.2,<2.0a0 + - openssl >=3.5.7,<4.0a0 + - zstd >=1.5.7,<1.6.0a0 + license: curl + license_family: MIT + run_exports: {} + size: 184777 + timestamp: 1787184665411 - conda: https://prefix.dev/conda-forge/osx-64/git-lfs-3.8.0-hb8084c2_0.conda sha256: 37079e2772cb1b70cbafa4c9ad1f6629996c17db35e402851236e3d1cf479daa md5: cca2a4a0d8503b25a2f4ef9e857af25d @@ -2658,6 +2821,18 @@ packages: run_exports: {} size: 5106572 timestamp: 1787876942518 +- conda: https://prefix.dev/conda-forge/osx-64/go-yq-4.53.6-had63097_0.conda + sha256: e90056c279e7e23952ecfefcadba9493775b1a34897e6287d15f912d5dbe9158 + md5: 56428be68bcf0bdce743c95513f4ce0b + depends: + - __osx >=11.0 + constrains: + - __osx >=10.12 + license: MIT + license_family: MIT + run_exports: {} + size: 5639908 + timestamp: 1787237352990 - conda: https://prefix.dev/conda-forge/osx-64/icu-78.3-py313hbf1d544_2.conda sha256: 3abd86f3441f143b6b3203c92ae0d88dd8396a8857940af468f1fab854cdae57 md5: f13f4740c18b562bf2662d494bad6099 @@ -2719,6 +2894,16 @@ packages: run_exports: {} size: 576296 timestamp: 1787699413070 +- conda: https://prefix.dev/conda-forge/osx-64/libcxx-23.1.1-h19cb2f5_0.conda + sha256: b702c638bb8f0c6f0a5dd6941e77ca2309b73cd4e575d34b4c5b8e4d01996ccc + md5: 23a540fb2961933d47ad411c9a679385 + depends: + - __osx >=11.0 + license: Apache-2.0 WITH LLVM-exception + license_family: Apache + run_exports: {} + size: 572932 + timestamp: 1788869719775 - conda: https://prefix.dev/conda-forge/osx-64/libedit-3.1.20250104-pl5321hba2e2ab_1.conda sha256: 4aa5161db41602af1abff73f5af415902135a47855d02c1ac05681a36320bd4b md5: 17532a8cca2c887fa24fbdcd5336c3af @@ -2843,17 +3028,17 @@ packages: - libpsl >=0.23.1,<0.24.0a0 size: 72605 timestamp: 1786970907332 -- conda: https://prefix.dev/conda-forge/osx-64/libpython-3.14.7-hfe304d0_104_cp314.conda - build_number: 104 - sha256: d9affb73924acc5847688220d269662631e78a84cb242d80da867419bf8c4c2b - md5: 0c6144a9c80e6cfa383afa31fc3c62e3 +- conda: https://prefix.dev/conda-forge/osx-64/libpython-3.14.7-hfe304d0_106_cp314.conda + build_number: 106 + sha256: ddd0f95c3a5da64b9b37b925309f74d9078376f7f0e52f1f32b8b9209d020d6d + md5: 186a99fb514373907206c453031c3938 depends: - __osx >=11.0 - libcxx >=20 license: Python-2.0 run_exports: {} - size: 2113303 - timestamp: 1788162983256 + size: 2112028 + timestamp: 1788385157401 - conda: https://prefix.dev/conda-forge/osx-64/libsqlite-3.53.4-ha5db789_1.conda sha256: 78afe0bf88da66d7df62d39632aa69cb73eb32d923cd1175230ce2978618d9c8 md5: 254c302876eacc77a4682b3fa6f72385 @@ -2950,6 +3135,18 @@ packages: - openssl >=3.6.4,<4.0a0 size: 2780873 timestamp: 1787700098779 +- conda: https://prefix.dev/conda-forge/osx-64/perl-5.32.1-7_h10d778d_perl5.conda + build_number: 7 + sha256: 8ebd35e2940055a93135b9fd11bef3662cecef72d6ee651f68d64a2f349863c7 + md5: dc442e0885c3a6b65e61c61558161a9e + license: GPL-1.0-or-later OR Artistic-1.0-Perl + run_exports: + weak: + - perl >=5.32.1,<5.33.0a0 *_perl5 + noarch: + - perl >=5.32.1,<6.0a0 *_perl5 + size: 12334471 + timestamp: 1703311001432 - conda: https://prefix.dev/conda-forge/osx-64/python-3.12.14-hd04fa83_0_cpython.conda sha256: 494038cb9ba6cbab5bef4863c6e5ff81301ab6191d29a8f8a3c79c8c8bafec6b md5: 4d9966c94b15dac2d261ad6d3de77ebb @@ -2977,10 +3174,10 @@ packages: - python size: 13788477 timestamp: 1787354668160 -- conda: https://prefix.dev/conda-forge/osx-64/python-3.14.7-hafa0b4b_104_cp314.conda - build_number: 104 - sha256: 006a0b0f82b2afedc155d1b267547a438b1229e4fb5b883b0b55b56dc3905449 - md5: 87796beb07a8408c219bcb9df73aa942 +- conda: https://prefix.dev/conda-forge/osx-64/python-3.14.7-hafa0b4b_106_cp314.conda + build_number: 106 + sha256: 74e72b101d4985b9919fcf01fec55ff9c82e862377d6be23b99bfe5562ffc207 + md5: 148a7a307869b0f1e4560ec5400d29bb depends: - __osx >=11.0 - bzip2 >=1.0.8,<2.0a0 @@ -2988,7 +3185,7 @@ packages: - libffi >=3.7.0,<3.8.0a0 - liblzma >=5.8.3,<6.0a0 - libmpdec >=4.0.0,<5.0a0 - - libpython 3.14.7 hfe304d0_104_cp314 + - libpython 3.14.7 hfe304d0_106_cp314 - libsqlite >=3.53.4,<4.0a0 - libzlib >=1.3.2,<2.0a0 - ncurses >=6.6,<7.0a0 @@ -3004,8 +3201,8 @@ packages: - python_abi 3.14.* *_cp314 noarch: - python - size: 12545933 - timestamp: 1788163144008 + size: 12612709 + timestamp: 1788385311014 python_site_packages_path: lib/python3.14/site-packages - conda: https://prefix.dev/conda-forge/osx-64/pyyaml-6.0.3-py312h51361c1_1.conda sha256: d85e3be523b7173a194a66ae05a585ac1e14ccfbe81a9201b8047d6e45f2f7d9 @@ -3114,18 +3311,20 @@ packages: - tk >=8.6.13,<8.7.0a0 size: 3512384 timestamp: 1787272935349 -- conda: https://prefix.dev/conda-forge/osx-64/uv-0.12.9-h6c1caad_0.conda - sha256: 8ac38fee2b085aedfc327d2b50e2d3280cf68fdbaf0b165018b3cda7c159f2ca - md5: b5ceee5bc00661647f3d6abb61cf75e3 +- conda: https://prefix.dev/conda-forge/osx-64/uv-0.12.12-hdfb64f4_0.conda + sha256: 263f18803f836d4b7bf2430029a7982b804402ef6b27225496b3c6212f1686b7 + md5: 33db4d082e922315ee5c6155e58fed47 depends: - __osx >=11.0 - libcxx >=21 + - zstd >=1.5.7,<1.6.0a0 + - liblzma >=5.8.3,<6.0a0 constrains: - __osx >=11.0 license: Apache-2.0 OR MIT run_exports: {} - size: 16190174 - timestamp: 1788302930085 + size: 16159126 + timestamp: 1788981068127 - conda: https://prefix.dev/conda-forge/osx-64/yaml-0.2.5-had63097_3.conda sha256: b63a29a5e4968b28c8403525549fd662de8ff5863e6287f89cfaac7d1d688ea0 md5: 9b30f8e851965211d981aca9c9bd1196 @@ -3263,6 +3462,23 @@ packages: run_exports: {} size: 16632236 timestamp: 1757877846468 +- conda: https://prefix.dev/conda-forge/osx-arm64/curl-8.21.0-h6651222_5.conda + sha256: b9e7e07f4487109f9bcafc581f778784a19b6fb8e2ca4b5c86be6088e642821d + md5: a78919380afa9842a9c46f35fc7a518c + depends: + - __osx >=11.0 + - krb5 >=1.22.2,<1.23.0a0 + - libcurl 8.21.0 h6651222_5 + - libpsl >=0.23.1,<0.24.0a0 + - libssh2 >=1.11.1,<2.0a0 + - libzlib >=1.3.2,<2.0a0 + - openssl >=3.5.7,<4.0a0 + - zstd >=1.5.7,<1.6.0a0 + license: curl + license_family: MIT + run_exports: {} + size: 180586 + timestamp: 1787183693425 - conda: https://prefix.dev/conda-forge/osx-arm64/git-lfs-3.8.0-h7021a9e_0.conda sha256: ded5736ccccf1cef73644da2046f5103973dc6f09dbf2d068ac9bf811554e799 md5: 76d68fb4ba2dcd93f60ab108dbf5b48b @@ -3271,6 +3487,16 @@ packages: run_exports: {} size: 4617448 timestamp: 1787873873544 +- conda: https://prefix.dev/conda-forge/osx-arm64/go-yq-4.53.6-h74c22ad_0.conda + sha256: 2e9ca95f62de6d1f861bdd6a20fc545fda0a064b8024a484986a04f2545ada5b + md5: bad8dc3ffd9d86a31e6c3800c19e5772 + depends: + - __osx >=11.0 + license: MIT + license_family: MIT + run_exports: {} + size: 5127366 + timestamp: 1787237368441 - conda: https://prefix.dev/conda-forge/osx-arm64/icu-78.3-py310h579977c_2.conda sha256: 6cdb5dee54c72e56ab189fb3ad33cb28533553d42590e7e831160248f4416a43 md5: a5efc0b42bb8b42e97d0a29ae3e3c187 @@ -3332,6 +3558,16 @@ packages: run_exports: {} size: 575940 timestamp: 1787698697875 +- conda: https://prefix.dev/conda-forge/osx-arm64/libcxx-23.1.1-h55c6f16_0.conda + sha256: 3f902803f0fc2643a4f82ff15a06811d974ff5fb6fa8f957720a7ef84e13ad98 + md5: b61106a0b5ac7cfe874f8b2e4f067dfa + depends: + - __osx >=11.0 + license: Apache-2.0 WITH LLVM-exception + license_family: Apache + run_exports: {} + size: 578565 + timestamp: 1788869180613 - conda: https://prefix.dev/conda-forge/osx-arm64/libedit-3.1.20250104-pl5321h26f1114_1.conda sha256: 257c926f19e32bdb981fc674c76966049b6fc73f706bae58e9fed8757ad1da70 md5: 843ef89082f368cb889305084d3b483c @@ -3456,17 +3692,17 @@ packages: - libpsl >=0.23.1,<0.24.0a0 size: 72673 timestamp: 1786970928205 -- conda: https://prefix.dev/conda-forge/osx-arm64/libpython-3.14.7-h4311e70_104_cp314.conda - build_number: 104 - sha256: 551c2160312cbba2e8b4573c827a756d8ab7824a05f0eb64d954f0a18b2e5c21 - md5: 9ef5086783f252da744fc0f7a336e4d8 +- conda: https://prefix.dev/conda-forge/osx-arm64/libpython-3.14.7-h4311e70_106_cp314.conda + build_number: 106 + sha256: b239028180e1ba2f7daff4053c89e41f7c0f1a3c21bb82f6dcb09384d123ec1f + md5: 4d7a303343eff82e8b92d52c5fd3991a depends: - __osx >=11.0 - libcxx >=20 license: Python-2.0 run_exports: {} - size: 1883387 - timestamp: 1788160791643 + size: 1875368 + timestamp: 1788383432953 - conda: https://prefix.dev/conda-forge/osx-arm64/libsqlite-3.53.4-hca69786_1.conda sha256: 839b31d4830e896b4d315b551d27f2bb08026bc946df04bcc360d8627c3ba2cd md5: fde96d40ebe9a9cb34e4122380189ddb @@ -3564,6 +3800,18 @@ packages: - openssl >=3.6.4,<4.0a0 size: 3110142 timestamp: 1787698648639 +- conda: https://prefix.dev/conda-forge/osx-arm64/perl-5.32.1-7_h4614cfb_perl5.conda + build_number: 7 + sha256: b0c55040d2994fd6bf2f83786561d92f72306d982d6ea12889acad24a9bf43b8 + md5: ba3cbe93f99e896765422cc5f7c3a79e + license: GPL-1.0-or-later OR Artistic-1.0-Perl + run_exports: + weak: + - perl >=5.32.1,<5.33.0a0 *_perl5 + noarch: + - perl >=5.32.1,<6.0a0 *_perl5 + size: 14439531 + timestamp: 1703311335652 - conda: https://prefix.dev/conda-forge/osx-arm64/python-3.12.14-hd1323d7_0_cpython.conda sha256: e49baab119eaf6b37cd3fec27dd6b3a6fad10b67ac79842145fd15a340f2c3ba md5: f68540325a8a1385c22938a01e851355 @@ -3591,10 +3839,10 @@ packages: - python size: 13409190 timestamp: 1787352325281 -- conda: https://prefix.dev/conda-forge/osx-arm64/python-3.14.7-h0ae1c2c_104_cp314.conda - build_number: 104 - sha256: 90df7fc0a043b2888cce45361c55473ce37cb57ec5f8e1bc301d981b5ba8087a - md5: 86c5773c0f675287d7852068554806c9 +- conda: https://prefix.dev/conda-forge/osx-arm64/python-3.14.7-h0ae1c2c_106_cp314.conda + build_number: 106 + sha256: 5ffc8349ca089ec5ac39ad36a095323ad177ebe05cbfc690c1e135560cfd68b7 + md5: 5fd37c78250b4f57c2bcf9ad2e54beb1 depends: - __osx >=11.0 - bzip2 >=1.0.8,<2.0a0 @@ -3602,7 +3850,7 @@ packages: - libffi >=3.7.0,<3.8.0a0 - liblzma >=5.8.3,<6.0a0 - libmpdec >=4.0.0,<5.0a0 - - libpython 3.14.7 h4311e70_104_cp314 + - libpython 3.14.7 h4311e70_106_cp314 - libsqlite >=3.53.4,<4.0a0 - libzlib >=1.3.2,<2.0a0 - ncurses >=6.6,<7.0a0 @@ -3618,8 +3866,8 @@ packages: - python_abi 3.14.* *_cp314 noarch: - python - size: 12357045 - timestamp: 1788160826259 + size: 12223441 + timestamp: 1788383470498 python_site_packages_path: lib/python3.14/site-packages - conda: https://prefix.dev/conda-forge/osx-arm64/pyyaml-6.0.3-py312h04c11ed_1.conda sha256: 737959262d03c9c305618f2d48c7f1691fb996f14ae420bfd05932635c99f873 @@ -3730,18 +3978,20 @@ packages: - tk >=8.6.13,<8.7.0a0 size: 3342183 timestamp: 1787272852357 -- conda: https://prefix.dev/conda-forge/osx-arm64/uv-0.12.9-h0e72303_0.conda - sha256: 0f7c68e5025b582ab470508853d53ea4cc0baf1c8ec335c4451ffac5da96fe59 - md5: 80f4b3156a6e232cd349828de35fc6ed +- conda: https://prefix.dev/conda-forge/osx-arm64/uv-0.12.12-h3207ac5_0.conda + sha256: 0e5fe81299c2a49a3057ca521eb3e4ba42a4d9d9f671ab610a1963e57196d4a4 + md5: 415643ca9ec11ed1823ed89dab0cd779 depends: - - __osx >=11.0 - libcxx >=21 + - __osx >=11.0 + - zstd >=1.5.7,<1.6.0a0 + - liblzma >=5.8.3,<6.0a0 constrains: - __osx >=11.0 license: Apache-2.0 OR MIT run_exports: {} - size: 14663869 - timestamp: 1788302699813 + size: 14589253 + timestamp: 1788980916379 - conda: https://prefix.dev/conda-forge/osx-arm64/yaml-0.2.5-h74c22ad_3.conda sha256: 3e78c43207502418fc5fb2317bbbefe5df8b6fc1051d90bdcd1c881c76bb4193 md5: 31cf6dcc138abe673c9440cd6fe6c6fe @@ -3870,6 +4120,23 @@ packages: run_exports: {} size: 14669008 timestamp: 1757878123930 +- conda: https://prefix.dev/conda-forge/win-64/curl-8.21.0-hdb0ef4a_5.conda + sha256: 61185005c73fe2ebdf1656a7b730a47eaf1802409d5a76ac6a54d1f70a78ac1c + md5: b0dcd6182bfd56a219563a153d550d20 + depends: + - krb5 >=1.22.2,<1.23.0a0 + - libcurl 8.21.0 hdb0ef4a_5 + - libpsl >=0.23.1,<0.24.0a0 + - libssh2 >=1.11.1,<2.0a0 + - libzlib >=1.3.2,<2.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: curl + license_family: MIT + run_exports: {} + size: 189161 + timestamp: 1787183770186 - conda: https://prefix.dev/conda-forge/win-64/git-2.55.0-h57928b3_1.conda sha256: 2546ad3f04d1a3b120656d3fa496f8fa9a1d586adf4ab1c6d47bd1b31eda8158 md5: 42538faedfafda26c304520257b49151 @@ -3886,6 +4153,18 @@ packages: run_exports: {} size: 4736189 timestamp: 1787873863303 +- conda: https://prefix.dev/conda-forge/win-64/go-yq-4.53.6-h6a83c73_0.conda + sha256: a8172b0e4429b9ad9c6e35638b789baa4ba207050f4790e264286d90df3864bb + md5: 91cb60bac2631a236ec87847c7d1e355 + depends: + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + license: MIT + license_family: MIT + run_exports: {} + size: 5526321 + timestamp: 1787237283815 - conda: https://prefix.dev/conda-forge/win-64/icu-78.3-h5112557_2.conda sha256: 75c549b55b673e15de8785a8e5dd85bca7eb612eee0ff4dc8d7bdaa15eacbdbb md5: e596942e8ee6ee17fdcf1e6a77757a66 @@ -4024,18 +4303,18 @@ packages: - libpsl >=0.23.1,<0.24.0a0 size: 73511 timestamp: 1786970749988 -- conda: https://prefix.dev/conda-forge/win-64/libpython-3.14.7-h4f90d01_104_cp314.conda - build_number: 104 - sha256: 4ffd32fd57d21d4aef34ce82dd7b5ab0248260d0481a26fff64a411f7ea9858b - md5: 83748d09d722103f7aa891ecfa13d672 +- conda: https://prefix.dev/conda-forge/win-64/libpython-3.14.7-h4f90d01_106_cp314.conda + build_number: 106 + sha256: 95b7bd6fec10031b44b20276e57c11d71cd1095f966aa84c1bba5ece0eea64d2 + md5: 2d48db2a15a7b768bb563d2675c99b2c depends: - ucrt >=10.0.20348.0 - vc >=14.3,<15 - vc14_runtime >=14.44.35208 license: Python-2.0 run_exports: {} - size: 51176 - timestamp: 1788162060329 + size: 51250 + timestamp: 1788384361391 - conda: https://prefix.dev/conda-forge/win-64/libsqlite-3.53.4-hf5d6505_1.conda sha256: 0a45d7c0f20146fff787a106f8fa187872e309c70975ff8f0936e188914c26ad md5: a72d495965b144bb7da033642d389047 @@ -4147,6 +4426,18 @@ packages: - openssl >=3.6.4,<4.0a0 size: 9474879 timestamp: 1787699876495 +- conda: https://prefix.dev/conda-forge/win-64/perl-5.32.1.1-7_h57928b3_strawberry.conda + build_number: 7 + sha256: 9e8ab3e0a3a264e68c6a36897b6fdcdb5d32d30b22f238f23a89ab670f1e6612 + md5: 07cdf8cf0276211b079a5d57d7853dc4 + license: GPL-1.0-or-later OR Artistic-1.0-Perl + run_exports: + weak: + - perl >=5.32.1.1,<5.33.0a0 *_strawberry + noarch: + - perl >=5.32.1.1,<6.0a0 *_strawberry + size: 28889712 + timestamp: 1703310809518 - conda: https://prefix.dev/conda-forge/win-64/python-3.12.14-hb12b558_0_cpython.conda sha256: 0911d8c3e93d5746e7cb1d8f76ba680aa7cbdf90a68dcd697e641e9f761642af md5: 1948cdb3b317f50c8c8c4b6b96ce8a72 @@ -4174,17 +4465,17 @@ packages: - python size: 15964232 timestamp: 1787352042257 -- conda: https://prefix.dev/conda-forge/win-64/python-3.14.7-h53f6dd8_104_cp314.conda - build_number: 104 - sha256: 70c04a977ba943691cc9ff9c7cbe4326b3e9bd27a5a040184ca892192d6e3143 - md5: 00cc3f77b4714fd8f297d8f51762bbaf +- conda: https://prefix.dev/conda-forge/win-64/python-3.14.7-h53f6dd8_106_cp314.conda + build_number: 106 + sha256: 9fdcb8a5018d91a22484e67ac6c5ae9116f082f953328f43ed4421418740dfb1 + md5: df0b471269a379db0262256e332c1e7c depends: - bzip2 >=1.0.8,<2.0a0 - libexpat >=2.8.1,<3.0a0 - libffi >=3.7.0,<3.8.0a0 - liblzma >=5.8.3,<6.0a0 - libmpdec >=4.0.0,<5.0a0 - - libpython 3.14.7 h4f90d01_104_cp314 + - libpython 3.14.7 h4f90d01_106_cp314 - libsqlite >=3.53.4,<4.0a0 - libzlib >=1.3.2,<2.0a0 - openssl >=3.5.8,<4.0a0 @@ -4201,8 +4492,8 @@ packages: - python_abi 3.14.* *_cp314 noarch: - python - size: 18570404 - timestamp: 1788162197665 + size: 18377601 + timestamp: 1788384478011 python_site_packages_path: Lib/site-packages - conda: https://prefix.dev/conda-forge/win-64/pyyaml-6.0.3-py312h05f76fc_1.conda sha256: 1cab6cbd6042b2a1d8ee4d6b4ec7f36637a41f57d2f5c5cf0c12b7c4ce6a62f6 @@ -4303,17 +4594,19 @@ packages: run_exports: {} size: 694692 timestamp: 1756385147981 -- conda: https://prefix.dev/conda-forge/win-64/uv-0.12.9-hc31ddbc_0.conda - sha256: 552e6a092e45e0002c74614f33ecae23e2f3611b0cf9f3dcd8382e4ab82b9cde - md5: d581f5a3886b81416f8942caae95f6c7 +- conda: https://prefix.dev/conda-forge/win-64/uv-0.12.12-h8a923dc_0.conda + sha256: c60dcda6b72b6b0fdac9b6e82bdc58dbf70b6feb8593f4c3dad16ad2feb89448 + md5: 8ddb80ad2630b13acc779dd0fccfdda1 depends: - vc >=14.3,<15 - vc14_runtime >=14.44.35208 - ucrt >=10.0.20348.0 + - zstd >=1.5.7,<1.6.0a0 + - liblzma >=5.8.3,<6.0a0 license: Apache-2.0 OR MIT run_exports: {} - size: 15738366 - timestamp: 1788302779423 + size: 15629494 + timestamp: 1788981020485 - conda: https://prefix.dev/conda-forge/win-64/vc-14.5-ha367084_41.conda sha256: 35444c55a92e2f7f7ba26bc70f81e56e52344f7d064c0fd4b40a46a58517b79c md5: aa805b5522c2a98fa286e551a1f48546 @@ -4408,7 +4701,58 @@ packages: - zstd >=1.5.7,<1.6.0a0 size: 387535 timestamp: 1786599623274 -- conda_source: vinca[2f07e57d] @ git+https://github.com/robostack/vinca#4683e080a18be89703b4088c90fca8eaa8620ebe +- conda_source: vinca[2a1cbee0] @ git+https://github.com/tobias-fischer/vinca?rev=9e44663eaf17a1a7ae698e3140ff095a78e849e7#9e44663eaf17a1a7ae698e3140ff095a78e849e7 + version: 0.2.0 + build: pyh4616a5c_0 + subdir: noarch + noarch: python + variants: + target_platform: noarch + depends: + - python >=3.9 + - python * + - catkin_pkg >=0.4.16 + - ruamel.yaml >=0.16.6,<0.18.0 + - rosdistro >=0.8.0 + - empy >=3.3.4,<4.0.0 + - requests >=2.24.0 + - networkx >=2.5 + - rich >=10 + - jinja2 >=3.0.0 + - license-expression >=30.0.0 + - packaging >=23.0 + - zstandard >=0.19.0 + license: MIT + host_packages: + - conda: https://prefix.dev/conda-forge/noarch/ca-certificates-2026.7.22-h4c7d964_0.conda + - conda: https://prefix.dev/conda-forge/noarch/editables-0.6-pyhcf101f3_0.conda + - conda: https://prefix.dev/conda-forge/noarch/hatchling-1.32.0-pyhcf101f3_0.conda + - conda: https://prefix.dev/conda-forge/noarch/packaging-26.3-pyhc364b38_0.conda + - conda: https://prefix.dev/conda-forge/noarch/pathspec-1.1.1-pyhd8ed1ab_0.conda + - conda: https://prefix.dev/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda + - conda: https://prefix.dev/conda-forge/noarch/python_abi-3.14-9_cp314.conda + - conda: https://prefix.dev/conda-forge/noarch/tomli-2.4.1-pyhcf101f3_0.conda + - conda: https://prefix.dev/conda-forge/noarch/tomlkit-0.15.1-pyhcf101f3_0.conda + - conda: https://prefix.dev/conda-forge/noarch/trove-classifiers-2026.6.1.19-pyhcf101f3_0.conda + - conda: https://prefix.dev/conda-forge/noarch/tzdata-2026c-h151e31d_0.conda + - conda: https://prefix.dev/conda-forge/win-64/bzip2-1.0.8-h0ad9c76_10.conda + - conda: https://prefix.dev/conda-forge/win-64/libexpat-2.8.1-hac47afa_1.conda + - conda: https://prefix.dev/conda-forge/win-64/libffi-3.7.0-h3d046cb_1.conda + - conda: https://prefix.dev/conda-forge/win-64/liblzma-5.8.3-hfd05255_1.conda + - conda: https://prefix.dev/conda-forge/win-64/libmpdec-4.0.0-hfd05255_2.conda + - conda: https://prefix.dev/conda-forge/win-64/libpython-3.14.7-h4f90d01_106_cp314.conda + - conda: https://prefix.dev/conda-forge/win-64/libsqlite-3.53.4-hf5d6505_1.conda + - conda: https://prefix.dev/conda-forge/win-64/libzlib-1.3.2-hfd05255_3.conda + - conda: https://prefix.dev/conda-forge/win-64/openssl-3.6.4-hf411b9b_0.conda + - conda: https://prefix.dev/conda-forge/win-64/python-3.14.7-h53f6dd8_106_cp314.conda + - conda: https://prefix.dev/conda-forge/win-64/tk-8.6.13-h967ab96_4.conda + - conda: https://prefix.dev/conda-forge/win-64/ucrt-10.0.26100.0-h57928b3_0.conda + - conda: https://prefix.dev/conda-forge/win-64/uv-0.12.12-h8a923dc_0.conda + - conda: https://prefix.dev/conda-forge/win-64/vc-14.5-ha367084_41.conda + - conda: https://prefix.dev/conda-forge/win-64/vc14_runtime-14.51.36247-habf1de7_41.conda + - conda: https://prefix.dev/conda-forge/win-64/vcomp14-14.51.36247-habf1de7_41.conda + - conda: https://prefix.dev/conda-forge/win-64/zstd-1.5.7-h534d264_7.conda +- conda_source: vinca[45925f45] @ git+https://github.com/tobias-fischer/vinca?rev=9e44663eaf17a1a7ae698e3140ff095a78e849e7#9e44663eaf17a1a7ae698e3140ff095a78e849e7 version: 0.2.0 build: pyh4616a5c_0 subdir: noarch @@ -4441,17 +4785,17 @@ packages: - conda: https://prefix.dev/conda-forge/linux-aarch64/libgomp-16.2.0-h8acb6b2_4.conda - conda: https://prefix.dev/conda-forge/linux-aarch64/liblzma-5.8.3-he30d5cf_1.conda - conda: https://prefix.dev/conda-forge/linux-aarch64/libmpdec-4.0.0-he30d5cf_2.conda - - conda: https://prefix.dev/conda-forge/linux-aarch64/libpython-3.14.7-hc71fabe_104_cp314.conda + - conda: https://prefix.dev/conda-forge/linux-aarch64/libpython-3.14.7-hc71fabe_106_cp314.conda - conda: https://prefix.dev/conda-forge/linux-aarch64/libsqlite-3.53.4-h399dd60_1.conda - conda: https://prefix.dev/conda-forge/linux-aarch64/libstdcxx-16.2.0-hef695bb_4.conda - - conda: https://prefix.dev/conda-forge/linux-aarch64/libuuid-2.42.2-h1022ec0_0.conda + - conda: https://prefix.dev/conda-forge/linux-aarch64/libuuid-2.42.3-hd6fdeab_0.conda - conda: https://prefix.dev/conda-forge/linux-aarch64/libzlib-1.3.2-hdc9db2a_3.conda - conda: https://prefix.dev/conda-forge/linux-aarch64/ncurses-6.6-h2b6f883_1.conda - conda: https://prefix.dev/conda-forge/linux-aarch64/openssl-3.6.4-he6ad1d5_0.conda - - conda: https://prefix.dev/conda-forge/linux-aarch64/python-3.14.7-hbec3b18_104_cp314.conda + - conda: https://prefix.dev/conda-forge/linux-aarch64/python-3.14.7-hbec3b18_106_cp314.conda - conda: https://prefix.dev/conda-forge/linux-aarch64/readline-8.3-ha7194a6_1.conda - conda: https://prefix.dev/conda-forge/linux-aarch64/tk-8.6.13-noxft_hf03c496_4.conda - - conda: https://prefix.dev/conda-forge/linux-aarch64/uv-0.12.9-h12615e1_0.conda + - conda: https://prefix.dev/conda-forge/linux-aarch64/uv-0.12.12-hed74729_0.conda - conda: https://prefix.dev/conda-forge/linux-aarch64/zstd-1.5.7-h9d15635_7.conda - conda: https://prefix.dev/conda-forge/noarch/ca-certificates-2026.7.22-hbd8a1cb_0.conda - conda: https://prefix.dev/conda-forge/noarch/editables-0.6-pyhcf101f3_0.conda @@ -4464,7 +4808,7 @@ packages: - conda: https://prefix.dev/conda-forge/noarch/tomlkit-0.15.1-pyhcf101f3_0.conda - conda: https://prefix.dev/conda-forge/noarch/trove-classifiers-2026.6.1.19-pyhcf101f3_0.conda - conda: https://prefix.dev/conda-forge/noarch/tzdata-2026c-h151e31d_0.conda -- conda_source: vinca[9e613799] @ git+https://github.com/robostack/vinca#4683e080a18be89703b4088c90fca8eaa8620ebe +- conda_source: vinca[68481890] @ git+https://github.com/tobias-fischer/vinca?rev=9e44663eaf17a1a7ae698e3140ff095a78e849e7#9e44663eaf17a1a7ae698e3140ff095a78e849e7 version: 0.2.0 build: pyh4616a5c_0 subdir: noarch @@ -4500,22 +4844,22 @@ packages: - conda: https://prefix.dev/conda-forge/noarch/tzdata-2026c-h151e31d_0.conda - conda: https://prefix.dev/conda-forge/osx-arm64/bzip2-1.0.8-h4e30115_10.conda - conda: https://prefix.dev/conda-forge/osx-arm64/icu-78.3-py310h579977c_2.conda - - conda: https://prefix.dev/conda-forge/osx-arm64/libcxx-23.1.0-h55c6f16_0.conda + - conda: https://prefix.dev/conda-forge/osx-arm64/libcxx-23.1.1-h55c6f16_0.conda - conda: https://prefix.dev/conda-forge/osx-arm64/libexpat-2.8.1-hf6b4638_1.conda - conda: https://prefix.dev/conda-forge/osx-arm64/libffi-3.7.0-h47dc5ef_1.conda - conda: https://prefix.dev/conda-forge/osx-arm64/liblzma-5.8.3-h8088a28_1.conda - conda: https://prefix.dev/conda-forge/osx-arm64/libmpdec-4.0.0-h84a0fba_2.conda - - conda: https://prefix.dev/conda-forge/osx-arm64/libpython-3.14.7-h4311e70_104_cp314.conda + - conda: https://prefix.dev/conda-forge/osx-arm64/libpython-3.14.7-h4311e70_106_cp314.conda - conda: https://prefix.dev/conda-forge/osx-arm64/libsqlite-3.53.4-hca69786_1.conda - conda: https://prefix.dev/conda-forge/osx-arm64/libzlib-1.3.2-h8088a28_3.conda - conda: https://prefix.dev/conda-forge/osx-arm64/ncurses-6.6-he64c551_1.conda - conda: https://prefix.dev/conda-forge/osx-arm64/openssl-3.6.4-h55eecbc_0.conda - - conda: https://prefix.dev/conda-forge/osx-arm64/python-3.14.7-h0ae1c2c_104_cp314.conda + - conda: https://prefix.dev/conda-forge/osx-arm64/python-3.14.7-h0ae1c2c_106_cp314.conda - conda: https://prefix.dev/conda-forge/osx-arm64/readline-8.3-h8b90a29_1.conda - conda: https://prefix.dev/conda-forge/osx-arm64/tk-8.6.13-hbeba79b_4.conda - - conda: https://prefix.dev/conda-forge/osx-arm64/uv-0.12.9-h0e72303_0.conda + - conda: https://prefix.dev/conda-forge/osx-arm64/uv-0.12.12-h3207ac5_0.conda - conda: https://prefix.dev/conda-forge/osx-arm64/zstd-1.5.7-hf451053_7.conda -- conda_source: vinca[be849743] @ git+https://github.com/robostack/vinca#4683e080a18be89703b4088c90fca8eaa8620ebe +- conda_source: vinca[c31d34e5] @ git+https://github.com/tobias-fischer/vinca?rev=9e44663eaf17a1a7ae698e3140ff095a78e849e7#9e44663eaf17a1a7ae698e3140ff095a78e849e7 version: 0.2.0 build: pyh4616a5c_0 subdir: noarch @@ -4548,17 +4892,17 @@ packages: - conda: https://prefix.dev/conda-forge/linux-64/libgomp-16.2.0-he0feb66_4.conda - conda: https://prefix.dev/conda-forge/linux-64/liblzma-5.8.3-hb03c661_1.conda - conda: https://prefix.dev/conda-forge/linux-64/libmpdec-4.0.0-hb03c661_2.conda - - conda: https://prefix.dev/conda-forge/linux-64/libpython-3.14.7-hdc7f604_104_cp314.conda + - conda: https://prefix.dev/conda-forge/linux-64/libpython-3.14.7-hdc7f604_106_cp314.conda - conda: https://prefix.dev/conda-forge/linux-64/libsqlite-3.53.4-h13e7031_1.conda - conda: https://prefix.dev/conda-forge/linux-64/libstdcxx-16.2.0-h934c35e_4.conda - - conda: https://prefix.dev/conda-forge/linux-64/libuuid-2.42.2-h5347b49_0.conda + - conda: https://prefix.dev/conda-forge/linux-64/libuuid-2.42.3-hcfc3c73_0.conda - conda: https://prefix.dev/conda-forge/linux-64/libzlib-1.3.2-h25fd6f3_3.conda - conda: https://prefix.dev/conda-forge/linux-64/ncurses-6.6-hdb14827_1.conda - conda: https://prefix.dev/conda-forge/linux-64/openssl-3.6.4-h781a0a9_0.conda - - conda: https://prefix.dev/conda-forge/linux-64/python-3.14.7-hcd007b5_104_cp314.conda + - conda: https://prefix.dev/conda-forge/linux-64/python-3.14.7-hcd007b5_106_cp314.conda - conda: https://prefix.dev/conda-forge/linux-64/readline-8.3-hd6e31c0_1.conda - conda: https://prefix.dev/conda-forge/linux-64/tk-8.6.13-noxft_h1df4ec4_4.conda - - conda: https://prefix.dev/conda-forge/linux-64/uv-0.12.9-h86a270d_0.conda + - conda: https://prefix.dev/conda-forge/linux-64/uv-0.12.12-h841d291_0.conda - conda: https://prefix.dev/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_7.conda - conda: https://prefix.dev/conda-forge/noarch/ca-certificates-2026.7.22-hbd8a1cb_0.conda - conda: https://prefix.dev/conda-forge/noarch/editables-0.6-pyhcf101f3_0.conda @@ -4571,7 +4915,7 @@ packages: - conda: https://prefix.dev/conda-forge/noarch/tomlkit-0.15.1-pyhcf101f3_0.conda - conda: https://prefix.dev/conda-forge/noarch/trove-classifiers-2026.6.1.19-pyhcf101f3_0.conda - conda: https://prefix.dev/conda-forge/noarch/tzdata-2026c-h151e31d_0.conda -- conda_source: vinca[e231a206] @ git+https://github.com/robostack/vinca#4683e080a18be89703b4088c90fca8eaa8620ebe +- conda_source: vinca[cd13d65b] @ git+https://github.com/tobias-fischer/vinca?rev=9e44663eaf17a1a7ae698e3140ff095a78e849e7#9e44663eaf17a1a7ae698e3140ff095a78e849e7 version: 0.2.0 build: pyh4616a5c_0 subdir: noarch @@ -4606,69 +4950,18 @@ packages: - conda: https://prefix.dev/conda-forge/noarch/trove-classifiers-2026.6.1.19-pyhcf101f3_0.conda - conda: https://prefix.dev/conda-forge/noarch/tzdata-2026c-h151e31d_0.conda - conda: https://prefix.dev/conda-forge/osx-64/bzip2-1.0.8-h374f1ed_10.conda - - conda: https://prefix.dev/conda-forge/osx-64/libcxx-23.1.0-h19cb2f5_0.conda + - conda: https://prefix.dev/conda-forge/osx-64/libcxx-23.1.1-h19cb2f5_0.conda - conda: https://prefix.dev/conda-forge/osx-64/libexpat-2.8.1-hcc62823_1.conda - conda: https://prefix.dev/conda-forge/osx-64/libffi-3.7.0-h6b3a05b_1.conda - conda: https://prefix.dev/conda-forge/osx-64/liblzma-5.8.3-hbb4bfdb_1.conda - conda: https://prefix.dev/conda-forge/osx-64/libmpdec-4.0.0-ha1e9b39_2.conda - - conda: https://prefix.dev/conda-forge/osx-64/libpython-3.14.7-hfe304d0_104_cp314.conda + - conda: https://prefix.dev/conda-forge/osx-64/libpython-3.14.7-hfe304d0_106_cp314.conda - conda: https://prefix.dev/conda-forge/osx-64/libsqlite-3.53.4-ha5db789_1.conda - conda: https://prefix.dev/conda-forge/osx-64/libzlib-1.3.2-hbb4bfdb_3.conda - conda: https://prefix.dev/conda-forge/osx-64/ncurses-6.6-hcc0dc9a_1.conda - conda: https://prefix.dev/conda-forge/osx-64/openssl-3.6.4-h332eb6d_0.conda - - conda: https://prefix.dev/conda-forge/osx-64/python-3.14.7-hafa0b4b_104_cp314.conda + - conda: https://prefix.dev/conda-forge/osx-64/python-3.14.7-hafa0b4b_106_cp314.conda - conda: https://prefix.dev/conda-forge/osx-64/readline-8.3-h000c2f7_1.conda - conda: https://prefix.dev/conda-forge/osx-64/tk-8.6.13-ha6c374e_4.conda - - conda: https://prefix.dev/conda-forge/osx-64/uv-0.12.9-h6c1caad_0.conda + - conda: https://prefix.dev/conda-forge/osx-64/uv-0.12.12-hdfb64f4_0.conda - conda: https://prefix.dev/conda-forge/osx-64/zstd-1.5.7-hbc1a06c_7.conda -- conda_source: vinca[e5ba8080] @ git+https://github.com/robostack/vinca#4683e080a18be89703b4088c90fca8eaa8620ebe - version: 0.2.0 - build: pyh4616a5c_0 - subdir: noarch - noarch: python - variants: - target_platform: noarch - depends: - - python >=3.9 - - python * - - catkin_pkg >=0.4.16 - - ruamel.yaml >=0.16.6,<0.18.0 - - rosdistro >=0.8.0 - - empy >=3.3.4,<4.0.0 - - requests >=2.24.0 - - networkx >=2.5 - - rich >=10 - - jinja2 >=3.0.0 - - license-expression >=30.0.0 - - packaging >=23.0 - - zstandard >=0.19.0 - license: MIT - host_packages: - - conda: https://prefix.dev/conda-forge/noarch/ca-certificates-2026.7.22-h4c7d964_0.conda - - conda: https://prefix.dev/conda-forge/noarch/editables-0.6-pyhcf101f3_0.conda - - conda: https://prefix.dev/conda-forge/noarch/hatchling-1.32.0-pyhcf101f3_0.conda - - conda: https://prefix.dev/conda-forge/noarch/packaging-26.3-pyhc364b38_0.conda - - conda: https://prefix.dev/conda-forge/noarch/pathspec-1.1.1-pyhd8ed1ab_0.conda - - conda: https://prefix.dev/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda - - conda: https://prefix.dev/conda-forge/noarch/python_abi-3.14-9_cp314.conda - - conda: https://prefix.dev/conda-forge/noarch/tomli-2.4.1-pyhcf101f3_0.conda - - conda: https://prefix.dev/conda-forge/noarch/tomlkit-0.15.1-pyhcf101f3_0.conda - - conda: https://prefix.dev/conda-forge/noarch/trove-classifiers-2026.6.1.19-pyhcf101f3_0.conda - - conda: https://prefix.dev/conda-forge/noarch/tzdata-2026c-h151e31d_0.conda - - conda: https://prefix.dev/conda-forge/win-64/bzip2-1.0.8-h0ad9c76_10.conda - - conda: https://prefix.dev/conda-forge/win-64/libexpat-2.8.1-hac47afa_1.conda - - conda: https://prefix.dev/conda-forge/win-64/libffi-3.7.0-h3d046cb_1.conda - - conda: https://prefix.dev/conda-forge/win-64/liblzma-5.8.3-hfd05255_1.conda - - conda: https://prefix.dev/conda-forge/win-64/libmpdec-4.0.0-hfd05255_2.conda - - conda: https://prefix.dev/conda-forge/win-64/libpython-3.14.7-h4f90d01_104_cp314.conda - - conda: https://prefix.dev/conda-forge/win-64/libsqlite-3.53.4-hf5d6505_1.conda - - conda: https://prefix.dev/conda-forge/win-64/libzlib-1.3.2-hfd05255_3.conda - - conda: https://prefix.dev/conda-forge/win-64/openssl-3.6.4-hf411b9b_0.conda - - conda: https://prefix.dev/conda-forge/win-64/python-3.14.7-h53f6dd8_104_cp314.conda - - conda: https://prefix.dev/conda-forge/win-64/tk-8.6.13-h967ab96_4.conda - - conda: https://prefix.dev/conda-forge/win-64/ucrt-10.0.26100.0-h57928b3_0.conda - - conda: https://prefix.dev/conda-forge/win-64/uv-0.12.9-hc31ddbc_0.conda - - conda: https://prefix.dev/conda-forge/win-64/vc-14.5-ha367084_41.conda - - conda: https://prefix.dev/conda-forge/win-64/vc14_runtime-14.51.36247-habf1de7_41.conda - - conda: https://prefix.dev/conda-forge/win-64/vcomp14-14.51.36247-habf1de7_41.conda - - conda: https://prefix.dev/conda-forge/win-64/zstd-1.5.7-h534d264_7.conda diff --git a/pixi.toml b/pixi.toml index 1057ff06c..f82e56846 100644 --- a/pixi.toml +++ b/pixi.toml @@ -23,7 +23,16 @@ cmake = "<4.0" # Some git repos may need git-lfs, see https://github.com/RoboStack/ros-jazzy/issues/118 git-lfs = "*" rattler-index = ">=0.27.16" -vinca = { git = "https://github.com/RoboStack/vinca.git" } +curl = "*" +go-yq = "*" +colordiff = "*" +vinca = { git = "https://github.com/Tobias-Fischer/vinca.git", rev = "9e44663eaf17a1a7ae698e3140ff095a78e849e7" } +# TEMPORARY: pinned to RoboStack/vinca@1f1dca5 (last commit before the +# rosdistro-cache-snapshot feature landed -- our already-generated +# rosdistro_snapshot.yaml wasn't produced with that machinery and broke +# against it) with the raw.githubusercontent.com tag-URL ambiguity fix +# (RoboStack/vinca#156) cherry-picked on top. Revert to RoboStack/vinca.git +# once #156 merges and the snapshot format is reconciled. # For local development uncomment: # vinca.path = "../vinca" @@ -37,7 +46,9 @@ git = "*" [tasks] generate-recipes = { cmd = "vinca -m", depends-on = ["remove-recipes"] } generate-gha-workflows = { cmd = "vinca-gha --trigger-branch dummy_build_branch_as_it_is_unused -d ./recipes", depends-on = ["generate-recipes"] } -check-patches = { cmd = "python check_patches_clean_apply.py", depends-on = ["generate-recipes"] } +check-orphaned-patches = { cmd = "python check_orphaned_platform_patches.py", description = "Detect patch/ files vinca's add_package_name_variants() will never wire into any recipe because a same-package patch exists under a different name-prefix variant (see script docstring)." } +check-patches = { cmd = "python check_patches_clean_apply.py", depends-on = ["generate-recipes", "check-orphaned-patches"] } +check-deps = { cmd = "python check_dependency_compat.py", depends-on = ["generate-recipes"], description = "Solve one fake package containing every non-ROS dependency plus the mutex constraints to find pin conflicts before building anything. Run `python check_dependency_compat.py --stale` to list already-built artifacts that conflict with the current pins." } create_snapshot = { cmd = "vinca-snapshot -d jazzy -o rosdistro_snapshot.yaml" } upload = "rattler-build upload anaconda -o robostack-jazzy -a $ANACONDA_API_TOKEN" build_continue_on_failure = { cmd = "rattler-build build --recipe-dir ./recipes -m ./conda_build_config.yaml -c https://prefix.dev/robostack-jazzy -c https://prefix.dev/conda-forge --continue-on-failure --skip-existing", depends-on = ["generate-recipes"] } @@ -52,8 +63,15 @@ description = "Build all packages, from the ./recipes dir. This will skip alread cmd = "rm -rf recipes_only_patch; rm -rf recipes; mkdir recipes" description = "Remove all generated recipes, before regenerating them." +[tasks.conda-build-config-upstream-diff] +cmd = """ +curl -sLo .tmp.yaml https://github.com/conda-forge/conda-forge-pinning-feedstock/raw/refs/heads/main/recipe/conda_build_config.yaml && \ +yq eval 'with_entries(.value = (load(".tmp.yaml")[.key] // .value))' conda_build_config.yaml | colordiff -u conda_build_config.yaml - ;\ +rm .tmp.yaml +""" +description = "Check if there are differences between the local conda_build_config.yaml and the one in the conda-forge-pinning-feedstock." + [tasks.build-one] cmd = "cp ./patch/{{ PACKAGE }}.*patch ./recipes/{{ PACKAGE }}/patch/; rattler-build build --recipe ./recipes/{{ PACKAGE }}/recipe.yaml -m ./conda_build_config.yaml -c https://prefix.dev/robostack-jazzy -c https://prefix.dev/conda-forge" args = [{ arg = "PACKAGE", default = "ros-jazzy-ros-workspace" }] description = "Build a single package, from the ./recipes dir. Add the `ros-jazzy-` prefix to the package name, e.g. `pixi build-one ros-jazzy-ros-workspace`" - diff --git a/pkg_additional_info.yaml b/pkg_additional_info.yaml index 77b492990..8a9241066 100644 --- a/pkg_additional_info.yaml +++ b/pkg_additional_info.yaml @@ -4,6 +4,8 @@ apriltag: max_pin: 'x.x.x' aws_sdk_cpp_vendor: additional_cmake_args: "-DAMENT_VENDOR_POLICY=NEVER_VENDOR_IGNORE_SATISFIED_CHECK" +behaviortree_cpp_v3: + additional_cmake_args: "-DBUILD_UNIT_TESTS=OFF" cartographer: generate_dummy_package_with_run_deps: dep_name: cartographer @@ -12,10 +14,22 @@ cartographer: override_version: '2.0.0' cartographer_ros: additional_cmake_args: "-DCMAKE_WINDOWS_EXPORT_ALL_SYMBOLS=ON" +coal: + generate_dummy_package_with_run_deps: + dep_name: coal + max_pin: 'x.x.x' + override_version: '3.0.4' console_bridge_vendor: additional_cmake_args: "-DAMENT_VENDOR_POLICY=NEVER_VENDOR_IGNORE_SATISFIED_CHECK" +cyclonedds: + generate_dummy_package_with_run_deps: + dep_name: cyclonedds + max_pin: 'x.x' data_tamer_cpp: + # Remove once https://github.com/PickNikRobotics/data_tamer/pull/58 is merged and released additional_cmake_args: "-DCMAKE_WINDOWS_EXPORT_ALL_SYMBOLS=ON" +depthai: + additional_cmake_args: '-DCMAKE_POLICY_VERSION_MINIMUM=3.5' diagnostic_aggregator: additional_cmake_args: "-DCMAKE_WINDOWS_EXPORT_ALL_SYMBOLS=ON" diagnostic_updater: @@ -68,7 +82,22 @@ hpp_fcl: dep_name: hpp-fcl max_pin: 'x.x.x' # the version on ros is outdated w.r.t. to the conda-forge one - override_version: '3.0.2' + override_version: '3.0.4' +iceoryx_binding_c: + generate_dummy_package_with_run_deps: + dep_name: libiceoryx-binding-c + max_pin: 'x.x' + override_version: '2.95.8' +iceoryx_hoofs: + generate_dummy_package_with_run_deps: + dep_name: libiceoryx-hoofs + max_pin: 'x.x' + override_version: '2.95.8' +iceoryx_posh: + generate_dummy_package_with_run_deps: + dep_name: libiceoryx-posh + max_pin: 'x.x' + override_version: '2.95.8' ignition_cmake2_vendor: additional_cmake_args: "-DAMENT_VENDOR_POLICY=NEVER_VENDOR_IGNORE_SATISFIED_CHECK" ignition_math6_vendor: @@ -90,6 +119,8 @@ libcamera: override_version: '0.5.0' libcurl_vendor: additional_cmake_args: "-DAMENT_VENDOR_POLICY=NEVER_VENDOR_IGNORE_SATISFIED_CHECK" +libg2o: + additional_cmake_args: "-DCMAKE_WINDOWS_EXPORT_ALL_SYMBOLS=ON" liblz4_vendor: additional_cmake_args: "-DAMENT_VENDOR_POLICY=NEVER_VENDOR_IGNORE_SATISFIED_CHECK" librealsense2: @@ -100,6 +131,10 @@ magic_enum: generate_dummy_package_with_run_deps: dep_name: magic_enum max_pin: 'x.x' +mcap_vendor: + additional_cmake_args: + if: unix + then: '-DCMAKE_CXX_FLAGS="-include cstdint"' mujoco_vendor: additional_cmake_args: "-DAMENT_VENDOR_POLICY=NEVER_VENDOR_IGNORE_SATISFIED_CHECK" octomap: @@ -122,6 +157,12 @@ ouster_ros: additional_cmake_args: "-DOUSTER_USE_VCPKG_IF_AVAILABLE=OFF" pcl_ros: additional_cmake_args: "-DCMAKE_WINDOWS_EXPORT_ALL_SYMBOLS=ON" +pinocchio: + generate_dummy_package_with_run_deps: + dep_name: pinocchio + max_pin: 'x.x.x' + # the version on ros is outdated w.r.t. to the conda-forge one + override_version: '4.1.0' proxsuite: generate_dummy_package_with_run_deps: dep_name: proxsuite @@ -168,7 +209,6 @@ robot_state_publisher: additional_cmake_args: "-DCMAKE_WINDOWS_EXPORT_ALL_SYMBOLS=ON" rviz_ogre_vendor: additional_cmake_args: "-DRVIZ_OGRE_VENDOR_MANGLE_NAME_OF_LIBRARIES_USED_BY_RVIZ=ON" -# Remove once https://github.com/PickNikRobotics/data_tamer/pull/58 is merged and released sdformat_vendor: additional_cmake_args: "-DAMENT_VENDOR_POLICY=NEVER_VENDOR_IGNORE_SATISFIED_CHECK" sick_scan_xd: @@ -202,28 +242,6 @@ visp: dep_name: visp max_pin: 'x.x' # the version on ros is outdated w.r.t. to the conda-forge one - override_version: '3.6.0' + override_version: '3.7.0' zenoh_cpp_vendor: additional_cmake_args: "-DAMENT_VENDOR_POLICY=NEVER_VENDOR_IGNORE_SATISFIED_CHECK -DUSE_SYSTEM_ZENOH=ON" -coal: - generate_dummy_package_with_run_deps: - dep_name: coal - max_pin: 'x.x.x' - override_version: '3.0.4' - # Remove on next full rebuild: bumped so main rebuilds the 3.0.4 dummy - build_number: 22 -nav2_mppi_controller: - build_number: 22 -pinocchio: - generate_dummy_package_with_run_deps: - dep_name: pinocchio - max_pin: 'x.x.x' - # the version on ros is outdated w.r.t. to the conda-forge one - override_version: '4.1.0' - # Remove on next full rebuild: bumped so main rebuilds the 4.1.0 dummy - build_number: 22 -ros2cli: - build_number: 22 -rosidl_cli: - build_number: 22 - diff --git a/robostack.yaml b/robostack.yaml index 3725f12b5..4f84672fd 100644 --- a/robostack.yaml +++ b/robostack.yaml @@ -276,7 +276,10 @@ libcurl: libcurl-dev: robostack: [libcurl] libdc1394-dev: - robostack: [libdc1394] + robostack: + linux: [libdc1394] + osx: [libdc1394] + win64: [] libdraco-dev: robostack: [draco] libdw-dev: @@ -1162,7 +1165,10 @@ yaml: yaml-cpp: robostack: [yaml-cpp] zbar: - robostack: [zbar] + robostack: + linux: [zbar] + osx: [zbar] + win64: [] zlib: robostack: [zlib] zziplib: diff --git a/vinca.yaml b/vinca.yaml index b611c7b55..318d84518 100644 --- a/vinca.yaml +++ b/vinca.yaml @@ -10,12 +10,12 @@ conda_index: - robostack.yaml - packages-ignore.yaml -# Reminder for next full rebuild, the next build number should be 23 -build_number: 21 +# Reminder for next full rebuild, the next build number should be 24 +build_number: 23 mutex_package: name: "ros2-distro-mutex" - version: "0.16.0" + version: "0.17.0" upper_bound: "x.x" run_constraints: - libboost 1.90.* @@ -23,7 +23,7 @@ mutex_package: - pcl 1.15.1.* - gazebo 11.* - libprotobuf 7.35.* - - vtk 9.6.2.* + - vtk 9.7.0.* packages_skip_by_deps: @@ -85,6 +85,73 @@ packages_select_by_deps: - topic_based_ros2_control # Generic dependency used by Isaac ROS without Jazzy rosdistro releases. - turtlebot3 - turtlebot3_simulations + + # Parity sweep with ros-humble (2026-09-04): packages humble ships but jazzy's + # meta-package tree doesn't pull in on its own. Cross-platform (humble has these + # as unconditional or "not wasm32" seeds; jazzy has no wasm32 platform). + - ament_cmake_nose + - apex_test_tools + - automatika_ros_sugar + - autoware_adapi_v1_msgs + - autoware_adapi_version_msgs + - autoware_auto_msgs + - autoware_component_interface_specs + - autoware_geography_utils + - autoware_global_parameter_loader + - autoware_interpolation + - autoware_kalman_filter + - autoware_lanelet2_extension + - autoware_lanelet2_extension_python + - autoware_msgs + - autoware_node + - autoware_object_recognition_utils + - autoware_point_types + - autoware_signal_processing + - autoware_vehicle_info_utils + - aws_robomaker_small_warehouse_world + - behaviortree_cpp_v3 + - bno055 + - bond_core + - color_util + - dynmsg + - geographic_info + - geometry_tutorials + - imu_calib + - imu_transformer + - libnabo + - libpointmatcher + - marker_msgs + - moveit_chomp_optimizer_adapter + - open3d_conversions + - persist_parameter_server + - pick_ik + - polygon_utils + - proxsuite + - ptz_action_server_msgs + - radar_msgs + - rclc + - rclc_lifecycle + - rclc_parameter + - robot_controllers + - rqt + - rqt_controller_manager + - rqt_moveit + - rqt_robot_dashboard + - rqt_robot_steering + - rtabmap + - sick_safetyscanners_base + - stubborn_buddies + - system_modes + - turtle_tf2_cpp + - turtle_tf2_py + - urg_node + - vector_pursuit_controller + - velodyne_simulator + - visp + # Note: humble also ships the classic gazebo/ignition family (gazebo_ros_pkgs, + # ign_ros2_control, ros_ign*) here; deliberately not added since jazzy already + # uses the modern gz-sim stack (ros_gz above) instead. + - turtlebot4_description - turtlebot4_desktop - turtlebot4_gz_bringup @@ -98,15 +165,107 @@ packages_select_by_deps: - ur - ur_simulation_gz + # Packages only built on Linux (hardware-specific: turtlebot4/irobot_create- + # style deps, or Linux-only APIs like readlink/socketcan/v4l; a few were + # previously attempted on macOS/Windows and failed there). - if: linux then: + - apriltag_ros # Depends (indirectly) on libcamera + - easynav + - easynav_bonxai_maps_manager + - easynav_common + - easynav_controller + - easynav_core + - easynav_costmap_localizer + - easynav_costmap_maps_manager + - easynav_costmap_planner + - easynav_fusion_localizer + - easynav_gps_localizer + - easynav_interfaces + - easynav_localizer + - easynav_maps_manager + - easynav_mpc_controller + - easynav_mppi_controller + - easynav_navmap_localizer + - easynav_navmap_maps_manager + - easynav_navmap_planner + - easynav_octomap_maps_manager + - easynav_planner + - easynav_regulated_pp_controller + - easynav_routes_maps_manager + - easynav_sensors + - easynav_serest_controller + - easynav_simple_common + - easynav_simple_controller + - easynav_simple_localizer + - easynav_simple_maps_manager + - easynav_simple_planner + - easynav_support_py + - easynav_system + - easynav_tools + - easynav_vff_controller + - io_context + - livox_ros_driver2 + - mavros_extras # on macos it fails with https://github.com/RoboStack/ros-jazzy/pull/135#issuecomment-3772187665 + - mujoco_ros2_control # Use readlink and access at runtime linux-specific file + - mujoco_ros2_control_demos # Use readlink and access at runtime linux-specific file + - navmap_core + - navmap_ros + - navmap_ros_interfaces + - nobleo_socketcan_bridge # Depends on socketcan + - openvdb_vendor + - orbbec_camera + - plansys2_bringup + - plansys2_bt_actions + - plansys2_core + - plansys2_domain_expert + - plansys2_executor + - plansys2_lifecycle_manager + - plansys2_msgs + - plansys2_pddl_parser + - plansys2_planner + - plansys2_popf_plan_solver + - plansys2_problem_expert + - plansys2_support_py + - plansys2_terminal + - plansys2_tests + - plansys2_tools + - popf + - proto2ros + - realsense2-camera + - realsense2-description + - roboplan_ros_franka # exec_depends on mujoco_ros2_control, which is Linux-only + - ros2_medkit_action_status_bridge + - ros2_medkit_beacon_common + - ros2_medkit_cmake + - ros2_medkit_diagnostic_bridge + - ros2_medkit_fault_manager + - ros2_medkit_fault_reporter + - ros2_medkit_gateway + - ros2_medkit_graph_provider + - ros2_medkit_integration_tests + - ros2_medkit_linux_introspection + - ros2_medkit_log_bridge + - ros2_medkit_msgs + - ros2_medkit_param_beacon + - ros2_medkit_serialization + - ros2_medkit_sovd_service_interface + - ros2_medkit_topic_beacon + - ros2_socketcan # Depends on socketcan + - septentrio_gnss_driver + - serial_driver # Serial communication only implemented for linux + - smacc2 + - spatio_temporal_voxel_layer # Uses linux-specific flags in https://github.com/SteveMacenski/spatio_temporal_voxel_layer/blob/e23d730d35407bd8e2bf9c33d10388a6a07c735d/spatio_temporal_voxel_layer/CMakeLists.txt#L124, + - swri_serial_util # Serial communication only implemented for linux - turtlebot4_base - turtlebot4_bringup - - turtlebot4_bringup - turtlebot4_diagnostics - turtlebot4_robot - turtlebot4_setup - turtlebot4_tests + - udp_driver # Serial communication only implemented for linux + - usb_cam # Depends on v4l + - v4l2_camera # Depends on v4l that is only available on linux - irobot_create_toolbox - irobot_create_nodes @@ -253,109 +412,32 @@ packages_select_by_deps: - roboplan_toppra - toppra - # These packages are only built on Linux as they depend on Linux-specific API - - if: linux - then: - - apriltag_ros # Depends (indirectly) on libcamera - - mujoco_ros2_control # Use readlink and access at runtime linux-specific file - - mujoco_ros2_control_demos # Use readlink and access at runtime linux-specific file - - nobleo_socketcan_bridge # Depends on socketcan - - plansys2_bringup - - plansys2_bt_actions - - plansys2_core - - plansys2_domain_expert - - plansys2_executor - - plansys2_lifecycle_manager - - plansys2_msgs - - plansys2_pddl_parser - - plansys2_planner - - plansys2_popf_plan_solver - - plansys2_problem_expert - - plansys2_support_py - - plansys2_terminal - - plansys2_tests - - plansys2_tools - - popf - - realsense2-camera - - realsense2-description - - roboplan_ros_franka # exec_depends on mujoco_ros2_control, which is Linux-only - - ros2_medkit_action_status_bridge - - ros2_medkit_beacon_common - - ros2_medkit_cmake - - ros2_medkit_diagnostic_bridge - - ros2_medkit_fault_manager - - ros2_medkit_fault_reporter - - ros2_medkit_gateway - - ros2_medkit_graph_provider - - ros2_medkit_integration_tests - - ros2_medkit_linux_introspection - - ros2_medkit_log_bridge - - ros2_medkit_msgs - - ros2_medkit_param_beacon - - ros2_medkit_serialization - - ros2_medkit_sovd_service_interface - - ros2_medkit_topic_beacon - - ros2_socketcan # Depends on socketcan - - septentrio_gnss_driver - - usb_cam # Depends on v4l - - v4l2_camera # Depends on v4l that is only available on linux - - # These packages are currently only build on Linux, but they currently only build on - # Linux as trying to build them in the past on macos or Windows resulted in errors - - if: linux - then: - - easynav - - easynav_bonxai_maps_manager - - easynav_common - - easynav_controller - - easynav_core - - easynav_costmap_localizer - - easynav_costmap_maps_manager - - easynav_costmap_planner - - easynav_fusion_localizer - - easynav_gps_localizer - - easynav_interfaces - - easynav_localizer - - easynav_maps_manager - - easynav_mpc_controller - - easynav_mppi_controller - - easynav_navmap_localizer - - easynav_navmap_maps_manager - - easynav_navmap_planner - - easynav_octomap_maps_manager - - easynav_planner - - easynav_regulated_pp_controller - - easynav_routes_maps_manager - - easynav_sensors - - easynav_serest_controller - - easynav_simple_common - - easynav_simple_controller - - easynav_simple_localizer - - easynav_simple_maps_manager - - easynav_simple_planner - - easynav_support_py - - easynav_system - - easynav_tools - - easynav_vff_controller - - io_context - - livox_ros_driver2 - - mavros_extras # on macos it fails with https://github.com/RoboStack/ros-jazzy/pull/135#issuecomment-3772187665 - - navmap_core - - navmap_ros - - navmap_ros_interfaces - - openvdb_vendor - - orbbec_camera - - proto2ros - - serial_driver # Serial communication only implemented for linux - - smacc2 - - spatio_temporal_voxel_layer # Uses linux-specific flags in https://github.com/SteveMacenski/spatio_temporal_voxel_layer/blob/e23d730d35407bd8e2bf9c33d10388a6a07c735d/spatio_temporal_voxel_layer/CMakeLists.txt#L124, - - swri_serial_util # Serial communication only implemented for linux - - udp_driver # Serial communication only implemented for linux # These packages are currently not build on Windows, but they be with some work - if: not win then: + # Parity sweep with ros-humble (2026-09-04): "not wasm32 and not win" seeds + # there (jazzy has no wasm32 platform, so this collapses to "not win"). + - as2_cli + - as2_msgs + # automatika_embodied_agents' generated rosidl_typesupport_fastrtps_c + # library fails to link on win-64 with dozens of "unresolved external + # symbol __imp_get_serialized_size___msg__" errors for + # sensor_msgs/std_msgs/unique_identifier_msgs/builtin_interfaces types, + # same as humble (same upstream source) -- root cause unclear without a + # Windows build environment to iterate against. + - automatika_embodied_agents + - autoware_core + - autoware_core_control + - autoware_core_localization + - autoware_ekf_localizer + - autoware_lanelet2_utils + - autoware_motion_utils + - autoware_osqp_interface + - autoware_pose_initializer + - autoware_qp_interface + - autoware_trajectory - bonxai_ros - cloudini-lib - cloudini-ros @@ -387,7 +469,20 @@ packages_select_by_deps: - mavros - med14_moveit_config - med7_moveit_config + - microstrain_inertial_driver + - microstrain_inertial_examples + - microstrain_inertial_msgs + - microstrain_inertial_rqt - mobile_robot_simulator + - mocap4r2_control + - mocap4r2_control_msgs + - mocap4r2_dummy_driver + - mocap4r2_marker_publisher + - mocap4r2_marker_viz + - mocap4r2_marker_viz_srvs + - mocap4r2_robot_gt + - mocap4r2_robot_gt_msgs + - motion_capture_tracking - moveit-py - moveit-ros-occupancy-map-monitor - moveit-ros-perception @@ -401,6 +496,17 @@ packages_select_by_deps: - plotjuggler-ros - point_cloud_transport_plugins # Error: LINK : fatal error LNK1181: cannot open input file 'zstd.lib' [%SRC_DIR%\build\zstd_point_cloud_transport.vcxproj] - rmw_stats_shim + # rosbag2_performance_benchmarking_msgs' generated Python extension + # ("_s") rosidl typesupport target hits MSVC error C1083 "Cannot open + # compiler generated file: ''" on win-64 -- a known rosidl/ament_cmake + # codegen race between the main C library target and its Python + # extension sibling both consuming the same generated .c file without + # a proper build dependency edge (same error signature already seen + # on humble for iiwa14_moveit_config). Reproduced consistently across + # two separate CI runs, not a one-off flake. Excluding the tool + # itself since rosbag2_performance_benchmarking_msgs is its only + # dependency and it has no purpose without it. + - rosbag2_performance_benchmarking - rosgraph_monitor - rosgraph_monitor_msgs - rplidar_ros @@ -423,6 +529,7 @@ packages_select_by_deps: - yasmin_plugins_manager - yasmin_ros - yasmin_viewer + - zed_msgs patch_dir: patch rosdistro_snapshot: rosdistro_snapshot.yaml diff --git a/vinca_pinning.yaml b/vinca_pinning.yaml new file mode 100644 index 000000000..5d4563acc --- /dev/null +++ b/vinca_pinning.yaml @@ -0,0 +1,64 @@ +conda_forge_pinning_version: 2026.09.01.16.28.00 +migrations: + - giflib6 + - go_macos + - gstreamer128 + - hdf52 + - libboost190 + - pybind11_abi11 + - urdfdom6 + - vtk970 +pinning_overrides: + # Build commands provide their channels with `-c`, so omit the inherited + # conda-forge-pinning channel_sources value from the rendered configuration. + channel_sources: null + channel_targets: null + # glibc floor raised from 2.17 (CentOS 7) to 2.28: conda-forge packages such as + # gazebo/openal-soft already require it. macOS deployment target raised to 14.0. + # c_stdlib_version shares a zip_keys group with the compiler versions, so the whole + # group has to be overridden; the compiler entries mirror the conda-forge base file + # and must be refreshed when `vinca-pinning-update` moves to a newer compiler. + c_stdlib_version: + - 2.28 # [linux and not riscv64] + - 2.39 # [linux and riscv64] + - 2.28 # [linux and (x86_64 or aarch64) and os.environ.get("CF_CUDA_ENABLED", "False") == "True"] + - 14.0 # [osx] + c_compiler_version: + - 15 # [linux] + - 21 # [osx] + - 14 # [linux and (x86_64 or aarch64) and os.environ.get("CF_CUDA_ENABLED", "False") == "True"] + cxx_compiler_version: + - 15 # [linux] + - 21 # [osx] + - 14 # [linux and (x86_64 or aarch64) and os.environ.get("CF_CUDA_ENABLED", "False") == "True"] + fortran_compiler_version: + - 15 # [unix] + - 5 # [win64] + - 22 # [win and arm64] + - 14 # [linux and (x86_64 or aarch64) and os.environ.get("CF_CUDA_ENABLED", "False") == "True"] + cuda_compiler_version: + - None + - 12.9 # [((linux and (x86_64 or aarch64)) or win64) and os.environ.get("CF_CUDA_ENABLED", "False") == "True"] + libzenohc: + - 1.9.0 + libzenohcxx: + - 1.9.0 + # conda-forge's sip 6.16.x (6.16.1 uploaded 2026-09-08) regressed ABI + # targeting for PyQt5-based bindings: sip-build now fails with "ABI v12 + # is being targeted but the module doesn't support it" for + # packages like qt_gui_cpp_sip, which build against pyqt5-sip's fixed + # ABI v12. Pin back to the last known-good line until upstream fixes it. + sip: + - 6.15 + # nav2_mppi_controller needs xtensor 0.25.0's API; robostack.yaml maps + # the plain (unpinned) xtensor name so this variant pin controls the + # actual version instead of a hardcoded exact-version dependency name. + xtensor: + - 0.25.0 + python: + - 3.12.* *_cpython + is_python_min: + - false + python_impl: + - cpython +