Skip to content

Instantly share code, notes, and snippets.

@tustvold
Created March 18, 2018 13:38
Show Gist options
  • Save tustvold/72f676549468b2df7b7f102744df3673 to your computer and use it in GitHub Desktop.
Save tustvold/72f676549468b2df7b7f102744df3673 to your computer and use it in GitHub Desktop.
A way to consume ROS without catkin
# Try to find ROS
#
# Supports the following components
#
# common
# serialization
# time
# traits
# lz4
# bag_storage
#
# Once done this will define
#
# ROS_FOUND - System has ROS
# ROS_INCLUDE_DIRS - The ROS include directories
# ROS_LIBRARIES - The libraries needed to use ROS
# ROS_DISTRO - The ROS distro in use
# ROS::${COMPONENT} - A libary that can be linked against for the requested component
#-------------------------------------------------------------------------------
# FindROS functions & macros
#
if (NOT DEFINED FIND_ROS_DEBUG)
set(FIND_ROS_DEBUG 0)
endif ()
#
# Get component dependencies. Requires the dependencies to have been
# defined for the ROS distro
#
# component - the component to check
# _ret - list of library dependencies
#
function(_ROS_COMPONENT_DEPENDENCIES component _ret)
if (ROS_DISTRO STREQUAL kinetic)
set(_ROS_SERIALIZATION_DEPENDENCIES common time traits)
set(_ROS_TIME_DEPENDENCIES common)
set(_ROS_TRAITS_DEPENDENCIES common time)
set(_ROS_LZ4_DEPENDENCIES serialization lz4)
set(_ROS_BAG_STORAGE_DEPENDENCIES common time traits serialization lz4)
else ()
message(WARNING "Component Dependencies for ROS Distro")
endif ()
string(TOUPPER ${component} uppercomponent)
set(${_ret} ${_ROS_${uppercomponent}_DEPENDENCIES} PARENT_SCOPE)
set(_ROS_IMPORTED_TARGETS ${_ROS_IMPORTED_TARGETS} PARENT_SCOPE)
string(REGEX REPLACE ";" " " _ros_DEPS_STRING "${_ROS_${uppercomponent}_DEPENDENCIES}")
if (NOT _ros_DEPS_STRING)
set(_ros_DEPS_STRING "(none)")
endif ()
if (FIND_ROS_DEBUG)
message(STATUS "Dependencies for ROS::${component}: ${_ros_DEPS_STRING}")
endif ()
endfunction()
#
# Get component headers. This is the primary header (or headers) for
# a given component, and is used to check that the headers are present
# as well as the library itself as an extra sanity check of the build
# environment.
#
# component - the component to check
# _hdrs
#
function(_ROS_COMPONENT_HEADERS component _hdrs)
set(_ROS_COMMON_HEADERS "ros/header.h")
set(_ROS_TIME_HEADERS "ros/time.h")
set(_ROS_TRAITS_HEADERS "ros/message_traits.h")
set(_ROS_SERIALIZATION_HEADERS "ros/serialization.h")
set(_ROS_LZ4_HEADERS "roslz4/lz4s.h")
set(_ROS_BAG_STORAGE_HEADERS "rosbag/bag.h")
string(TOUPPER ${component} uppercomponent)
set(${_hdrs} ${_ROS_${uppercomponent}_HEADERS} PARENT_SCOPE)
string(REGEX REPLACE ";" " " _ros_HDRS_STRING "${_ROS_${uppercomponent}_HEADERS}")
if (NOT _ros_HDRS_STRING)
set(_ros_HDRS_STRING "(none)")
endif ()
if (FIND_ROS_DEBUG)
message(STATUS "Headers for ROS::${component}: ${_ros_HDRS_STRING}")
endif ()
endfunction()
#
# Determine if any missing dependencies require adding to the component list.
#
# Sets _ROS_${COMPONENT}_DEPENDENCIES for each required component,
# plus _ROS_IMPORTED_TARGETS (TRUE if imported targets should be
# defined; FALSE if dependency information is unavailable).
#
# componentvar - the component list variable name
# extravar - the indirect dependency list variable name
#
#
function(_ROS_MISSING_DEPENDENCIES componentvar extravar)
# _ros_unprocessed_components - list of components requiring processing
# _ros_processed_components - components already processed (or currently being processed)
# _ros_new_components - new components discovered for future processing
#
list(APPEND _ros_unprocessed_components ${${componentvar}})
while (_ros_unprocessed_components)
list(APPEND _ros_processed_components ${_ros_unprocessed_components})
foreach (component ${_ros_unprocessed_components})
string(TOUPPER ${component} uppercomponent)
set(${_ret} ${_ROS_${uppercomponent}_DEPENDENCIES} PARENT_SCOPE)
_ROS_COMPONENT_DEPENDENCIES("${component}" _ROS_${uppercomponent}_DEPENDENCIES)
set(_ROS_${uppercomponent}_DEPENDENCIES ${_ROS_${uppercomponent}_DEPENDENCIES} PARENT_SCOPE)
set(_ROS_IMPORTED_TARGETS ${_ROS_IMPORTED_TARGETS} PARENT_SCOPE)
foreach (componentdep ${_ROS_${uppercomponent}_DEPENDENCIES})
if (NOT ("${componentdep}" IN_LIST _ros_processed_components OR "${componentdep}" IN_LIST _ros_new_components))
list(APPEND _ros_new_components ${componentdep})
endif ()
endforeach ()
endforeach ()
set(_ros_unprocessed_components ${_ros_new_components})
unset(_ros_new_components)
endwhile ()
set(_ros_extra_components ${_ros_processed_components})
if (_ros_extra_components AND ${componentvar})
list(REMOVE_ITEM _ros_extra_components ${${componentvar}})
endif ()
set(${componentvar} ${_ros_processed_components} PARENT_SCOPE)
set(${extravar} ${_ros_extra_components} PARENT_SCOPE)
endfunction()
#
# End functions/macros
#
#-------------------------------------------------------------------------------
#-------------------------------------------------------------------------------
# main.
#-------------------------------------------------------------------------------
if (NOT DEFINED ROS_DISTRO)
set(ROS_DISTRO kinetic)
endif ()
if (FIND_ROS_DEBUG)
message(STATUS "Looking for ROS distro \"${ROS_DISTRO}\"")
endif ()
if (NOT DEFINED ROS_ROOT)
find_path(ROS_ROOT
NAMES "include/ros/header.h" "setup.bash"
PATHS "/opt/ros/${ROS_DISTRO}"
NO_DEFAULT_PATH
)
endif ()
message(STATUS "Found ROS in ${ROS_ROOT}")
set(ROS_INCLUDE_DIRS ${ROS_ROOT}/include)
# Additional components may be required via component dependencies.
# Add any missing components to the list.
_ROS_MISSING_DEPENDENCIES(ROS_FIND_COMPONENTS _ROS_EXTRA_FIND_COMPONENTS)
set(_ros_LIBRARY_SEARCH_DIRS_ ${ROS_ROOT}/lib)
# ------------------------------------------------------------------------
# Begin finding ros libraries
# ------------------------------------------------------------------------
foreach (COMPONENT ${ROS_FIND_COMPONENTS})
string(TOUPPER ${COMPONENT} UPPERCOMPONENT)
#
# Find headers
#
_ROS_COMPONENT_HEADERS("${COMPONENT}" ROS_${UPPERCOMPONENT}_HEADER_NAME)
# Look for a standard ros header file.
if (ROS_${UPPERCOMPONENT}_HEADER_NAME)
if (NOT EXISTS "${ROS_ROOT}/include/${ROS_${UPPERCOMPONENT}_HEADER_NAME}")
message(WARNING "Header not found for ROS::${COMPONENT}")
endif ()
else ()
set(ROS_${UPPERCOMPONENT}_HEADER ON)
message(WARNING "No header defined for ROS::${COMPONENT}; skipping header check")
endif ()
#
# Find libraries
#
# Work around ROS's inconsistent library naming
set(_ros_library_names lib${COMPONENT}.so libros${COMPONENT}.so libcpp_${COMPONENT}.so libroscpp_${COMPONENT}.so)
find_library(ROS_${UPPERCOMPONENT}_LIBRARY
NAMES ${_ros_library_names}
PATHS ${_ros_LIBRARY_SEARCH_DIRS_}
NO_DEFAULT_PATH
)
if (FIND_ROS_DEBUG)
message(STATUS "Libary for ROS::${COMPONENT}: ${ROS_${UPPERCOMPONENT}_LIBRARY}")
endif ()
endforeach ()
# ------------------------------------------------------------------------
# End finding ros libraries
# ------------------------------------------------------------------------
# ------------------------------------------------------------------------
# Add imported targets
# ------------------------------------------------------------------------
foreach (COMPONENT ${ROS_FIND_COMPONENTS})
if (NOT TARGET ROS::${COMPONENT})
string(TOUPPER ${COMPONENT} UPPERCOMPONENT)
if (EXISTS "${ROS_${UPPERCOMPONENT}_LIBRARY}")
add_library(ROS::${COMPONENT} UNKNOWN IMPORTED)
set_target_properties(ROS::${COMPONENT} PROPERTIES
IMPORTED_LINK_INTERFACE_LANGUAGES "CXX"
IMPORTED_LOCATION "${ROS_${UPPERCOMPONENT}_LIBRARY}")
else()
add_library(ROS::${COMPONENT} IMPORTED INTERFACE)
endif ()
if (ROS_INCLUDE_DIRS)
set_target_properties(ROS::${COMPONENT} PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${ROS_INCLUDE_DIRS}")
endif ()
# In case of header-only components
if (EXISTS "${ROS_${UPPERCOMPONENT}_LIBRARY}")
set_target_properties(ROS::${COMPONENT} PROPERTIES
IMPORTED_LINK_INTERFACE_LANGUAGES "CXX"
IMPORTED_LOCATION "${ROS_${UPPERCOMPONENT}_LIBRARY}")
endif ()
if (_ROS_${UPPERCOMPONENT}_DEPENDENCIES)
unset(_ROS_${UPPERCOMPONENT}_TARGET_DEPENDENCIES)
foreach (dep ${_ROS_${UPPERCOMPONENT}_DEPENDENCIES})
list(APPEND _ROS_${UPPERCOMPONENT}_TARGET_DEPENDENCIES ROS::${dep})
endforeach ()
set_target_properties(ROS::${COMPONENT} PROPERTIES
INTERFACE_LINK_LIBRARIES "${_ROS_${UPPERCOMPONENT}_TARGET_DEPENDENCIES}")
endif ()
endif ()
endforeach ()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment