Для получения триального ключа
заполните форму ниже
Team license
Enterprise license
** Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

Запросите информацию о ценах
Новая лицензия
Продление лицензии
--Выберите валюту--
USD
EUR
RUB
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

Бесплатная лицензия PVS-Studio для специалистов Microsoft MVP
** Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

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

Мне интересно попробовать плагин на:
** Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

Ваше сообщение отправлено.

Мы ответим вам на


Если вы так и не получили ответ, пожалуйста, проверьте папку
Spam/Junk и нажмите на письме кнопку "Не спам".
Так Вы не пропустите ответы от нашей команды.

>
>
Как мы исправили один баг в CMake

Как мы исправили один баг в CMake

23 Мар 2020

В августе 2019 года в CMake появилась долгожданная поддержка предкомпилированных заголовков. До этого приходилось использовать разные плагины, например, Cotire. Сразу после выпуска CMake с новым функционалом было ещё несколько доработок. Но уже осенью мы посчитали, что можно начать использовать эту фичу, и переписали наши скрипты. Позже мы нашли баг, который формировал неправильные параметры компилятора Clang и мешал запуску анализатора PVS-Studio. Баг пришлось исправить самим.

0719_CMakePchFix_ru/image1.png

Что не так?

Проблема была в том, что исходный файл, в котором использовался предкомпилированный заголовок, был некорректно препроцессирован, если использовался компилятор Clang. На месте header-файла было пустое место. Но в GCC и MSVC все работало нормально.

Что делает CMake?

Стоит рассказать о том, как CMake формирует предкомпилированный заголовок. Для каждого target'а (а начиная с CMake 3.17 и для каждого типа сборки – Debug, Release, ...) создается 2 файла: cmake_pch.hxx и cmake_pch.cxx. hxx-файл – это header-файл, из которого уже будет сформирован предкомпилированный заголовок, а cxx – пустой файл с содержимым:

/* Generated by CMake */

Нужен он для генерации предкомпилированного заголовка – он используется как исходник при запуске компилятора.

Во время сборки проекта заголовочный файл включается через передачу флагов компилятора. Для Clang это:

-Xclang -include-pch -Xclang <PCH_FILE>

Т.е. в команду компиляции передается уже созданный предкомпилированный заголовок. В итоге команды запуска сохраняются в файле compile_commands.json, который анализатор использует для проверки проекта.

Проблема

Однако на этом моменте имя оригинального header-файла потеряно. При запуске препроцессора Clang пытается достать имя заголовочного файла из созданного предкомпилированного заголовка и в итоге использует пустой файл cmake_pch.cxx. Почему? Если взглянуть в документацию Clang, то можно увидеть их способ создания предкомпилированных заголовков:

To generate PCH files using clang -cc1, use the option -emit-pch:
$ clang -cc1 test.h -emit-pch -o test.h.pch

Заголовочный файл test.h используется в качестве исходного. А вот как делает CMake:

-Xclang -emit-pch -Xclang -include -Xclang <PCH_HEADER>

Он включает его через специальный флаг, а затем передает cmake_pch.cxx как исходник. Информация о включенных файлах, переданных через командную строку, к сожалению, теряется, а информация об исходном файле остается. Это можно узнать, посмотрев документацию Clang:

Original file name
    The full path of the header that was used to generate the AST file.

Но как в этом случае работал Cotire?

Cotire по своей структуре похож на CMake, однако cxx-файл выглядел примерно так:

#ifdef __cplusplus
#include "/path/to/header.hxx"
#endif

В исходнике у него была директива include, поэтому препроцессор работал нормально. Это первое, что мы хотели предложить в качестве исправления.

Однако при таком подходе появились проблемы - нарушалась кодировка файлов (компилятор может преобразовывать исходный файл в свою кодировку), могла сломаться работа других компиляторов, а в CMake 3.17 файл cmake_pch.cxx создавался только один для каждого типа сборки, когда hxx-файлы могли отличаться.

Решение

В итоге было решено передавать в строку компиляции еще и оригинальный исходный файл:

-Xclang -include-pch -Xclang <PCH_FILE> -Xclang -include -Xclang <PCH_HEADER>

Благодаря опции -Xclang следующий флаг передается напрямую в препроцессор, минуя драйвер, который выполняет поиск соответствующего заголовку .pch/.gch файла. Ссылка на патч: PCH: Clang: Update PCH usage flags to include original header.

Заключение

Наш небольшой патч вошел в CMake 3.17, исправив проблему. Надеюсь, было интересно, и вы узнали чуть больше о работе CMake.

Мы можем рекомендовать использовать эту фичу в реальных проектах.

Последние статьи:

Опрос:

Популярные статьи по теме
Как Apple и другие крупные компании настиг программный баг

Дата: 09 Ноя 2022

Автор: Ульяна Гришина

Сегодня мы отобрали свежие случаи программных ошибок, чтобы вы могли немного отвлечься и, возможно, узнать что-то новенькое. Если вам интересно узнать, как программисту удалось сломать Интернет по вс…
Единороги компании PVS-Studio

Дата: 30 Авг 2022

Автор: Андрей Карпов

Скорее всего вы перешли на эту статью, заинтересовавшись одним из наших рисунков единорогов. Приятно видеть ваш интерес. Сейчас мы расскажем, почему рисуем этих единорогов, что они означают и чем воо…
Обрабатывать ли в PVS-Studio вывод других инструментов?

Дата: 26 Май 2022

Автор: Андрей Карпов

Анализатор PVS-Studio умеет "схлопывать" повторяющиеся предупреждения. Предоставляет возможность задать baseline, что позволяет легко внедрять статический анализ в legacy-проекты. Стоит ли предостави…
15000 ошибок в открытых проектах

Дата: 24 Май 2022

Автор: Андрей Карпов

Количество багов в нашей коллекции перевалило за отметку 15000. Именно такое количество ошибок обнаружила команда PVS-Studio в различных открытых проектах. Особенно интересно, что это всего лишь побо…
Комментарии в коде как вид искусства

Дата: 04 Май 2022

Автор: Сергей Хренов

Приветствую всех программистов, а также сочувствующих. Кто из нас хотя бы раз в жизни не оставлял комментарии в коде? Был ли это ваш код, а может, чужой? Что за комментарии вы написали: полезные или …

Комментарии (0)

Следующие комментарии
Unicorn with delicious cookie
Мы используем куки, чтобы пользоваться сайтом было удобно.
Хорошо