Skip to content
Merged
185 changes: 43 additions & 142 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,161 +1,62 @@
cmake_minimum_required(VERSION 3.8)
project(sas_core)

option(ROS2_BUILD "Enable ROS2/ament build (examples + ament integration)" ON)

if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
add_compile_options(-Wall -Wextra -Wpedantic)
endif()

#################################
# pybind11 import block [BEGIN] #
# vvvvvvvvvvvvvvvvvvvvvvvvvvvvv #
set(PYBIND11_FINDPYTHON ON) # Fix CMP0148 Warning. https://github.com/pybind/pybind11/issues/4785
add_subdirectory(pybind11)
# ^^^^^^^^^^^^^^^^^^^^^^^^^^^ #
# pybind11 import block [END] #
###############################

# find dependencies
find_package(ament_cmake REQUIRED)
find_package(Eigen3 REQUIRED)

##### CPP LIBRARY #####

add_library(${PROJECT_NAME} SHARED
src/sas_clock.cpp
src/sas_core.cpp
src/sas_object.cpp
src/sas_shutdown_signaler.cpp
# sas_robot_driver
src/sas_robot_driver.cpp
src/examples/sas_robot_driver_example.cpp
src/eigen3_std_conversions.cpp
)

ament_target_dependencies(${PROJECT_NAME} Eigen3)

target_include_directories(${PROJECT_NAME}
PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>)

ament_export_targets(export_${PROJECT_NAME} HAS_LIBRARY_TARGET)
ament_export_dependencies(Eigen3)

target_link_libraries(${PROJECT_NAME}
-ldqrobotics
Eigen3::Eigen
)

install(
DIRECTORY include/
DESTINATION include
)

install(
TARGETS ${PROJECT_NAME}
EXPORT export_${PROJECT_NAME}
LIBRARY DESTINATION lib
#ARCHIVE DESTINATION lib
RUNTIME DESTINATION bin
INCLUDES DESTINATION include
)

##END## CPP LIBRARY #####

##### CPP BINARY #####

add_executable(sas_core_example
src/examples/sas_core_example.cpp)

target_link_libraries(sas_core_example
-ldqrobotics
${PROJECT_NAME}
)

install(TARGETS
sas_core_example
DESTINATION lib/${PROJECT_NAME})
# ---- Core libraries (always built) ----
include(cmake/cpplib.cmake)

##END## CPP BINARY #####

##### CPP BINARY #####

add_executable(sas_clock_example
src/examples/sas_clock_example.cpp)

target_link_libraries(sas_clock_example
${PROJECT_NAME}
)

install(TARGETS
sas_clock_example
DESTINATION lib/${PROJECT_NAME})

##END## CPP BINARY #####

##### CPP BINARY #####

add_executable(sas_clock_sched_fifo_example
src/examples/sas_clock_sched_fifo_example.cpp)

target_link_libraries(sas_clock_sched_fifo_example
${PROJECT_NAME}
)
if(ROS2_BUILD)
find_package(ament_cmake REQUIRED)
ament_python_install_package(${PROJECT_NAME})
set(_SAS_PYTHON_INSTALL_DIR "${PYTHON_INSTALL_DIR}/${PROJECT_NAME}")
endif()

install(TARGETS
sas_clock_sched_fifo_example
DESTINATION lib/${PROJECT_NAME})
include(cmake/pythonlib.cmake)

##END## CPP BINARY #####
# ---- ROS2 / ament integration (conditional) ----
if(ROS2_BUILD)
# INTERFACE alias for downstream ROS packages
add_library(sas_core INTERFACE)
target_link_libraries(sas_core INTERFACE sas_core_pure)

##### CPP BINARY #####
ament_export_targets(export_${PROJECT_NAME} HAS_LIBRARY_TARGET)
ament_export_dependencies(Eigen3)

add_executable(sas_robot_driver_example
src/examples/sas_robot_driver_example_main.cpp)
install(DIRECTORY include/ DESTINATION include)

