CMake and Visual Studio

CMake produces Visual Studio solutions seamlessly. This post will map CMake commands to the Visual Studio IDE with an example which makes learning much easier. It is primarily intended for a C++ developer using Visual Studio. Most references here is based on Visual Studio 2010 but will apply equally well to other versions. Continuing from the preface CMake for Visual Studio Developers.

Visual Studio to CMake Mapping
    Source Structure
    Execute CMake
    Visual Studio Solution Explorer View
    Build and Run
    CMakeLists.txt Details
CMake pre-defined projects
Debug and Release Configurations


A short background on the CMake philosophy. Typically source should be considered as any files that are explicitly modified by the developer. Anything that is or can be consistently generated from the source files should be considered as output of the build process. A build will always generate a lot of temporary/intermediate files and to avoid polluting the actual source, it is recommended to have out of source builds.

Other than the typical intermediate files like .obj, Visual Studio produces many more transient files including .sln, .sbr, .suo, .vcxproj.user, .vcxproj.filters. These need not (and should not) be checked into the source repository as sometimes they are large and user specific.

A Visual Studio developer might consider the project file (.vcproj) as a “source” since it involves adding, removing source files and modifying dependencies etc. However, with CMake you can consider this to be an intermediate file too, as CMake will generate it and is recommended for it to be outside the source directory.

In a CMake build system, the build “rules” or “project settings” are defined in text files called CMakeLists.txt.

Visual Studio to CMake Mapping

Some common Visual Studio project operations and settings and its mapping to CMake is listed below as an overview.

Visual Studio CMake Command
Solution file (.sln) project
Project file (.vcproj) target name in the command add_executable or add_library
executable (.exe) add_executable
static library (.lib) add_library
dynamic library (.dll) add_library(SHARED)
Source Folders source_group
Project Folders set_property(TARGET PROPERTY FOLDER )
Properties->C/C++->Preprocessor->Preprocessor Definitions add_definitions
Properties->C/C++->General->Additional Include Directories include_directories
Properties->Linker->General->Additional Library Directories link_directories
Properties->Linker->Input->Additional Dependencies target_link_libraries


The CMake tutorial from is a very simple example. Please refer to it if you are not familiar with the basics. Here it has been enhanced to show specific aspects commonly used on Windows.
The example code can be accessed via GitHub at For those not familiar with GitHub, the same example code is in a 7z file. Right mouse click on tutorial-7z.jpg, Save Link As on to disk, rename it as Tutorial.7z and extract the zip file for the sources.

Source Structure

   |-- app
   |   |-- CMakeLists.txt
   |   |-- main.cxx
   |-- math
   |   |-- advanced
   |   |   |-- AdvancedFunctions.cxx
   |   |   |-- AdvancedFunctions.h
   |   |-- simple
   |   |   |-- SimpleFunctions.cxx
   |   |   |-- SimpleFunctions.h
   |   |-- CMakeLists.txt
   |   |-- MathExports.h
   |-- CMakeLists.txt

Execute CMake

As recommended earlier, for an out of source build, create a directory where CMake will produce the required Visual Studio Project files and a lot of CMake specific files.

D:\tmp\CMake-VisualStudio-Example> mkdir _build

Make the build directory the current working directory.

D:\tmp\CMake-VisualStudio-Example> cd _build

Run the CMake command and specify where to find the first(root) CMakeLists.txt. In this case ".." is used to indicate one directory up from the current working directory. The -G option specifies it to generate a Visual Studio 2010 Win64 project files.

D:\tmp\CMake-VisualStudio-Example\_build> cmake .. -G "Visual Studio 10 Win64"

Note that other Visual Studio (e.g. VS 2012, VS 2013, VS 2015) generators can be specified. Use cmake --help to see the full list.

Visual Studio 11 2012 = Generates Visual Studio 11 (VS 2012) project files
Visual Studio 12 2013 = Generates Visual Studio 12 (VS 2013) project files
Visual Studio 14 2015 = Generates Visual Studio 14 (VS 2015) project files

