Переопределить флаги компиляции для отдельных файлов

Я хотел бы использовать глобальный набор флагов для компиляции проекта, что означает, что в моем файле 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
, но это не помогло

Нет ли элегантного решения для этого?

86

Решение

Ваши попытки выше добавляют дополнительные флаги к вашему файлу / цели, а не перезаписывают, как вы ожидаете. Например, из документов для Свойства исходных файлов — COMPILE_FLAGS:

Эти флаги будут добавлены в список флагов компиляции при сборке этого исходного файла.

Вы должны быть в состоянии противостоять -Weffc++ пометка для foo.cpp, делая

set_source_files_properties(foo.cpp PROPERTIES COMPILE_FLAGS -Wno-effc++)

Это должно иметь эффект добавления -Wno-effc++ после -Weffc++ в команде компилятора, и последний параметр выигрывает. Чтобы увидеть полную команду и проверить, что это действительно так, вы можете сделать

make VERBOSE=1

Кроме того, один из сопровождающих Стандартной библиотеки GNU C ++ представляет довольно негативное мнение о -Weffc++ в этот ответ.

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

Было бы предпочтительнее использовать add_compile_options

add_compile_options(-Wall -Weffc++ -pedantic -std=c++0x)

или для версий CMake < 3.0 сделать что-то более похожее на:

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Weffc++ -pedantic -std=c++0x")

В ответ на дальнейшие вопросы в комментариях ниже, я считаю, что невозможно надежно Удалить флаг на одном файле. Причина в том, что для любого данного исходного файла, он имеет COMPILE_OPTIONS а также COMPILE_FLAGS1 его цели применены, но они не отображаются ни в одном из свойств этого исходного файла.

Вы могли бы посмотреть на удаление флага проблемы с цели 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 имущество по целям устарело.

102

Другие решения

Просто добавлю к правильному ответу @ Fraser.

Если вы хотите добавить специальный флаг в определенные папки, вы можете сделать:

file(GLOB SPECIAL_SRC_FILES
"path/one/src/*.cpp""path/two/src/*.cpp")
set_property(SOURCE ${SPECIAL_SRC_FILES} PROPERTY COMPILE_FLAGS -Wno-effc++)

или же

file(GLOB SPECIAL_SRC_FILES
"path/one/src/*.cpp""path/two/src/*.cpp")
set_source_files_properties(${SPECIAL_SRC_FILES} PROPERTIES COMPILE_FLAGS -Wno-effc++)

Обратите внимание, что не рекомендуется использовать GLOB как обсуждено Вот

2

По вопросам рекламы [email protected]