Как добавить add_custom_command() для самого процесса сборки CMake?
Есть ли способ сделать эквивалент add_custom_command (запустить внешний скрипт при изменении определенного файла), но для чего-то, что должно быть запущено во время выполнения самого скрипта CMake? (То есть для генерации графа зависимостей.)
У нас есть файлы исходного кода, разделенные на несколько под-библиотек, и есть файлы конфигурации, в которых указывается, какой исходный файл идет с какой библиотекой. (Формат этих файлов конфигурации фиксируется другим инструментом, который мы используем.) В настоящее время мы запускаем собственный внешний скрипт, который анализирует эти файлы конфигурации и записывает новые файлы, которые затем загружаются процессом сборки CMake, чтобы дать список имен файлов для быть передано в add_library(). Это означает, что каждый раз, когда исходный файл добавляется / удаляется, мы должны помнить, что нужно повторно запускать команду prebuild, перед повторным запуском CMake, а затем перезапускать команду build.
Я знаю, что CMake может распознать, что ему нужно перезапустить себя, поэтому я надеюсь, что мы можем заставить CMake 1) распознать, что файлы конфигурации изменены 2) перезапустить анализатор configfile 3) загрузить новый список файлов 4) используйте новый список файлов для регенерации дерева зависимостей. 5) наконец запустите реальный процесс сборки / компиляции с включением новых файлов. ... и все это из стандартной команды сборки, без необходимости вручную запускать внешний синтаксический анализатор configfile или повторного запуска команды CMake, а также без ненужного выполнения, когда configfile не изменился.
При поиске я нашел этот вопрос, где предлагается использовать configure_file(), но это не касается того, как вызвать скрипт синтаксического анализатора внешнего configfile.
1 ответ
Превращаю мой комментарий в ответ
configure_file()
является правильным выбором для повторного запуска процесса конфигурации. А также execute_process()
используется для запуска команд на этапе настройки.
Вот абстрактный фрагмент CMake шагов в вашем описании:
function(my_add_library_from_cfg _target _cfg_file)
# Retrigger configuration process each time config file changes
get_filename_component(_cfg_name "${_cfg_file}" NAME)
configure_file("${_cfg_file}" "${_cfg_name}.tmp")
# Generating sources and file list
execute_process(
COMMAND ${CMAKE_COMMAND} -E echo "#define FOO"
OUTPUT_FILE foo.c
)
execute_process(
COMMAND ${CMAKE_COMMAND} -E echo "foo.c"
OUTPUT_FILE files.lst
)
# Reading file list and add library
file(STRINGS "${CMAKE_CURRENT_BINARY_DIR}/files.lst" _sources_lst)
add_library(${_target} ${_sources_lst} "${_cfg_file}")
endfunction(my_add_library_from_cfg)
configure_file()
будет повторно запускать CMake каждый раз, когда данный.cfg
изменения файла- если вы действительно используете
.cfg
файл в качестве параметра командной строки вexecute_process()
Вы должны использовать сгенерированный.tmp
версия в текущем двоичном каталоге
- если вы действительно используете
execute_process()
может сделать много вещей- Я использовал это, чтобы повторить
stdout
и записать вывод в файлы - по умолчанию
WORKING_DIRECTORY
здесь текущий бинарный каталог
- Я использовал это, чтобы повторить
file()
читает в списке исходных файлов- полные пути каждый, разделенные новой строкой
- Я записал сгенерированные файлы по назначению в каталог двоичного вывода
- это облегчает чистую сборку, просто удалите всю директорию двоичного вывода
- и CMake имеет встроенную поддержку для этого; он будет искать исходные файлы без абсолютного пути сначала в текущем источнике, а затем в текущем двоичном каталоге
- И я не использовал
GENERATED
свойство исходного файла- потому что это будет необходимо, только если источники были сгенерированы на предыдущем этапе сборки
- и сам CMake больше не распознает, когда на самом деле файл из списка исходных файлов будет отсутствовать