[CMake] How to change (and account for) default Visual Studio compiler flags

Jason Heeris jason.heeris at gmail.com
Thu Jun 28 01:19:06 EDT 2018


I'm using CMake (3.12 currently) in Windows 10 to build a DLL to be
compatible with what an existing program expects. To this end, I need
near-total control over the compiler and linker flags used to generate that
DLL.

I created a very simple project, with a single compilation unit, main.c,
containing

int main(void) { return 0; }

My CMakeLists.txt started off containing only:

cmake_minimum_required(VERSION 3.8)
add_executable(main "main.c")

I then generated the build files for Visual Studio 2017 and ran "cmake
--build .". The cl.exe contained a number of flags, presumably sensible
defaults for VS 2017. I have no issue with that. But now I want to change
those flags, starting with removing all of them completely. Obviously not
super useful, but at this point I just want to know how to start from a
clean slate.

Adding target_compile_options() won't work because it just appends to the
defaults. Also totally understandable, but not what I need here.

I tried adding this to CMakeLists.txt:

set_target_properties(main PROPERTIES COMPILER_OPTIONS "")

I still end up with a bunch of compiler flags. So I try:

set(CMAKE_C_FLAGS "")
set(CMAKE_C_FLAGS_DEBUG "")

I'm not 100% that the latter is relevant, because I think the "_DEBUG"
affects the build *type* (a Makefile generator thing) and not the build
*configuration* (a VS thing). But I try it anyway. I still get lots of
compiler flags. Specifically, at this point I have:

/c /nologo /W1 /WX- /diagnostics:classic /O2 /Oy- /D
"CMAKE_INTDIR=\"Debug\"" /D _MBCS /Gm- /MD /GS /fp:precise /Zc:wchar_t
/Zc:forScope /Zc:inline /Fo"main.dir\Debug\\" /Fd"main.dir\Debug\vc141.pdb"
/Gd /TC /analyze- /FC /errorReport:queue

Some flags I recognise as perfectly harmless, others could in theory be
overridden by appending contrasting flags. However some like /fp:precise
have (AFAIK) a real effect on code generation. Others might not have an
override, or might produce warnings if overridden.

Finally, I try something I saw on Stackoverflow[1]. I create a file
"ClearVS.cmake":

if (MSVC)
    set(CMAKE_C_FLAGS_INIT "")
    set(CMAKE_CXX_FLAGS_INIT "")
    set(CMAKE_C_FLAGS_DEBUG_INIT "")
    set(CMAKE_CXX_FLAGS_DEBUG_INIT "")
endif()

In my CMakeLists.txt I add:

set(CMAKE_USER_MAKE_RULES_OVERRIDE "ClearVS.cmake")

...right after cmake_minimum_required(). The compiler flags remain.

So I have two questions:

1. How do I clear default compiler flags for the Visual Studio generator? I
would strongly prefer a solution that can apply to specific targets, but if
not, so be it.

2. How do I... I guess, research this behaviour? Where is it documented,
what these default flags are, where they come from eg. which ones apply to
all build types, which ones are there because I selected Debug instead of
Release, which ones are there because it's VS 2017 not VS 2015, etc?

Again, let me emphasise that I absolutely get the need for a set of
sensible default (and build type-specific) flags. It's a good thing that
CMake has this. But in my situation, I need a bit more control.

- Jason

[1] https://stackoverflow.com/a/46000520/188535
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://cmake.org/pipermail/cmake/attachments/20180628/9d372de8/attachment.html>


More information about the CMake mailing list