Skip to content

Commit 5696315

Browse files
authored
fix: added generated bindings for ROS Humble, Jazzy, Kilted and Rolling (#512)
* fix: added generated bindings for ROS Humble and Jazzy Signed-off-by: Esteve Fernandez <[email protected]> * build: add script for generating bindings. Removed generation of bindings in build.rs. Added GitHub workflow to update the generated bindings every night Signed-off-by: Esteve Fernandez <[email protected]> * build: target Rust 1.75 for bindgen. Updated bindings Signed-off-by: Esteve Fernandez <[email protected]> * build: added generated bindings for Kilted and Rolling Signed-off-by: Esteve Fernandez <[email protected]> * fix: assume yes when installing cargo-binstall Signed-off-by: Esteve Fernandez <[email protected]> * fix: configure token so that CI job can push branches Signed-off-by: Esteve Fernandez <[email protected]> * fix: fix call to Python script Signed-off-by: Esteve Fernandez <[email protected]> --------- Signed-off-by: Esteve Fernandez <[email protected]>
1 parent da8268c commit 5696315

8 files changed

+29571
-210
lines changed
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
name: Generate bindings
2+
3+
on:
4+
schedule:
5+
# Run the CI at 02:22 UTC every Tuesday
6+
# We pick an arbitrary time outside of most of the world's work hours
7+
# to minimize the likelihood of running alongside a heavy workload.
8+
- cron: '22 2 * * 2'
9+
workflow_dispatch:
10+
11+
env:
12+
CARGO_TERM_COLOR: always
13+
14+
jobs:
15+
build:
16+
strategy:
17+
matrix:
18+
ros_distribution:
19+
- humble
20+
- jazzy
21+
- kilted
22+
- rolling
23+
include:
24+
# Humble Hawksbill (May 2022 - May 2027)
25+
- docker_image: rostooling/setup-ros-docker:ubuntu-jammy-ros-humble-ros-base-latest
26+
ros_distribution: humble
27+
ros_version: 2
28+
# Jazzy Jalisco (May 2024 - May 2029)
29+
- docker_image: rostooling/setup-ros-docker:ubuntu-noble-ros-jazzy-ros-base-latest
30+
ros_distribution: jazzy
31+
ros_version: 2
32+
# Kilted Kaiju (May 2025 - Dec 2026)
33+
- docker_image: rostooling/setup-ros-docker:ubuntu-noble-ros-kilted-ros-base-latest
34+
ros_distribution: kilted
35+
ros_version: 2
36+
# Rolling Ridley (June 2020 - Present)
37+
- docker_image: rostooling/setup-ros-docker:ubuntu-noble-ros-rolling-ros-base-latest
38+
ros_distribution: rolling
39+
ros_version: 2
40+
runs-on: ubuntu-latest
41+
permissions:
42+
contents: write
43+
pull-requests: write
44+
container:
45+
image: ${{ matrix.docker_image }}
46+
steps:
47+
- uses: actions/checkout@v4
48+
49+
- name: Setup ROS environment
50+
uses: ros-tooling/[email protected]
51+
with:
52+
required-ros-distributions: ${{ matrix.ros_distribution }}
53+
use-ros2-testing: ${{ matrix.ros_distribution == 'rolling' }}
54+
55+
- name: Setup Rust
56+
uses: dtolnay/[email protected]
57+
with:
58+
components: clippy, rustfmt
59+
60+
- name: Install cargo binstall
61+
run: curl -L --proto '=https' --tlsv1.2 -sSf https://raw.githubusercontent.com/cargo-bins/cargo-binstall/main/install-from-binstall-release.sh | bash
62+
63+
- name: Install bindgen
64+
run: cargo binstall -y bindgen
65+
66+
- name: Generate bindings
67+
run: |
68+
cd rclrs/src
69+
../generate_bindings.py rcl_wrapper.h ${{ matrix.ros_distribution }} .
70+
71+
- name: Submit PR
72+
run: |
73+
if git diff --exit-code; then
74+
exit 0
75+
fi
76+
git config --global user.email "[email protected]"
77+
git config --global user.name "GitHub Action"
78+
git remote set-url origin https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }}
79+
git remote update origin
80+
CREATE_PR=0
81+
if !git checkout update-bindings-${{ matrix.ros_distribution }}; then
82+
CREATE_PR=1
83+
git checkout -b update-bindings-${{ matrix.ros_distribution }}
84+
fi
85+
git add rclrs/src/rcl_bindings_generated_${{ matrix.ros_distribution }}.rs
86+
git commit -m "Regenerate bindings for ${{ matrix.ros_distribution }}"
87+
git push -u origin update-bindings-${{ matrix.ros_distribution }}
88+
if [ $CREATE_PR -eq 1 ]; then
89+
gh pr create --base main --head update-bindings-${{ matrix.ros_distribution }} --title "Regenerate bindings for ${{ matrix.ros_distribution }}" --body "This PR regenerates the bindings for ${{ matrix.ros_distribution }}."
90+
fi
91+
env:
92+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
93+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

