Skip to content

Commit de7a61c

Browse files
authored
Extra packages implementation (#12)
* Add extra packages step * Add extra packages to CI testing * Debug CI * Add vcs install to CI * Fix typo * Avoid vcs call * Add yaml depend * Fix yaml depend * Move import on main script * Print copied extra packages * Improve method name
1 parent 6a98281 commit de7a61c

File tree

7 files changed

+145
-4
lines changed

7 files changed

+145
-4
lines changed
+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
repositories:
2+
control_msgs:
3+
type: git
4+
url: https://github.com/ros-controls/control_msgs
5+
version: galactic-devel
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
cmake_minimum_required(VERSION 3.5)
2+
project(my_custom_message)
3+
4+
# Default to C99
5+
if(NOT CMAKE_C_STANDARD)
6+
set(CMAKE_C_STANDARD 99)
7+
endif()
8+
9+
# Default to C++14
10+
if(NOT CMAKE_CXX_STANDARD)
11+
set(CMAKE_CXX_STANDARD 14)
12+
endif()
13+
14+
if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
15+
add_compile_options(-Wall -Wextra -Wpedantic)
16+
endif()
17+
18+
# find dependencies
19+
find_package(ament_cmake REQUIRED)
20+
# uncomment the following section in order to fill in
21+
# further dependencies manually.
22+
# find_package(<dependency> REQUIRED)
23+
24+
if(BUILD_TESTING)
25+
find_package(ament_lint_auto REQUIRED)
26+
# the following line skips the linter which checks for copyrights
27+
# uncomment the line when a copyright and license is not present in all source files
28+
#set(ament_cmake_copyright_FOUND TRUE)
29+
# the following line skips cpplint (only works in a git repo)
30+
# uncomment the line when this package is not in a git repo
31+
#set(ament_cmake_cpplint_FOUND TRUE)
32+
ament_lint_auto_find_test_dependencies()
33+
endif()
34+
35+
find_package(rosidl_default_generators REQUIRED)
36+
37+
rosidl_generate_interfaces(${PROJECT_NAME}
38+
"msg/MyCustomMessage.msg"
39+
)
40+
41+
ament_package()
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
bool bool_test
2+
byte byte_test
3+
char char_test
4+
float32 float32_test
5+
float64 double_test
6+
int8 int8_test
7+
uint8 uint8_test
8+
int16 int16_test
9+
uint16 uint16_test
10+
int32 int32_test
11+
uint32 uint32_test
12+
int64 int64_test
13+
uint64 uint64_test
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?xml version="1.0"?>
2+
<?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
3+
<package format="3">
4+
<name>my_custom_message</name>
5+
<version>0.0.0</version>
6+
<description>TODO: Package description</description>
7+
<maintainer email="root@todo.todo">root</maintainer>
8+
<license>TODO: License declaration</license>
9+
10+
<buildtool_depend>ament_cmake</buildtool_depend>
11+
12+
<build_depend>rosidl_default_generators</build_depend>
13+
<exec_depend>rosidl_default_runtime</exec_depend>
14+
<member_of_group>rosidl_interface_packages</member_of_group>
15+
16+
<test_depend>ament_lint_auto</test_depend>
17+
<test_depend>ament_lint_common</test_depend>
18+
19+
<export>
20+
<build_type>ament_cmake</build_type>
21+
</export>
22+
</package>

ci/src/main.cpp

+6
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,12 @@
1414

1515
#include <std_msgs/msg/int32.h>
1616

17+
// Test extra packages
18+
#include <control_msgs/msg/joint_controller_state.h>
19+
#include <my_custom_message/msg/my_custom_message.h>
20+
control_msgs__msg__JointControllerState control_message;
21+
my_custom_message__msg__MyCustomMessage custom_msg;
22+
1723
rcl_publisher_t publisher;
1824
std_msgs__msg__Int32 msg;
1925
rclc_executor_t executor;

extra_script.py

+5-3
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,21 @@
11
Import("env")
22
import os, sys
3-
import microros_utils.library_builder as library_builder
43

54
##############################
65
#### Install dependencies ####
76
##############################
87

98
pip_packages = [x.split("==")[0] for x in os.popen('{} -m pip freeze'.format(env['PYTHONEXE'])).read().split('\n')]
10-
required_packages = ["catkin-pkg", "lark-parser", "empy", "colcon-common-extensions", "importlib-resources"]
9+
required_packages = ["catkin-pkg", "lark-parser", "empy", "colcon-common-extensions", "importlib-resources", "pyyaml"]
1110
if all([x in pip_packages for x in required_packages]):
1211
print("All required Python pip packages are installed")
1312

1413
for p in [x for x in required_packages if x not in pip_packages]:
1514
print('Installing {} with pip at PlatformIO environment'.format(p))
1615
env.Execute('$PYTHONEXE -m pip install {}'.format(p))
1716

17+
import microros_utils.library_builder as library_builder
18+
1819
##########################
1920
#### Global variables ####
2021
##########################
@@ -39,6 +40,7 @@
3940
board = env['BOARD']
4041
framework = env['PIOFRAMEWORK'][0]
4142
main_path = os.path.realpath(".")
43+
extra_packages_path = "{}/extra_packages".format(env['PROJECT_DIR'])
4244

4345
selected_board_meta = boards_metas[board] if board in boards_metas else "colcon.meta"
4446

@@ -70,7 +72,7 @@
7072
"{} {} -fno-rtti -DCLOCK_MONOTONIC=0 -D'__attribute__(x)='".format(' '.join(env['CXXFLAGS']), ' '.join(env['CCFLAGS']))
7173
)
7274

73-
builder = library_builder.Build(main_path)
75+
builder = library_builder.Build(library_folder=main_path, packages_folder=extra_packages_path)
7476
builder.run('{}/metas/{}'.format(main_path, selected_board_meta), cmake_toolchain.path, microros_user_meta)
7577

7678
#######################################################

microros_utils/library_builder.py

+53-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import os
22
import json
3+
import yaml
34
import shutil
45
import xml.etree.ElementTree as xml_parser
56

@@ -127,8 +128,9 @@ class Build:
127128
'galactic': ['rcl_logging_log4cxx', 'rcl_logging_spdlog', 'rcl_yaml_param_parser', 'rclc_examples']
128129
}
129130

130-
def __init__(self, library_folder, distro = 'galactic'):
131+
def __init__(self, library_folder, packages_folder, distro = 'galactic'):
131132
self.library_folder = library_folder
133+
self.packages_folder = packages_folder
132134
self.build_folder = library_folder + "/build"
133135
self.distro = distro
134136

@@ -195,6 +197,56 @@ def download_mcu_environment(self):
195197

196198
print('\t - Downloaded {}{}'.format(package.name, " (ignored)" if package.ignored else ""))
197199

200+
self.download_extra_packages()
201+
202+
def download_extra_packages(self):
203+
if not os.path.exists(self.packages_folder):
204+
print("\t - Extra packages folder not found, skipping...")
205+
return
206+
207+
print("Checking extra packages")
208+
209+
# Load and clone repositories from extra_packages.repos file
210+
extra_repos = self.get_repositories_from_yaml("{}/extra_packages.repos".format(self.packages_folder))
211+
for repo_name in extra_repos:
212+
repo_values = extra_repos[repo_name]
213+
version = repo_values['version'] if 'version' in repo_values else None
214+
Repository(repo_name, repo_values['url'], self.distro, version).clone(self.mcu_src_folder)
215+
print("\t - Downloaded {}".format(repo_name))
216+
217+
extra_folders = os.listdir(self.packages_folder)
218+
if 'extra_packages.repos' in extra_folders:
219+
extra_folders.remove('extra_packages.repos')
220+
221+
for folder in extra_folders:
222+
print("\t - Adding {}".format(folder))
223+
224+
shutil.copytree(self.packages_folder, self.mcu_src_folder, ignore=shutil.ignore_patterns('extra_packages.repos'), dirs_exist_ok=True)
225+
226+
def get_repositories_from_yaml(self, yaml_file):
227+
repos = {}
228+
try:
229+
with open(yaml_file, 'r') as repos_file:
230+
root = yaml.safe_load(repos_file)
231+
repositories = root['repositories']
232+
233+
if repositories:
234+
for path in repositories:
235+
repo = {}
236+
attributes = repositories[path]
237+
try:
238+
repo['type'] = attributes['type']
239+
repo['url'] = attributes['url']
240+
if 'version' in attributes:
241+
repo['version'] = attributes['version']
242+
except KeyError as e:
243+
continue
244+
repos[path] = repo
245+
except (yaml.YAMLError, KeyError, TypeError) as e:
246+
print("Error on {}: {}".format(yaml_file, e))
247+
finally:
248+
return repos
249+
198250
def build_mcu_environment(self, meta_file, toolchain_file, user_meta = ""):
199251
if os.path.exists(self.mcu_folder + '/build'):
200252
print("micro-ROS already built")

0 commit comments

Comments
 (0)