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

Modern CMake adjustements #91

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all 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
48 changes: 27 additions & 21 deletions orocos_kdl/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
#
# Test CMake version
#
CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
IF(POLICY CMP0048)
CMAKE_POLICY(SET CMP0048 NEW)
ENDIF()
CMAKE_MINIMUM_REQUIRED(VERSION 3.2)
Copy link
Member

Choose a reason for hiding this comment

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

I'm hesitant to require newer cmake version higher then 2.8 because: "2.8.12 is the version shipped starting from Ubuntu Trusty (April 2014) or Debian Jessie (April 2015). Other Linux distributions released at approximately the same time have typically newer versions. So that's where we would cut off. Ubuntu Precise (cmake 2.8.7) goes EOL in April 2017, Debian Wheezy (cmake 2.8.9) in May 2018, so probably its a good idea to stay compatible with 2.8.9 until at least next year."

Choose a reason for hiding this comment

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

CMake 3.5 was backported to Trusty a few months ago: https://packages.ubuntu.com/trusty/cmake3.

#MARK_AS_ADVANCED( FORCE CMAKE_BACKWARDS_COMPATIBILITY )


Expand Down Expand Up @@ -54,10 +51,14 @@ ENDIF ( NOT CMAKE_BUILD_TYPE )
SET( KDL_CFLAGS "")

find_package(Eigen3 QUIET)
if(NOT EIGEN3_FOUND)
if(NOT EIGEN3_FOUND OR NOT TARGET Eigen3::Eigen)
include(${PROJ_SOURCE_DIR}/cmake/FindEigen3.cmake)
endif()
include_directories(${EIGEN3_INCLUDE_DIR})

if(NOT TARGET Eigen3::Eigen)
message(FATAL_ERROR "Eigen3 NOT FOUND")
endif()

SET(KDL_CFLAGS "${KDL_CFLAGS} -I${EIGEN3_INCLUDE_DIR}")

# Check the platform STL containers capabilities
Expand Down Expand Up @@ -104,28 +105,33 @@ ENDIF(ENABLE_TESTS )

OPTION(ENABLE_EXAMPLES OFF "Enable building of examples")

# Configuration variables
set(orocos_kdl_TARGETS_EXPORT_NAME "OrocosKDLTargets")
set(orocos_kdl_VERSION_CONFIG_FILENAME "${PROJECT_NAME}-config-version.cmake")
set(orocos_kdl_CONFIG_FILENAME "${PROJECT_NAME}-config.cmake")

ADD_SUBDIRECTORY( doc )
ADD_SUBDIRECTORY( src )
ADD_SUBDIRECTORY( tests )
ADD_SUBDIRECTORY( models )
ADD_SUBDIRECTORY( examples )


export(TARGETS orocos-kdl
FILE "${PROJECT_BINARY_DIR}/OrocosKDLTargets.cmake")

export(PACKAGE orocos_kdl)

# Generate CMake package configuration
CONFIGURE_FILE(orocos_kdl-config.cmake.in
${PROJECT_BINARY_DIR}/orocos_kdl-config.cmake @ONLY)
CONFIGURE_FILE(orocos_kdl-config-version.cmake.in
${PROJECT_BINARY_DIR}/orocos_kdl-config-version.cmake @ONLY)

INSTALL(FILES cmake/FindEigen3.cmake DESTINATION share/orocos_kdl/cmake)
INSTALL(FILES ${PROJECT_BINARY_DIR}/orocos_kdl-config.cmake DESTINATION share/orocos_kdl/cmake)
INSTALL(FILES ${PROJECT_BINARY_DIR}/orocos_kdl-config-version.cmake DESTINATION share/orocos_kdl/cmake)
INSTALL(EXPORT OrocosKDLTargets DESTINATION share/orocos_kdl/cmake)
include(CMakePackageConfigHelpers)

set(orocos_kdl_CMAKE_INSTALL_SUFFIX share/orocos_kdl/cmake)

configure_package_config_file(orocos_kdl-config.cmake.in ${orocos_kdl_CONFIG_FILENAME}
INSTALL_DESTINATION ${orocos_kdl_CMAKE_INSTALL_SUFFIX})
write_basic_package_version_file(${orocos_kdl_VERSION_CONFIG_FILENAME}
VERSION ${KDL_VERSION}
COMPATIBILITY AnyNewerVersion)

INSTALL(FILES cmake/FindEigen3.cmake
${CMAKE_CURRENT_BINARY_DIR}/${orocos_kdl_CONFIG_FILENAME}
${CMAKE_CURRENT_BINARY_DIR}/${orocos_kdl_VERSION_CONFIG_FILENAME}
DESTINATION ${orocos_kdl_CMAKE_INSTALL_SUFFIX})
INSTALL(EXPORT OrocosKDLTargets DESTINATION ${orocos_kdl_CMAKE_INSTALL_SUFFIX})

# Generate pkg-config package configuration
CONFIGURE_FILE(orocos_kdl.pc.in ${CMAKE_CURRENT_BINARY_DIR}/orocos-kdl.pc @ONLY)
Expand Down
7 changes: 7 additions & 0 deletions orocos_kdl/cmake/FindEigen3.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -87,3 +87,10 @@ else (EIGEN3_INCLUDE_DIR)
mark_as_advanced(EIGEN3_INCLUDE_DIR)

endif(EIGEN3_INCLUDE_DIR)