The Visual Studio solution file will be created in the _build directory.

Visual Studio Solution Explorer View

Open the solution file in Visual Studio.

Build and Run

Build the solution in Visual Studio. The output binary files (app.exe, math.dll) from the build are created under their own sub-directories in the _build directory. So you will not be able to run the executable in this state because it will not be able to find math.dll

This is where install comes into play. Build INSTALL.vcproj as it does not get built as part of the solution. This project copies the binaries to _build\bin\ directory.

The executable can now be run in a command window.

D:\tmp\CMake-VisualStudio-Example\_build\bin> app.exe 200
The sum of 200 and 200 is 400
The square root of 200 is 14.1421
⚠ Note that project ALL_BUILD is the default “Startup Project”. This is never the case for debugging. So right click on the executable project (app in this case) and select as “Startup Project”.

⚠ To run/debug it from Visual Studio, the properties on the executable project (app in this case), must be changed.
Set Properties->Debugging->Command to ..\bin\app.exe.
Set Properties->Debugging->Command Arguments to 200


Invoking CTest from the build directory will run the tests. Alternatively, the tests can be run within the Visual Studio environment by right click “Build” on the RUN_TESTS project and the test run report will be displayed in the output window.

Test project D:/tmp/CMake-VisualStudio-Example/_build
    Start 1: AppTest1
1/3 Test #1: AppTest1 .........................   Passed    0.00 sec
    Start 2: AppTest2
2/3 Test #2: AppTest2 .........................   Passed    0.00 sec
    Start 3: AppTest3
3/3 Test #3: AppTest3 .........................   Passed    0.00 sec

100% tests passed, 0 tests failed out of 3

Total Test time (real) =   0.03 sec

CMakeLists.txt Details

The comments in each line provides more details about each CMake command.

File: CMake-VisualStudio-Example/CMakelist.txt

cmake_minimum_required (VERSION 2.6)

# Maps to Visual Studio solution file (Tutorial.sln)
# The solution will have all targets (exe, lib, dll) 
# as Visual Studio projects (.vcproj)
project (Tutorial)

# Turn on the ability to create folders to organize projects (.vcproj)
# It creates "CMakePredefinedTargets" folder by default and adds CMake
# defined projects like INSTALL.vcproj and ZERO_CHECK.vcproj

# Set compiler flags and options. 
# Here it is setting the Visual Studio warning level to 4

# Command to output information to the console
# Useful for displaying errors, warnings, and debugging
message ("cxx Flags:" ${CMAKE_CXX_FLAGS})

# Sub-directories where more CMakeLists.txt exist
add_subdirectory (math)

# Turn on CMake testing capabilities

# Add test cases
add_test(AppTest1 ${PROJECT_BINARY_DIR}/bin/app.exe 100)
add_test(AppTest2 ${PROJECT_BINARY_DIR}/bin/app.exe 200)
add_test(AppTest3 ${PROJECT_BINARY_DIR}/bin/app.exe 300)

File: CMake-VisualStudio-Example/math/CMakeLists.txt

# Collect sources into the variable MATH_SOURCES without
# having to explicitly list each header and source file.
# CMake documentation states "We do not recommend using GLOB to collect a
# list of source files from your source tree. If no CMakeLists.txt file
# changes when a source is added or removed then the generated build system
# cannot know when to ask CMake to regenerate".

# Collect sources into the variable SIMPLE_FUNCTION_SOURCES

# The recommended way to collect sources in variable 
# ADVANCED_FUNCTION_SOURCES by explicitly specifying the source files

# Create named folders for the sources within the .vcproj
# Empty name lists them directly under the .vcproj
source_group("" FILES ${MATH_SOURCES})
source_group("simple" FILES ${SIMPLE_FUNCTION_SOURCES})
source_group("advanced" FILES ${ADVANCED_FUNCTION_SOURCES})

# Properties->C/C++->General->Additional Include Directories
include_directories (.)

