Robotics StackExchange | Archived questions

Generating a .msg file dynamically at build time

I have a non-ROS type definition file and a tool that translates these definitions to .msg files. I would catkin to first run the translation to produce the .msgs, and then add them to the package.

My attempt looked something like this:

set(GENERATED_MSGS_DIR "${CMAKE_CURRENT_BINARY_DIR}/msg")
add_custom_command(
    OUTPUT ${GENERATED_MSGS_DIR}
    COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/translate.py
            -o ${GENERATED_MSGS_DIR}
            ${CMAKE_CURRENT_SOURCE_DIR}/types.txt
    WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
)

file(GLOB_RECURSE GENERATED_MSG_FILES RELATIVE ${GENERATED_MSGS_DIR} *.msg)
add_message_files(FILES ${GENERATED_MSG_FILES})
generate_messages()

However this doesn't quite work. CMake will only run the custom command if an output file is needed by a target that gets built. In this case, I don't know the name of the .msg files that will come out of the translator, just the directory they'll be added to. And add_message_files also doesn't seem to like getting files outside of the package's msg directory.

As an alternative I could have the translate script produce a complete ROS package, if there's a way to dynamically add that package directory as a dependency.

Asked by rgov on 2020-07-27 18:26:49 UTC

Comments

Answers

I now use execute_process which runs the command when CMake is invoked to configure the process. This is OK but it does not track the dependency of the generated messages on the source types file.

set(GENERATED_MSGS_DIR "${CMAKE_CURRENT_BINARY_DIR}/msg")
execute_process(
    COMMAND "${CMAKE_CURRENT_SOURCE_DIR}/translate.py"
            -o "${GENERATED_MSGS_DIR}"
            "${CMAKE_CURRENT_SOURCE_DIR}/types.txt"
    RESULT_VARIABLE COMMAND_RESULT
)
if(NOT COMMAND_RESULT EQUAL 0)
    message(FATAL_ERROR "Translation command failed.")
endif()

add_message_files(DIRECTORY "${GENERATED_MSGS_DIR}")
generate_messages()

Asked by rgov on 2020-07-28 11:14:01 UTC

Comments

You might want to use add_custom_command instead where you can specify DEPENDS explicitly. As an alternative you might want to "stamp" your input files (see https://github.com/ament/ament_cmake/blob/96d279c261fd5908b6028659136ee2293d782c8f/ament_cmake_core/cmake/core/stamp.cmake#L22) which will ensure CMake to reconfigure in case they change.

Asked by Dirk Thomas on 2020-07-28 11:26:22 UTC

@Dirk I would rather do that, but what would I put under DEPENDS? Note I want generate_messages to depend on the output of my command, not the other way around. I thought I would use OUTPUT but I don't know how to wire it through to add_message_files etc.

Asked by rgov on 2020-07-28 12:24:22 UTC

DEPENDS would be the input files you use to derive the msg files from. OUTPUT would then indeed be the msg files.

Asked by Dirk Thomas on 2020-07-28 12:31:29 UTC