target_link_libraries(sas_robot_driver_example
${PROJECT_NAME}
install(TARGETS sas_core sas_core_pure
EXPORT export_${PROJECT_NAME}
ARCHIVE DESTINATION lib
INCLUDES DESTINATION include
)

install(TARGETS
sas_robot_driver_example
DESTINATION lib/${PROJECT_NAME})

##END## CPP BINARY #####

##### PYBIND11 LIBRARY #####
# Example executables
foreach(_name IN ITEMS sas_core_example sas_clock_example
sas_clock_sched_fifo_example)
add_executable(${_name} src/examples/${_name}.cpp)
target_link_libraries(${_name} sas_core_pure)
if(_name STREQUAL "sas_core_example")
target_link_libraries(${_name} -ldqrobotics)
endif()
install(TARGETS ${_name} DESTINATION lib/${PROJECT_NAME})
endforeach()

ament_python_install_package(${PROJECT_NAME})
add_executable(sas_robot_driver_example
src/examples/sas_robot_driver_example_main.cpp)
target_link_libraries(sas_robot_driver_example sas_core_pure)
install(TARGETS sas_robot_driver_example DESTINATION lib/${PROJECT_NAME})


pybind11_add_module(_${PROJECT_NAME} SHARED
src/sas_core_py.cpp
src/sas_robot_driver_py.cpp
install(PROGRAMS
scripts/sas_clock_example_py.py
scripts/sas_robot_driver_subclass_example_py.py
scripts/sas_clock_sched_fifo_example_py.py
DESTINATION lib/${PROJECT_NAME}
)

target_include_directories(_${PROJECT_NAME}
PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>)

target_compile_definitions(_${PROJECT_NAME} PRIVATE IS_SAS_PYTHON_BUILD)
# https://github.com/pybind/pybind11/issues/387
target_link_libraries(_${PROJECT_NAME} PRIVATE ${PROJECT_NAME} -ldqrobotics)

install(TARGETS _${PROJECT_NAME}
DESTINATION "${PYTHON_INSTALL_DIR}/${PROJECT_NAME}"
)

##END## PYBIND11 LIBRARY #####

# According to https://github.com/SmartArmStack/sas_datalogger/blob/78ac681f9cb049c5b9715d215f163565f16b5cdc/CMakeLists.txt
##### PYTHON EXECUTABLES #####
install(PROGRAMS
scripts/sas_clock_example_py.py
scripts/sas_robot_driver_subclass_example_py.py
scripts/sas_clock_sched_fifo_example_py.py
DESTINATION lib/${PROJECT_NAME}
)
##END## PYTHON EXECUTABLES #####

ament_package()
ament_package()
endif()
22 changes: 22 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,27 @@
- `scripts/` — example Python scripts.
- `src/examples/` — C++ example programs and test nodes.

## Using as a non-ROS2 dependency (CMake FetchContent)

To include `sas_core_pure` in a plain CMake project (no ROS2/ament required):

```cmake
include(FetchContent)
FetchContent_Declare(
sas_core
GIT_REPOSITORY https://github.com/SmartArmStack/sas_core.git
GIT_TAG jazzy
)

set(ROS2_BUILD OFF CACHE BOOL "" FORCE)
FetchContent_MakeAvailable(sas_core)

target_link_libraries(your_target PRIVATE sas_core_pure)
```

The library depends on **Eigen3** and **dqrobotics**; make sure both are
available on your system.

## Examples

Testing on a docker container.
Expand All @@ -35,3 +56,4 @@ ros2 run sas_core sas_clock_sched_fifo_example_py.py
The `scripts/sas_robot_driver_subclass_example_py.py` file demonstrates how to
subclass `sas_core.RobotDriver` in Python and contains a minimal working
example.

24 changes: 24 additions & 0 deletions cmake/cpplib.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Build the pure C++ library (no ROS2/ament dependencies)
find_package(Eigen3 REQUIRED)

add_library(sas_core_pure STATIC)
target_sources(sas_core_pure PRIVATE
${CMAKE_CURRENT_LIST_DIR}/../src/sas_clock.cpp
${CMAKE_CURRENT_LIST_DIR}/../src/sas_core.cpp
${CMAKE_CURRENT_LIST_DIR}/../src/sas_object.cpp
${CMAKE_CURRENT_LIST_DIR}/../src/sas_shutdown_signaler.cpp
${CMAKE_CURRENT_LIST_DIR}/../src/sas_robot_driver.cpp
${CMAKE_CURRENT_LIST_DIR}/../src/examples/sas_robot_driver_example.cpp
${CMAKE_CURRENT_LIST_DIR}/../src/eigen3_std_conversions.cpp
)

set_target_properties(sas_core_pure PROPERTIES
POSITION_INDEPENDENT_CODE ON
)

target_include_directories(sas_core_pure PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/../include>
$<INSTALL_INTERFACE:include>
)

target_link_libraries(sas_core_pure PUBLIC -ldqrobotics Eigen3::Eigen)
27 changes: 27 additions & 0 deletions cmake/pythonlib.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Python wrapper module via pybind11
find_package(Python3 REQUIRED COMPONENTS Development)

set(PYBIND11_FINDPYTHON ON)
add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/../pybind11 ${CMAKE_CURRENT_BINARY_DIR}/pybind11)

pybind11_add_module(_sas_core SHARED
${CMAKE_CURRENT_LIST_DIR}/../src/sas_core_py.cpp
${CMAKE_CURRENT_LIST_DIR}/../src/sas_robot_driver_py.cpp
)

target_include_directories(_sas_core PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/../include>
$<INSTALL_INTERFACE:include>
)

target_compile_definitions(_sas_core PRIVATE IS_SAS_PYTHON_BUILD)
target_link_libraries(_sas_core PRIVATE sas_core_pure -ldqrobotics)

# Install path: ament PYTHON_INSTALL_DIR if available, else site-packages
if(DEFINED _SAS_PYTHON_INSTALL_DIR)
set(_SAS_PY_DEST "${_SAS_PYTHON_INSTALL_DIR}")
else()
set(_SAS_PY_DEST "lib/python3/dist-packages/sas_core")
endif()

install(TARGETS _sas_core DESTINATION "${_SAS_PY_DEST}")
3 changes: 2 additions & 1 deletion docker/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ ENV BASH_ENV="/etc/bash_env"
RUN sudo apt-get update && sudo apt-get upgrade -y
RUN python3 -m pip install --upgrade dqrobotics --break-system-packages
RUN sudo sudo apt-get remove -y ros-jazzy-sas-core
RUN mkdir -p /root/sas_core_devel/src/
RUN mkdir -p /root/sas_core_devel/src/
COPY . /root/sas_core_devel/src/sas_core
6 changes: 3 additions & 3 deletions docker/compose.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
services:
sas_core:
build: .
volumes:
- ../../sas_core:/root/sas_core_devel/src/sas_core
build:
context: ..
dockerfile: docker/Dockerfile
environment:
PYTHONUNBUFFERED: 1
command: /bin/bash -c "
Expand Down