# Set Properties->General->Configuration Type to Dynamic Library(.dll)
# Creates math.dll with the listed sources collected in the variables
# Also adds sources to the Solution Explorer
add_library(math SHARED ${MATH_SOURCES} 

# Creates folder "libraries" and adds target project (math.vcproj)
set_property(TARGET math PROPERTY FOLDER "libraries")

# Adds logic to INSTALL.vcproj to copy math.dll to destination directory
install (TARGETS math

File: CMake-VisualStudio-Example/app/CMakeLists.txt

# Properties->C/C++->General->Additional Include Directories
include_directories ("${PROJECT_SOURCE_DIR}/Math")

# Set Properties->General->Configuration Type to Application(.exe)
# Creates app.exe with the listed sources (main.cxx)
# Adds sources to the Solution Explorer
add_executable (app main.cxx)

# Properties->Linker->Input->Additional Dependencies
target_link_libraries (app math)

# Creates a folder "executables" and adds target 
# project (app.vcproj) under it
set_property(TARGET app PROPERTY FOLDER "executables")

# Adds logic to INSTALL.vcproj to copy app.exe to destination directory
install (TARGETS app

CMake pre-defined projects

To add some CMake functionality to the Visual Studio environment, it creates a few project files which can be ignored for the most part. In any case, a brief description is given below.

INSTALL CMake install specification. It is simulating the Linux make install so it has to be manually built after the full build.
RUN_TESTS CMake test specification. This project will enable running tests in Visual Studio and the test run report will be shown in the output window
ZERO_CHECK Used to make sure that the project files are up-to-date with respect to the CMakeLists.txt files
ALL_BUILD Builds all projects with its dependency order

Debug and Release Configurations

Visual Studio supports multiple configurations in a single project file and creates a per-configuration directory. CMake generates four configurations by default: Debug, Release, MinSizeRel and RelWithDebInfo.

See the link for changing the default.
CMake Wiki: How can I specify my own configurations (for generators that allow it) ?


CMake is a better build system than Visual Studio projects and solutions. It is compact and much more easier to maintain even for a Windows only projects.

Hope the the document is useful. Feel free to comment if you need any clarifications or further information.



  1. Thanks a lot.
    As a beginner of cmake learning, I found the learning material is rare. Could you recommend me what material and procedure is helpful to learn cmake?
    Thank you in advance!

  2. I’ve been struggling with the cmake basics with VS10 for over a day now. Your tutorial finally got me out of the ditch I was stuck in. Thank you so much! Your one line *Note that project ALL_BUILD is the default “Startup Project”. This is never the case for debugging. So right click on the executable project (app in this case) and select as “Startup Project” finally put it all together. I never thought to check the startup project. ARGH!!!!
    Keep up the great info please!

    1. Glad it helped. I had spent days to figure out the “Startup Project”, so that is why I added the note. Based on your feedback, I have made that information a little more visible (rather than a minor side note).

  3. In Windows is there an equivalent command to the ‘make install DESTDIR=’ function that cmake provides on linux? I’m wondering about how to package and deploy my dll and exe files that are built in in the solution using cmake.

    1. If you have INSTALL command in your CMake file, it will generate INSTALL.vcxproj in the build folder which will have install instructions. For valid reasons, INSTALL.vcxproj is excluded when building the solution by Visual Studio.
      To emulate Linux make install you could create a Windows batch file to first build the solution and then build the INSTALL project.

      devenv /Build Debug INSTALL.vcxproj
      devenv.exe Tutorial.sln /Build Debug /Project INSTALL
    2. Hi there,

      yes there is an equivalent cmake command for this:

      cmake -DCMAKE_INSTALL_PREFIX={install_path}

      Also as a sidenote, if you want to build and install in one command regardless of the cmake generator, use the following:

      cmake --build . --target install --config Release

      This must be run in the build directory. Also the option –config Release only makes sense for IDE style generators (Visual Studio, XCode etc), but it doesn’t hurt even when using make style generators. To get make generators to do the same (release build) use -DCMAKE_BUILD_TYPE=Release

      1. Good suggestion.
        Please do keep in mind the following.

        “If a full path (with a leading slash or drive letter) is given it is used directly. If a relative path is given it is interpreted relative to the value of CMAKE_INSTALL_PREFIX”

        Note that the example in the post uses absolute path for the install destination.

  4. 2 corrections:

    1. Your example for
    cmake ..\.. -DCMAKE_BUILD_TYPE=Release -G “Visual Studio 10 Win64”
    is very misleading. The VS generators ignore DCMAKE_BUILD_TYPE, as it builds a solution that includes both debug and release configurations. Thus, the command-line string you give, should never be used.

    2. File GLOBbing should not be used, it’s bad practice. Please don’t give this bad example.

    1. Thanks for the feedback.

      1. You are right, -DCMAKE_BUILD_TYPE is valid only for single configuration systems and has been corrected.
      CMake wiki: How can I build multiple modes without switching ?

      2. I have noted the caveat with GLOBbing as per the CMake documentation.

      “We do not recommend using GLOB to collect a list of source files from your source tree. If no CMakeLists.txt file changes when a source is added or removed then the generated build system cannot know when to ask CMake to regenerate”

      However, it is still useful as long as you know the limitation and often allows you to jump start in using/migrating the CMake system.

  5. Thanks for the tutorial. I went through it and got “The program can’t start because math.dll is missing from your computer. Try reinstalling the program to fix this problem.”

    My cmake_test directory contains:
    1. app directory
    2. build directory
    3. math directory
    4. CMakeLists.txt
    6. TutorialConfig.h.i.n

    Any ideas on how to resolve this problem?

  6. Hi,

    Excuse me if the topic is not appropriate for this group (I do not find any
    other forum for this question yet). We have an old PC which was installed a
    MSVC project. This project was generated from a Cmake file suite. The project
    can be built well on this computer. Now, I have a new PC and want to run this
    project too. First of all, I install Cmake to this new PC. Then, I copy all
    the MSVC project from the old PC to this new PC. there are three Cmake folder in the MSVC


    MSVC building has these errors:

    1>—— Build started: Project: ZERO_CHECK, Configuration: Debug Win32 —-
    2>—— Skipped Build: Project: RUN_TESTS, Configuration: Debug Win32 —-
    2>Project not selected to build for this solution configuration
    1>C:\Program Files(x86)\MSBuild\Microsoft.Cpp\v4.0\Platforms
    error MSB8008: Specified platform toolset (v110) is not installed or invalid.
    Please make sure that a supported PlatformToolset value is selected.
    3>—— Build started: Project: wws-lxc, Configuration: Debug Win32 —
    4>—— Build started: Project: wws-lxd2, Configuration: Debug Win32 —
    5>—— Build started: Project: wws-lxdd, Configuration: Debug Win32 —-

    I have read a few Cmake tutorials, but it does not help yet. Because I am in
    a hurry to make it work. Could you help me on these questions?

    1. Whether it is possible to copy a Cmake generated MSVC 10.0 project from a
    computer to another computer?
    2. If some manual modifications are needed, what should I do to make it work?

    Thanks in advance,

    1. This is probably not the best forum for this question but will try to help.

      Generally, it’s not a good idea to copy the vcproj files. You should instead regenerate the project using CMake. Do you have the original CMake files (CMakeLists.txt) in the source? If so, you should be able to regenerate the project files for the new machine.

      If at all you want to reuse a vcproj files there may be a number of things that needs to be changed. First, do you have the same compiler installed on the new machine as the old one?

  7. “To run/debug it from Visual Studio, the Properties->Debugging->Command default must be changed to the executable in the _install directory.”
    Could you please clarify this ?
    do you mean the executable (in this case is app), right click on app-> property->Debugging->Command ..change to folder INSTALL ? (which file in the folder INSTALL ? )

  8. Thanks for such a very well structured explanation, I have been using cmake on linux and Mac over few years but there are few things in your tutorial I was unfamiliar. Moreover just switching to windows for cross platform development I was looking for a quick sneak in VS and CMAKE and you have done a great job. Keep up with good work.

  9. Hi,

    I’m configurating Cmake 3.4.3 with Visual Studio C++ 2010 Express, but Cmake has an error:

    CMake Error at cmake/Modules/Geant4MacroLibraryTargets.cmake:69 (target_compile_features):
    The compiler feature “cxx_alias_templates” is not known to CXX compiler


    version 16.0.30319.1.
    Call Stack (most recent call first):
    cmake/Modules/Geant4MacroLibraryTargets.cmake:300 (GEANT4_LIBRARY_TARGET)
    source/analysis/CMakeLists.txt:30 (GEANT4_GLOBAL_LIBRARY_TARGET)

    CMake Error at cmake/Modules/Geant4MacroLibraryTargets.cmake:94 (target_compile_features):
    The compiler feature “cxx_alias_templates” is not known to CXX compiler


    Configuring download of missing dataset G4NDL (4.5)
    Configuring download of missing dataset G4EMLOW (6.48)
    Configuring download of missing dataset PhotonEvaporation (3.2)
    Configuring download of missing dataset RadioactiveDecay (4.3)
    Configuring download of missing dataset G4NEUTRONXS (1.4)
    Configuring download of missing dataset G4PII (1.3)
    Configuring download of missing dataset RealSurface (1.0)
    Configuring download of missing dataset G4SAIDDATA (1.1)
    Configuring download of missing dataset G4ABLA (3.0)
    Configuring download of missing dataset G4ENSDFSTATE (1.2)
    CMake Warning at C:/Program Files/CMake/share/cmake-3.4/Modules/InstallRequiredSystemLibraries.cmake:440 (message):
    system runtime library file does not exist:
    Call Stack (most recent call first):
    cmake/Modules/Geant4CPackBase.cmake:9 (include)
    CMakeLists.txt:147 (include)

    The following Geant4 features are enabled:
    GEANT4_BUILD_CXXSTD: Compiling against C++ Standard ’11’

    Configuring incomplete, errors occurred!
    See also “E:/GEANT4/geant4_10_02_build/CMakeFiles/CMakeOutput.log”.
    See also “E:/GEANT4/geant4_10_02_build/CMakeFiles/CMakeError.log”.

    Any ideas on how to resolve this problem?
    Thanks so much!

    1. You may already be aware that VS Express is a “basic” version of the full professional environment. My guess is that some expected compiler features are not supported in VS Express. Having said that, this question is more appropriate in a forum like StackOverflow where you may get a more definitive answer.

    1. Visual Studio can have a user settings file vcxproj.user which can define these properties.

      In the CMakeLists.txt, copy this predefined vcxproj.user to the build directory using CONFIGURE_FILE command.

  10. Cmake with Visual Studio seems to work fine . But does Cmake work the same with CodeBlocks on Windows system? If yes can I know what is the Cmake generator for Codeblocks on windows

  11. Hi;

    Thanks for the tutorial.
    I trid it under linux with cmake version 3.5.1.
    Solely thing I found was:

    # Add test cases
    if(NOT UNIX)
    add_test(AppTest1 ${PROJECT_BINARY_DIR}/bin/app.exe 100)
    add_test(AppTest2 ${PROJECT_BINARY_DIR}/bin/app.exe 200)
    add_test(AppTest3 ${PROJECT_BINARY_DIR}/bin/app.exe 300)
    else(NOT UNIX)
    # Linux:
    add_test(AppTest1 ${PROJECT_BINARY_DIR}/app/app 100)
    add_test(AppTest2 ${PROJECT_BINARY_DIR}/app/app 200)
    add_test(AppTest3 ${PROJECT_BINARY_DIR}/app/app 300)
    endif(NOT UNIX)

    1. That’s a good observation. Alternatively, instead of
      if (NOT UNIX)
      you could also use
      if (WIN32)

      Do keep in mind that every now and then, differences (some quite subtle) have to be managed between Windows and Linux.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s