Skip to content

Commit

Permalink
Make middleware selection more independent of build-time package avai…
Browse files Browse the repository at this point in the history
…lability (#67)

* Rework dynamic RMW

Defer list of available RMWs to build time of downstream packages so you can build a dependent package even if RMW_IMPLEMENTATION is set to a value not available when the rmw_implementation package was built.

Remove CMake Config flag "RMW_IMPLEMENTATION_FORCE_DYNAMIC_LOADING".
Add CMake Config flag "RMW_IMPLEMENTATION_DISABLE_RUNTIME_SELECTION" so you can statically link a middleware, even if multiple present at build time. This value can be explicitly set, but by default preserves the behavior of "statically link if one middleware found".

Add a scary message if the user tries to change the implementation and built with RMW_IMPLEMENTATION_DISABLE_RUNTIME_SELECTION=ON

Signed-off-by: Dan Rose <dan@digilabs.io>

* remove unused selected_rmw_implementation variable

re-add logging call of rmw default

Signed-off-by: Dan Rose <dan@digilabs.io>
  • Loading branch information
rotu authored and dirk-thomas committed Sep 26, 2019
1 parent 4790322 commit b521289
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 87 deletions.
52 changes: 19 additions & 33 deletions rmw_implementation/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,6 @@ find_package(ament_cmake REQUIRED)

find_package(rcutils REQUIRED)

# provides FindPoco.cmake and Poco on platforms without it
find_package(poco_vendor)
find_package(Poco COMPONENTS Foundation)
find_package(rmw_implementation_cmake REQUIRED)

if(BUILD_TESTING)
Expand All @@ -27,42 +24,34 @@ endif()

get_default_rmw_implementation(RMW_IMPLEMENTATION)

get_available_rmw_implementations(RMW_IMPLEMENTATIONS)
message(STATUS "")
message(STATUS "Found these rmw implementations:")
foreach(impl IN LISTS RMW_IMPLEMENTATIONS)
message(STATUS " '${impl}'")
endforeach()

message(STATUS "")
message(STATUS "Default rmw implementation: '${RMW_IMPLEMENTATION}'")
message(STATUS "")

option(RMW_IMPLEMENTATION_FORCE_DYNAMIC_LOADING
"Force use of dynamic loading (via poco), even if there is only one implementation available"
OFF)

# Nominally use dynamic loading if poco is available.
set(RMW_IMPLEMENTATION_SUPPORTS_POCO ${Poco_FOUND})
# Determine if we're going to actually support dynamic loading.
if(RMW_IMPLEMENTATION_FORCE_DYNAMIC_LOADING)
# Force usage.
if(NOT Poco_FOUND)
message(FATAL_ERROR "Dynamic loading forced, but poco is not found!")
endif()
set(RMW_IMPLEMENTATION_SUPPORTS_POCO TRUE)
elseif(NOT RMW_IMPLEMENTATIONS MATCHES ";")
set(RMW_IMPLEMENTATION_SUPPORTS_POCO FALSE)
get_available_rmw_implementations(available_rmw_implementations)
list(LENGTH available_rmw_implementations count_available_rmw_implementations)
if(count_available_rmw_implementations EQUAL 1)
set(rmw_implementation_disable_runtime_selection_default ON)
else()
set(rmw_implementation_disable_runtime_selection_default OFF)
endif()

if(NOT RMW_IMPLEMENTATION_SUPPORTS_POCO)
message(STATUS "Dynamic loading disabled; directly referencing '${RMW_IMPLEMENTATION}'")
message(STATUS "")
option(RMW_IMPLEMENTATION_DISABLE_RUNTIME_SELECTION "\
Use only the RMW implementation specified at build time via the \
'RMW_IMPLEMENTATION' environment variable and the 'RMW_IMPLEMENTATION' \
CMake option, ignoring the runtime value of the 'RMW_IMPLEMENTATION' \
environment variable"
${rmw_implementation_disable_runtime_selection_default})

if(RMW_IMPLEMENTATION_DISABLE_RUNTIME_SELECTION)
message(STATUS "Runtime selection of RMW disabled; Only using "
"'${RMW_IMPLEMENTATION}'")
else()
message(STATUS "Dynamic loading enabled with any of the available rmw implementations")
message(STATUS "")
message(STATUS "Runtime selection of RMW enabled")

# provides FindPoco.cmake and Poco on platforms without it
find_package(poco_vendor REQUIRED)
find_package(Poco REQUIRED COMPONENTS Foundation)
find_package(rmw REQUIRED)

link_directories(${Poco_LIBRARY_DIR})
Expand All @@ -73,7 +62,6 @@ else()
"rmw")
target_compile_definitions(${PROJECT_NAME}
PUBLIC "DEFAULT_RMW_IMPLEMENTATION=${RMW_IMPLEMENTATION}")
target_link_libraries(${PROJECT_NAME})
configure_rmw_library(${PROJECT_NAME})

ament_export_libraries(${PROJECT_NAME})
Expand All @@ -91,8 +79,6 @@ register_rmw_implementation(
"cpp:rosidl_typesupport_cpp"
)

# necessary since get_available_rmw_implementations excludes rmw_implementation
list(APPEND RMW_IMPLEMENTATIONS "rmw_implementation")
ament_package(
CONFIG_EXTRAS "rmw_implementation-extras.cmake.in"
)
93 changes: 39 additions & 54 deletions rmw_implementation/rmw_implementation-extras.cmake.in
Original file line number Diff line number Diff line change
Expand Up @@ -15,68 +15,53 @@
# generated from rmw_implementation/rmw_implementation-extras.cmake.in

