Last active
April 25, 2026 09:00
-
-
Save rosterloh/230aa4ce19963ddc6ca538908d9f5aa8 to your computer and use it in GitHub Desktop.
Debian bullseye ros2 build scripts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| !/bin/bash | |
| export DEB_BUILD_OPTIONS=nocheck | |
| if [ ! -f "package.xml" ]; then | |
| echo "This script must be run in the package directory" | |
| exit 1 | |
| fi | |
| ROS_DISTRO=jazzy | |
| DISTRIBUTION=$(lsb_release -i --short | tr '[:upper:]' '[:lower:]') | |
| DEB_DISTRO=$(lsb_release -c --short) | |
| PKG_NAME=$(colcon list -n) | |
| APT_REPO=$HOME/vulcanexus/apt_repo | |
| if [ ! -d $APT_REPO ]; then | |
| mkdir -p $APT_REPO | |
| fi | |
| if [ ! -f "$APT_REPO/1-local.list" ]; then | |
| echo "yaml file://$APT_REPO/local.yaml $ROS_DISTRO" > "$APT_REPO/1-local.list" | |
| fi | |
| if [ ! -f "$APT_REPO/local.yaml" ]; then | |
| PKG_NAMES=( $(colcon list --base-paths $APT_REPO/../src --topological-order --names-only) ) | |
| for PKG in "${PKG_NAMES[@]}"; do | |
| printf "%s:\n %s:\n - %s\n" "$PKG" "$DISTRIBUTION" "vulcanexus-$ROS_DISTRO-$(printf '%s' "$PKG" | tr '_' '-')" >> "$APT_REPO/local.yaml" | |
| done | |
| ROS_HOME="$APT_REPO/ros" ROSDEP_SOURCE_PATH="$APT_REPO:/etc/ros/rosdep/sources.list.d/" rosdep update --rosdistro=$ROS_DISTRO -q | |
| fi | |
| # setup.sh and local_setup.sh moan for some reason | |
| export COLCON_CURRENT_PREFIX=/opt/vulcanexus/$ROS_DISTRO | |
| ROS_HOME="$APT_REPO/ros" bloom-generate "rosdebian" --os-name="$DISTRIBUTION" --os-version="$DEB_DISTRO" --ros-distro="$ROS_DISTRO" | |
| if [ ! $? -eq 0 ]; then | |
| echo "Failed to bloom. Exiting." | |
| exit $? | |
| fi | |
| echo 13 > debian/compat | |
| # Change ros to vulcanexus | |
| find debian -type f -print0 | xargs -0 sed -i "s/ros-${ROS_DISTRO}/vulcanexus-${ROS_DISTRO}/g" | |
| find debian -type f -print0 | xargs -0 sed -i "s/\/opt\/ros\/${ROS_DISTRO}/\/opt\/vulcanexus\/${ROS_DISTRO}/g" | |
| # Add args from colcon.meta | |
| if [ "$PKG_NAME" = "fastdds" ]; then | |
| sed -i 's/$(BUILD_TESTING_ARG)/-DSECURITY=ON \\\n\t\t-DFASTDDS_STATISTICS=ON \\\n\t\t$(BUILD_TESTING_ARG)/' debian/rules | |
| fi | |
| if [ "$PKG_NAME" = "rmw_fastrtps_cpp" ] || [ "$PKG_NAME" = "rmw_fastrtps_dynamic_cpp" ] || [ "$PKG_NAME" = "rmw_fastrtps_shared_cpp" ]; then | |
| sed -i 's/$(BUILD_TESTING_ARG)/-DSECURITY=ON \\\n\t\t$(BUILD_TESTING_ARG)/' debian/rules | |
| fi | |
| fakeroot debian/rules binary | |
| if [ $? -eq 0 ]; then | |
| # Clean up | |
| test -d debian && rm -rf debian | |
| test -d .pybuild && rm -rf .pybuild | |
| test -d "$PKG_NAME.egg-info" && rm -rf "$PKG_NAME.egg-info" | |
| test -d .obj-aarch64-linux-gnu && rm -rf .obj-aarch64-linux-gnu | |
| fi |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/bash | |
| CONTINUE_PACKAGE_GENERATION=1 | |
| while getopts r:o:d: flag | |
| do | |
| case "${flag}" in | |
| r) ROS_DISTRO=${OPTARG};; | |
| o) DISTRIBUTION=${OPTARG};; | |
| d) DEB_DISTRO=${OPTARG};; | |
| esac | |
| done | |
| [ -z "$ROS_DISTRO" ] && ROS_DISTRO=iron | |
| [ -z "$DISTRIBUTION" ] && DISTRIBUTION=debian | |
| [ -z "$DEB_DISTRO" ] && DEB_DISTRO=bullseye | |
| echo "ROS_DISTRO: $ROS_DISTRO"; | |
| echo "DISTRIBUTION: $DISTRIBUTION"; | |
| echo "DEB_DISTRO: $DEB_DISTRO"; | |
| ROS_DEB="$ROS_DISTRO-" | |
| PYTHON_VER="$(python --version | sed 's/Python /python/' | cut -d'.' -f1-2)" | |
| # make output directory | |
| test -z "$CONTINUE_PACKAGE_GENERATION" && rm -rf apt_repo | |
| mkdir -p apt_repo | |
| APT_REPO="$(pwd)/apt_repo" | |
| echo "Add unreleased packages to rosdep" | |
| # For debugging use x to show commands | |
| # set -ex | |
| set -e | |
| test -f $APT_REPO/local.yaml && rm $APT_REPO/local.yaml | |
| PKG_NAMES=( $(colcon list --base-paths src --topological-order --names-only) ) | |
| for PKG in "${PKG_NAMES[@]}"; do | |
| printf "%s:\n %s:\n - %s\n" "$PKG" "$DISTRIBUTION" "ros-$ROS_DEB$(printf '%s' "$PKG" | tr '_' '-')" >> "$APT_REPO/local.yaml" | |
| done | |
| echo "yaml file://$APT_REPO/local.yaml $ROS_DISTRO" > "$APT_REPO/1-local.list" | |
| # echo "$ROSDEP_SOURCE" > "$APT_REPO/2-remote.list" | |
| ROS_HOME="$APT_REPO/ros" ROSDEP_SOURCE_PATH="$APT_REPO:/etc/ros/rosdep/sources.list.d/" rosdep update --rosdistro=$ROS_DISTRO -q | |
| echo "Run build" | |
| # Don't build tests | |
| export DEB_BUILD_OPTIONS=nocheck | |
| # Some packages fail to dependencies until the ros_workspace is built | |
| export PYTHONPATH=/opt/ros/$ROS_DISTRO/lib/$PYTHON_VER/site-packages | |
| TOTAL=${#PKG_NAMES[@]} | |
| COUNT=1 | |
| for PKG_PATH in $(colcon list --base-paths src --topological-order --paths-only); do | |
| PKG_MANIFEST=$(find $PKG_PATH -name package.xml | head -n1) | |
| PKG_VERSION=$(sed -e ':l;N;$!b l;s/\n/ /g;s|^.*<version>\(.*\)</version>.*|\1|' ${PKG_MANIFEST}) | |
| echo "::group::Building $COUNT/$TOTAL: $PKG_PATH $PKG_VERSION" | |
| test -f "$PKG_PATH/CATKIN_IGNORE" && echo "Skipped" && continue | |
| test -f "$PKG_PATH/COLCON_IGNORE" && echo "Skipped" && continue | |
| ( | |
| cd "$PKG_PATH" | |
| PKG_NAME=${PKG_PATH#src/} | |
| #GENERATED_DEBIAN_PACKAGE="ros-${ROS_DEB}$( (colcon list --topological-order --names-only) | tr '_' '-')" | |
| GENERATED_DEBIAN_PACKAGE="ros-${ROS_DEB}$(printf '%s' "$PKG_NAME" | tr '_' '-')" | |
| if [ -n "$CONTINUE_PACKAGE_GENERATION" ] && ls "$APT_REPO/${GENERATED_DEBIAN_PACKAGE}_"*.deb >/dev/null 2>&1; then | |
| echo " Skipping already generated package: ${GENERATED_DEBIAN_PACKAGE}" | |
| exit | |
| fi | |
| WAS_BLOOMD=true | |
| # Most of the packages cloned have already been bloom'd | |
| if [ ! -d "debian" ]; then | |
| WAS_BLOOMD=false | |
| ROS_HOME="$APT_REPO/ros" bloom-generate "rosdebian" --os-name="$DISTRIBUTION" --os-version="$DEB_DISTRO" --ros-distro="$ROS_DISTRO" | |
| if [ "$PKG_NAME" = "behaviortree_cpp" ]; then | |
| echo "Fixing BehaviorTree.CPP rules" | |
| sed -i "s/-DBUILD_TESTING=OFF/-DBTCPP_UNIT_TESTS=OFF/" debian/rules | |
| fi | |
| # If we bloom ourselves we don't get the build number from the tag | |
| BUILD_TAG=$(git describe --tag | grep -o '[^/]*$') | |
| #BUILD_TAG=$(git describe --tag | rev | cut -d "/" -f 1 | rev) | |
| TAG_WITHOUT_BUILD=$(echo $BUILD_TAG | cut -d "-" -f 1) | |
| sed -i "1 s/$TAG_WITHOUT_BUILD-0/$BUILD_TAG/" debian/changelog | |
| fi | |
| if [ "$PKG_NAME" != "fastcdr" ]; then | |
| # https://github.com/ros-infrastructure/bloom/pull/643 | |
| echo 11 > debian/compat | |
| fi | |
| # Set the version based on the checked out tag that contains at least one digit | |
| # strip any leading non digits as they are not part of the version number | |
| #sed -i "1 s@([^)]*)@($( (git describe --tag --match "*[0-9]*" 2>/dev/null || echo 0) | sed 's@^[^0-9]*@@').$(date +%Y%m%d.%H%M%S))@" debian/changelog | |
| # dpkg-source-opts: no need for upstream.tar.gz | |
| #sbuild --chroot-mode=unshare --no-clean-source --no-run-lintian \ | |
| # --dpkg-source-opts="-Zgzip -z1 --format=1.0 -sn" --build-dir="$APT_REPO" \ | |
| # --extra-package="$APT_REPO" "$@" | |
| fakeroot debian/rules binary | |
| #rm -f debian/rules debian/compat debian/changelog debian/control debian/copyright debian/source/format debian/source/options | |
| #rmdir -p debian/source || true | |
| # Cleanup | |
| if [ "$WAS_BLOOMD" = false ]; then | |
| rm -rf debian | |
| fi | |
| test -d .pybuild && rm -rf .pybuild | |
| test -d "$PKG_NAME.egg-info" && rm -rf "$PKG_NAME.egg-info" | |
| test -d .obj-aarch64-linux-gnu && rm -rf .obj-aarch64-linux-gnu | |
| # Install newly built package locally | |
| sudo apt install "../${GENERATED_DEBIAN_PACKAGE}_"*.deb -y | |
| #mv "../${GENERATED_DEBIAN_PACKAGE}_"*.deb $APT_REPO | |
| ) | |
| COUNT=$((COUNT+1)) | |
| echo "::endgroup::" | |
| done | |
| #rm -r "$APT_REPO/ros" | |
| ccache -s #v |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| from argparse import ArgumentParser | |
| from pathlib import Path | |
| import subprocess | |
| import sys | |
| import shutil | |
| import logging | |
| from rosdistro import get_index_url, get_index, get_cached_distribution | |
| SRC_PATH = Path.cwd() / "src" | |
| APT_REPO_PATH = Path.cwd() / "apt_repo" | |
| class ColourFormatter(logging.Formatter): | |
| grey = "\x1b[38;20m" | |
| yellow = "\x1b[33;20m" | |
| red = "\x1b[31;20m" | |
| bold_red = "\x1b[31;1m" | |
| reset = "\x1b[0m" | |
| format = "%(message)s" | |
| FORMATS = { | |
| logging.DEBUG: grey + format + reset, | |
| logging.INFO: grey + format + reset, | |
| logging.WARNING: yellow + format + reset, | |
| logging.ERROR: red + format + reset, | |
| logging.CRITICAL: bold_red + format + reset | |
| } | |
| def format(self, record: logging.LogRecord) -> str: | |
| log_fmt = self.FORMATS.get(record.levelno) | |
| formatter = logging.Formatter(log_fmt) | |
| return formatter.format(record) | |
| handler = logging.StreamHandler() | |
| handler.setFormatter(ColourFormatter()) | |
| logger = logging.getLogger() | |
| logger.addHandler(handler) | |
| logger.setLevel(logging.INFO) | |
| def main(argv=sys.argv[1:]): | |
| parser = ArgumentParser( | |
| prog='check_for_updates', | |
| description="Checks for package updates in the current build environment", | |
| ) | |
| parser.add_argument( | |
| "-r", | |
| "--rosdistro", | |
| choices=["humble", "iron", "jazzy", "kilted", "rolling"], | |
| default="jazzy", | |
| type=str, | |
| help="Name of the ROS distribution to build for", | |
| ) | |
| parser.add_argument( | |
| "-d", | |
| "--distro", | |
| choices=["bullseye", "bookworm"], | |
| default="bookworm", | |
| type=str, | |
| help="Name of the OS distribution to build for", | |
| ) | |
| arguments = parser.parse_args(argv) | |
| ros_distro_name = arguments.rosdistro | |
| os_distro_name = arguments.distro | |
| index_url = get_index_url() | |
| index = get_index(index_url) | |
| dist_file = get_cached_distribution(index, ros_distro_name) | |
| pkgs_in_order = None | |
| result = subprocess.run(['colcon', 'list', '--base-paths', 'src', '--topological-order', '--names-only'], capture_output=True, text=True) | |
| if result.returncode == 0: | |
| # Remove extra \n at the end | |
| pkgs_in_order = result.stdout[0:-2].split('\n') | |
| total_count = 0 | |
| updates = {} | |
| # repo_path = Path('./apt_repo').resolve() | |
| for f in APT_REPO_PATH.iterdir(): | |
| if f.is_file() and f.suffix == '.deb': | |
| # Skip dbgsym packages | |
| if 'dbgsym' in f.name: | |
| continue | |
| # Remove prefix and suffix | |
| name = f.name.replace(f'ros-{ros_distro_name}-', '').replace(f'{os_distro_name}_arm64.deb', '').split('_') | |
| pkg_name = name[0].replace('-', '_') | |
| pkg_version = name[1] | |
| pkg_version_wo_build = pkg_version.split('-')[0] | |
| if pkg_name in dist_file.release_packages: | |
| total_count += 1 | |
| pkg = dist_file.release_packages[pkg_name] | |
| repo_name = pkg.repository_name | |
| repo = dist_file.repositories[repo_name] | |
| dist_pkg_version = repo.release_repository.version | |
| dist_pkg_version_wo_build = dist_pkg_version.split('-')[0] | |
| # if pkg_version_wo_build != dist_pkg_version_wo_build: | |
| if pkg_version != dist_pkg_version: | |
| updates[pkg_name] = [pkg_version, dist_pkg_version] | |
| else: | |
| logger.warning(f'Not a released package name: {pkg_name}') | |
| logger.info(f'{len(updates)} of {total_count} packages have updates') | |
| if pkgs_in_order is not None: | |
| for pkg in pkgs_in_order: | |
| if pkg in updates: | |
| logger.info(f'{pkg}: {updates[pkg][0]} -> {updates[pkg][1]}') | |
| if len(updates) > 0: | |
| resp = input("Clean for rebuild?\n") | |
| if resp.upper() == "Y" or resp.upper() == "YES": | |
| for pkg in pkgs_in_order: | |
| if pkg in updates: | |
| src_path = SRC_PATH / pkg | |
| if src_path.is_dir(): | |
| logger.debug(f"Removing {src_path}") | |
| shutil.rmtree(src_path, ignore_errors=True) | |
| else: | |
| logger.error(f"{src_path} not found") | |
| pkg_name = pkg.replace('_', '-') | |
| deb_name = f"ros-{ros_distro_name}-{pkg_name}_{updates[pkg][0]}{os_distro_name}_arm64.deb" | |
| deb_path = APT_REPO_PATH / deb_name | |
| try: | |
| logger.debug(f"Removing {deb_path}") | |
| deb_path.unlink(missing_ok=False) | |
| except FileNotFoundError: | |
| logger.error(f"{deb_path} not found") | |
| deb_dbg_name = f"ros-{ros_distro_name}-{pkg_name}-dbgsym_{updates[pkg][0]}{os_distro_name}_arm64.deb" | |
| deb_dbg_path = APT_REPO_PATH / deb_dbg_name | |
| if deb_dbg_path.exists() and deb_dbg_path.is_file(): | |
| logger.debug(f"Removing {deb_dbg_path}") | |
| deb_dbg_path.unlink(missing_ok=True) | |
| if __name__ == '__main__': | |
| sys.exit(main()) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| from argparse import ArgumentParser | |
| from pathlib import Path | |
| import subprocess | |
| import sys | |
| from catkin_pkg.package import Dependency, parse_package_string | |
| from rosdistro import get_index_url, get_index, get_cached_distribution, get_distribution_cache | |
| def _get_and_parse_distribution_cache( | |
| index, rosdistro_name, pkg_names, include_test_deps, include_group_deps | |
| ): | |
| dist_cache = get_distribution_cache(index, rosdistro_name) | |
| pkg_names = set(['ros_workspace']).union(pkg_names) | |
| cached_pkgs = { | |
| pkg_name: parse_package_string(pkg_xml) | |
| for pkg_name, pkg_xml in dist_cache.release_package_xmls.items() | |
| if pkg_name in pkg_names | |
| } | |
| condition_context = { | |
| 'ROS_DISTRO': rosdistro_name, | |
| 'ROS_PYTHON_VERSION': 3, | |
| 'ROS_VERSION': 2 | |
| } | |
| for pkg in cached_pkgs.values(): | |
| pkg.evaluate_conditions(condition_context) | |
| for pkg in cached_pkgs.values(): | |
| for group_depend in pkg.group_depends: | |
| if group_depend.evaluated_condition is not False: | |
| group_depend.extract_group_members(cached_pkgs.values()) | |
| # for ROS 2 distributions bloom injects a dependency on ros_workspace | |
| # into almost all packages (except its dependencies) | |
| # therefore the same dependency needs to to be injected here | |
| distribution_type = index.distributions[rosdistro_name].get('distribution_type') | |
| if distribution_type == 'ros2' and 'ros_workspace' in cached_pkgs: | |
| no_ros_workspace_dep = set(['ros_workspace']).union( | |
| get_direct_dependencies( | |
| 'ros_workspace', cached_pkgs, pkg_names, | |
| include_test_deps=include_test_deps, | |
| include_group_deps=include_group_deps)) | |
| for pkg_name, pkg in cached_pkgs.items(): | |
| if pkg_name not in no_ros_workspace_dep: | |
| pkg.exec_depends.append(Dependency('ros_workspace')) | |
| return cached_pkgs | |
| def get_direct_dependencies( | |
| pkg_name, cached_pkgs, pkg_names, include_test_deps=True, | |
| include_group_deps=False, | |
| ): | |
| if pkg_name not in cached_pkgs: | |
| return None | |
| pkg = cached_pkgs[pkg_name] | |
| pkg_deps = (pkg.buildtool_depends + pkg.build_depends + | |
| pkg.buildtool_export_depends + pkg.build_export_depends) | |
| if include_test_deps: | |
| pkg_deps += pkg.exec_depends + pkg.test_depends | |
| # test dependencies are treated similar to build dependencies by bloom | |
| # so if configured to include test dependencies, we need them here to | |
| # ensure that all dependencies are available before starting a build | |
| depends = set([ | |
| d.name for d in pkg_deps | |
| if d.name in pkg_names and | |
| d.evaluated_condition is not False]) | |
| if include_group_deps: | |
| depends.update( | |
| m for group_dep in pkg.group_depends for m in group_dep.members if | |
| group_dep.evaluated_condition is not False) | |
| return depends | |
| def topological_order_packages(packages): | |
| """ | |
| Order packages topologically. | |
| First returning packages which have message generators and then | |
| the rest based on all direct depends and indirect recursive run_depends. | |
| :param packages: A dict mapping relative paths to ``Package`` objects ``dict`` | |
| :returns: A list of tuples containing the relative path and a ``Package`` object, ``list`` | |
| """ | |
| from catkin_pkg.topological_order import _PackageDecorator | |
| from catkin_pkg.topological_order import _sort_decorated_packages | |
| decorators_by_name = {} | |
| for path, package in packages.items(): | |
| decorators_by_name[package.name] = _PackageDecorator(package, path) | |
| # calculate transitive dependencies | |
| for decorator in decorators_by_name.values(): | |
| decorator.depends_for_topological_order = set([]) | |
| all_depends = \ | |
| decorator.package.build_depends + decorator.package.buildtool_depends + \ | |
| decorator.package.run_depends + decorator.package.test_depends | |
| # skip external dependencies, meaning names that are not known packages | |
| unique_depend_names = set([ | |
| d.name for d in all_depends if d.name in decorators_by_name.keys() and | |
| d.evaluated_condition is not False]) | |
| unique_depend_names.update([ | |
| m for d in decorator.package.group_depends for m in d.members if | |
| d.evaluated_condition is not False]) | |
| for name in unique_depend_names: | |
| if name in decorator.depends_for_topological_order: | |
| # avoid function call to improve performance | |
| # check within the loop since the set changes every cycle | |
| continue | |
| decorators_by_name[name]._add_recursive_run_depends( | |
| decorators_by_name, decorator.depends_for_topological_order) | |
| ordered_pkg_tuples = _sort_decorated_packages(decorators_by_name) | |
| for pkg_path, pkg in ordered_pkg_tuples: | |
| if pkg_path is None: | |
| raise RuntimeError('Circular dependency in: %s' % pkg) | |
| return ordered_pkg_tuples | |
| def main(argv=sys.argv[1:]): | |
| parser = ArgumentParser( | |
| prog='get_sources', | |
| description="Gets sources for all packages and their dependencies", | |
| ) | |
| parser.add_argument( | |
| "--rosdistro", | |
| choices=["humble", "iron", "jazzy", "kilted", "rolling"], | |
| default="jazzy", | |
| type=str, | |
| help="Name of the ROS distribution to build for", | |
| ) | |
| parser.add_argument( | |
| "--distro", | |
| choices=["debian"], | |
| default="debian", | |
| type=str, | |
| help="Name of the OS distribution to build for", | |
| ) | |
| parser.add_argument( | |
| "--release", | |
| choices=["bullseye", "bookworm"], | |
| default="bullseye", | |
| type=str, | |
| help="Codename of the OS release to build for", | |
| ) | |
| parser.add_argument( | |
| "--arch", | |
| default="arm64", | |
| type=str, | |
| help="Architecture to build for", | |
| ) | |
| arguments = parser.parse_args(argv) | |
| ros_distro_name = arguments.rosdistro | |
| os_distro_name = arguments.distro | |
| os_release_name = arguments.release | |
| arch = arguments.arch | |
| ignored_packages = set(['rmw_connextdds', 'rmw_cyclonedds_cpp']) | |
| index_url = get_index_url() | |
| index = get_index(index_url) | |
| platforms = [(f'{os_distro_name}', f'{os_release_name}')] | |
| print('The building for the following targets:') | |
| for os_name, os_code_name in platforms: | |
| print(f' - {os_name} {os_code_name}: {arch}') | |
| dist_file = get_cached_distribution(index, ros_distro_name) | |
| dist_cache = get_distribution_cache(index, ros_distro_name) | |
| pkg_names = dist_file.release_packages.keys() | |
| cached_pkgs = _get_and_parse_distribution_cache( | |
| index, ros_distro_name, pkg_names, | |
| include_test_deps=True, | |
| include_group_deps=False) | |
| pkgs_to_build = set([]) | |
| for pkg_name in ( | |
| 'ros_core', | |
| 'ros_base', | |
| 'perception', | |
| 'rosbridge_server', | |
| 'micro_ros_diagnostic_bridge', | |
| 'micro_ros_msgs', | |
| 'foxglove_bridge', | |
| 'dynamixel_workbench_toolbox', | |
| 'diagnostics', | |
| 'ros2trace', | |
| 'tracetools_launch', | |
| # 'ros2_control', | |
| # 'ros2_controllers', | |
| 'xacro', | |
| 'behaviortree_cpp' | |
| ): | |
| direct_dependencies = get_direct_dependencies( | |
| pkg_name, cached_pkgs, pkg_names) or set([]) | |
| pkgs_to_build.update(direct_dependencies) | |
| if pkg_name not in pkgs_to_build: | |
| pkgs_to_build.update(set([pkg_name])) | |
| i = 0 | |
| while True: | |
| i += 1 | |
| downstream_pkg_names = set([]) | |
| for pkg_name in pkgs_to_build: | |
| deps = parse_package_string(dist_cache.release_package_xmls[pkg_name]) | |
| for dep_type in ( | |
| 'build_depends', | |
| 'buildtool_depends', | |
| 'build_export_depends', | |
| 'buildtool_export_depends', | |
| 'exec_depends' | |
| ): | |
| depends = getattr(deps, dep_type) | |
| for dep in depends: | |
| if dep.name in dist_file.release_packages and \ | |
| dep.name not in downstream_pkg_names and \ | |
| dep.name not in ignored_packages: | |
| downstream_pkg_names.add(dep.name) | |
| missing = downstream_pkg_names.difference(pkgs_to_build) | |
| if len(missing) > 0: | |
| pkgs_to_build = pkgs_to_build.union(missing) | |
| else: | |
| print(f'Recursed {i} iterations before stabilising') | |
| break | |
| for pkg_name in set(pkg_names).difference(cached_pkgs.keys()): | |
| print("Skipping package '%s': no released package.xml in cache" % | |
| (pkg_name), file=sys.stderr) | |
| ordered_pkg_tuples = topological_order_packages(cached_pkgs) | |
| for pkg_name in [p.name for _, p in ordered_pkg_tuples]: | |
| if pkg_name in pkgs_to_build: | |
| if pkg_name not in dist_file.release_packages: | |
| print(f'Not a released package name: {pkg_name}') | |
| continue | |
| pkg = dist_file.release_packages[pkg_name] | |
| repo_name = pkg.repository_name | |
| repo = dist_file.repositories[repo_name] | |
| if not repo.release_repository.version: | |
| print(f"Repository '{repo_name}' has no release version") | |
| continue | |
| pkg_version = repo.release_repository.version | |
| debian_package_name = f"ros-{ros_distro_name}-{pkg_name.replace('_', '-')}" | |
| if ros_distro_name == "jazzy": | |
| # Pre Bloom'd | |
| tag = f'{platforms[0][0]}/{ros_distro_name}/{platforms[0][1]}/{pkg_name}' | |
| else: | |
| tag = repo.release_repository.tags['release'].format(package=pkg_name, version=pkg_version) | |
| sources_dir = f'src/{pkg_name}' | |
| if (not Path(sources_dir).exists()): | |
| print(f"Cloning {debian_package_name} version: {pkg_version} from {repo.release_repository.url}") | |
| cmd = [ | |
| 'git', 'clone', | |
| '--branch', tag, | |
| # fetch all branches and tags but no history | |
| '--depth', '1', '--no-single-branch', | |
| repo.release_repository.url, sources_dir] | |
| subprocess.check_call(cmd) | |
| if __name__ == '__main__': | |
| sys.exit(main()) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/sh | |
| DEB_DISTRO=bullseye | |
| echo "Install dependencies" | |
| set -ex | |
| sudo apt update | |
| # python3-colcon-installed-package-information | |
| # sudo DEBIAN_FRONTEND=noninteractive apt install -y --no-install-recommends sbuild mmdebstrap distro-info debian-archive-keyring ccache python3-vcstool python3-rosdep python3-colcon-cmake python3-colcon-library-path python3-colcon-package-information python3-colcon-pkg-config python3-colcon-recursive-crawl python3-colcon-test-result python3-bloom curl apt-cacher-ng fakechroot proot | |
| sudo DEBIAN_FRONTEND=noninteractive apt install -y --no-install-recommends ccache curl dh-python fakeroot python3-bloom python3-rosdep python3-vcstool | |
| echo "Setup build environment" | |
| mkdir -p "$HOME/.cache/sbuild" | |
| mmdebstrap --variant=buildd --include=apt,ccache,auto-apt-proxy \ | |
| --customize-hook='chroot "$1" update-ccache-symlinks' \ | |
| --components=main,universe "$DEB_DISTRO" "$HOME/.cache/sbuild/$DEB_DISTRO-arm64.tar" | |
| ccache --zero-stats --max-size=10.0G | |
| # allow ccache access from sbuild | |
| chmod a+X "$HOME" "$HOME/.cache" | |
| chmod -R a+rwX "$HOME/.cache/ccache" | |
| #cat << "EOF" > "$HOME/.sbuildrc" | |
| #$build_environment = { "CCACHE_DIR" => "/build/ccache" }; | |
| #$path = "/usr/lib/ccache:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games"; | |
| #$build_path = "/build/package/"; | |
| #$dsc_dir = "package"; | |
| #$unshare_bind_mounts = [ { directory => "$HOME/.cache/ccache", mountpoint => "/build/ccache" } ]; | |
| #$verbose = 1; | |
| #EOF | |
| #echo "$SBUILD_CONF" >> "$HOME/.sbuildrc" | |
| #test "$REPOS_FILE" = "sources.repos" -a ! -f "$REPOS_FILE" && exit | |
| echo "Checkout workspace" | |
| python get_sources.py | |
| #mkdir src | |
| #vcs import --recursive --input "$REPOS_FILE" src |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment