Использование ADD_CUSTOM_COMMAND от CMake для обработки перед компиляцией

#cmake

#cmake

Вопрос:

Мой проект состоит из нескольких компонентов. Каждый из них зависит от одного или нескольких *.hpp файлов, которые генерируются из *.lcm с помощью внешнего инструмента. Я хотел бы иметь возможность указать список, *.lcm какие файлы требуются для каждого компонента, и заставить CMake автоматически выполнять компиляцию при необходимости, возможно, заданную с помощью небольшого макроса:

 REQUIRED_LCMS (the_component x.lcm z.lcm)
  

Для компиляции *.lcm , я думаю, должно сработать следующее:

 ADD_CUSTOM_COMMAND (OUTPUT  ${CMAKE_CURRENT_BINARY_DIR}/${lcm_basename}.hpp
                    DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${lcm}
                    COMMAND "lcm-gen"
                    ARGS    "--lazy --cpp ${CMAKE_CURRENT_SOURCE_DIR}/${lcm}"
                    COMMENT "  ${lcm} -> ${lcm_basename}.hpp")
  

…но я не уверен, что должно быть в REQUIRED_LCMS . ADD_CUSTOM_COMMAND и ADD_CUSTOM_TARGET ?

Ответ №1:

Мне удалось заставить это работать без детализации (т. Е. зависимости от файла lcm), выполнив следующее:

 SET (LCM_MESSAGES x.lcm
                  y.lcm
                  z.lcm)

SET (LCM_COMPILED_MESSAGES)
FOREACH (_file ${LCM_MESSAGES})

  GET_FILENAME_COMPONENT (_filewe ${_file} NAME_WE)
  STRING (TOUPPER ${_filewe} _FILEWE)
  SET (_filehpp ${_filewe}.hpp)
  SET (_filehpp_output ${CMAKE_CURRENT_BINARY_DIR}/${_filehpp})

  ADD_CUSTOM_COMMAND (OUTPUT  ${_filehpp_output}
                      DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${_file}
                      COMMAND lcm-gen
                      ARGS    --lazy --cpp ${CMAKE_CURRENT_SOURCE_DIR}/${_file})

  LIST (APPEND LCM_COMPILED_MESSAGES ${_filehpp_output})

ENDFOREACH ()

ADD_CUSTOM_TARGET (LCM_MESSAGES DEPENDS ${LCM_COMPILED_MESSAGES})
  

… и затем в CMakeLists.txt каждого компонента:

 ADD_DEPENDENCIES (the_component LCM_MESSAGES)
  

Комментарии:

1. Этот ответ довольно хорош, с одним подвохом. Включение выходных данных пользовательской команды в список источников для целевого объекта автоматически добавит зависимость, поэтому, если вы добавите $ {LCM_COMPILED_MESSAGES} в свой список источников для целевых объектов, которые ее используют, зависимость будет автоматической. Недостатком этого подхода в отличие от пользовательского является то, что он будет отображать сгенерированные файлы в вашем списке исходных текстов IDE, если это применимо, и я думаю, что это может потребоваться в том же каталоге (тот же CMakeLists.txt файл) в качестве пользовательской команды.