Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: refactor cmake project to deal with robot model dependencies #178

Merged
merged 8 commits into from
Apr 11, 2024
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 31 additions & 16 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ RUN echo "Set disable_coredump false" >> /etc/sudo.conf
# create the credentials to be able to pull private repos using ssh
RUN mkdir /root/.ssh/ && ssh-keyscan github.com | tee -a /root/.ssh/known_hosts

ARG CMAKE_BUILD_TYPE=Release

FROM base as apt-dependencies
COPY apt-packages.tx[t] /

Expand Down Expand Up @@ -81,31 +83,44 @@ ARG TARGETPLATFORM
ARG CACHEID
COPY dependencies/base_dependencies.cmake CMakeLists.txt
RUN --mount=type=cache,target=/build,id=cmake-base-deps-${TARGETPLATFORM}-${CACHEID},uid=1000 \
cmake -B build -DCMAKE_BUILD_TYPE=Release && cmake --build build && cmake --install build --prefix /tmp/deps
cmake -B build -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} && cmake --build build && cmake --install build --prefix /tmp/deps

FROM base as pinocchio-dependencies
COPY --from=apt-dependencies /tmp/apt /
COPY --from=base-dependencies /tmp/deps /usr
ARG TARGETPLATFORM
ARG CACHEID
ARG PINOCCHIO_TAG=v2.9.0
ARG HPP_FCL_TAG=v1.8.1
ARG PINOCCHIO_TAG=v2.6.9
ARG HPP_FCL_TAG=v2.4.4
# FIXME: it would be nicer to have it all in the root CMakelists.txt but:
# * `pinocchio` doesn't provide an include directory we can easily plug into `target_include_directories` and thus needs to be installed first
# * `pinocchio` uses hacks relying on undocumented CMake quirks which break if you use `FetchContent`
# FIXME: it needs `CMAKE_INSTALL_PREFIX` and `--prefix` because it doesn't install to the right place otherwise
RUN --mount=type=cache,target=/hpp-fcl,id=cmake-hpp-fcl-src-${HPP_FCL_TAG}-${TARGETPLATFORM}-${CACHEID},uid=1000 \
--mount=type=cache,target=/build,id=cmake-hpp-fcl-${HPP_FCL_TAG}-${TARGETPLATFORM}-${CACHEID},uid=1000 \
if [ ! -f hpp-fcl/CMakeLists.txt ]; then rm -rf hpp-fcl/* && git clone --depth 1 -b ${HPP_FCL_TAG} --recursive https://github.com/humanoid-path-planner/hpp-fcl; fi \
&& cmake -B build -S hpp-fcl -DBUILD_TESTING=OFF -DCMAKE_BUILD_TYPE=Release -DBUILD_PYTHON_INTERFACE=OFF -DCMAKE_INSTALL_PREFIX=/tmp/deps \
&& cmake --build build --target all install
RUN --mount=type=cache,target=/pinocchio,id=cmake-pinocchio-src-${PINOCCHIO_TAG}-${TARGETPLATFORM}-${CACHEID},uid=1000 \
--mount=type=cache,target=/build,id=cmake-pinocchio-${PINOCCHIO_TAG}-${TARGETPLATFORM}-${CACHEID},uid=1000 \
if [ ! -f pinocchio/CMakeLists.txt ]; then rm -rf pinocchio/* && git clone --depth 1 -b ${PINOCCHIO_TAG} --recursive https://github.com/stack-of-tasks/pinocchio; fi \
&& cmake -B build -S pinocchio -DBUILD_TESTING=OFF -DCMAKE_BUILD_TYPE=Release -DBUILD_PYTHON_INTERFACE=OFF -DBUILD_WITH_COLLISION_SUPPORT=ON -DCMAKE_INSTALL_PREFIX=/tmp/deps \
&& cmake --build build --target all install
--mount=type=cache,target=/hpp-fcl,id=cmake-hpp-fcl-src-${HPP_FCL_TAG}-${TARGETPLATFORM}-${CACHEID},uid=1000 \
--mount=type=cache,target=/build,id=cmake-pinocchio-${PINOCCHIO_TAG}-${HPP_FCL_TAG}-${TARGETPLATFORM}-${CACHEID},uid=1000 \
<<EOF
set -e

if [ ! -f hpp-fcl/CMakeLists.txt ]; then
rm -rf hpp-fcl/*
git clone --depth 1 -b ${HPP_FCL_TAG} --recursive https://github.com/humanoid-path-planner/hpp-fcl
fi

cmake -B build/hpp-fcl -S hpp-fcl -DBUILD_TESTING=OFF -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -DBUILD_PYTHON_INTERFACE=OFF -DCMAKE_INSTALL_PREFIX=/tmp/deps
cmake --build build/hpp-fcl --target all install

if [ ! -f pinocchio/CMakeLists.txt ]; then
rm -rf pinocchio/*
git clone --depth 1 -b ${PINOCCHIO_TAG} --recursive https://github.com/stack-of-tasks/pinocchio
fi

cmake -B build/pinocchio -S pinocchio -DBUILD_TESTING=OFF -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -DBUILD_PYTHON_INTERFACE=OFF -DBUILD_WITH_COLLISION_SUPPORT=ON -DCMAKE_INSTALL_PREFIX=/tmp/deps
cmake --build build/pinocchio --target all install

# FIXME: pinocchio produces non-portable paths
RUN find /tmp/deps -type f -exec sed -i 's#/tmp/deps#/usr#g' '{}' \;
find /tmp/deps -type f -exec sed -i 's#/tmp/deps#/usr#g' '{}' \;
EOF

FROM base as dependencies
ARG TARGETPLATFORM
Expand All @@ -114,7 +129,7 @@ ARG CACHEID
COPY --from=base-dependencies /tmp/deps /usr
COPY dependencies/dependencies.cmake CMakeLists.txt
RUN --mount=type=cache,target=/build,id=cmake-deps-${TARGETPLATFORM}-${CACHEID},uid=1000 \
cmake -B build -Dprotobuf_BUILD_TESTS=OFF -DCMAKE_BUILD_TYPE=Release && cmake --build build && cmake --install build --prefix /tmp/deps
cmake -B build -Dprotobuf_BUILD_TESTS=OFF -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} && cmake --build build && cmake --install build --prefix /tmp/deps
COPY --from=base-dependencies /tmp/deps /tmp/deps
COPY --from=pinocchio-dependencies /tmp/deps /tmp/deps

Expand Down Expand Up @@ -163,13 +178,13 @@ COPY protocol protocol
COPY source source
COPY CMakeLists.txt CMakeLists.txt
RUN --mount=type=cache,target=/build,id=cmake-build-${TARGETPLATFORM}-${CACHEID},uid=1000 \
cmake -B build -DCMAKE_BUILD_TYPE=Release && cmake --build build
cmake -B build -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} && cmake --build build

FROM build as cpp-test
ARG TARGETPLATFORM
ARG CACHEID
RUN --mount=type=cache,target=/build,id=cmake-build-${TARGETPLATFORM}-${CACHEID},uid=1000 \
cmake -B build -DBUILD_TESTING=ON && cd build && make && CTEST_OUTPUT_ON_FAILURE=1 make test
cmake -B build -DBUILD_TESTING=ON && make -C build && CTEST_OUTPUT_ON_FAILURE=1 make -C build test

FROM build as install
ARG TARGETPLATFORM
Expand Down
28 changes: 6 additions & 22 deletions source/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -54,46 +54,30 @@ if(EXPERIMENTAL_FEATURES)
add_compile_definitions(EXPERIMENTAL_FEATURES)
endif()

set(INSTALL_SUPPORTED_COMPONENTS)

add_subdirectory(state_representation)
list(APPEND INSTALL_INTERFACE_LINK_LIBRARIES state_representation)
get_target_property(TARGET_INTERFACE_LINK_LIBRARIES state_representation INTERFACE_LINK_LIBRARIES)
if(TARGET_INTERFACE_LINK_LIBRARIES)
list(APPEND INSTALL_INTERFACE_LINK_LIBRARIES "${TARGET_INTERFACE_LINK_LIBRARIES}")
endif()
list(APPEND INSTALL_SUPPORTED_COMPONENTS state_representation)
add_pkgconfig_library(state_representation ${PROJECT_VERSION})

if(BUILD_DYNAMICAL_SYSTEMS)
add_subdirectory(dynamical_systems)
list(APPEND INSTALL_INTERFACE_LINK_LIBRARIES dynamical_systems)
get_target_property(TARGET_INTERFACE_LINK_LIBRARIES dynamical_systems INTERFACE_LINK_LIBRARIES)
if(TARGET_INTERFACE_LINK_LIBRARIES)
list(APPEND INSTALL_INTERFACE_LINK_LIBRARIES "${TARGET_INTERFACE_LINK_LIBRARIES}")
endif()
list(APPEND INSTALL_SUPPORTED_COMPONENTS dynamical_systems)
add_pkgconfig_library(dynamical_systems ${PROJECT_VERSION})
endif()

if(BUILD_ROBOT_MODEL OR BUILD_CONTROLLERS)
add_subdirectory(robot_model)
list(APPEND INSTALL_INTERFACE_LINK_LIBRARIES robot_model)
get_target_property(TARGET_INTERFACE_LINK_LIBRARIES robot_model INTERFACE_LINK_LIBRARIES)
if(TARGET_INTERFACE_LINK_LIBRARIES)
list(APPEND INSTALL_INTERFACE_LINK_LIBRARIES "${TARGET_INTERFACE_LINK_LIBRARIES}")
endif()
list(APPEND INSTALL_SUPPORTED_COMPONENTS robot_model)
add_pkgconfig_library(robot_model ${PROJECT_VERSION})
endif()

if(BUILD_CONTROLLERS)
add_subdirectory(controllers)
list(APPEND INSTALL_INTERFACE_LINK_LIBRARIES controllers)
get_target_property(TARGET_INTERFACE_LINK_LIBRARIES controllers INTERFACE_LINK_LIBRARIES)
if(TARGET_INTERFACE_LINK_LIBRARIES)
list(APPEND INSTALL_INTERFACE_LINK_LIBRARIES "${TARGET_INTERFACE_LINK_LIBRARIES}")
endif()
list(APPEND INSTALL_SUPPORTED_COMPONENTS controllers)
add_pkgconfig_library(controllers ${PROJECT_VERSION})
endif()

list(REMOVE_DUPLICATES INSTALL_INTERFACE_LINK_LIBRARIES)

# generate the version file for the config file
write_basic_package_version_file(
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake"
Expand Down
46 changes: 35 additions & 11 deletions source/control_librariesConfig.cmake.in
Original file line number Diff line number Diff line change
@@ -1,34 +1,58 @@
@PACKAGE_INIT@

set(_control_libraries_supported_components state_representation dynamical_systems robot_model controllers)
set(control_libraries_LIBRARIES "@INSTALL_INTERFACE_LINK_LIBRARIES@")
set(_control_libraries_namespace "control_libraries::")
set(_control_libraries_supported_components "@INSTALL_SUPPORTED_COMPONENTS@")

include(CMakeFindDependencyMacro)
find_dependency(Eigen3)

# Find robot model dependencies if it is in the interface library list and no components are explicitly listed
if ("robot_model" IN_LIST control_libraries_LIBRARIES AND NOT control_libraries_FIND_COMPONENTS)
find_dependency(pinocchio)
find_dependency(OsqpEigen)
find_dependency(osqp)
set(_control_libraries_to_find ${control_libraries_FIND_COMPONENTS})
if (NOT control_libraries_FIND_COMPONENTS)
set(_control_libraries_to_find ${_control_libraries_supported_components})
endif()

foreach(_comp ${control_libraries_FIND_COMPONENTS})
set(control_libraries_LIBRARIES "")
while(_control_libraries_to_find)
list(POP_FRONT _control_libraries_to_find _comp)

if (${_comp} IN_LIST _control_libraries_supported_components)
set(control_libraries_${_comp}_FOUND True)
else()
set_and_check(control_libraries_FOUND False)
set_and_check(control_libraries_NOT_FOUND_MESSAGE "Unsupported component: ${_comp}")
endif()

# Find robot model dependencies if the corresponding components are explicitly listed
if (${_comp} STREQUAL "controllers" OR ${_comp} STREQUAL "robot_model")
# Find robot model dependencies if the corresponding component is needed
# FIXME: this should be done automatically
if (${_comp} STREQUAL "robot_model")
find_dependency(pinocchio)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need hpp-fcl here?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure. It built and ran correctly for me so I imagine pinocchio might be pulling it itself?

find_dependency(OsqpEigen)
find_dependency(osqp)
endif()

include("${CMAKE_CURRENT_LIST_DIR}/control_libraries_${_comp}_targets.cmake")
endforeach()

list(APPEND control_libraries_LIBRARIES "${_control_libraries_namespace}${_comp}")

get_property(_comp_link_libraries TARGET "${_control_libraries_namespace}${_comp}" PROPERTY INTERFACE_LINK_LIBRARIES)
foreach(_dep ${_comp_link_libraries})
if (_dep MATCHES "^${_control_libraries_namespace}")
string(REPLACE "${_control_libraries_namespace}" "" _dep ${_dep})
if (NOT _dep IN_LIST _control_libraries_to_find)
list(APPEND _control_libraries_to_find ${_dep})
endif()
else()
list(APPEND control_libraries_LIBRARIES ${_dep})
endif()
endforeach()
endwhile()

list(REMOVE_DUPLICATES control_libraries_LIBRARIES)

unset(_dep)
unset(_comp)
unset(_comp_link_libraries)
unset(_control_libraries_to_find)
unset(_control_libraries_supported_components)

check_required_components(control_libraries)
2 changes: 1 addition & 1 deletion source/controllers/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ target_include_directories(${LIBRARY_NAME}
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
)

target_link_libraries(${LIBRARY_NAME} robot_model)
target_link_libraries(${LIBRARY_NAME} ${PROJECT_NAME}::robot_model)

# install the target and create export-set
install(TARGETS ${LIBRARY_NAME}
Expand Down
2 changes: 1 addition & 1 deletion source/dynamical_systems/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ target_include_directories(${LIBRARY_NAME}
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
)

target_link_libraries(${LIBRARY_NAME} state_representation)
target_link_libraries(${LIBRARY_NAME} ${PROJECT_NAME}::state_representation)

# install the target and create export-set
install(TARGETS ${LIBRARY_NAME}
Expand Down
6 changes: 3 additions & 3 deletions source/robot_model/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
set(LIBRARY_NAME robot_model)

set(PINOCCHIO_VERSION 2.9.0)
set(HPP_FCL_VERSION 1.8.1)
set(PINOCCHIO_VERSION 2.6.9)
set(HPP_FCL_VERSION 2.4.4)
set(OSQP_EIGEN_VERSION 0.8.1)
find_package(pinocchio ${PINOCCHIO_VERSION} REQUIRED)
find_package(hpp-fcl ${HPP_FCL_VERSION} REQUIRED)
Expand All @@ -24,7 +24,7 @@ target_include_directories(${LIBRARY_NAME}
)

target_link_libraries(${LIBRARY_NAME}
state_representation
${PROJECT_NAME}::state_representation
${PINOCCHIO_LIBRARIES}
${hpp-fcl_LIBRARIES}
OsqpEigen::OsqpEigen
Expand Down
2 changes: 1 addition & 1 deletion source/robot_model/test/tests/test_model.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -128,4 +128,4 @@ TEST_F(RobotModelTest, TestCreateURDFFromStringFail) {
TEST_F(RobotModelTest, TestModelGetter) {
const pinocchio::Model& robot_model = franka->get_pinocchio_model();
EXPECT_TRUE(robot_model.existBodyName("panda_link0"));
}
}
Loading