find_package(rmw_implementation_cmake REQUIRED)
set(default_rmw_implementation "@RMW_IMPLEMENTATION@")
set(available_rmw_implementations "@RMW_IMPLEMENTATIONS@")

if(NOT "${RMW_IMPLEMENTATION}" STREQUAL "")
set(requested_rmw_implementation ${RMW_IMPLEMENTATION})
if(@RMW_IMPLEMENTATION_SUPPORTS_POCO@)
if(NOT requested_rmw_implementation IN_LIST available_rmw_implementations)
message(FATAL_ERROR
"The RMW implementation has been specified as "
"'${requested_rmw_implementation}' through CMake, "
"however it is not in the list of supported rmw implementations, "
"which was specified when the 'rmw_implementation' package was built.")
endif()
else()
if(NOT requested_rmw_implementation STREQUAL default_rmw_implementation)
message(FATAL_ERROR
"The RMW implementation has been specified as "
"'${requested_rmw_implementation}' through CMake, "
"however this needs to match the RMW implementation "
"'${default_rmw_implementation}', "
"which was specified when the 'rmw_implementation' package was built.")
endif()
endif()
set(requested_rmw_implementation "${RMW_IMPLEMENTATION}")
set(requested_rmw_implementation_from "CMake")
elseif(NOT "$ENV{RMW_IMPLEMENTATION}" STREQUAL "")
set(requested_rmw_implementation "$ENV{RMW_IMPLEMENTATION}")
set(requested_rmw_implementation_from
"environment variable 'RMW_IMPLEMENTATION'")
else()
set(requested_rmw_implementation "@RMW_IMPLEMENTATION@")
set(requested_rmw_implementation_from
"the default when @PROJECT_NAME@ was built")
endif()

if(NOT "$ENV{RMW_IMPLEMENTATION}" STREQUAL "")
set(requested_rmw_implementation $ENV{RMW_IMPLEMENTATION})
if(@RMW_IMPLEMENTATION_SUPPORTS_POCO@)
if(NOT requested_rmw_implementation IN_LIST available_rmw_implementations)
message(FATAL_ERROR
"The RMW implementation has been specified as "
"'${requested_rmw_implementation}' through the environment variable "
"'RMW_IMPLEMENTATION', "
"however it is not in the list of supported rmw implementations, "
"which was specified when the 'rmw_implementation' package was built.")
endif()
else()
if(NOT requested_rmw_implementation STREQUAL default_rmw_implementation)
message(FATAL_ERROR
"The RMW implementation has been specified as "
"'${requested_rmw_implementation}' "
"through the environment variable 'RMW_IMPLEMENTATION', "
"however this needs to match the RMW implementation "
"'${default_rmw_implementation}', "
"which was specified when the 'rmw_implementation' package was built.")
endif()
if(@RMW_IMPLEMENTATION_DISABLE_RUNTIME_SELECTION@)
message(STATUS "Using RMW implementation '@RMW_IMPLEMENTATION@'")
if(NOT requested_rmw_implementation STREQUAL "@RMW_IMPLEMENTATION@")
message(FATAL_ERROR
"The RMW implementation has been specified as "
"'${requested_rmw_implementation}' via "
"${requested_rmw_implementation_from}, but rmw_implementation was built "
"only with support for '@RMW_IMPLEMENTATION@'.")
endif()
endif()
find_package("@RMW_IMPLEMENTATION@" REQUIRED)

if(@RMW_IMPLEMENTATION_SUPPORTS_POCO@)
set(selected_rmw_implementation "@PROJECT_NAME@")
# no need to find_package @PROJECT_NAME@
# since this code is already part of a find_package call of that package
# TODO should never need definitions and include dirs?
list(APPEND rmw_implementation_DEFINITIONS
${@RMW_IMPLEMENTATION@_DEFINITIONS})
list(APPEND rmw_implementation_INCLUDE_DIRS
${@RMW_IMPLEMENTATION@_INCLUDE_DIRS})
list(APPEND rmw_implementation_LIBRARIES
${@RMW_IMPLEMENTATION@_LIBRARIES})
else()
set(selected_rmw_implementation "${default_rmw_implementation}")
message(STATUS "Using RMW implementation '${selected_rmw_implementation}' as default")
find_package("${selected_rmw_implementation}" REQUIRED)
get_available_rmw_implementations(available_rmw_implementations)

# TODO should never need definitions and include dirs?
list(APPEND rmw_implementation_DEFINITIONS ${${selected_rmw_implementation}_DEFINITIONS})
list(APPEND rmw_implementation_INCLUDE_DIRS ${${selected_rmw_implementation}_INCLUDE_DIRS})
list(APPEND rmw_implementation_LIBRARIES ${${selected_rmw_implementation}_LIBRARIES})
if(NOT requested_rmw_implementation IN_LIST available_rmw_implementations)
message(FATAL_ERROR
"The RMW implementation has been specified as "
"'${requested_rmw_implementation}' via "
"${requested_rmw_implementation_from}, but it is not available at this "
"time.\n\nCurrently available middlewares:\n"
"'${available_rmw_implementations}'")
endif()
message(STATUS "Using RMW implementation '${requested_rmw_implementation}' as default")

# no need to find_package @PROJECT_NAME@
# since this code is already part of a find_package call of that package
endif()

find_package(Threads REQUIRED)
Expand Down

0 comments on commit b521289

Please sign in to comment.