Я хотел бы использовать глобальный набор флагов для компиляции проекта, что означает, что в моем файле CMakeLists.txt верхнего уровня я указал:
ADD_DEFINITIONS ( -Wall -Weffc++ -pedantic -std=c++0x )
Однако для конкретного файла (скажем, «foo.cpp») в подкаталоге я хочу отключить флаги компиляции, чтобы не применять -Weffc ++ (включенная коммерческая библиотека, которую я не могу изменить). Чтобы упростить ситуацию использовать только -Wall, я попробовал:
SET_SOURCE_FILES_PROPERTIES( foo.cpp PROPERTIES COMPILE_FLAGS -Wall )
ADD_EXECUTABLE( foo foo.cpp )
, что не сработало. Я тоже пробовал
SET_PROPERTY( SOURCE foo.cpp PROPERTY COMPILE_FLAGS -Wall )
ADD_EXECUTABLE( foo foo.cpp )
и
ADD_EXECUTABLE( foo foo.cpp )
SET_TARGET_PROPERTIES( foo PROPERTIES COMPILE_FLAGS -Wall )
, в котором ни один из них не работал.
Наконец, я попытался удалить это определение:
REMOVE_DEFINITIONS( -Weffc++ )
ADD_EXECUTABLE( foo foo.cpp )
ADD_DEFINITIONS( -Weffc++ )
, что также не сработало (то есть я получаю много предупреждений о стилях коммерческой библиотеки). (** Примечание: предупреждения ПОДАВАЮТСЯ, если Я НЕ повторно включаю директиву -Weffc ++ после сборки исполняемого файла.)
Я также попытался временно удалить флаги компиляции: http://www.cmake.org/pipermail/cmake/2007-June/014614.html , но это не помогло.
Разве это не изящное решение?
источник
Ответы:
Ваши попытки выше добавляют дополнительные флаги к вашему файлу / цели, а не перезаписывают, как вы, кажется, ожидаете. Например, из документации по свойствам исходных файлов - COMPILE_FLAGS :
Вы должны иметь возможность отменить
-Weffc++
флаг для foo.cpp, выполнивЭто должно иметь эффект добавления
-Wno-effc++
после-Weffc++
в команде компилятора, и последний параметр выигрывает. Чтобы увидеть полную команду и убедиться, что это действительно так, вы можете сделатьКстати, один из разработчиков стандартной библиотеки GNU C ++ высказывает довольно отрицательное мнение
-Weffc++
в этом ответе .Другой момент заключается в том, что вы злоупотребляете
add_definitions
в том смысле, что используете это для флагов компилятора, а не для предполагаемых определений препроцессора.Было бы предпочтительнее использовать
add_compile_options
или для версий CMake <3.0, чтобы сделать что-то вроде:
Отвечая на дополнительные вопросы в комментариях ниже, я считаю, что невозможно надежно удалить флаг в одном файле. Причина в том, что для любого исходного файла он имеет
COMPILE_OPTIONS
иCOMPILE_FLAGS
1 его целевого объекта, но они не отображаются ни в одном из свойств этого исходного файла.Вы могли бы посмотреть, как убрать флаг проблемы с целевой
COMPILE_OPTIONS
, а затем применить его к каждому из целевых источников по отдельности, при необходимости исключив его из конкретного исходного файла.Однако, хотя это может работать во многих сценариях, у него есть несколько проблем.
Во-первых, свойства исходных файлов не включают
COMPILE_OPTIONS
, толькоCOMPILE_FLAGS
. Это проблема, потому чтоCOMPILE_OPTIONS
цель может включать выражения генератора , ноCOMPILE_FLAGS
не поддерживает их. Таким образом, вам придется использовать выражения генератора при поиске вашего флага, и вам, возможно, даже придется «анализировать» выражения генератора, если ваш флаг содержится в одном или нескольких, чтобы увидеть, следует ли его повторно применить к оставшимся исходные файлы.Во-вторых, начиная с CMake v3.0, цели могут указывать
INTERFACE_COMPILE_OPTIONS
. Это означает, что зависимость вашей цели может добавлять или переопределять вашу цельCOMPILE_OPTIONS
через своиINTERFACE_COMPILE_OPTIONS
. Таким образом, вам также придется рекурсивно перебирать все зависимости вашей цели (не особенно простая задача, поскольку списокLINK_LIBRARIES
для цели также может содержать выражения генератора), чтобы найти любые, которые применяют флаг проблемы, и попытаться удалить его из тех целиINTERFACE_COMPILE_OPTIONS
тоже.На этом этапе сложности я хотел бы отправить патч в CMake, чтобы обеспечить функциональность для безоговорочного удаления определенного флага из исходного файла.
1: Обратите внимание, что, в отличие от
COMPILE_FLAGS
свойства исходных файлов,COMPILE_FLAGS
свойство целевых объектов устарело.источник
Просто добавив к правильному ответу @Fraser.
В случае, если вы хотите добавить специальный флаг в определенные папки, вы можете сделать:
или
Обратите внимание, что не рекомендуется использовать GLOB, как обсуждается здесь
источник
Используя ответ @Fraser, я создал следующее для обработки включений Qt, потому что переменная включает несколько путей, разделенных точкой с запятой. Это означает, что мне пришлось сначала добавить
foreach()
цикл и вручную создать флаги включения . Но это позволяет мне иметь одно исключение: foo.cpp (этот файл сейчас использует Qt, но в долгосрочной перспективе я хочу удалить эту зависимость, и я хочу убедиться, что Qt не закрадывается в другое место).Также обратите внимание, что я использую
-isystem
вместо,-I
чтобы избежать некоторых предупреждений, которые в противном случае генерируются заголовками Qt (у меня включена масса предупреждений).источник