Search code examples
c++cmakevisual-studio-2017conan

cmake and Visual Studio 15 2017 generator - defining a build type


I work on Windows 10. I use cmake with Visual Studio 15 2017 generator. CMakeLists.txt requires CMAKE_BUILD_TYPE to be defined because it is used by Conan command called from cmake (execute_process). Here is the cmake command:

cmake -DCMAKE_BUILD_TYPE=Release -G "Visual Studio 15 2017" ..

When I run build command this way:

cmake --build .

I get the following error:

error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MT_StaticRelease' doesn't match value 'MTd_StaticDebug' in Tests.obj

Conan installs a release library (MT_StaticRelease) but CMAKE_BUILD_TYPE is ignored during build. Building works when I use the following command:

cmake --build . --config Release

How does it work ? When I have to define --config buildType ? What with other generators, for example Ninja ?


Solution

  • Visual Studio is a multi-configuration system. It means that the build type is selected at build time, lets say when you are using the IDE, you can select at that time the Release or Debug configuration and build. So when you are generating the Visual Studio solution (project generation or configure step), with cmake -G "Visual Studio ...", CMake doesnt have a value for CMAKE_BUILD_TYPE.

    So the CMake invocations need to be different depending on the system:

    In multi-configuration environments like Visual Studio, you use just 1 build folder:

    $ mkdir build && cd build # assume we are in the folder containing CMakeLists.txt
    $ cmake .. -G "Visual Studio 15 2017 Win64" # Unless building for 32 bits, add the Win64 
    $ cmake --build . --config Release # Or open IDE, change config to Release and build 
    $ cmake --build . --config Debug
    

    In single-configuration environments like gcc with Makefiles, you need to use 1 folder for every configuration

    $ mkdir build_release && cd build_release # assume we are in the folder containing CMakeLists.txt
    $ cmake .. -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release
    $ cmake --build . 
    $ cd .. && mkdir build_debug && cd build_debug
    $ cmake .. -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Debug
    $ cmake --build . 
    

    A different issue is the definition of the MT (static) Visual Studio runtime. It is possible that you have defined in your Conan profile compiler.runtime=MT, or it is being set by your CMakeLists.txt directly. Conan doesn't install such static MT_StaticRelease library, it is part of Visual Studio. If you are trying to statically link the visual studio environment, your used profiles should look like:

    # for debug
    $ conan install .. -s build_type=Debug -s compiler.runtime=MTd
    # for release
    $ conan install .. -s build_type=Release -s compiler.runtime=MT