if(EIGEN3_FOUND AND NOT TARGET Eigen3::Eigen)
add_library(Eigen3::Eigen INTERFACE IMPORTED)
set_target_properties(Eigen3::Eigen PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${EIGEN3_INCLUDE_DIR}")
endif()

11 changes: 0 additions & 11 deletions orocos_kdl/orocos_kdl-config-version.cmake.in

This file was deleted.

15 changes: 10 additions & 5 deletions orocos_kdl/orocos_kdl-config.cmake.in
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@
# orocos_kdl_LIBRARIES - libraries to link against for Orocos KDL
# orocos_kdl_PKGCONFIG_DIR - directory containing the .pc pkgconfig files

# Compute paths
get_filename_component(orocos_kdl_PREFIX "${CMAKE_CURRENT_LIST_DIR}/../../.." ABSOLUTE)
@PACKAGE_INIT@

# Find dependencies
find_package(Eigen3 QUIET)
Expand All @@ -19,15 +18,21 @@ if(KDL_USE_NEW_TREE_INTERFACE)
endif()

if(NOT TARGET orocos-kdl)
include("${CMAKE_CURRENT_LIST_DIR}/OrocosKDLTargets.cmake")
include("${CMAKE_CURRENT_LIST_DIR}/@orocos_kdl_TARGETS_EXPORT_NAME@.cmake")
endif()

get_target_property(orocos_kdl_INCLUDE_DIR orocos-kdl INTERFACE_INCLUDE_DIRECTORIES)

set_and_check(orocos_kdl_INCLUDE_DIR "${orocos_kdl_INCLUDE_DIR}")

set(orocos_kdl_INCLUDE_DIRS
${orocos_kdl_PREFIX}/include
${orocos_kdl_INCLUDE_DIR}
${Boost_INCLUDE_DIRS}
${EIGEN3_INCLUDE_DIR}
)
set(orocos_kdl_LIBRARIES orocos-kdl)

# where the .pc pkgconfig files are installed
set(orocos_kdl_PKGCONFIG_DIR "${orocos_kdl_PREFIX}/lib/pkgconfig")
set(orocos_kdl_PKGCONFIG_DIR "${PACKAGE_PREFIX_DIR}/lib/pkgconfig")

check_required_components("@PROJECT_NAME@")
7 changes: 4 additions & 3 deletions orocos_kdl/src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -80,14 +80,15 @@ ENDIF()
#####end RPATH

# Needed so that the generated config.h can be used
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR})
TARGET_LINK_LIBRARIES(orocos-kdl ${Boost_LIBRARIES})
TARGET_INCLUDE_DIRECTORIES(orocos-kdl PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}> )
Copy link
Contributor

Choose a reason for hiding this comment

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

This additionally needs a $<INSTALL_INTERFACE:include> to export an include directory in the install case.

Copy link
Member

Choose a reason for hiding this comment

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

Isn't that what

install(TARGETS ...
  INCLUDES DESTINATION include
)

is supposed to do here?

From the documentation:

INCLUDES DESTINATION
This option specifies a list of directories which will be added to the INTERFACE_INCLUDE_DIRECTORIES target property of the <targets> when exported by the install(EXPORT) command. If a relative path is specified, it is treated as relative to the $<INSTALL_PREFIX>.

So probably both are valid approaches to achieve the same at the end. But having both might be redundant.

TARGET_LINK_LIBRARIES(orocos-kdl PUBLIC ${Boost_LIBRARIES} Eigen3::Eigen)

Choose a reason for hiding this comment

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

This target was introduced in Eigen 3.3.1, you'll need to add some fallback behavior (if(TARGET Eigen3::Eigen)...else()...endif()).

Copy link
Author

Choose a reason for hiding this comment

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

Sorry for the (very) long absence, is this still relevant?

Copy link

@PeterBowman PeterBowman Feb 14, 2021

Choose a reason for hiding this comment

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

Since KDL doesn't enforce a minimum version, anyone trying to use Eigen<3.3.1 can experience errors, so I think this is still an issue. However, you could just tweak FindEigen3.cmake so that modern CMake targets are made available for use both by KDL itself and projects consuming KDL (make sure this gives precedence to the local file or just add OR NOT TARGET Eigen3::Eigen in the if clause). See upstream find module, especially the last few lines:

if(EIGEN3_FOUND AND NOT TARGET Eigen3::Eigen)
  add_library(Eigen3::Eigen INTERFACE IMPORTED)
  set_target_properties(Eigen3::Eigen PROPERTIES
    INTERFACE_INCLUDE_DIRECTORIES "${EIGEN3_INCLUDE_DIR}")
endif()

Copy link
Author

Choose a reason for hiding this comment

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

currently if Eigen is not found there is no error? Adding eigen with the TARGET_LINK_LIBRARIES will print an error when generating.

Copy link

@PeterBowman PeterBowman Feb 20, 2021

Choose a reason for hiding this comment

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

If Eigen is a required dependency, there should be a check somewhere else (and before those lines) to issue an error. I wouldn't delegate such responsibility to the target_link_libraries call, typically you would use find_package(<pkg> REQUIRED) or a simple if(NOT <pkg>_FOUND)-then-message(FATAL_ERROR ...) condition instead.


INSTALL(TARGETS orocos-kdl
EXPORT OrocosKDLTargets
EXPORT ${orocos_kdl_TARGETS_EXPORT_NAME}
ARCHIVE DESTINATION lib${LIB_SUFFIX}
LIBRARY DESTINATION lib${LIB_SUFFIX}
PUBLIC_HEADER DESTINATION include/kdl
INCLUDES DESTINATION include
)

INSTALL(FILES ${UTIL_HPPS} DESTINATION include/kdl/utilities)