4

I am trying to learn CMake with a simple project. This is my sample CMakeLists.txt

cmake_minimum_required(VERSION 3.11 FATAL_ERROR)
set(PROJECT_NAME "MyLib" CXX)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
project(${PROJECT_NAME})

include(${CMAKE_SOURCE_DIR}/Sources.cmake) 
set(SOURCE_FILES ${COMMON_CPP_FILES} ${COMMON_H_FILES})

include_directories(include)

add_compile_options("$<$<CONFIG:Debug>:/EHa /MTd /W3 /w14640>")

add_library(${PROJECT_NAME} STATIC ${SOURCE_FILES})

I tried to create a Visual Studio project based on this file but I cannot figure out how to properly set the compile flags. When I open Visual Studio I can see the flags (/EHa) as part of "Additional Options" but I can still see the default (/EHsc) flags.

enter image description here

Why the default flags are still there and how can I make sure the compiler is really using the flags that I have specified?

Ali
  • 1,001
  • 2
  • 14
  • 32
  • 1
    You are on the right track. There is just the fact that you should use one flag per generator expression or you have to use `;` semicolons instead of spaces to make it a list of options (otherwise it get's quoted and interpreted as a single command line option). So in your case it should work with `$<$:/EHa;/MTd;/W3;/w14640>`. – Florian Jun 23 '18 at 21:15
  • @Florian According to [this](https://stackoverflow.com/questions/23995019/what-is-the-modern-method-for-setting-general-compile-flags-in-cmake) answer, it's better to use `target_compile_options`. However when I use `target_compile_options` I noticed that the flags are not replaced and are simply added and I am getting warnings when I use ninja, as mentioned [here](https://cmake.org/pipermail/cmake/2010-January/034717.html). However when I use `add_compile_options` I do not get any warnings as it seems this command is smarter and actually replaces instead of adding. Which one do you suggest? – Ali Jul 25 '18 at 02:49

1 Answers1

2

You can check what default flags CMake uses by printing CMAKE_CXX_FLAGS and CMAKE_CXX_FLAGS_{RELEASE|DEBUG}. Setting these variables with something like

set(CMAKE_CXX_FLAGS "") 

will not clear them however.

The only way I've found to do what you are saying (clear specific default flags) is something like this for every default flag:

string(REPLACE "/EHsc" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
string(REPLACE "/RTC1" "" CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}")

Why you cannot clear all the default flags easily and without this syntax is beyond me, however.

Dan Ganea
  • 540
  • 4
  • 18
  • 4
    I have been doing something similar but there is so much hype about "Modern CMake" everywhere and how it is not good practice to manually play with `CMAKE_CXX_FLAGS` that I was hoping something as simple as setting the flags is finally sorted out. – Ali Jun 23 '18 at 21:14