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

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

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

Однако для определенного файла (скажем, "foo.cpp" ) в подкаталоге, я хочу переключить компилировать флаги, чтобы не применять -WeffС++ (включая коммерческую библиотеку, которую я не могу изменить). Чтобы упростить ситуацию, чтобы использовать только -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++ )

что также не сработало (то есть, я получаю много предупреждений о стиле в коммерческой библиотеке). (** Примечание. Предупреждения ARE подавляются, если я НЕ повторно включаю директиву -WeffС++ после создания исполняемого файла.)

Я также попытался временно удалить флаги компиляции: http://www.cmake.org/pipermail/cmake/2007-June/014614.html , но это не помогло.

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

Ответ 1

Ваши попытки выше добавляют дополнительные флага к вашему файлу/цели, а не переписывают, как вы, кажется, ожидаете. Например, из документации для set_source_files_properties(foo.cpp PROPERTIES COMPILE_FLAGS -Wno-effc++)

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

make VERBOSE=1

Как один из сторонников стандартной библиотеки GNU С++ представляет довольно негативное мнение о -Weffc++ в .

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

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

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")

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

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

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

Сначала не включают COMPILE_OPTIONS, только COMPILE_FLAGS. Это проблема, потому что COMPILE_OPTIONS цели может включать , но COMPILE_FLAGS не поддерживает их. Таким образом, вам придется приспосабливать выражения генератора во время поиска вашего флага, и даже вам, возможно, придется даже "разобрать" генераторные выражения, если ваш флаг содержался в одном или нескольких, чтобы увидеть, следует ли его повторно применить к оставшимся исходные файлы.

Второй - с CMake v3.0 цели могут указывать . Это означает, что зависимость вашей цели может добавить или переопределить целевую COMPILE_OPTIONS через ее INTERFACE_COMPILE_OPTIONS. Таким образом, вам также придется рекурсивно перебирать все ваши целевые зависимости (не очень простая задача, так как список для цели также может содержать выражения генератора), чтобы найти любые, которые применяют флаг проблемы, и попытаться удалить и из этих целей 'INTERFACE_COMPILE_OPTIONS.

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

1: Обратите внимание, что в отличие от свойства COMPILE_FLAGS в исходных файлах свойство COMPILE_FLAGS для целей устарело.

Ответ 2

Просто добавив правильный ответ @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, как обсуждалось здесь