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

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

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

2 ответов


ваши попытки выше добавляют дополнительные флаги к вашему файлу / цели, а не перезаписывают, как вы, похоже, ожидаете. Например, из документов для свойства исходных файлов-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

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, например, В3.0, цели могут указать INTERFACE_COMPILE_OPTIONS. Это означает, что зависимость вашей цели может добавить или переопределить COMPILE_OPTIONS через INTERFACE_COMPILE_OPTIONS. Таким образом, вам придется рекурсивно перебирать все зависимости вашей цели (не особенно простая задача, так как список LINK_LIBRARIES для цели также может содержать выражения генератора), чтобы найти любые, которые применяют флаг проблемы, и попытаться удалить его из этих целей"INTERFACE_COMPILE_OPTIONS тоже.

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


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


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