How to set compiler options with CMake in Visual Studio 2017 : <p>Visual Studio 2017 comes with full CMake integration. To learn about this combination, I was starting with this basic sample:</p>

<pre><code># CMakeLists.txt
cmake_minimum_required(VERSION 3.8)
project(foo)
add_executable(foo foo.cpp)
</code></pre>

<p>and</p>

<pre><code>// foo.cpp
int main() {}
</code></pre>

<p>This properly generates build scripts, and compiles and links with no issues. That was easy.</p>

<p>Trying to set compiler options, on the other hand, turned out to be anything but trivial. In my case I was attempting to set the warning level to 4.</p>

<p>The obvious solution</p>

<pre><code>add_compile_options("/W4")
</code></pre>

<p>didn't pan out as expected. The command line passed to the compiler now contains both <code>/W4</code> (as intended) as well as <code>/W3</code> (picked up from somewhere else), producing the following warning:</p>

<blockquote>
<pre><code>cl : Command line warning D9025: overriding '/W3' with '/W4'
</code></pre>
</blockquote>

<p>To work around this, I would need to <em>replace</em> any incompatible compiler option(s) instead of just adding one. CMake does not provide any immediate support for this, and the standard solution (as <a href="https://stackoverflow.com/q/2368811/1889329">this Q&amp;A suggests</a>) seems to be:</p>

<pre><code>if(CMAKE_CXX_FLAGS MATCHES "/W[0-4]")
    string(REGEX REPLACE "/W[0-4]" "/W4" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
else()
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4")
endif()
</code></pre>

<p>This, however, has two issues:</p>

<ul>
<li>It sets the global <code>CMAKE_CXX_FLAGS</code>, applying to all C++ targets. This may not be intended (not an issue for me right now).</li>
<li>It doesn't scale. For every compiler option to add, you would have to read up on incompatible options, and manually strip those first. This will inevitably fail<sup>1</sup>.</li>
</ul>

<p>My question is two-fold:</p>

<ol>
<li>Where does the CMake integration pick up default settings from, and can this be controlled?</li>
<li>How do you set compiler options in general? (If this is too broad a topic, I'd be happy for help on setting the warning level only.)</li>
</ol>

<p><hr/>
<sup>1</sup> <em>Incidentally, the solution I replicated fails to account for the <code>/Wall</code> option, that is incompatible with <code>/W4</code> as well.</em></p>