rclrs/build.rs

Lines changed: 0 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -38,78 +38,8 @@ fn main() {
3838
println!("cargo:rustc-check-cfg=cfg(ros_distro, values(\"humble\", \"jazzy\", \"rolling\"))");
3939
println!("cargo:rustc-cfg=ros_distro=\"{ros_distro}\"");
4040

41-
let mut builder = bindgen::Builder::default()
42-
.header(BINDGEN_WRAPPER)
43-
.derive_copy(false)
44-
.allowlist_type("rcl_.*")
45-
.allowlist_type("rmw_.*")
46-
.allowlist_type("rcutils_.*")
47-
.allowlist_type("rosidl_.*")
48-
.allowlist_function("rcl_.*")
49-
.allowlist_function("rmw_.*")
50-
.allowlist_function("rcutils_.*")
51-
.allowlist_function("rosidl_.*")
52-
.allowlist_var("rcl_.*")
53-
.allowlist_var("rmw_.*")
54-
.allowlist_var("rcutils_.*")
55-
.allowlist_var("rosidl_.*")
56-
.layout_tests(false)
57-
.default_enum_style(bindgen::EnumVariation::Rust {
58-
non_exhaustive: false,
59-
})
60-
.parse_callbacks(Box::new(bindgen::CargoCallbacks::new()));
61-
62-
// Invalidate the built crate whenever this script or the wrapper changes
63-
println!("cargo:rerun-if-changed=build.rs");
64-
println!("cargo:rerun-if-changed={BINDGEN_WRAPPER}");
65-
66-
// #############
67-
// # ALGORITHM #
68-
// #############
69-
//
70-
// For each prefix in ${AMENT_PREFIX_PATH}:
71-
// Search through ament index at ${prefix}/share/ament_index/resource_index/packages/ to find packages to include
72-
// The include root will be located at either:
73-
// - ${prefix}/include/ (old style)
74-
// - ${prefix}/include/${package_name} (new style)
75-
// - ${prefix}/include/CycloneDDS (special case, match for this)
76-
// End of loop
77-
// Compiled libraries are always at ${prefix}/lib
78-
//
79-
// See REP 122 for more details: https://www.ros.org/reps/rep-0122.html#filesystem-layout
80-
8141
let ament_prefix_paths = get_env_var_or_abort(AMENT_PREFIX_PATH);
8242
for ament_prefix_path in ament_prefix_paths.split(':').map(Path::new) {
83-
// Locate the ament index
84-
let ament_index = ament_prefix_path.join("share/ament_index/resource_index/packages");
85-
if !ament_index.is_dir() {
86-
continue;
87-
}
88-
89-
// Old-style include directory
90-
let include_dir = ament_prefix_path.join("include");
91-
92-
// Including the old-style packages
93-
builder = builder.clang_arg(format!("-isystem{}", include_dir.display()));
94-
95-
// Search for and include new-style-converted package paths
96-
for dir_entry in read_dir(&ament_index).unwrap().filter_map(|p| p.ok()) {
97-
let package = dir_entry.file_name();
98-
let package_include_dir = include_dir.join(&package);
99-
100-
if package_include_dir.is_dir() {
101-
let new_style_include_dir = package_include_dir.join(&package);
102-
103-
// CycloneDDS is a special case - it needs to be included as if it were a new-style path, but
104-
// doesn't actually have a secondary folder within it called "CycloneDDS"
105-
// TODO(jhdcs): if this changes in future, remove this check
106-
if package == "CycloneDDS" || new_style_include_dir.is_dir() {
107-
builder =
108-
builder.clang_arg(format!("-isystem{}", package_include_dir.display()));
109-
}
110-
}
111-
}
112-
11343
// Link the native libraries
11444
let library_path = ament_prefix_path.join("lib");
11545
println!("cargo:rustc-link-search=native={}", library_path.display());
@@ -120,11 +50,4 @@ fn main() {
12050
println!("cargo:rustc-link-lib=dylib=rcutils");
12151
println!("cargo:rustc-link-lib=dylib=rmw");
12252
println!("cargo:rustc-link-lib=dylib=rmw_implementation");
123-
124-
let bindings = builder.generate().expect("Unable to generate bindings");
125-
126-
let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
127-
bindings
128-
.write_to_file(out_path.join("rcl_bindings_generated.rs"))
129-
.expect("Couldn't write bindings!");
13053
}

rclrs/generate_bindings.py

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
#!/usr/bin/env python3
2+
import ament_index_python
3+
import os
4+
import subprocess
5+
import sys
6+
7+
def main():
8+
if len(sys.argv) != 4:
9+
print("Usage: generate_bindings.py <header_file> <ros_distribution> <output_directory>")
10+
sys.exit(1)
11+
12+
header_file = sys.argv[1]
13+
ros_distribution = sys.argv[2]
14+
output_directory = sys.argv[3]
15+
bindgen_command = []
16+
bindgen_command.append('bindgen')
17+
bindgen_command.append(header_file)
18+
bindgen_command.append('-o')
19+
bindgen_command.append(f'{output_directory}/rcl_bindings_generated_{ros_distribution}.rs')
20+
bindgen_command.append('--rust-edition')
21+
bindgen_command.append('2021')
22+
bindgen_command.append('--rust-target')
23+
bindgen_command.append('1.75')
24+
bindgen_command.append('--no-derive-copy')
25+
bindgen_command.append('--allowlist-type')
26+
bindgen_command.append('rcl_.*')
27+
bindgen_command.append('--allowlist-type')
28+
bindgen_command.append('rmw_.*')
29+
bindgen_command.append('--allowlist-type')
30+
bindgen_command.append('rcutils_.*')
31+
bindgen_command.append('--allowlist-type')
32+
bindgen_command.append('rosidl_.*')
33+
bindgen_command.append('--allowlist-function')
34+
bindgen_command.append('rcl_.*')
35+
bindgen_command.append('--allowlist-function')
36+
bindgen_command.append('rmw_.*')
37+
bindgen_command.append('--allowlist-function')
38+
bindgen_command.append('rcutils_.*')
39+
bindgen_command.append('--allowlist-function')
40+
bindgen_command.append('rosidl_.*')
41+
bindgen_command.append('--allowlist-var')
42+
bindgen_command.append('rcl_.*')
43+
bindgen_command.append('--allowlist-var')
44+
bindgen_command.append('rmw_.*')
45+
bindgen_command.append('--allowlist-var')
46+
bindgen_command.append('rcutils_.*')
47+
bindgen_command.append('--allowlist-var')
48+
bindgen_command.append('rosidl_.*')
49+
bindgen_command.append('--no-layout-tests')
50+
bindgen_command.append('--default-enum-style')
51+
bindgen_command.append('rust')
52+
bindgen_command.append('--')
53+
for package, prefix in ament_index_python.get_packages_with_prefixes().items():
54+
package_include_dir = os.path.join(prefix, 'include', package)
55+
if os.path.isdir(package_include_dir):
56+
bindgen_command.append('-isystem')
57+
bindgen_command.append(package_include_dir)
58+
subprocess.run(bindgen_command)
59+
60+
if __name__ == "__main__":
61+
main()

0 commit comments

Comments
 (0)