Вопрос или проблема
Когда cmake
сталкивается с ошибкой, иногда он не останавливается мгновенно, а продолжает обрабатывать все файлы CMake. Только в конце обработки мы узнаем, что произошла ошибка, и нам приходится прокручивать весь лог, чтобы увидеть, где она находится.
Существует ли какой-либо вариант, переменная или средство, чтобы остановить CMake сразу после первой ошибки?
Уточнение: я не пытаюсь остановить компиляцию исходного кода, а генерацию CMake (например, на Linux генерацию Makefiles).
Вот пример (это не мой реальный проект, это специально создано для генерации ошибок).
Мой файл CMakeLists.txt:
cmake_minimum_required(VERSION 3.6)
project(test)
set_property(TARGET foo PROPERTY PROP1 TRUE)
set_property(TARGET bar PROPERTY PROP2 TRUE)
И когда я запускаю cmake .
, я получаю следующий вывод :
CMake Error at CMakeLists.txt:3 (set_property):
set_property не смог найти ЦЕЛЬ foo. Возможно, она еще не была
создана.
CMake Error at CMakeLists.txt:4 (set_property):
set_property не смог найти ЦЕЛЬ bar. Возможно, она еще не была
создан.
-- Конфигурация неполная, произошли ошибки!
Что бы я хотел узнать, есть ли у cmake
возможность остановиться сразу после первой зарегистрированной ошибки.
Вы можете попробовать использовать инструменты, такие как awk
или sed
, чтобы разобрать вывод CMake и извлечь первое сообщение об ошибке. Вот пример того, как вы можете использовать оба:
$ cmake . 2>&1 | awk '/^CMake Error/ { print; exit }' // или
$ cmake . 2>&1 | sed -n '/^CMake Error/{p;q;}'
Это выведет первое сообщение об ошибке, которое выводит CMake, а затем завершит работу. Вы можете использовать этот вывод, чтобы помочь определить источник ошибки.
Вы можете использовать less
или ccmake
, чтобы просмотреть вывод, начиная с верхней части. Элементы управления являются частью less
, и он не заполняет буфер вашего терминала (использует отдельный буфер). Вам нужно будет перенаправить stderr в stdout, используя перенаправление 2>&1
. (CCMake — это интерфейс терминала, отдельный пакет)
Например, cmake .. 2>&1 | less
или ccmake ..
, а затем c для запуска конфигурации
Если вы хотите скрыть другой вывод, т.е. информацию о определении, вы можете перенаправить stdout в null (cmake .. 2>&1 >/dev/null
).
Показать только предупреждения/только ошибки (весь текст сообщения после них) или показать только одно сложно, потому что они могут содержать пустую строку, например, и не всегда выглядят так красиво, как эти две ошибки.
Вы можете, но вам нужно будет написать некоторую базовую управляющую логику для каждой цели.
Таким образом, ваш пример будет выглядеть так:
cmake_minimum_required(VERSION 3.6)
project(test)
if(TARGET foo)
set_property(TARGET foo PROPERTY PROP1 TRUE)
else()
message(FATAL_ERROR "Цель foo не существует.")
endif()
if(TARGET bar)
set_property(TARGET bar PROPERTY PROP2 TRUE)
else()
message(FATAL_ERROR "Цель bar не существует.")
endif()
Теперь конфигурация прерывается на foo
и никогда не доходит до цели bar
.
Ответ или решение
Вопрос о том, может ли CMake сразу остановиться после первой ошибки, представляет собой важный аспект работы с системой сборки. Когда CMake анализирует файлы и находит ошибки, существует риск, что он продолжит обработку других файлов, что затрудняет диагностику проблемы. В данном ответе мы рассмотрим возможности CMake в этом контексте и предложим несколько решений, которые помогут вам эффективно справляться с ошибками в конфигурации.
Способности CMake по остановке генерации
По умолчанию, CMake не останавливает свою работу после нахождения первой ошибки, а продолжает обрабатывать конфигурацию. Это может быть нежелательным поведением, особенно для больших и сложных проектов, где наличие нескольких ошибок может привести к значительным временным затратам на анализ выходных данных.
Подходы к остановке после первой ошибки
Несмотря на то что CMake по умолчанию продолжает выполнение, есть несколько подходов, которые помогут вам добиться желаемого поведения:
-
Условная логика в CMakeLists.txt:
Чтобы управлять процессом конфигурации, вы можете использовать условные конструкции в вашемCMakeLists.txt
. Например, вы можете проверять наличие целей и выдавать ошибки, если они отсутствуют:cmake_minimum_required(VERSION 3.6) project(test) if(NOT TARGET foo) message(FATAL_ERROR "Target foo does not exist.") else() set_property(TARGET foo PROPERTY PROP1 TRUE) endif() if(NOT TARGET bar) message(FATAL_ERROR "Target bar does not exist.") else() set_property(TARGET bar PROPERTY PROP2 TRUE) endif()
В этом примере при обнаружении отсутствующей цели CMake завершит выполнение и выдаст сообщение об ошибке, что упростит процесс отладки.
-
Использование инструментов обработки вывода:
Если вам важно быстро получить информацию о первой ошибке без модификации CMake файлов, можно использовать инструменты командной строки, такие какawk
илиsed
, для фильтрации вывода:cmake . 2>&1 | awk '/^CMake Error/ { print; exit }'
Этот подход позволяет быстро получить первую запись об ошибке из вывода CMake, что упрощает диагностику.
-
Использование интерфейса CMake, такого как
ccmake
:
Вы также можете использовать графический интерфейс командной строки CMake для более удобного управления конфигурацией. Командаccmake ..
предоставляет интерфейс, в котором можно просматривать и редактировать параметры конфигурации, а также отмечать возможные ошибки в процессе генерации.
Заключение
CMake не предлагает встроенной опции для немедленной остановки после первой ошибки в процессе генерации, однако вы можете использовать упомянутые методы для повышения эффективности работы. Понимание возможности условной логики в CMake и использование командной строки для фильтрации ошибок помогут вам сосредоточиться на нужных задачах и оптимизировать процесс разработки. Если вам нужно больше информации о настройках и параметрах CMake, вы всегда можете обратиться к официальной документации, которая предоставляет обширные ресурсы для разработчиков.