Можно ли CMake остановиться на первой ошибке?

Вопрос или проблема

Когда 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 по умолчанию продолжает выполнение, есть несколько подходов, которые помогут вам добиться желаемого поведения:

  1. Условная логика в 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 завершит выполнение и выдаст сообщение об ошибке, что упростит процесс отладки.

  2. Использование инструментов обработки вывода:
    Если вам важно быстро получить информацию о первой ошибке без модификации CMake файлов, можно использовать инструменты командной строки, такие как awk или sed, для фильтрации вывода:

    cmake . 2>&1 | awk '/^CMake Error/ { print; exit }'

    Этот подход позволяет быстро получить первую запись об ошибке из вывода CMake, что упрощает диагностику.

  3. Использование интерфейса CMake, такого как ccmake:
    Вы также можете использовать графический интерфейс командной строки CMake для более удобного управления конфигурацией. Команда ccmake .. предоставляет интерфейс, в котором можно просматривать и редактировать параметры конфигурации, а также отмечать возможные ошибки в процессе генерации.

Заключение

CMake не предлагает встроенной опции для немедленной остановки после первой ошибки в процессе генерации, однако вы можете использовать упомянутые методы для повышения эффективности работы. Понимание возможности условной логики в CMake и использование командной строки для фильтрации ошибок помогут вам сосредоточиться на нужных задачах и оптимизировать процесс разработки. Если вам нужно больше информации о настройках и параметрах CMake, вы всегда можете обратиться к официальной документации, которая предоставляет обширные ресурсы для разработчиков.

Оцените материал
Добавить комментарий

Капча загружается...