Ограничить использование флагов компиляции только определенными файлами

Я пытаюсь ввести флаг -Werror в довольно большой унаследованный проект. Как и ожидалось, он полностью ломает компиляцию. Поэтому я решил вводить его постепенно, и в первую очередь для нового кода. Мой первоначальный подход состоял в том, чтобы скомпилировать новые функции в виде отдельных статических целей и связать их с проектом, что хорошо работает как с точки зрения структуры проекта, так и с точки зрения читабельности. Проблема, которая сохраняется, — это ранее существовавшие запутанные включения. По сути, даже после исправления всех предупреждений в новом коде у меня осталась цепочка включений, представляющих новые предупреждения. Есть ли способ строго ограничить использование флагов предупреждений заданными исходными файлами? Я понимаю, что включение означает в основном копирование/вставку заголовков в cpps, поэтому это невозможно только с настройками cmake. Тогда, может быть, прагмы?

Это невероятно просто с bazel, и вы также можете включить свой старый проект cmake, но кривая обучения может быть немного сложной в начале.

Taekahn 23.04.2022 03:16
3 метода стилизации элементов HTML
3 метода стилизации элементов HTML
Когда дело доходит до применения какого-либо стиля к нашему HTML, существует три подхода: встроенный, внутренний и внешний. Предпочтительным обычно...
Формы c голосовым вводом в React с помощью Speechly
Формы c голосовым вводом в React с помощью Speechly
Пытались ли вы когда-нибудь заполнить веб-форму в области электронной коммерции, которая требует много кликов и выбора? Вас попросят заполнить дату,...
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Будучи разработчиком веб-приложений, легко впасть в заблуждение, считая, что приложение без JavaScript не имеет права на жизнь. Нам становится удобно...
Flatpickr: простой модуль календаря для вашего приложения на React
Flatpickr: простой модуль календаря для вашего приложения на React
Если вы ищете пакет для быстрой интеграции календаря с выбором даты в ваше приложения, то библиотека Flatpickr отлично справится с этой задачей....
В чем разница между Promise и Observable?
В чем разница между Promise и Observable?
Разберитесь в этом вопросе, и вы значительно повысите уровень своей компетенции.
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Клиент для URL-адресов, cURL, позволяет взаимодействовать с множеством различных серверов по множеству различных протоколов с синтаксисом URL.
0
1
41
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Вы можете использовать команду set_source_files_properties, чтобы установить свойство COMPILE_OPTIONS для нужных вам файлов.

Что-то вроде этого:

set_source_files_properties(bad.cpp PROPERTIES COMPILE_OPTIONS -Werror)
Ответ принят как подходящий

Я не знаю ни о каких флагах компилятора, которые позволяют вам применять флаги только к некоторым включенным файлам, поэтому cmake не может вам помочь. Поэтому прагмы - это путь.

В основном то, что вы действительно хотите в своих файлах cpp, выглядит примерно так:

#pragma GCC diagnostic push
#pragma GCC diagnostic error "-Wall"

#include "updated_lib/header1.hpp"
#include "updated_lib/header2.hpp"
...

#pragma GCC diagnostic pop

#include "non_updated_lib/header1.hpp"
#include "non_updated_lib/header2.hpp"

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

В качестве альтернативы вы можете продублировать подкаталоги файла заголовка и сделать необновленные версии доступными по одному пути, а обновленные заголовки - по другому, например. для заголовка foo/bar/baz.hpp либо сделайте заголовок доступным через путь old/foo/bar/baz.hpp, либо new/foo/bar/baz.hpp и создайте новый заголовок, доступный через foo/bar/baz.hpp, который выглядит следующим образом:

#if __has_include("new/foo/bar/baz.hpp")
#   pragma GCC diagnostic push
#   pragma GCC diagnostic error "-Wall"

#   include "new/foo/bar/baz.hpp"

#   pragma GCC diagnostic pop
#else
#   pragma GCC diagnostic push
#   pragma GCC diagnostic warning "-Wall"

#   include "old/foo/bar/baz.hpp"

#   pragma GCC diagnostic pop
#endif

Обратите внимание, что вам, вероятно, потребуется написать такие заголовки для вас. Вы даже можете сгенерировать фактические включения через cmake во время создания проекта, что сократит заголовки до 3 прагм плюс одно включение; это дало бы дополнительное преимущество работы с версиями компилятора, не поддерживающими __has_include.

function(my_generate_include OUT_LIST DESTINATION_DIR FIRST_HEADER)
    set(GENERATED_HEADERS ${${OUT_LIST}})
    foreach(HEADER IN ITEMS ${FIRST_HEADER} ${ARGN})
        if (HEADER MATCHES "^old/(.*)$")
            configure_file(old_include.hpp.in "${DESTINATION_DIR}/${CMAKE_MATCH_1}")
            list(APPEND GENERATED_HEADERS "${DESTINATION_DIR}/${CMAKE_MATCH_1}")
        elseif (HEADER MATCHES "^new/(.*)$")
            configure_file(new_include.hpp.in "${DESTINATION_DIR}/${CMAKE_MATCH_1}")
            list(APPEND GENERATED_HEADERS "${DESTINATION_DIR}/${CMAKE_MATCH_1}")
        else()
            message(FATAL_ERROR "Header '${HEADER}' doesn't start with 'new/' or 'old/'")
        endif()
    endforeach()
    set(${OUT_LIST} ${GENERATED_HEADERS} PARENT_SCOPE)
endfunction()

...

set(HEADERS)

my_generate_include(HEADERS ${CMAKE_CURRENT_BINARY_DIR}/generated_includes
   old/a/b/c.hpp
   new/d/e/f.hpp
)

Другие вопросы по теме