覆盖单个文件的编译标志
我想使用全局标志来编译一个项目,这意味着在我指定的顶层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++ )
,也没有工作(这意味着,我收到了很多关于商业图书馆的风格警告)。 (**注意:如果在构build可执行文件之后不重新包含-Weffc ++指令,则警告被抑制。)
我也尝试暂时删除编译标志: http : //www.cmake.org/pipermail/cmake/2007-June/014614.html ,但没有帮助。
有没有一个优雅的解决scheme呢?
您的上述尝试将更多的标志添加到您的文件/目标,而不是像您期望的那样覆盖。 例如,从源文件上的属性文件 – COMPILE_FLAGS :
当这个源文件构build时,这些标志将被添加到编译标志列表中。
你应该能够通过这样做来反制-Weffc++
标志
set_source_files_properties(foo.cpp PROPERTIES COMPILE_FLAGS -Wno-effc++)
这应该会在编译命令后添加-Wno-effc++
之后的-Weffc++
,后者设置-Weffc++
获胜。 要查看完整的命令并检查确实如此,可以这样做
make VERBOSE=1
另外,GNU C ++标准库的-Weffc++
在这个答案中对-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_FLAGS
1 ,但这些文件不会显示在该源文件的任何属性中。
您可以查看从目标的COMPILE_OPTIONS
中剥离问题标志,然后将其分别应用于每个目标源,并根据需要从特定的源文件中省略它。
但是,虽然这可以在许多情况下工作,但它有一些问题。
第一个源文件的属性不包括COMPILE_OPTIONS
,只COMPILE_FLAGS
。 这是一个问题,因为目标的COMPILE_OPTIONS
可以包含生成器expression式 ,但是COMPILE_FLAGS
不支持它们。 所以你必须在search你的旗子的时候适应生成器的expression式,如果你的标志被包含在一个或者多个中,你甚至可能需要“parsing”生成器expression式,看它是否应该被重新应用到其余的源文件。
其次 – 自CMake v3.0以来,目标可以指定INTERFACE_COMPILE_OPTIONS
。 这意味着目标的依赖关系可以通过INTERFACE_COMPILE_OPTIONS
添加或覆盖目标的COMPILE_OPTIONS
。 所以你还需要迭代遍历所有目标的依赖关系(不是一个特别容易的任务,因为目标的LINK_LIBRARIES
列表也可以包含生成器expression式)来查找正在应用问题标志的任何应用程序,并尝试将其从那些目标也是INTERFACE_COMPILE_OPTIONS
。
在这个复杂的阶段,我会考虑向CMake提交一个补丁,以提供从源文件中无条件移除特定标志的function。
1:请注意,与源文件上的COMPILE_FLAGS
属性不同,目标上的COMPILE_FLAGS
属性已弃用。