Override compile flags for single files
Your attempts above are adding further flags to your file/target rather than overwriting as you seem to expect. For example, from the docs for Properties on Source Files - COMPILE_FLAGS:
These flags will be added to the list of compile flags when this source file builds.
You should be able to countermand the -Weffc++
flag for foo.cpp by doing
set_source_files_properties(foo.cpp PROPERTIES COMPILE_FLAGS -Wno-effc++)
This should have the effect of adding -Wno-effc++
after -Weffc++
in the compiler command, and the latter setting wins. To see the full command and check that this is indeed the case, you can do
make VERBOSE=1
As an aside, one of the maintainers of the GNU C++ Standard Library presents a pretty negative opinion on -Weffc++
in this answer.
Another point is that you're misusing add_definitions
in the sense that you're using this for compiler flags rather than the intended preprocessor definitions.
It would be preferable to use add_compile_options
add_compile_options(-Wall -Weffc++ -pedantic -std=c++0x)
or for CMake versions < 3.0 to do something more like:
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Weffc++ -pedantic -std=c++0x")
In response to further questions in the comments below, I believe it's impossible to reliably remove a flag on a single file. The reason is that for any given source file, it has the COMPILE_OPTIONS
and COMPILE_FLAGS
1 of its target applied, but these don't show up in any of the properties for that source file.
You could look at stripping the problem flag from the target's COMPILE_OPTIONS
, then applying it to each of the target's sources individually, omitting it from the specific source file as required.
However, while this could work in many scenarios, it has a couple of problems.
First - source files' properties don't include COMPILE_OPTIONS
, only COMPILE_FLAGS
. This is a problem because the COMPILE_OPTIONS
of a target can include generator expressions, but COMPILE_FLAGS
doesn't support them. So you'd have to accommodate generator expressions while searching for your flag, and indeed you'd maybe even have to "parse" generator expressions if your flag was contained in one or more to see whether it should be re-applied to the remaining source files.
Second - since CMake v3.0, targets can specify INTERFACE_COMPILE_OPTIONS
. This means that a dependency of your target can add or override your target's COMPILE_OPTIONS
via its INTERFACE_COMPILE_OPTIONS
. So you'd further have to recursively iterate through all your target's dependencies (not a particularly easy task since the list of LINK_LIBRARIES
for the target can also contain generator expressions) to find any which are applying the problem flag, and try and remove it from those targets' INTERFACE_COMPILE_OPTIONS
too.
At this stage of complexity, I'd be looking to submit a patch to CMake to provide the functionality to remove a specific flag unconditionally from a source file.
1: Note that unlike the COMPILE_FLAGS
property on source files, the COMPILE_FLAGS
property on targets is deprecated.
CMake per file optimizations
You can't overwrite compiler options with the makefile
CMake generators on source file level. Options are always appended (see my answer at Is Cmake set variable recursive? for the complete formula).
This is - as far as I know - only supported with the Visual Studio
solution/project generators. These generators have flag tables to identify flags that are in the same group/that does overwrite a previous defined flag.
So yours is more like a feature request to also add compiler option tables to CMake's makefile
generators.
Alternatives
I just wanted to add some crazy CMake magic I came up with as a workaround. Add the following to your main CMakeLists.txt
after the project()
command:
if (CMAKE_BUILD_TYPE)
define_property(
SOURCE
PROPERTY COMPILE_FLAGS
INHERITED
BRIEF_DOCS "brief-doc"
FULL_DOCS "full-doc"
)
string(TOUPPER ${CMAKE_BUILD_TYPE} _build_type)
set_directory_properties(PROPERTIES COMPILE_FLAGS "${CMAKE_CXX_FLAGS_${_build_type}}")
set(CMAKE_CXX_FLAGS_${_build_type} "")
endif()
This example moves the CMAKE_CXX_FLAGS_<build type>
content into an new COMPILE_FLAGS
directory property that is then linked to COMPILE_FLAGS
source file property via define_property(... INHERITED ...)
.
Now the build type specific flags are only defined in COMPILE_FLAGS
for each source file and you can overwrite/change them e.g. with the code snippet from your example:
set_source_files_properties(
hello.c
PROPERTIES
COMPILE_FLAGS -O0
)
References
- Directory properties and subdirectories
- CMake: How do I change properties on subdirectory project targets?
Related Topics
What Exactly Is an 'Aligned Pointer'
Is There Any Lame C++ Wrapper\Simplifier (Working on Linux MAC and Win from Pure Code)
Program Behaving Strangely on Online Ides
Determining Exception Type After the Exception Is Caught
Does New[] Call Default Constructor in C++
Popen Simultaneous Read and Write
C++: Deep Copying a Base Class Pointer
Configuring the Gcc Compiler Switches in Qt, Qtcreator, and Qmake
How Is Vector Implemented in C++
Are There Any MACros to Determine If My Code Is Being Compiled to Windows
How to Make a Heterogeneous Boost::Map
"Launch Failed. Binary Not Found." Snow Leopard and Eclipse C/C++ Ide Issue
Should I Copy an Std::Function or How to Always Take a Reference to It
How Large Is a Dword with 32- and 64-Bit Code
Determine If Type Is a Pointer in a Template Function