ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question
0

Ament Cmake: How to add interface files generated from build step to library

asked 2020-07-23 22:46:17 -0500

atyshka gravatar image

I am working on implementing a client library from swift, utilizing CMake's swift support, and I'm running into issues with interface files. Unlike C/C++, swift interfaces are not declared in source code. From the swift files, the compiler generates both the .so file and a swiftmodule file, which defines the external interface for other targets to include. Working off of the swift cmake examples, I accomplished this as so:

cmake_minimum_required(VERSION 3.15.1)

project(rclswift_common Swift)

find_package(ament_cmake REQUIRED)

add_library(RclSwiftCommon
  "swift/Interfaces.swift"
)

set_target_properties(RclSwiftCommon PROPERTIES INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_CURRENT_BINARY_DIR})

install(
  TARGETS RclSwiftCommon
  EXPORT RclSwiftCommon
  ARCHIVE DESTINATION lib
  LIBRARY DESTINATION lib
  RUNTIME DESTINATION bin
)

ament_export_targets(RclSwiftCommon HAS_LIBRARY_TARGET)

ament_package()

The set_target_properties makes sure that the generated swift modules are included with the target. However, when I use ament_export_targets, I get the following error from ament_export_targets:

CMake Error in CMakeLists.txt:
  Target "RclSwiftCommon" INTERFACE_INCLUDE_DIRECTORIES property contains
  path:

    "/home/alex/ros2/build/rclswift_common"

  which is prefixed in the build directory.


CMake Generate step failed.  Build files cannot be regenerated correctly.

Why won't ament let me include from the build directory, and is there any workaround I can implement to achieve a working setup?

edit retag flag offensive close merge delete

1 Answer

Sort by ยป oldest newest most voted
1

answered 2020-07-24 17:48:24 -0500

Dirk Thomas gravatar image

updated 2020-07-25 07:24:26 -0500

gvdhoorn gravatar image

Just to clarify in the beginning that I have no idea about Swift - so all of the following is just me extrapolating from how CMake works for C / C++.

The exported target will use the property INTERFACE_INCLUDE_DIRECTORIES when downstream packages try to find headers (in C / C++). Since the build directory can potentially be deleted after package rclswift_common has been built and installed the property shouldn't point to a build directory.

For C++ projects you commonly need some include directories to build a packages and other include directories for downstream packages to use the installed headers, e.g. https://github.com/ros2/rcl/blob/2a4d... (you will find the same pattern in almost all ROS core packages in Foxy and newer):

target_include_directories(
  your_library_target PUBLIC
  "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>"
  "$<INSTALL_INTERFACE:include>")

The $<BUILD_INTERFACE:... could also or additionally point to something under CMAKE_CURRENT_BINARY_DIR.

If you need to declare include directories for downstream packages you also need to install some files which you expect to be used by downstream packages.

For C++ that would be the header files. Maybe for Swift you have to install swift/Interfaces.swift? Assuming you would install that file to include you need to declare the INSTALL_INTERFACE on the target like this:

target_include_directories(
  RclSwiftCommon PUBLIC
  "$<INSTALL_INTERFACE:include>")
edit flag offensive delete link more

Comments

Thank you Dirk! I was able to successfully implement something working based off that:

set_target_properties(RclSwiftCommon PROPERTIES Swift_MODULE_DIRECTORY modules)

target_include_directories(RclSwiftCommon PUBLIC  
$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/modules>  
$<INSTALL_INTERFACE:modules> )
install(
  DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/modules/
  DESTINATION modules
)
atyshka gravatar image atyshka  ( 2020-07-24 18:27:00 -0500 )edit

Question Tools

1 follower

Stats

Asked: 2020-07-23 22:46:17 -0500

Seen: 1,836 times

Last updated: Jul 25 '20