Compiler Flags from CMakeLists.txt don't appear in CMake-Gui or CMakeCache.txt

11,486

Solution 1

The flags you specified in the CMakeLists.txt file are probably correctly used by the compiler. You can't see them directly in CMakeCache.txt but:

  1. You can see command lines by running make VERBOSE=1 instead of standard make
  2. Also, you can set CMAKE_VERBOSE_MAKEFILE to 1 to enable printing of commands (this can be found by checking "Advanced" in CMake GUI)
  3. As @Angew said, if you really want to see the updated flags in the CMake GUI, set your variables with CACHE FORCE

As an example, i use this kind of configuration in a project for some month, and never had problem:

if(MSVC) # MSVC compiler (Win32 only)
    # Display more warnings
    set(CMAKE_CXX_FLAGS "/W3")
elseif(UNIX OR CMAKE_COMPILER_IS_GNUCXX) # Clang OR Gcc (Linux, Mac OS or Win32 with MingW)
    # Enable C++11 and displays all warnings
    set(CMAKE_CXX_FLAGS "-Wall -std=c++11")
    if(APPLE) # Clang / Mac OS only
        # Required on OSX to compile c++11
        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++ -mmacosx-version-min=10.7")
    endif(APPLE)
endif()

Update:

Starting with CMake 3.0, you can replace set(CMAKE_CXX_FLAGS "...") by add_compile_options(-std=c++11)

CMake 3.1 introduced a new syntax to configure the compiler with specific C++ version:

set(CMAKE_CXX_STANDARD 11)

Solution 2

You can first, set the variable to a value only if it is not in cache already. The last parameter is the description which we don't need since we'll override it anyway.

set(VARIABLE "Hello World!" CACHE STRING "")

Then force the value into cache using its existing value from the line above. Since that is cached, users can still change the variable and it won't be set back every time.

set(VARIABLE ${VARIABLE} CACHE STRING "Description." FORCE)

This is a bit hacky in CMake as you can see, but it works reliably.

Share:
11,486
Schnigges
Author by

Schnigges

Updated on July 19, 2022

Comments

  • Schnigges
    Schnigges almost 2 years

    I just started to learn CMake and thought I would have understood the basic process of first writing the CMakeLists.txt, then configuring to generate the CMakeCache.txtand at the end generating the Makefiles.

    However, when I try to apply it to the following CMakeLists.txt, I'm not getting the expected results and I'm not sure what is going wrong. Part of the CMakeLists.txt looks like this:

    # compiler flags
    if (CMAKE_COMPILER_IS_GNUCXX)
        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -fpermissive -Wall -Wformat-security")
        if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 4.8)
            set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unused-local-typedefs")
        endif()
    endif()
    

    Since I'm using gcc/g++ 4.7.3, the compiler flags from the first if-statement should be set. But if I configure this with CMake-Gui, there are no compiler flags pre-defined whatsoever. The same happens when I out-comment the if-statements and just keep the set(CMAKE_CXX_FLAGS ...). When searching the CMakeCache.txt for any -std=c++11 flags, I don't get any results, too.

    Why does this happen? What's the point of specifying compiler flags inside the CMakeLists.txt when they aren't used? Or am I getting something completely wrong and they are used, but then I don't know why and how I could check.

    When generating the actual (Eclipse CDT) project with make and importing it to Eclipse, I'm getting error messages that C++11 features can't be resolved, the __cplusplus macro contains the value 199711 so the -std=c++11 flag is obviously not used.

  • bhaller
    bhaller almost 6 years
    This answer seems to be true; I can see the flags I requested when I do make VERBOSE=1. But it doesn't fully answer the OP's question: why do the specified flags not appear in CMakeCache.txt? What's the point of showing the flags strings in CMakeCache.txt if they're not actually accurate anyway and are set up by some sort of magic elsewhere? As someone learning cmake, I'd really like to understand what's actually going on here.
  • Antwane
    Antwane almost 6 years
    They do not appear in cache unless you set the variable with CACHE FORCE option (see point 3)
  • bhaller
    bhaller almost 6 years
    OK, but... why? What's the rationale behind this bizarre and confusing design? Neither your point 3 nor the page linked to actually explains what's going on, apart from documenting that "this is the way it is". I'm trying to actually understand cmake, not just use it by rote.
  • Antwane
    Antwane almost 6 years
    CMake does make a difference between normal variables, which are not kept across runs, and cache variables, which are persisted between 2 run of the processor. The linked page explains the differences between these 2 kind of variables.