diff --git a/CMakeLists.txt b/CMakeLists.txt index dbe631d..6431729 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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 - $ - $) - -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 - $ - $) - -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() diff --git a/README.md b/README.md index d300394..e549058 100644 --- a/README.md +++ b/README.md @@ -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. @@ -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. + diff --git a/cmake/cpplib.cmake b/cmake/cpplib.cmake new file mode 100644 index 0000000..0497114 --- /dev/null +++ b/cmake/cpplib.cmake @@ -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 + $ + $ +) + +target_link_libraries(sas_core_pure PUBLIC -ldqrobotics Eigen3::Eigen) \ No newline at end of file diff --git a/cmake/pythonlib.cmake b/cmake/pythonlib.cmake new file mode 100644 index 0000000..ee1f3dd --- /dev/null +++ b/cmake/pythonlib.cmake @@ -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 + $ + $ +) + +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}") \ No newline at end of file diff --git a/docker/Dockerfile b/docker/Dockerfile index bacfc61..6cd2542 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -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/ \ No newline at end of file +RUN mkdir -p /root/sas_core_devel/src/ +COPY . /root/sas_core_devel/src/sas_core \ No newline at end of file diff --git a/docker/compose.yml b/docker/compose.yml index e2e485a..ea4e18c 100644 --- a/docker/compose.yml +++ b/docker/compose.yml @@ -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 "